美人時計の全画像を取得するスクリプトをバッチ化してみた

2009年11月20日

カテゴリー: Ruby, 美人時計 — admin @ 11:18 AM

最近流行り(?)の美人時計。Web業界の人間ならだいたいの人は知っているんじゃないでしょうかね。1分置きに女の子が変わるというこのサービス。女の子が変わるまでずーっと24時間も待っていられないので、全画像を取得するスクリプトをつくってしまいたくなりました。

とりあえず誰かすでにつくってるんじゃないだろうかと思い、google先生にきいてみました。

案の定すぐみつかりましたよ!素敵スクリプトをつくっている方が!

▽こちら
Yamashiro0217の日記

Rubyで組まれているようです。僕はPHP派なので、Rubyまったくわかりませんが、この際Rubyに入門してしまおう!ってことで、Yamashiro0217さんのスクリプトを参考にスクリプトをつくってみようと思います。

まずはRubyスクリプトの動作確認
Yamashiro0217さんのスクリプトをコピペで動かしてみます。

▽開発環境
Fedora10のインストールされたLinuxサーバ。
Rubyはすでにインストール済み。

▽美人時計の全画像取得スクリプト
bijin.ruby

RUBY:
  1. require 'net/http'
  2. require 'uri'
  3.  
  4. error_files = ""
  5. 0..24.times do |hour|
  6.    0..60.times do |minute|
  7.       now_hour = sprintf("%0#{2}d", hour)
  8.       now_minute = sprintf("%0#{2}d", minute)
  9.       sleep 1
  10.       begin
  11.          Net::HTTP.start("bijint.com", 80) do |http|
  12.          response = http.get(
  13.             "/jp/img/clk/#{now_hour}#{now_minute}.jpg",
  14.             {"Referer" => "http://bijint.com/jp/" }
  15.          )
  16.          open( "#{now_hour}#{now_minute}.jpg", "wb" ) do |file|
  17.              file.puts response.body
  18.          end
  19.       end
  20.       rescue
  21.          p "#{now_hour}#{now_minute}.jpg can not get"
  22.          error_files += "http://bijint.com/jp/img/clk/#{now_hour}#{now_minute}.jpg\n"
  23.       end
  24.    end
  25. end

▽コマンドから実行

CODE:
  1. [ooiwa@eva bijin_tokei]$ ruby bijin.ruby

おぉー!画像がどんどん落ちてきたよー!これは感動!とりあえず動作確認はOKと。

ただこの美人時計、落とした画像ファイルと、本番サイトの美人時計側で女の子の表示が違うときがあります。どうやら日々ちょこちょこ女の子が更新されているようです。これはなんということ!全女の子コンプリートするには定期的にチェックするしかないじゃないか!ということで、この際毎日取得してしまうスクリプトを組んでみようと思います。

それではバッチをつくっていきます。
定期的に1日毎に決まった時間に全画像を取得して、なおかつ日付ごとにディレクトリを分けて保存する、バッチをまわすのはCron、スクリプト言語はRubyをつかってつくっていきます。

まず、Yamashiro0217さんのスクリプトをこのまま使うと、スクリプトと同じパスに画像をそのままダウンロードしてきますので、日付毎にディレクトリを切ってくれる関数を用意します。
今回はわかりやすいようにスクリプトを起動した日の日付を取得して"yyyymmdd"形式で文字列を返す関数と、ディレクトリを生成する関数を用意します。

▽今日の日付をyyyymmdd型の文字列に変換する関数

RUBY:
  1. def getTimeNow()
  2.     day = Time.now
  3.     putMonth = day.month.to_s
  4.     putDay = day.day.to_s
  5.  
  6.     if day.month <10 && day.day <10
  7.         putMonth = '0' + day.month.to_s
  8.         putDay = '0' + day.day.to_s
  9.     elsif day.month <10
  10.         putMonth = '0' + day.month.to_s
  11.     elsif day.day <10
  12.         putDay = '0' + day.day.to_s
  13.     end
  14.  
  15.     nowTime = day.year.to_s + putMonth + putDay
  16.     return nowTime
  17. end

▽ディレクトリの生成

RUBY:
  1. def mkdir(path)
  2.     if Dir::mkdir( path, 0777 )
  3.         return true
  4.     else
  5.         return false
  6.     end
  7. end

あとは、Yamashiro0217さんのスクリプトにディレクトリパスを突っ込んで、一通り完成させる。今回Cronでバッチ処理させるため、ディレクトリパスは絶対パスで書く。

▽スクリプトをまとめたのがこれ
bijin.ruby

RUBY:
  1. #――――――――――――――――――――――――――――――
  2. #  美人時計の画像を全取得するスクリプト
  3. #
  4.  
  5. #------------------------------------------------------------
  6. #  ライブラリのインポート
  7. #
  8. require 'net/http'
  9. require 'uri'
  10.  
  11. #------------------------------------------------------------
  12. #  Global var
  13. #
  14. $scriptPath = '/home/ooiwa/tmp_ruby/bijin_tokei/'
  15.  
  16. #------------------------------------------------------------
  17. #  今日の日付をyyyymmdd型の文字列に変換する関数
  18. #
  19. def getTimeNow()
  20.     day = Time.now
  21.     putMonth = day.month.to_s
  22.     putDay = day.day.to_s
  23.  
  24.     if day.month <10 && day.day <10
  25.         putMonth = '0' + day.month.to_s
  26.         putDay = '0' + day.day.to_s
  27.     elsif day.month <10
  28.         putMonth = '0' + day.month.to_s
  29.     elsif day.day <10
  30.         putDay = '0' + day.day.to_s
  31.     end
  32.  
  33.     nowTime = day.year.to_s + putMonth + putDay
  34.     return nowTime
  35. end
  36.  
  37. #------------------------------------------------------------
  38. #  ディレクトリの生成
  39. #
  40. def mkdir(path)
  41.     if Dir::mkdir( path, 0777 )
  42.         return true
  43.     else
  44.         return false
  45.     end
  46. end
  47.  
  48. #------------------------------------------------------------
  49. #  美人時計から画像を取得
  50. #
  51. #  スクリプト参考元: Yamashiro0217さん
  52. #  http://d.hatena.ne.jp/Yamashiro0217/20090930/1254305886
  53. #
  54. def getBijin()
  55.     error_files = ""
  56.     0..24.times do |hour|
  57.        0..60.times do |minute|
  58.           now_hour = sprintf("%0#{2}d", hour)
  59.           now_minute = sprintf("%0#{2}d", minute)
  60.           sleep 1
  61.           begin
  62.              Net::HTTP.start("bijint.com", 80) do |http|
  63.              response = http.get(
  64.                 "/jp/img/clk/#{now_hour}#{now_minute}.jpg",
  65.                 {"Referer" => "http://bijint.com/jp/" }
  66.              )
  67.              open( $scriptPath + getTimeNow() + '/' + "#{now_hour}#{now_minute}.jpg", "wb" ) do |file|
  68.                  file.puts response.body
  69.              end
  70.           end
  71.           rescue
  72.              p "#{now_hour}#{now_minute}.jpg can not get"
  73.              error_files += "http://bijint.com/jp/img/clk/#{now_hour}#{now_minute}.jpg\n"
  74.           end
  75.        end
  76.     end
  77. end
  78.  
  79. #------------------------------------------------------------
  80. #  初期実行関数
  81. #
  82. def init()
  83.     if mkdir( $scriptPath + getTimeNow() )
  84.         getBijin()
  85.     end
  86. end
  87.  
  88. init()

Rubyは変数の定義がグローバルとローカルでスコープがわかりやすいから良いですね!なんかPHPより全然カンタンだし、オブジェクト指向言語だし、個人的にはだいぶ気に入りました。

完成したスクリプトを早速実行してみます。

CODE:
  1. [ooiwa@eva bijin_tokei]$ ruby /home/ooiwa/tmp_ruby/bijin_tokei/bijin.ruby
  2. [ooiwa@eva bijin_tokei]$ ls
  3. 20091120  bijin.ruby
  4. [ooiwa@eva bijin_tokei]$ ls 20091120/
  5. 0000.jpg 0001.jpg 0002.jpg

うまく動いていれば、本日の日付ディレクトリが生成され、そのディレクトリの中に画像をどんどんたまっていっているのがわかります。

最後はこの完成したスクリプトをCronでまわす処理をします。

CODE:
  1. [ooiwa@eva bijin_tokei]$ crontab -e
  2. #毎日10:00に bijin.ruby スクリプトを実行
  3. 0 10 * * * ruby /home/ooiwa/tmp_ruby/bijin_tokei/bijin.ruby

あとは毎日10時になるとCronがRubyスクリプトを実行してくれます。
これであとは目視で比較するか、md5で比較するツールでもつくって差分を分けるスクリプトを足すかでもすればどの女の子が削除されて追加されたかがわかりますね。

美人時計、面白いです。

JavaScriptのDateオブジェクトについて

2009年11月13日

カテゴリー: JavaScript — admin @ 11:20 AM

ハマった・・・、がっつりハマった・・・。

DateオブジェクトのgetMonth()という月をとるメソッドがあるんですが、0~11の値が返ってくるんです。
0が1月で、11が12月。見事計算を間違えまして、(getMonth()+1) を先に変数に代入して、そこから1ヶ月計算する式をつくったのです。それがバグでした。11月から12月にかかるとき、11+1=12 にならないので、何でかなーと思っていたら、11までだったので、0に戻ってしまうんですね。なので、変数に代入せず、出力の際に直接、(getMonth()+1) を使えば良かったんです。

間違ったコード

JavaScript:
  1. var date = new Date( today.getFullYear(), (today.getMonth() + 1), (today.getDate() + arg) );
  2. return date.getFullYear() + '.' + date.getMonth() + '.' + date.getDate();

修正後

JavaScript:
  1. var date = new Date( today.getFullYear(), today.getMonth(), (today.getDate() + arg) );
  2. return date.getFullYear() + '.' + (date.getMonth() + 1) + '.' + date.getDate();

んー、なかなかどうしてミスってしまった・・・。
うっかりさんなんだぜ!

Facebookユーザーを標的にしたメール詐欺に対抗してみた2

2009年11月6日

カテゴリー: Linux, sendmail — admin @ 12:36 AM

前記事にて、特定ドメインからの受信を拒否してみたんだけど、全然メール拒否できてなかった。
そりゃこれだけ手の込んだフィッシングメールなんだから当然だよね。メールヘッダ見たら全然違ったし、しかもドメイン複数あるし偽造されてるしで結局わからんちんだったので、webmaster宛にメールは届いていたので、webmaster宛のメールをすべて拒否することにした。

CODE:
  1. [root@host ~]# vi /etc/aliases
  2. webmaster: root
  3.   ↓に変更
  4. #webmaster: root
  5.  
  6. [root@host ~]# newaliases

うん、ばっちり来なくなった。
そもそもwebmasterとかinfoとかrootとか狙われやすいんだから、デフォルトでオフにしとくべきした。

Facebookユーザーを標的にしたメール詐欺に対抗してみた

2009年10月31日

カテゴリー: Linux, sendmail — admin @ 4:39 PM

最近、フィッシングサイトへの誘導メールがよく来る。なりすましはFacebookである。
ググってみたらどうやら今全世界で流行っているらしいですねー。

#ニュース記事
Facebookユーザーを標的にしたメール詐欺--トロイの木馬「Zeus」で個人情報を盗む

メールのくる間隔としては、1日に2~3通は来るのでかなり迷惑。

ってことで、送信元ドメインごとメール受信を拒否することにした。

ウチはsendmailなので、まず設定ファイルを修正する。

CODE:
  1. [root@host ~]#vi /etc/mail/access
  2. #追記↓
  3. facebookmail.com  REJECT

"[ドメイン名] REJECT" と記述することで、このドメインのメールはすべて受信拒否にする。
次に、アクセスファイルをデータベースに変換します。変換にはsendmailに付属のmakemapコマンドを使用します。
その後、sendmailを再起動すれば設定が反映されます。

CODE:
  1. [root@host ~]# makemap -v hash /etc/mail/access.db </etc/mail/access
  2. [root@host ~]# /etc/rc.d/init.d/sendmail restart

これで指定ドメインのメールが拒否できます。
ちなみに受信したい場合は、"RELAY" を使うことでメールを受信することができるようになります。

フィッシング、こわいよ、フィッシング。

JavaScript OOP入門編2

2009年10月28日

カテゴリー: JavaScript — admin @ 2:19 AM

こんぬつわ。JavaScript OOP入門その2です。久しぶりです。
ちなみにその1はこちらです。

僕自身もJavaScript、そんなによくわかってる訳ではないのですが、つらづら書いていきまする。

まず、型ってものをつくります。
Javaでいうところのクラス的なものです。JavaScriptはClassというものが存在しないので、functionで定義します。

JavaScript:
  1. var ObjectA = function(){
  2.     this._var;
  3.     this._method = function(arg){
  4.         return arg;
  5.     }
  6. }

1行目が型の定義になっています。functionになっていれば書き方は自由でおkじゃないかと。
そして、このObjectAがもっている子要素オブジェクト(JSはすべてがオブジェクトとして扱う)は、型のない"_var"プロパティと、引数を返すだけの"_method"メソッドが定義されています。ObjectAの子要素として定義するため、"this"を使って定義しています。この"this"はObjectA自身への参照となります。

そして、この型はまだ実体化していないため、実体化して、実際に使える状態にします。

JavaScript:
  1. var objectA = new ObjectA();
  2. objectA._var = 'hello world';
  3. alert( objectA._method( objectA._var ) );

1行目で ObjectAをnewしてobjectAとして実体化します。設計図から実際に実体を作った状態です。
2行目では、_varプロパティにString型の"hello world" を代入しています。
3行目では、_methodを使って、_varに代入された値を返し、それをアラート表示しています。

なんだか文章が堅くなってつまんなくなってしまいました・・・。
次回もっとわかりやすく書こうと思います。

なんだか説明あってねーよ!まちがってんよ!とご指摘などありましたら恐縮ではございますが、ご指摘いただければ助かります。

ってな訳でまた来週!(やるのかな?)

Patchmatchが変態すぐるwww – Adobe Photoshop CS5

2009年10月17日

カテゴリー: Adobe — admin @ 2:17 AM

Photoshop CS5 がやばすぐる件。
前回のFlash Professional CS5 の記事でも書いたが、CS5がなんだかすごいことになっているらしいwwwww

今回はPatchmatchを紹介します。

他にももろもろ変態ツールがたっぷり搭載されているらしい。

CS5、やばいよ、CS5。
ってかCS3やCS4すら使いこなせてませんよ。

起動スクリプトの作成 /etc/rc.d/init.d/

2009年10月11日

カテゴリー: Linux, bash — admin @ 2:34 AM

bash、面白いよ、bash。

bashを全然使いこなせないので、ちょっと頑張ってもろもろ勉強せなあかんですなと思ったので、まずはいつも手作業で行っていた作業を自動化していくことにした。

ウチのサーバちゃんでは、sambaでファイルサーバも使っているのだが、バックアップもかねて、外部HDDをUSBでつないで、それをsamba内で管理しているディレクトリにマウントして使っている。
このマウント作業を手作業で行っていたため、マシンをリブートした時に、また再度手作業で行わなくてはいけない。毎回これはめんどくさいので、いい加減自動化しようと思ったのがことの経緯であるわけです。

外部HDDはwindowsでも使えるようにNTFSでフォーマットしてあるため、下記のコマンドでいつもマウントしている

CODE:
  1. host# mount.ntfs-3g /dev/sdb1 /home/hiroki/samba/mnt/

このコマンドをサーバが立ち上がった時に自動でブートするようにする。

/etc/rc.d/init.d/ ディレクトリにbashでスクリプトを組む。
startとstopで起動、終了を制御するため、start関数とstop関数を用意する。

CODE:
  1. host# vi /etc/rc.d/init.d/mnt_music

スクリプトの中身

CODE:
  1. #!/bin/bash
  2.  
  3. # chkconfig: 2345 97 97
  4. # description: mnt_music
  5.  
  6. start(){
  7.     if mount.ntfs-3g /dev/sdb1 /home/hiroki/samba/mnt/; then
  8.         echo "mount success!!"
  9.     fi
  10. }
  11. stop(){
  12.     if umount /home/hiroki/samba/mnt/; then
  13.         echo "umount success!!"
  14.     fi
  15. }
  16.  
  17. case "$1" in
  18.     start)
  19.         start;;
  20.     stop)
  21.         stop;;
  22. esac

3行目の "# chkconfig" は、chkconfigに登録できるようにする記述である。
数値部分は、「ランレベル」「起動プライオリティ」「終了プライオリティ」の順である。

スクリプトを実行する。

CODE:
  1. host# /etc/rc.d/init.d/mnt_music start
  2. umount success!!

ランレベル3に、シンボリックリンクを登録する。

CODE:
  1. host# ln -s /etc/rc.d/init.d/mnt_music /etc/rc3.d/S97mnt_music

chkconfigに "mnt_music" を登録し、起動時のブートを有効にする。

CODE:
  1. host# chkconfig --add mnt_music
  2. host# chkconfig mnt_music on

これで、毎回手作業でコマンドを実行することなく、自動でHDDをマウントすることができるようになった。

ActionScript3.0でiPhoneアプリ開発がAdobe CS5で実現!?

2009年10月9日

カテゴリー: ActionScript3, Flash — admin @ 1:43 AM

ActionScript3.0、はじまったな・・・。
iPhoneアプリをObjective-CじゃなくてもAS3で開発できちゃうってんなら、かなり敷居が下がりまくりだよね。

Flash Professional CS5(英語サイト)
Flash Professional CS5 のアナウンスと iPhone

こんなことができるらしい。

  • AS 3 のプロジェクトから iPhone, iPod Touch 用アプリケーションの書き出し
  • Text Layout Framework (TLF) を用いた新規のテキストコントロールによる新しい表現
  • XML ベースの FLA ファイル (ソース管理システムを使ったバージョン管理が可能に)
  • コードスニペットパネル (事前に作成済みのコードをプロジェクトでそのまま利用)
  • Flash Builder の統合 (ActionScript エディタとして使用できる)
  • ActionScript エディタの改良 (コードヒントや自動補完機能など)

これはActionScript3.0の開発者が一気に増えそうな予感がしまくりんぐですよ!

それに比べ、googleのAndroid使ったみましたが、動きはもっさりだし、あいつイマイチっす。やっぱりJavaってとこがあかんじゃないのかなー。重いし、iPhoneに慣れてしまっていると、どうしてもiPhoneと同じような操作しちゃうんだけど、けっこう融通が利かない。ユーザビリティもいまいちでwebブラウジングもイマイチだし、売れても流行らないと思う。結果、売れないと思う。

JavaScriptやってる人は今からActionScript3.0にどっぷりいっちゃって良いと思うよ!(^ω^)

import.js って流行ってるの?ってことで自分なりにつくってみた

2009年10月8日

カテゴリー: JavaScript — admin @ 12:43 AM

いつもならばJSファイルの読み込み方って、

HTML:
  1. <html lang="ja">
  2.  
  3. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  4. <meta http-equiv="Content-Script-Type" content="text/javascript" />
  5.  
  6. <script type="text/javascript" src="./xxxxxxx.js"></script>
  7. <script type="text/javascript" src="./yyyyyyy.js"></script>
  8. <script type="text/javascript" src="./zzzzzzz.js"></script>
  9.  
  10. </head>
  11.  
  12. <h1>hello test</h1>
  13.  
  14. </body>
  15. </html>

みたいな感じで、headタグ内に読み込むJSファイルを直接書くけど、最近流行ってるのか、それとも廃れたのかわからないが、こんな感じのソースを見た。

HTML:
  1. <script type="text/javascript" src="./import.js"></script>

1つのJSファイルだけを読み込んで、その import.js にグローバルで読み込みたいJSファイルを document.write() で読み込むようだ。

そのソースには、

JavaScript:
  1. document.write( '<script type="text/javascript" src="./xxxxxxxx.js"></script>' );
  2. document.write( '<script type="text/javascript" src="./yyyyyyyy.js"></script>' );
  3. document.write( '<script type="text/javascript" src="./zzzzzzzz.js"></script>' );

というように書かれていた。

コレはなかなか面白いし、まとまって良いなと思ったので、自分も簡単にまとめてつくってみた。

JavaScript:
  1. /**
  2. *
  3. *   import.js
  4. *   JSファイルをまとめて読み込む
  5. */
  6. (function(){
  7.     var importSrc = function(e){
  8.         return '<script type="text/javascript" src="'+ e +'"></script>' + "\n";
  9.     }
  10.     var path = './static/common/js/';
  11.     //jQueryフレームワーク
  12.     document.write( importSrc( path + 'jquery-1.3.2.min.js' ) );
  13.     //サイト全体で使用するJS
  14.     document.write( importSrc( path + 'global.js' ) );
  15. })();

scriptタグを毎回書くのもめんどくさかったので、importSrc() というショートカット関数をつくってまとめてみた。

import.js を使ってみんなまとめちゃえば良いと思うよ!
そのページ独自で使うJSはまとめちゃダメだと思うけどねw

フルFlashのサイトにHTMLフッターをつけてみる

2009年10月2日

カテゴリー: Flash, JavaScript — admin @ 4:39 PM

フルFlashのサイトに対して、HTMLフッターをつけたいという要望があったので、つけてみることにした。
Flashの埋め込み方は、swfobject.js(versionは1.5)を使って埋めてみた。

HTML:
  1. <div id="content"><!-- ここにFlashがロードされます --></div>
  2. <script type="text/javascript" src="js/swfobject.js"></script>
  3. <script type="text/javascript">
  4. // <![CDATA[
  5.  
  6. var so = new SWFObject('swf/sample.swf', 'website', '100%', '100%', '9', '#ffffff');
  7. so.useExpressInstall('swf/expressinstall.swf');
  8. so.write('content');
  9.  
  10. // ]]>
  11. </script>

これでFlashがフルサイズで読み込まれる。

さて、今回はこれに対して、Flashの下に20pxばかりのHTMLでつくったフッターを埋め込みたい。
実装内容は下記の通り。

Flashを表示するエレメントの親要素に、全体レイアウトを設定する<div id="wrapper">を追加。この要素が実際にリサイズすることになる。
ウィンドウのサイズを取得して、それから20px引き、下部にHTML部分がピタっと出現するつくりにする。
フッターは、常にウィンドウ下部に固定することにする。

HTML:
  1. <div id="wrapper">
  2. <div id="content"><!-- ここにFlashがロードされます --></div>
  3. </div>
  4. <div id="footer">HTMLフッター部分</div>
  5. <style type="text/css">
  6. body {
  7.     position: relative;
  8. }
  9. #footer {
  10.     width: 100%;
  11.     height: 20px;
  12.     background: #000;
  13.     position: absolute;
  14.     left: 0;
  15.     bottom: 0;
  16.     color: #fff;
  17. }
  18. </style>
  19. <script type="text/javascript" src="js/swfobject.js"></script>
  20. <script type="text/javascript">
  21. // <![CDATA[
  22.  
  23. var so = new SWFObject('swf/sample.swf', 'website', '100%', '100%', '9', '#ffffff');
  24. so.useExpressInstall('swf/expressinstall.swf');
  25. so.write('content');
  26. (function(){
  27.     var resizeTo = function(e){
  28.         var winHeight = document.all ? (document.body.clientHeight - 20) : (window.innerHeight - 20);
  29.         var wrapper = document.getElementById(e);
  30.         wrapper.style.width = '100%';
  31.         wrapper.style.height = winHeight + 'px';
  32.     }
  33.     window.onload = function(){
  34.         resizeTo('wrapper');
  35.     }
  36.     window.onresize = function(){
  37.         resizeTo('wrapper');
  38.     }
  39. })();
  40.  
  41. // ]]>
  42. </script>

これでHTML要素のフッターを下部に維持しつつ、フルFlashを実現できる。
ってか、20pxあいてる時点でフルFlashじゃないじゃん!とかいう突っ込みはやめて~w

« 前ページへ次ページへ »