ロリポップをPHPとGmailでお手軽バックアップする

4月 19th, 2008 admin

ロリポップのファイルをバックアップするために任意のディレクトリをzipで圧縮してメールでGmailに送るスクリプトを書いた。
別にGmailでなくてもいいのだけどGmailなら6Gぐらい容量があるし、ゴミ箱に自動で入るように設定しておけば30日ごとに勝手に消してくれるので非常にお手軽なのです。

コード

メールの送信にphpmailerというのを使っています

PHP:
  1. <?php
  2.  
  3. //ライブラリ読み込み
  4. require("./PHPMailer/class.phpmailer.php");
  5.  
  6. //バックアップするディレクトリを指定
  7. $backup_dir = "../photo"; //この場合はphotoディレクトリ以下をバックアップ
  8. //ファイル名を指定
  9. $new_file = "domain.com.zip";
  10.  
  11. //送り先
  12. $to = "任意のメールアドレス@gmail.com";
  13. $subject = "domain.com backup";
  14. $body = "";
  15. $from = "任意のメールアドレス@gmail.com";
  16. $fromname = "domain.com";
  17. $attachfile = "./domain.com.zip";
  18.  
  19.  
  20. mb_language("japanese");
  21.  
  22. system("zip -r $new_file $backup_dir");
  23.  
  24.  
  25.  
  26. $mail = new PHPMailer();
  27. $mail->CharSet = "iso-2022-jp";
  28. $mail->Encoding = "7bit";
  29.  
  30. $mail->AddAddress($to);
  31. $mail->From = $from;
  32. $mail->FromName = mb_encode_mimeheader(mb_convert_encoding($fromname,"JIS","EUC-JP"));
  33. $mail->Subject = mb_encode_mimeheader(mb_convert_encoding($subject,"JIS","EUC-JP"));
  34. $mail->Body  = mb_convert_encoding($subject,"JIS","EUC-JP");
  35.  
  36.  
  37. $mail->AddAttachment($attachfile);
  38.  
  39. if (!$mail->Send()){
  40.     echo("メールが送信できませんでした。エラー:".$mail->ErrorInfo);
  41. }
  42.  
  43. unlink($new_file);
  44. ?>

まとめ

  • ロリポップは安いのにsystem関数使えて凄い、PHPのzip用のライブラリも入ってます
  • rmコマンドは使わせてもらえないらしい、unlink関数でファイルは消す
  • 現在Zipで送ってるだけなのでセキュリティ的にアウト、暗号化するのが望ましい
  • 定期的に実行するためにwebcronのようなサイトを使う(もしくは他サーバから、もしくは1日の最初の訪問者とかに踏ませる)
  • Gmailのほうでここからのメールはゴミ箱に直行の設定をしよう
  • Gmailで転送設定しておけば簡単に二重化ができる!
  • Gmailの規約は要確認

参考サイト

phpmailer
http://phpmailer.codeworxtech.com/
PHPで日本語メールを送る - 応用編 (添付ファイル、HTMLメール) - EC studio 技術ブログ
http://techblog.ecstudio.jp/tech-tips/mail-japanese-advance.html

CakePHP1.2での管理者用レイアウト設定

4月 14th, 2008 admin

admin routingを使っていて、adminの時だけ別のレイアウトを設定したい場合。
こうやってみればいいんじゃないかという例

コード

PHP:
  1. <?php
  2. //app/app_controller.php
  3. class AppController extends Controller {
  4.     function beforeRender() {
  5.         echo $this->action;
  6.         if (preg_match("/^" . Configure::read('Routing.admin')  . "_/i", $this->action)) {
  7.                 $this->layout = 'admin_default';
  8.         }
  9.     }
  10. }
  11. ?>

まとめ

他のやり方ってあるのかな?知りたいです。
あと、管理者用とユーザ用のコントローラを分けたいときにRailsのようにcontrollers/admin/user_controller.phpみたいにディレクトリを切りたいんだけど、それもやり方を知りたい。今はadmin_user_controller.phpとかを作っているけどカッコ悪い

Rubyで数独(ナンプレ)を解く(材料編)

4月 13th, 2008 admin

追記 解決編として正しいソースコードを掲載しました

毎日コードを書くというルールを決めたから酷いコードでもアップします
Rubyの本ももたずに15分ぐらいでやったんだという言い訳をさせてください
リファクタリングのやりがいがあるという意味では良コード

アルゴリズム

ナンプレを解くためのアルゴリズムとして以下のようなものを考えた。
(1)縦方向に調べて、調査中のマスに置ける数字の候補をリストする
(2)横方向にも同様に
(3)1と2の結果候補が1つならその数字を置く
んで、1~3をマスの数*マスの数やればOK

成果物

RUBY:
  1. require 'pp'
  2.  
  3. def search_h(index,x,sheet)
  4.   offset = (index / 9) * 9
  5.   possible = Array.new
  6.  
  7.   search_array = sheet.slice(offset..(offset+8))
  8.   (1..9).each do |i|
  9.     unless search_array.include?(i)
  10.       possible.push(i)
  11.     end
  12.   end
  13.  
  14.   return possible
  15. end
  16.  
  17. def search_v(index,x,sheet)
  18.   offset = index % 9
  19.   possible = Array.new
  20.  
  21.   search_array = Array.new
  22.   (0..8).each do |i|
  23.      search_array.push(sheet[offset + 9 * i])
  24.   end
  25.  
  26.   (1..9).each do |i|
  27.     unless search_array.include?(i)
  28.       possible.push(i)
  29.     end
  30.   end
  31.  
  32.   return possible
  33. end
  34.  
  35. sheet = Array.new
  36. sheet.concat [3,7,0,6,2,0,0,0,1]
  37. sheet.concat [0,0,8,0,5,0,0,6,9]
  38. sheet.concat [4,0,0,0,7,0,0,8,0]
  39. sheet.concat [0,6,0,0,0,4,0,3,8]
  40. sheet.concat [8,0,0,0,3,0,0,0,6]
  41. sheet.concat [5,2,0,0,8,6,0,9,0]
  42. sheet.concat [0,4,0,0,1,0,0,0,3]
  43. sheet.concat [9,3,0,0,6,0,8,0,0]
  44. sheet.concat [6,0,0,0,4,2,0,7,5]
  45.  
  46. width = 9
  47. height= 9
  48.  
  49. 81.times do
  50. index = 0
  51. sheet.each do |x|
  52.   if x == 0
  53.     result = search_h(index,x,sheet) & search_v(index,x,sheet)
  54.  
  55.     if(result.length == 1)
  56.         p index
  57.     pp result
  58.         sheet[index] = result.pop
  59.     end
  60.   end
  61.   index += 1
  62. end
  63. end
  64.  
  65. count = 1
  66. sheet.each do |x|
  67.   print x
  68.   print "\n" unless count % 9> 0
  69.   count += 1
  70. end

まとめ

・・・駄目らしい。このコードでは解けませんでしたw
で、ひさしぶりに頭を使ってコーディングした気がする。学生の頃を思い出して楽しかった。
明日には解けるようにしておきます。

as3でWebカメラ画像の2値化(白黒化)

4月 11th, 2008 admin

白黒の顔写真を取り込みたかっただけなんだけど、思ってたより1ピクセルが大きくてギザギザになった。
これをスムーズにする方法があるんだろうか。
このWebカメラは100万画素ぐらいあるはずなんだけど、取り込み用のそういうのはどこかで設定できるんだろうな。
今日はもう遅いのでまた明日調べよう

成果物

しみやそばかすを自動で消してくれるフォトレタッチソフト(落書きっぽいのは後付です)
flash2.jpg
サンプルはこちら(画面をクリックで白黒画像がとれます)

コード

package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.media.Camera;
	import flash.media.Video;
	import flash.text.TextField;

	public class Main extends flash.display.Sprite
	{
		private var camera_width:int = 200;
		private var camera_height:int = 150;
		private var video:Video = new Video(camera_width, camera_height);
		private var tfView:TextField;

		public function Main():void
		{

			tfView = addTextField(220, 0, 200, 150);
			tfView.appendText("start\n");
			var camera:Camera = Camera.getCamera();
			if (camera == null) {
				//error
				return;
			}
			video.attachCamera(camera);
			addChild(video);
			stage.addEventListener(MouseEvent.CLICK, onClick);
		}

		private function onClick(event:MouseEvent):void {
			tfView.appendText("click!\n");
			var s:BitmapData = new BitmapData(camera_width, camera_height)
			s.draw(video);

			var d:BitmapData = new BitmapData(camera_width, camera_height) 

			var r:Rectangle = new Rectangle(0, 0, camera_width, camera_height);
			d.fillRect(r, 0xFFFFFFFF);

			d.threshold(s, r, new Point(0, 0), "<=", 90, 0xFF000000, 255, false);

			var img:Bitmap = new Bitmap(d);
			addChild(img);
			img.x = 0;
			img.y =  160;
		}

		private function addTextField(x:Number, y:Number, w:Number, h:Number):TextField {
			var textField:TextField;
			textField = new TextField();
            addChild(textField);
            textField.x         = x;
            textField.y         = y;
            textField.width     = w;
            textField.height    = h;
            textField.text      ="";
            textField.selectable=true;
            textField.border    =true;

			return textField;
		}
	}
}

まとめ

BitmapDataにthresholdっていうすべてのピクセルを特定の条件で色を変えるっていうずばりそのもののコードがあったのでできた。そしてずばりそのもののコードが載っているサイトがあったのでできた。Webカメラから取り込んでいるというところだけがオリジナル。Webすごい

参考サイト

Flash Player 9/ActionScript3.0/Flex2の勉強日記

BitmapData - ActionScript 3.0 コンポーネントリファレンスガイド


trick7.com blog: BIT-101 : BitmapData Threshold Explorer

as3でWebカメラ画像の取り込みの練習

4月 8th, 2008 admin

話が逆な気もするけど「Flash+WebCam+Web」って凄い組み合わせだと思う。
今後数年以内に爆発的に流行ると思うので今から取り込みの練習。
ビデオを取得してそれをビットマップにすればいいらしい。

成果物

買ったし安くなかった割に読んでない本を自慢できるswf
flash.jpg
画面をクリックする度にWebカメラの画像が取り込まれて下につながっていく。それだけ。

コード

package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.media.Camera;
	import flash.media.Video;
	import flash.text.TextField;

	public class Main extends flash.display.Sprite
	{
		private var camera_width:int = 200;
		private var camera_height:int = 150;
		private var bitmap_y_offset:int = 160;
		private var video:Video = new Video(camera_width, camera_height);
		private var tfView:TextField;

		public function Main():void
		{

			tfView = addTextField(220, 0, 200, 150);
			tfView.appendText("start\n");
			var camera:Camera = Camera.getCamera();
			if (camera == null) {
				//error
				return;
			}
			video.attachCamera(camera);
			addChild(video);
			stage.addEventListener(MouseEvent.CLICK, onClick);
		}

		private function onClick(event:MouseEvent):void {
			tfView.appendText("click!\n");
			var bd:BitmapData = new BitmapData(camera_width, camera_height)
			bd.draw(video);
			var img:Bitmap = new Bitmap(bd);
			addChild(img);
			img.x = 0;
			img.y =  bitmap_y_offset;
			bitmap_y_offset += bitmap_y_offset;

		}

		private function addTextField(x:Number, y:Number, w:Number, h:Number):TextField {
			var textField:TextField;
			textField = new TextField();
            addChild(textField);
            textField.x         = x;
            textField.y         = y;
            textField.width     = w;
            textField.height    = h;
            textField.text      ="";
            textField.selectable=true;
            textField.border    =true;

			return textField;
		}
	}
}

まとめ

次はサーバにアップロードされるようにしたいと思う。そうすればサイトにアクセスしてWebカメラをポンとクリックしてスマートURLが発行されて友達に送れるっていう、お前なんかいてもいなくても同じなWebサービスの完成です。

疑問

videoのCLICKイベントを拾いたかったけど拾えなかった、どうやってやるんだろうか?

参考サイト

Flash Player 9/ActionScript3.0/Flex2の勉強日記
AS3でDisplayObjectをBitmapDataに変換してみたよ。 - Humming Via Kitchen