さくらVPSでDropbox
個人サーバーのバックアップがめんどうなので、dropboxのアカウント作ってそこに放り込むことにした。
環境はLinux。CentOS5.6(64bit)さくらVPS。
必要なものをインストール
python2.6
sudo yum install python26
dropboxコマンドの準備
ソースをダウンロードし、権限を与えパスが通っているディレクトリへ移動。
cd ~/src wget https://www.dropbox.com/download?dl=packages/dropbox.py chmod u+x dropbox.py vi dropbox.py 一行目、#!/usr/bin/pythonを#!/usr/bin/python26に変更 mv dropbox.py ~/bin/dropbox
dropboxインストール
dropbox start -i To link this computer to a dropbox account, visit the following url: https://www.dropbox.com/cli_link?host_id=39c6****c3d04b***e6&cl=ja
ブラウザでdropboxにログインし、このurlを叩くとアカウントが紐づく。
~/Dropboxが自動で作成され、同期がはじまる。GUIの時と同じ。
なんて簡単!
確認コマンド
cd ~/Dropbox ls -lA ステータス dropbox status ヘルプ dropbox help プロセス ps aux | grep dropbox
試しにディレクトリを作ってみる。
cd ~/Dropbox mkdir test
ブラウザでアクセス
https://www.dropbox.com/home
反映されているか確認。
起動と停止
dropbox start dropbox stop
自動起動
rootで作業。
サービスファイル作成。
変数のuserとexecの値は各々設定する。
vi /etc/init.d/dropbox
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
権限の付与
chmod u+x /etc/init.d/dropbox
自動起動に登録
chkconfig --add dropbox chkconfig dropbox on chkconfig --list dropbox dropbox 0:off 1:off 2:on 3:on 4:on 5:on 6:off
これで再起動しても自動で起動する。
gitリポジトリの作り方
gitリポジトリの作り方まとめ。
マスターリポジトリ(公開リポジトリ)の作成
mkdir -p /var/git/sample.git cd /var/git/sample.git git --bare init
マスターリポジトリは--bareをつけてinitする。
/home/user/sampleにあるソースをマスターにするためコミット
cd /home/user/sample git init git add . git commit -m 'import'
push先のリポジトリパスを指定し、push
git remote add origin file://var/git/sample.git git push origin master
追加したリポジトリパスを見る場合。
git remote -v
pushしたら、cloneでもってくる。
cd /var/www/vhosts git clone file:///var/git/sample.git sample
最後のsampleはディレクトリ名になる。
iPhoneプッシュ通知まとめ
2011/11/14 : 追記
moruguさんに指摘頂いてdeviceTokenのPOST処理を追記しました。
連絡手段がなかったのでここにお礼として書いておきます。どもです! m(_ _)m
iPhoneアプリ開発でプッシュ通知を使ったので、まとめ。
仕組み
1、APNsにPush通知許可の登録する。
2、APNsからデバイストークンが帰ってくる。
3、そのデバイストークンをサーバー(これは自分で用意します)に送ってDBなりに保存する。
4、サーバーからAPNsにPush通知依頼を出す。
5、APNsは登録済みの指定デバイスにPush通知を出す。
6、受け取ってAlert出すなり色々する。
実装前に準備
Push通知を行うには、iOSDeveloperCenterでPush通知用の証明書をインストールしたりしなければならない。
このフェーズは自分ではやってないので省略orz
参考サイトだけ載せておく。
実装
ここのメソッドは全てプロジェクトのdelegateクラス。
1、APNsにPush通知許可の登録する。
registerForRemoteNotificationTypesを叩くと『プッシュ送信を許可しますか?』のアラートが出て、APNsにリクエストが送られ登録される。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window.rootViewController = self.navigationController; [self.window makeKeyAndVisible]; [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge| UIRemoteNotificationTypeSound| UIRemoteNotificationTypeAlert)]; return YES; }
2、APNsからデバイストークンが帰ってくる。
レスポンスが返ってくると、didRegisterForRemoteNotificationsWithDeviceTokenメソッドがコールされる。
引数にデバイストークンがついてくる。
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)devToken{ NSLog(@"Success : Regist device token to APNS. (%@)", devToken); [self postDeviceToken:deviceTokenString]; // POST }
APNSへのデバイス登録失敗時
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)err{ NSLog(@"Error : Fail Regist to APNS. (%@)", err); }
3、そのデバイストークンをサーバー(これは自分で用意します)に送ってDBなりに保存する。
- (void)postDeviceToken:(NSString *)deviceToken { // prepare url. NSString* content = [NSString stringWithFormat:@"deviceToken=%@", deviceToken]; NSURL* url = [NSURL URLWithString:@"http://192.168.1.5:8080/registDeviceServelt"]; // create instance. NSMutableURLRequest* urlRequest = [[NSMutableURLRequest alloc]initWithURL:url]; [urlRequest setHTTPMethod:@"POST"]; [urlRequest setHTTPBody:[content dataUsingEncoding:NSUTF8StringEncoding]]; // post. NSURLResponse* response; NSError* error = nil; NSData* result = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error]; if(error) NSLog(@"error = %@", error); // get result. NSString* resultString = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]; NSLog(@"%@", resultString); // release. [resultString release]; [urlRequest release]; }
サーバー側でdeviceTokenを受け取り、DBに保存します。
4、サーバーからAPNsにPush通知依頼を出す。
PHPでやる場合
php-apnsというライブラリを使う。
使う前に証明書を作ったり、ルート証明書をダウンロードしないといけない。ここにやり方が載ってる。
何も考えずにコマンドを叩く^^;
Javaでやる場合
java-apnsというライブラリを使う。
証明書は、キーチェーンからPush通知用にインストールした証明書をエクスポートして使う。
サンプルコード
ApnsService service = APNS.newService() .withCert("/Users/*******.p12", "*****") .withSandboxDestination() .build(); String payload = APNS.newPayload().alertBody("Can't be simpler than this!").build(); String token = "638d09063fe6a73a6cb4*******************ab084e5ea8b0b390d1480f"; service.push(token, payload);
5、APNsは登録済みの指定デバイスにPush通知を出す。
ここはAPNsが勝手にやります。
6、受け取ってAlert出すなり色々する。
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { for (id key in userInfo) { NSLog(@"key: %@, value: %@", key, [userInfo objectForKey:key]); } }
まとめ
Push通知の仕組み自体がシンプルな上に、ライブラリも各種言語あるので簡単。
やっぱりappleはスゴイ。
iPhoneDeveloperに法人登録したまとめ
iPhone開発用に会社のアカウントを取得したときのメモです。
まず初めに
会社で法人として登録する場合、印鑑証明書か登記簿謄本のどっちか必要なので用意が必要です。
さらに審査?に時間がかかるので、今回の場合だと3週間ほどかかりました。
個人登録と同様に年間10800円かかります。
登録の流れ
流れ等は、以下のサイトを参考にして登録しました。とても参考になります。
- http://www.amunsnet.com/blog/iphone開発/317.html
- http://www.amunsnet.com/blog/iphone開発/330.html
- http://www.amunsnet.com/blog/iphone開発/343.html
困ったポイント
Documentation Requested for Your Program Enrollment
このようなタイトルでメールがきました。
登録のためにドキュメントが欲しいらしいのです。
が、何を送れというのが書いてありません。信じられない。。。。
しかたなくサポートにメールして聞いたところ、
申請書と印鑑証明書か登記簿謄本のどっちかを送れということでした。
申請書は、こんな感じで書式はお願いしますとご丁寧に送ってくれましたので、ワードで作って印刷しfaxしました。
faxが届くと、ちゃんと届いたと確認のメールが来るので安心です。
以下はサポートからのメールです。最初からこれ送ってこいや。
この度は iOS Developer Programへお申し込みいただき、ありがとうございます。このEメールは登録手続きに関するご案内です。 Appleでは、Program へお申し込みいただく企業について、実在確認をさせていただいております。 誠にお手数ではございますが、以下『計2点』の書類の写しをご用意いただき、FAXにて弊社までご送付ください。 1)本 Program への申請について、申請者が御社の代表取締役により権限が与えられている事を示す書面(御社本部の所在地と代表電話番号の記載、代表取締役の押印が必要です)1通。文面に関しましては、以下の例をご参照ください。 ---------- 申請証明書 ○○会社(日本語名称および英語名称)代表取締役である <代表取締役の氏名> は、Apple Developer Program の申請に関する一切について、 当社の社員である以下の申請者に委任している事を、この書面により証明する。 申請者氏名(Applicant Name): <申請者の氏名>(ローマ字表記を含む) 役職(あるいは所属部署): <申請者の役職名あるいは所属部署名> 日付 企業本部所在地 代表電話番号 <代表取締役の氏名>(ローマ字表記を含む) および捺印 ---------- 申請者が代表取締役である場合には、『○○会社代表取締役としての権限によりApple Developer Program へ申請する事を、この書面により証明する』といった文面で作成してください。 2)登記簿謄本(履歴事項全部証明書、又は現在事項全部証明書)、あるいは社印の印鑑証明書(本店のもの)のいずれか1通。 FAX番号: +1-408-974-7683 ※米国の番号となりますので、国際電話のダイヤル方法をご確認ください。 書類をお送りいただく際には、Enrollment ID: ******** と御社の代表電話番号を書類にお書き加えください。日本語表記のものをそのままお送りいただいて、問題ございません。 どうぞ、よろしくお願いいたします。もしご不明な点などございましたら、当方までご連絡ください。Apple Developer Programへのご参加、ありがとうございます。
OAuthの覚え書きメモ
OAuth1.0覚えたのでメモ。
1、RequestTokenを取得するリクエスト。
2、redirectしてそのサービスでログインしてリダイレクトして戻ってくる(コールバック)。
3、RequestTokenを認証(Authorized)するリクエスト。
4、AccessTokenを取得するリクエスト。
5、4で取得したtokenを使って、色々とapi叩く。
Zend_Oauth_Consumerがとても便利。OAuth1.0のみ対応。
これを使うと4のAccessTokenを取得するリクエストを送る前に、RequestTokenの認証を内部的に行ってくれる。
てかfacebookはOAuth2.0だし・・・
apacheのMaxClientを算出するスクリプトを作った
概要
apacheの設定にあるMaxClientsは、サーバースペック等から算出できるため、毎回手動で計算するのは面倒なのでスクリプトを作った。
計算方法
(サーバーメモリ量) / (httpd使用メモリ量 - httpd使用共有メモリ量) = MaxClients
psコマンドではなく、/proc/PID/smapsから取得しているためより正確。コマンドのみで算出しようと思ったが、平均値とか出すのが面倒だったためスクリプトにしてみた。でも、あくまで目安ということで。
ソースコード (get_max_client.php)
<?php //-------------------------------------------------------------------------------------- // Usage: php get_max_client.php // root only. // // This program is used to get MaxClient of apache. // Following step. // 1、get all pid of httpd. // 2、get average Rss of "/proc/$pid/smaps". // 3、get average Shared_Clean of "/proc/$pid/smaps". // 4、get average Shared_Dirty of "/proc/$pid/smaps". // 5、get memory size by free command. // 6、math max client by "memorySize / (rssAverage - (Shared_Clean + Shared_Dirty))". // 7、print max client. //-------------------------------------------------------------------------------------- $GLOBALS['debug'] = false; /** * Dump data. * If $GLOBALS['debug'] is true, dump. * * @param mixd $value * @param string $label */ function debugDump ($value, $label = null) { if ($GLOBALS['debug']) { if ($label) { $value = $label . ' : ' . $value; } var_dump($value); } } /** * command execute. error handling and logging. * if command is error, it will end. (exit(1)) * * @param string $arg * @return string */ function executeCommand ($arg) { $result = `$arg 2>&1`; if (substr(`echo $?`, 0, 1) === '0') { // success return rtrim($result); } else { // failure error_log(sprintf('command failure [%s][%s]', $arg, $result)); echo 0; exit(1); } } /** * This method is run. * If you want to see debug data, see this page top. * */ function run () { $httpdPidArr = getHttpdPidArr(); $rss = getRssAverage($httpdPidArr); $shr = getShrAverage($httpdPidArr); $memorySize = getMemorySize(); $maxClient = mathMaxClient($shr, $rss, $memorySize); debugDump($rss, '$rss'); debugDump($shr, '$shr'); debugDump($memorySize, '$memorySize'); debugDump($maxClient, '$maxClient'); echo sprintf('--------------------------------') . PHP_EOL; echo sprintf('memorySize / (rssAverage - shrAverage) = %dKB / (%dKB - %dKB) = %d', $memorySize, $rss, $shr, $maxClient) . PHP_EOL; echo sprintf('MaxClient maximum value is %d.', $maxClient) . PHP_EOL; echo sprintf('--------------------------------') . PHP_EOL; } /** * Get httpd pid. * * @return array */ function getHttpdPidArr () { $httpdPids = executeCommand('pgrep httpd'); if (empty($httpdPids)) { throw new Exception("Not found httpdPids. failure pgrep httpd."); } return explode(PHP_EOL, $httpdPids); } /** * Get rss. * This method is browse /proc/$pid/smaps. * * @return int */ function getRss ($pid) { $rss = executeCommand("cat /proc/$pid/smaps | grep Rss | awk '{rss += $2} END {print rss;};'"); if (empty($rss)) { throw new Exception("Rss not found. /proc/$pid/smaps not found?."); } return (int) $rss; } /** * Get rss average. * * @return int */ function getRssAverage ($httpdPidArr) { foreach ($httpdPidArr as $httpdPid) { $rssArr[] = $debug = getRss($httpdPid); } return (int) round(array_sum($rssArr) / count($rssArr)); } /** * Get rss. * This method is browse /proc/$pid/smaps. * * @return int */ function getShrClean ($pid) { $shrClean = executeCommand("cat /proc/$pid/smaps | grep Shared_Clean | awk '{shrc += $2} END {print shrc;};'"); if (empty($shrClean)) { throw new Exception("Shared_Clean not found. /proc/$pid/smaps not found?."); } return (int) $shrClean; } /** * Get rss. * This method is browse /proc/$pid/smaps. * * @return int */ function getShrDirty ($pid) { $shrDirty = executeCommand("cat /proc/$pid/smaps | grep Shared_Dirty | awk '{shrd += $2} END {print shrd;};'"); if (empty($shrDirty)) { throw new Exception("Shared_Dirty not found. /proc/$pid/smaps not found?."); } return (int) $shrDirty; } /** * Get shr average. * (Shared_Clean + Shared_Dirty) / count * * @return int */ function getShrAverage ($httpdPidArr) { foreach ($httpdPidArr as $httpdPid) { $shrClean = getShrClean($httpdPid); $shrDirty = getShrDirty($httpdPid); debugDump("pid=$httpdPid : shrClean $shrClean"); debugDump($shrDirty, '$shrDirty'); $shrArr[] = $shrClean + $shrDirty; } return (int) round(array_sum($shrArr) / count($shrArr)); } /** * Get memory size. * This method is execute free command. * * @return int */ function getMemorySize () { $result = executeCommand("free | grep Mem | awk '{print $2;};'"); if (empty($result)) { throw new Exception('memory size not found. failure free command...'); } return $result; } /** * Math MaxClient. * * @param int $shr * @param int $rss * @param int $memorySize * @return int MaxClient */ function mathMaxClient ($shr, $rss, $memorySize) { return (int) round($memorySize / ($rss - $shr)); } run();