プログラミングの最近のブログ記事
以前にもブログで書いたRubyでHTMLファイル作成ですが、さらに改良しExcelの1行を1つのHTMLファイルに変換するプログラムを書きました。さらに、前回同様HTMLテンプレート機能も使用しています。Excelデータはタブ区切りテキストにします。
※プログラムはクリエイティブコモンズです。
YAMLも使ってみました。詳細は以下を参照。
config.yamlは以下の通り。
data.txtにタブ区切りテキストです。1行目のheader行の項目名をテンプレートファイル(template.rhtml)に設定すると項目が書く行の設定値でHTML生成します。また、1行目のid項目は必須でその項目値がHTMLファイル名になります。
※プログラムはクリエイティブコモンズです。
#!/usr/bin/ruby -Ks
require 'erb'
require 'yaml'
include ERB::Util
$KCODE = 's'
class CreateHtml
def initialize
@config = YAML.load_file("config.yaml")
@erb = ERB.new(File.read(@config[:template]), nil, "-")
end
def generate
objs = input
for obj in objs do
output(obj)
end
end
def input
objs = Array.new
count = 0
open(@config[:data]).each{|input|
if count == 0
@headers = input.split
count = 1
next
end
h = Hash.new
arr = input.split
@headers.size.times{|i|
h.store(@headers[i], arr[i])
}
objs.push(h)
}
return objs
end
def output(o)
open(@config[:output]+"/"+o['id']+".html", "w"){ |output|
output.write(@erb.result(binding()))
}
end
end
obj = CreateHtml.new
obj.generate
YAMLも使ってみました。詳細は以下を参照。
config.yamlは以下の通り。
:template: template.rhtml :data: data.txt :output: output
data.txtにタブ区切りテキストです。1行目のheader行の項目名をテンプレートファイル(template.rhtml)に設定すると項目が書く行の設定値でHTML生成します。また、1行目のid項目は必須でその項目値がHTMLファイル名になります。
あるディレクトリにあるログファイルのなかからエラー情報を抜き出し、指定したメールに送信するというプログラムを書きました。cron登録して毎日エラーチェックしています。サーバの都合上、Perl5.8.0でCPANは使用できず。Linux、EUC環境でログファイルはShift-JISという環境で動作しています。メールはsendmailを使用しています。
1度チェックしたファイルはbackupディレクトリに移動し、2度はチェックしないようになっています。
ソースはクリエイティブコモンズでお願いします。
1度チェックしたファイルはbackupディレクトリに移動し、2度はチェックしないようになっています。
ソースはクリエイティブコモンズでお願いします。
#!/usr/bin/perl
use strict;
use File::Copy;
require "mimew.pl";
require "jcode.pl";
my $ERROR_DIR = '/var/log/error';
my $BACK_UP = '/var/log/error/backup';
opendir(DIR, $ERROR_DIR) or die;
foreach (readdir(DIR)){
my $file = $_;
my $error = "";
next if $file =~ /^\./ ;
next if $file =~ /backup/ ;
open(FILE, $ERROR_DIR."/".$file ) or die;
foreach (){
$error .= $_ unless $_ =~ /,0,0,/;
}
close(FILE);
print $file."\n";
jcode::convert(\$error, 'euc', 'sjis');
if ( length($error) > 1 ){
sendmail($file, $error)
}
move $ERROR_DIR."/".$file, $BACK_UP."/".$file or die "move Error. $!";
}
closedir(DIR);
sub sendmail(){
my @arg = @_;
my $sendmail = '/usr/lib/sendmail';
my $to = "to\@example.com";
my $from = "from\@example.com";
my $subject = @arg[0];
my $body = @arg[1];
jcode::convert(\$body,'jis', 'euc');
jcode::convert(\$subject,'jis', 'euc');
$subject = mimeencode($subject);
open(MAIL,"| $sendmail -t");
print MAIL "To: $to\n";
print MAIL "From: $from\n";
print MAIL "Subject: $subject\n";
print MAIL "\n";
print MAIL "$body\n";
close(MAIL);
}
ブログの更新も大分滞っていました。仕事が忙しくてなかなかWebScrapも作成する時間があまり取れないんですよね。おおよそ機能はつくれたのでいくつか、忘れないようにメモしときます。
今回は、Railsのエラーメッセージを日本語化するというもの。
Ruby-GetTextを使うのが一般的のようですが、今回はそこまできっちり作らなくても良いかなと思いActiveHeartを使用しました。以下手順載せます。すごい簡単ですよ。
まず以前にSubversionをインストールしてますので、railsコマンドで生成したフォルダで以下実行。
これだけでエラーメッセージが日本語化します。すごく簡単ですよね。
テーブルのカラム名はそのままですので、その場合はmodelに以下設定をすればOK
set_field_namesでカラム名と表示文字列をマッピングする
これで日本語化はOKです。ちなみにActiveHeart自体は非推奨とされており、Ruby-GetTextを使用するようにコメントされていますね。確かにサービスのグローバル化を考えればその方が良いと思います。
私はActiveRecordのエラー文言を日本語にしたいだけでしたので他のモジュールはコメントアウトしました。
一応そちらも記載しておきます。
【参考サイト】
今回は、Railsのエラーメッセージを日本語化するというもの。
Ruby-GetTextを使うのが一般的のようですが、今回はそこまできっちり作らなくても良いかなと思いActiveHeartを使用しました。以下手順載せます。すごい簡単ですよ。
まず以前にSubversionをインストールしてますので、railsコマンドで生成したフォルダで以下実行。
$ ruby script/plugin install http://svn.rails2u.com/public/plugins/trunk/active_heart/ + ./active_heart/init.rb + ./active_heart/lib/active_record_messages_ja.rb + ./active_heart/lib/iso2022jp_mailer.rb + ./active_heart/lib/trans_sid.rb
これだけでエラーメッセージが日本語化します。すごく簡単ですよね。
テーブルのカラム名はそのままですので、その場合はmodelに以下設定をすればOK
set_field_namesでカラム名と表示文字列をマッピングする
例)
class Bookmark < ActiveRecord::Base
set_field_names :title => 'タイトル', :url => 'URL'
validates_presence_of :title, :url,
:message => "が未入力です"
end
これで日本語化はOKです。ちなみにActiveHeart自体は非推奨とされており、Ruby-GetTextを使用するようにコメントされていますね。確かにサービスのグローバル化を考えればその方が良いと思います。
私はActiveRecordのエラー文言を日本語にしたいだけでしたので他のモジュールはコメントアウトしました。
一応そちらも記載しておきます。
warn 'ActiveHeart is obsolute plugin!' warn 'Please use Ruby-GetText or jpmobile' require_dependency 'active_record_messages_ja'if defined? ActiveRecord::Base
# Comment Out!
#require_dependency 'trans_sid' #require_dependency 'iso2022jp_mailer' if defined? ActionMailer::Base
【参考サイト】
こちらもWebScrapアプリケーションを作成中に疑問に思ったので覚書として書きます。操作完了したら元URLへリダイレクトしようと思ったのですが別サイト(別ドメイン)へのリダイレクトを以下2つの方法で試しました。
renderメソッドでは外部サイトにはリダイレクトできず、redirect_toを使用したら上手くいきました。
参考プログラムは以下の通りです。
renderメソッドでは外部サイトにはリダイレクトできず、redirect_toを使用したら上手くいきました。
参考プログラムは以下の通りです。
if @item.save
flash[:notice] = 'Item was successfully created.'
redirect_to("http://www.sample.com/")
else
render :action => 'new'
end
以前に話した「WebScrap」を仕事終わってから、作成しているのですが、Webページをキャッシュする部分でDBに保存するのはリソース上やはり厳しいということで自分のGMailに送信することにしました。
これであれば、Web上にHTMLのキャッシュを残しておくことができ、さらに過去にキャッシュしたHTMLページのデータもGoogleの検索エンジンで見つけられます。
Railsで通常のメールを送信するのは、以前の記事(ActionMailer)に書きましたが、HTML形式のメール送信の方法は以下の通りです。
まずはemailオブジェクトを生成し、content_typeを設定してからメール送信すればOKですね。
これであれば、Web上にHTMLのキャッシュを残しておくことができ、さらに過去にキャッシュしたHTMLページのデータもGoogleの検索エンジンで見つけられます。
Railsで通常のメールを送信するのは、以前の記事(ActionMailer)に書きましたが、HTML形式のメール送信の方法は以下の通りです。
- コントローラーに以下メソッドをprivateメソッドとして準備しました。
def sendmail(title, content, mail)
email = RMailer.create_sent( title, content, to )
email.set_content_type("text/html")
ScrapMailer.deliver(email)
end
まずはemailオブジェクトを生成し、content_typeを設定してからメール送信すればOKですね。
hrよりも細いラインを引きたいことがあります。hrだとIEでは細いアンダーラインがひけるのに、Firefoxでは細くならないということもあります。さらにborder 1pxより細いラインが引きたいというときはこれでOK!
他にもやり方あれば教えてください。
他にもやり方あれば教えてください。
.thinline {
border-color:#CCCCCC;
border-style:solid;
border-width:0pt 0pt 1px;
height:0pt;
}
最近、Webアプリケーションを全然つくっていなかったので、以前からつくりたかったScrapBookのWeb版をつくりたいと思います。過去のブログで書いた「Firefoxで必ず使う7つのアドオン」の3位にしたScrapBookの簡易版(きちんとつくるのは手間がかかりそうなので・・・)をWeb上に保存できるサービスを考えてみたいなと思います。
※この前読んだレバレッジ勉強法にもあるようにWebのデータをスクラップできて、どんどん捨てていくようなことが簡単にできるように
ということでいつも通り要件定義
片手間でも2週間くらいでつくれないかなぁー。
※この前読んだレバレッジ勉強法にもあるようにWebのデータをスクラップできて、どんどん捨てていくようなことが簡単にできるように
ということでいつも通り要件定義
- まずはユーザ登録(メールアドレスとパスワードくらいで十分でしょう)
- URLを入力するとサーバに保存できる
- どこからでも登録したサイトが確認できて、ブックマークと違いリンクが消えていることがない(データをサーバに保存するから)
片手間でも2週間くらいでつくれないかなぁー。
設定ファイルでよく変更のあるデータを外出しにしておきたいことがあります。PerlではYAMLを使ってたのでRubyでも使用できないかと検索したら、なんと標準で使えることがわかりました。
今回はRubyでYAMLを使う方法です。
YAML(ヤムル)とは?
簡単なサンプル(例:設定ファイル)
配列やハッシュもテキストファイルにかけるので便利ですね。
今後は、設定ファイルをYAMLを積極的に使っていくと思います。
【参考サイト】
今回はRubyでYAMLを使う方法です。
YAML(ヤムル)とは?
- テキストプレーンで記載できるのでXMLより楽に記載できる(タグとかを記載しなくてよい)
- データを「配列」、「ハッシュ」、「スカラー」を記載するとオブジェクトに変換してくれる
- 設定ファイル、ログファイル等に使うと便利
簡単なサンプル(例:設定ファイル)
- 配列
- item1 - item2 - item3
- ハッシュ
name: Taro age: 28 email: test@test.testRubyで使用したサンプルソース
- オブジェクトをYAMLフォーマットでダンプする(Ruby → テキスト)
#!/usr/bin/ruby -Ks
require 'yaml'
$KCODE = 's'
hash = {"name" => "Taro", "age" => 28, "email" => ["test1@test.test", "test2@test.test"] }
# YAMLフォーマットでダンプする
puts YAML.dump(hash)
# 実行結果 > ruby main.rb --- name: Taro age: 28 email: - test1@test.test - test2@test.test
- YAML形式の設定ファイルをRubyで取り込む
# config.yamlファイル name: Taro age: 28 email: - test1@test.test - test2@test.test
#!/usr/bin/ruby -Ks
require 'pp'
require 'yaml'
$KCODE = 's'
# YAMLフォーマットでダンプする
config = YAML.load_file("config.yaml")
pp config
# 実行結果
> ruby main.rb
{"name" => "Taro",
"age" => 28,
"email" => ["test1@test.test", "test2@test.test"] }
配列やハッシュもテキストファイルにかけるので便利ですね。
今後は、設定ファイルをYAMLを積極的に使っていくと思います。
【参考サイト】
何度も同じようなプログラム(Rubyでスクレーピング)を作成しているような気がしますが、久々のRubyでクローラー作成。なんでこんなに何度も書くのかというと結構チェックしたいサイトが多く、仕事でも頼まれるためです。
※Perlで作成したクローラーはこちら
今回はきっちりクラスらしく作りました。結構汎用的になっているのではないかと思います。簡単なスクリプトです。
ソースはこれまで通りクリエイティブコモンズで。
かなり以下のサイト参考になります。何度も読ませて頂きました。
【参考サイト】
※Perlで作成したクローラーはこちら
今回はきっちりクラスらしく作りました。結構汎用的になっているのではないかと思います。簡単なスクリプトです。
ソースはこれまで通りクリエイティブコモンズで。
#!/usr/bin/ruby -Ks
require 'hpricot'
require 'mechanize'
require 'kconv'
$KCODE = 's'
class Crawler
def initialize(wait_time, internal, ngwords)
@agent = WWW::Mechanize.new
@wait_time = wait_time
@internal = internal
@ngwords = ngwords
@links = []
end
def http_connect(url)
print "OK\n"
@page = @agent.get(url)
end
def crawl(root)
@page = @agent.get(root)
@page.links.with.href(%r{}).each{|link|
if link.href =~ /^http/
url = link.href
else
%r|http://([^/]*)/| =~ root
url = 'http://' + $1 + '/' + link.href
end
@links << url.sub(/#.*$/,'')
}
@links.uniq!.delete(root)
puts @links
@links.each{|link|
begin
print link if $DEBUG
next unless access_test?(link)
http_connect(link)
sleep @wait_time
rescue => ex
puts ex.message
end
}
end
private
def access_test?(link)
unless %r|#{@internal}| =~ link
print "External Link.\n"
return false
end
@ngwords.each{|ng|
if /#{ng}/ =~ link
print "NG Word\n"
return false
end
}
true
end
end
かなり以下のサイト参考になります。何度も読ませて頂きました。
【参考サイト】
- Rubyでスクレーピング(mechanizeとhpricot)
- Perlでクロールする(LWP::UserAgent)
- RubyScraping - FrontPage
- Greenbear Diary - RubyでHTMLとWebを操作するためのライブラリ、HpricotとWWW::Mechanize , HikiReload
Rubyで静的HTMLファイル吐き出しのプログラムを作成したいなぁ思い、PerlのHTML::TemplateのようなものがRubyにもないか探してみました。
以下サイトにRuby版のHTML::Templateがあり使用したいと思ったのですが、少し使い勝手がわるいようです。
そのためerbにより作成することにしました。以下がテスト用でつくったサンプルコードです。
■メインプログラム
■テンプレートファイル
コマンドプロンプトより以下を実行してくれればOK
もうちょっとデータの持ち方だけ考えればもっと使いやすくなりそうです。
今度は外部ファイルから静的HTML吐き出しをするプログラムを書いてみます。
追記
外部ファイルを読み込んで静的HTMLファイル吐き出しするプログラムを書きました
【参考サイト】
以下サイトにRuby版のHTML::Templateがあり使用したいと思ったのですが、少し使い勝手がわるいようです。
そのためerbにより作成することにしました。以下がテスト用でつくったサンプルコードです。
■メインプログラム
#!/usr/bin/ruby -Ks require 'erb' include ERB::Util $KCODE = 's' filename = ARGV[0] erb = ERB.new(File.read(filename), nil, "-") # hash create. h = Hash.new title = "title_key" title_value = "title_val" h.store(title, title_value) detail = "detail_key" detail_value = "detail_val" h.store(detail, detail_value) # list create. list = Array.new list.push(h) print erb.result(binding())
■テンプレートファイル
<dl> <%- i = 0 -%> <%- for item in list -%> <dt><%=h item['title_key'] %></dt> <dd><%=h item['detail_key'] %></dd> <%- i += 1 -%> <%- end -%> </dl>
コマンドプロンプトより以下を実行してくれればOK
>ruby create_html.rb sample.rhtml
- title_val
- detail_val
もうちょっとデータの持ち方だけ考えればもっと使いやすくなりそうです。
今度は外部ファイルから静的HTML吐き出しをするプログラムを書いてみます。
追記
外部ファイルを読み込んで静的HTMLファイル吐き出しするプログラムを書きました
【参考サイト】

