最近では、Ajaxでも3Dライブラリやサンプルを、みんな頑張って作ってるみたいだ。 個人が山ほど作ってるけど、どれを選択していいかわからないのが「Ajax」のダメなトコなんだよなぁ。 仕様が統一されてなくて、とにかくわかりにくい。。。
現状の3Dはまだまだ、Flash > Ajax + CSSだなぁ。 けど、HTMLある限りずっと付き合ってかなきゃいけないんだよねぇ(-_-)
とりあえず、今日見つけただけのサンプルを抜粋 ■jQuery 3D Rotator
あはwこのページの背景と同じっぽいw プロパティの設定の仕方はちと大変な気がするけど、HTMLだとしょうがないか? ちと、わかりにくいかなぁ?
「DisplayObject3D」とか「Camera3D」とかクラス名見る限り「Papervision3D」 を移植しようと思ってるのかな? ただ「Papervision3D」は、主力開発者が抜けて、すたれかけているような気がする。 何つってもCPUに負荷をかけるから重いしねぇ。
回転だけに特化してるので、書き方がシンプルでわかりやすい。 色んなことするのは難しそう。
シンプルでわかりやすそう。 コールバックもついてる。
このサイトの作りかけ中の「Photo」みたいな動きw 少ないコードで実現してますが、このままだと応用がきかなそうだ。
「OpenGL」に対応してくると、AjaxもFlashも格段に作り方が違うんだろうけど。 てか、おいらも「OpenGL」プログラムをそろそろ覚えないと(-_-;)
iPhoneの「Ustream Broadcaster」使ってみたけど、すげぇ簡単にライブ配信できる。 自分のiPhoneで早速試してみた(^_^) justinは完全に差をつけられた感じだなぁ。 Ustreamはかなり技術力あってSoftbankも出資したし、ストリーミングは「Ustream」一本で間違いないだろう。
って訳で、このサイトも「Ustream」対応しようかと。
ちなみに、CMSとかでHTML出力するブロガーなら、JSやFlashガジェットタグ貼り付けるだけっす。 このサイトみたくフルFlashや自作でガジェット作りたい人は、公式サイトに「Ustream API」を利用。 パッと見だけど、わかりやすくてよく出来てると思う。
■Ustream APIデベロッパー登録 http://developer.ustream.tv/
登録すると「API Key」がゲットできます。
■Ustream APIドキュメント(英語) http://developer.ustream.tv/data_api/docs
html,json,xml,phpのモードがあるけど、汎用性考えるとJSONっすね。 (PHPはsirializeで返ってくるけど、JSON使えればあんま意味ない気も) しかも「Flash Client API」まで公開されてる!
■Flash Client API ▽ドキュメント http://developer.ustream.tv/external/flash/
▽SVN http://svn.ustream.tv/flash/rsls/
クロスドメイン制限してないのかな? 後々試してみます。
■API例 ▽チャンネル一覧 http://api.ustream.tv/json/user/yohei/listAllVideos?key=API Key
■動作確認用のサンプル [as3] class UStreamService extends Service {
public function getChannels() {
$params->user = UstreamのユーザID;
$params->channel = Ustreamチャンネル名;
$url = $this->getChannelListURL($params);
$result = file_get_contents($url);
$results = json_decode($result);
return $results
}
private function getChannelListURL($params, $mode="json") {
$url = USTREAM_API_URL."/{$mode}/user/{$params->user}/listAllVideos?key=".USTREAM_API_KEY;
return $url;
}
} [/as3] 仕様決まれば簡単にファイル分離できそうです。 本家サンプルではcurl使ってるけど、この程度ならfile_get_contentsで十分かな?
おぉ!GoogleMapAPIのFlex用ライブラリーがswc形式でGoogle本家にあがってます(^_^)/ これで、わざわざFlashとJavaScriptの連携しなくてもよさげ? 3分クッキングで作成してみた。
■google_map.swf htmlTextは機能ダメダメだけど、imgタグでswfを直で読めるんだぁ・・・ (^_^)つ ペタッ まだクラスの中身を詳しく見てないけど、swf間で通信(LocalConnection等)を実装すれば色んなことできそうです。
■Google Maps API for Flash - FlexBuilder ▽チュートリアル http://code.google.com/intl/ja/apis/maps/documentation/flash/tutorial-flexbuilder.html
▽ダウンロード http://maps.googleapis.com/maps/flash/release/sdk.zip
■Maps API キーの取得 ドメイン毎にMapsAPIキーを生成できます。 http://code.google.com/intl/ja/apis/maps/signup.html ドメイン毎に発行なので、開発環境と本番ではキーを別々にしなければいけません。
プログラムは、クラス実装さえわかれば難しいことはなさげです。 「ARK-Web」にわかりやすくまとめられています。 実践編ではFlexとJavaScript連携でやってますが、Flexオンリーでやった方が軽そうだけど、 HTML派に考慮しての事かと思います。
■動作確認サンプル ▽ソース これだけで、あっさり表示されます。 [as3] import com.google.maps.controls.ZoomControl; import com.google.maps.controls.MapTypeControl; import com.google.maps.controls.PositionControl; import com.google.maps.LatLng; import com.google.maps.Map; import com.google.maps.MapEvent; import com.google.maps.MapType;
private var map:Map;
private var locateX:Number = 35.728912;
private var locateY:Number = 139.7095082;
private function onInitialize(event:Event):void {
map = new Map();
map.key = GoogleMapキー;
map.addEventListener(MapEvent.MAP_READY, onMapReady);
mapContainer.addChild(map);
}
private function onResize(event:Event):void {
map.setSize(new Point(mapContainer.width, mapContainer.height));
}
private function onMapReady(event:Event):void {
map.setCenter(new LatLng(locateX, locateY), 14, MapType.NORMAL_MAP_TYPE);
map.addControl(new ZoomControl());
map.addControl(new PositionControl());
map.addControl(new MapTypeControl());
}
[/as3] locateX、locateYの位置指定は、GoogleMapのパラメータを直接埋め込んでますが、 各パラメータをGoogleからシームレスにやり取りできるかですね。 只今、このサイトと連動できるよう作成中で、何だか面白くなってきました。
がちょーん!!FlashCSだけに「FlvPlayback」等の便利なVideoコンポーネントがあるw Flexにないコンポーネントってあるんだねぇ(^_^;) どうりで最近動画プレイヤーが出回ってると思ったら・・・。
■FlashのVideoコンポーネント(Flexには標準で未実装) ビデオプレイヤーの再生・停止は勿論、シークやボリューム等もGUIだけで作れちゃうん。 これならデザイナーさんには重宝されますなぁ(^_^) とは言っても、外部ビデオファイル取得とか他とのマッシュアップとかの処理は、結局ガリガリかかないといけないが・・・。
しかし、こんな便利なもんあるなら俺もFlashで作ろうか?と。 けど「fl.video」パッケージを探せば何とかなるんじゃね?と調べたら、ありました!
■Adobe Flash Media Server productivity tool FMS用のツールなんだけど、Flexでも使えそうです。 Adobe本家から「Adobe Flash Media Server productivity tool」をダウンロードできます。
https://www.adobe.com/cfusion/entitlement/index.cfm?event=custom&sku=FS0000503&e=fms35
FMS用のツールで、他にもやら面白げなライブラリーがある。
「Dynamic Streaming Class」って何?何?これ??(^_^) もしかして動的にAS書き出せちゃうのか???(違うか。。。)
とりあえず後回しで「FLVPlayback2.5」を使ってみる。 サンプルでスキンもswfで用意されている。 欲を言えば、スキンはswfでなくてas + 素材で欲しかったなぁ。 FlashCSみたくカスタムコンポーネント化すれば、もっと便利かも
■サンプルソース [as3] private function playTopVideo():void { var video:FLVPlayback = new FLVPlayback(); var ui:UIComponent = new UIComponent(); view.topVideo.addChild(ui); ui.addChild( video ); video.width = 320; video.height = 240; video.source = "movie/empire.mp4"; video.skinBackgroundColor = 0x666666; video.skin = "swf/FLVPlaybackSkins/SkinUnderAll.swf"; video.scaleMode = VideoScaleMode.MAINTAIN_ASPECT_RATIO; video.skinAutoHide = false; } [/as3]
かなり煩雑なコードになってきたので、クラス化と言う名のリファクタリング。 意地でもPEARや他のライブラリは使わないぞw
■修正内容 VoiceService ver0.2 (1) MixiVoice、Twitterクラス化・ファイル整理
VoiceService | getVoices() | MixiVoice --> HTTPService Twitter --> HTTPService
(2) HTTPサービスクラス「HTTPService」作成 「HTTPRequestService」の命名の方が正しいかも!?
(3) 同時投稿機能追加 とり合えず最低限の実装 ・Twitterは、Basic認証でなくてtokenにするのが今後の課題 ・Mixiは、htmlパースとログイン処理が課題
■VoiceService(抜粋) ファイル分離して非常にわかりやすくなったv(^_^)v
/**
* mixi & Twitterボイス取得
**/
public function getVoices()
{
$mixi_voice = new MixiVoice();
$voices['mixi'] = $mixi_voice->getVoices();
$twitter = new Twitter();
$voices['twitter'] = $twitter->getUserTimeline();
$results = $this->_marge_voices($voices);
dump($results);
return $results;
}
/**
* mixi & Twitterボイス同時投稿
**/
public function postVoice($values)
{
if ($values->message && $values->password == VOICE_PASSWORD) {
$mixi_voice = new MixiVoice();
$is_mixi = $mixi_voice->postMessage($values->message);
$twitter = new Twitter();
$is_twitter = $twitter->postMessage($values->message);
return ($is_mixi && $is_twitter);
}
}
※「$this->_marge_voices($voices)」は、MixiVoiceとTwitterデータをマージしてJSON化してる
■MixiVoice(抜粋) 「HTTPService->request」を実装して、paramsをオブジェクトで渡すようにした。 とりあえず、こんなもんかな?
/**
* mixiボイス取得
**/
public function getVoices()
{
$this->login();
$params->url = MIXI_ECHO_LIST_URL;
$params->method = 'POST';
$html = $this->request($params);
$results = $this->parseVoice($html);
return json_encode($results);
}
■Twitter(抜粋) このクラス名だと、また膨大になりそうな予感だけど。。。 これもパラメータをオブジェクトで渡すようにした。
/**
* Twitter投稿
**/
public function postMessage($message)
{
if (!$message) return;
$posts['status'] = $message;
$params->posts = $posts;
$params->url = TWITTER_UPDATE_JSON_URL;
$params->basic->id = TWITTER_USER_NAME;
$params->basic->password = TWITTER_PASS;
$results = $this->curlRequest($params);
return $results;
}
■HTTPService(抜粋) これが肝のクラス。 なので、頭が整理できてなずサッパリ(T_T)
cokkie処理やBasic認証が両立できなくて、とりあえず「curl」と「file_get_contents」の併用です。
▽各メリット ・curl:細かいことができそうで速い ・file_get_contents:ソースが短くできそう
最終的にはcurlで統一するかな?
/**
* HTTPリクエスト(curl)
**/
public function curlRequest($params)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $params->url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//POST
if ($params->posts) {
$posts = http_build_query($params->posts, '', '&');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $posts);
}
//cookies
//TODO
//curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie");
//BASIC認証
if ($params->basic) {
curl_setopt($ch, CURLOPT_USERPWD, "{$params->basic->id}:{$params->basic->password}");
dump($params->basic);
}
$results = curl_exec($ch);
curl_close($ch);
return $results;
}
/**
* HTTPリクエスト(file_get_contents)
**/
public function request($params) {
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
if (is_array($params->posts)) {
$content = http_build_query($params->posts, '', '&');
$content_length = strlen($content);
$headers[] = "Content-Length: {$content_length}";
$requests['http']['content'] = $content;
}
//Basic認証
if ($params->basic) {
$basic = base64_encode("{$params->basic->id}:{$params->basic->password}");
$header[] = "Authorization: Basic ".$basic;
}
//cokkie
//TODO paramsかセッションにする?
if ($this->cookie) {
$headers[] = "Cookie: {$this->cookie}";
}
if ($params->method) {
$method = $params->method;
} else {
$method = 'GET';
}
$requests['http']['method'] = $method;
$requests['http']['header'] = implode("\r\n", $headers);
$context = stream_context_create($requests);
$contents = file_get_contents($params->url, false, $context);
//cookie取得・設定
if ($http_response_header) {
$this->setCookieForHttpResponseHeader($http_response_header);
}
return $contents;
}
※「$this->setCookieForHttpResponseHeader」は、HTTPヘッダーをパース
FlashのhtmlTextの機能、何とかならんかね~>Adobe せめて画像の回り込みぐらい(T_T)
さて、Androido本を買ってみた(もち会社経費でw)。
「Google Androidプログラミング入門 (大型本)」
豆蔵社員が作ってて、本質的な基礎部分に触れていて結構わかりやすいと思う。
出版不況とは言えども、こう言う専門書籍とかは手に持ってみたい感じがする。
ざっと見た感じ、
(1) ファイル構成 (2) Actibity、イベント (3) Intentによるデータ管理
この辺の概念を抑えればとり合えずアプリは作れそうだ。 サンプルアプリ作ってみたけど、結構わかりやすいと思う。
とは言っても、コンポーネントやサービスが膨大っぽいし、実機を持ってないからなぁ・・・。 なんかAndroidの実機が欲しくなってきたこの頃(^^)
■個人的感想 ・Javaベースなので入りやすい →iPhone SDKみたく「Objective-C」覚えなくて良い
・思想がMVCっぽくて、階層がわかりやすい →人によって作り方が大きく変わることがない感じ これは重要
・XMLの定義は、FlexのMXMLと基本概念は同じ →UIベースで定義できるのでスピーディー ただ、第一印象では機能的に物足りない感(機能を知らないだけかも知れんが)
・データバインディングが面倒くさい感 →ソースベースでしかできないのかな? 「WebObjects」や「iPhone SDK」のInterfaceBuilder機能が搭載されれば、かなりスピーディーになると思う
・「自動ビルド」に設定しておくと、ビルドエラーが多発 →原因調べないと・・・
・イベント監視が面倒くさそう →モバイルフォンだから仕方ないが・・・
何か勉強してる時間がない。。。 と言い訳はしたくないから、無理にでもやるw
まずは環境整備から。 「Android SDK + Eclipse ADT」で構築してみる。
とりあえず、「Android Developers」を見ながらインストール。 ちょうど「Android 2.1 API Level 7」がリリースされてた。 そもそも、Ver1.xから何が違うのかすらわからない状態だが(笑)
基本は、 (1) SDKのパスとおして (2) Eclipse Plugin入れて (3) EclipseでSDK Componentsをインストール
自宅はMac、会社ではWindows版を。
自分メモ ■SDK (1) ダウンロード android-sdk_r04-windows.zip
(2) インストール先はC直下にした。 C:\air2_b1_sdk_win_111709
(3) toolsへのPath追加 C:\android-sdk-windows\tools
■ADT Plugin for Eclipse - 設定マニュアル http://developer.android.com/sdk/eclipse-adt.html
(1) Eclipse 3.4 (Ganymede)なので、以下のインストールURL https://dl-ssl.google.com/android/eclipse/
(2) ウィンドウ > 設定 > Androido (3) SDKロケーション設定して【適用】
C:\android-sdk-windows
この時点で、パッケージはインストールされてなかったので、
(4) ウィンドウ > Android SDK and AVD Manager > Avalible Pakages (5) パッケージを選択して【Install Selected】 ちょい時間がかかる。 全部入れる必要はなかったかな?w (6) Virtual Devicesもとり合えず設定
■動作確認でプロジェクト作成 基本は通常のプロジェクト作成と同じ
(1) ファイル > 新規 > Androidプロジェクト (2) 各項目設定 - BuildTarget:とり合えず最新の2.1(API Level7)を選択 - アプリケーション名:Hello - パッケージ:jp.co.telepath(任意) - Create Activity:Activityを継承するクラス名 ※Activity = Androidアプリ画面 Androidアプリ作成の基本“Activity”とは何か?
(3)【完了】
で、ここでBuildエラーw Eclipseで自動ビルドにしておくと、genがうまく作成されないらしい(ホント?) なんで、
■genのクリーンアップ (1)「自動的にビルド」のチェック外す (2) genディレクトリ削除 (3) プロジェクト > クリーン 一応、コンパイルされた。
■確認 (1) HelloWorld的なw [java] package jp.co.telepath;
import android.app.Activity; import android.os.Bundle; import android.widget.TextView;
public class Hello extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setText("OKOKOK"); setContentView(tv); }
} [/java]
onCreateはイベントハンドラっぽいな。 Activityの状態遷移に記載されてるのが全てなのかな? 何かイベント管理が大変そうだけど。。。 その前にActivityクラス等のソース見れるようにしないとw
(2) 実行 バーチャル携帯の起動遅い・・・結構ストレスかもw
てな訳で次は、まずAndoroidの基礎知識から!
iPhoneがFlashを載せない理由
Flashはバギーだし、HTML5で十分
やっとRIAが業界全体が動き始めた実感。
「Flash vs HTML5」って文字を良く見るけど、個人的にはどっちでも同じかなぁ?と思う。
どっちを選択しようと、デベロッパ的にはやる事は変わらないと思う。
問題は、FlashであろうとHTML5であろうと、デザイナーとデベロッパの境界線が更にグレーになる。
個人的には、FlashもHTML5(JS・CSS含む)もWebデザイナーで全部作ってくれと言いたいが・・・
多分、この中間層の人材需要が増えるんじゃないかな?と思う。
さて、HTML5優位とはいいつつ、現状はFlashに劣っている部分は否めないと思う。
■現状のHTML5 + JSの問題点・疑問点
(1) ブラウザ依存しすぎ これが一番懸念されてることすよね。
(2) ライブラリが規格統一されてない jQuery、PrototypeJs、YUIと選択肢が多すぎてこの先どうなるのか?
(3) 開発標準環境が確立されてない これはまだ仕方ないけど、時間短縮は開発ツールが命だからねえ。 JSに関してはせめてヒエラルキーを追えるツール探さなきゃ(Eclipse Pluginとかあるのかな?)
(4) 既にActionScript3.2で実現可能
JSでしかできない秀逸な機能が今のところ見当たらない FlashPlayer10.1 & Air2.0はかなり面白いのだが、どうなるのかなぁ? どちらにしろHTML5、JSのクラス実装くらいは把握しておかないと死ねる。 あとAndroido、XCodeは手をつけておかないと。
PHPライブラリは誰かの「twitter2mixivoice.php」もあったけど、
(1) PEAR依存 (2) 自前だと修正・拡張ができる
なんで、ライブラリも自前で。
■問題点 (1) mixiボイスのAPIがない →よって、無理矢理ログインしてHTMLパース以外方法なし
(2) クロスドメイン制限 →swfで直接通信が理想なんだけど、mixiもtwitterもクロスドメイン制限があるので断念 サーバかまして処理する事に
■主なポイント (1) AMF通信 →高速かつFlexとオブジェクトの親和性が高いAMFを採用 JSON、XML変換できるけど、今は必要なし てか、XMLって遅いし面倒だし通信においてメリットあるのか?といつも疑問に思う。
(2) データのマージ twitterはJSON、mixiはテキスト取得して日付ソートしながらデータマージ (超暫定で最低限のタイトルと日付だけ)
とりあえずデータ取得&マージまで作ったので、あとはマルチ投稿の仕様考える。 ある程度まとったら機能毎にクラス化へ。
途中までのソース うーん、デザイン的にコードは別途コンポーネント作った方がいいなw swf側ソースは、色々ネタが多いので別途記事にする予定(?)
■VoiceService.php
require_once 'Service.php';
class VoiceService extends Service {
/**
* データ取得
**/
public function getVoices() {
$voices['mixi'] = $this->mixi_voices();
$voices['twitter'] = $this->twitter_user_timeline();
$results = $this->_marge_voices($voices);
return $results;
}
/**
* Twitterタイムライン取得
**/
private function twitter_user_timeline()
{
$this->_twitter_auth();
$url = "http://twitter.com/statuses/user_timeline/{$this->twitter_user_name}.json";
$url.= "?since=".urlencode(date('D, d M Y G:i:s GMT', strtotime('-10 day')));
$results = $this->_twitter_request($url);
return $results;
}
/**
* Twitter投稿
**/
private function post_twitter()
{
if ($_POST['message']) {
$this->_twitter_auth();
$message = rawurlencode($_POST['message']);
$url = "http://twitter.com/statuses/update.json";
$posts = "status={$message}";
$results = $this->_twitter_request($url, $posts);
return $results;
}
}
/**
* mixiボイス取得
**/
private function mixi_voices()
{
$this->_mixi_login();
$url = 'http://mixi.jp/list_echo.pl';
$headers[] = "Cookie: {$this->cookie}";
$html = $this->_mixi_request($url, $headers, 'POST');
$results = $this->_parse_mixi_voice($html);
return json_encode($results);
}
/**
* mixiボイス投稿
**/
private function post_mixi_voice()
{
$this->_mixi_login();
$url = 'http://mixi.jp/list_echo.pl';
$headers[] = "Cookie: {$this->cookie}";
$html = $this->_mixi_request($url, $headers, 'GET');
$post_key = $this->_get_mixi_voice_post_key($html);
$url = 'http://mixi.jp/add_echo.pl';
$body = 'てすとー'.date('Y/m/d H:i');
$posts = array(
'body' => $body,
'post_key' => $post_key,
'redirect' => 'recent_echo',
'default_value' => $body,
);
$html = $this->_mixi_request($url, $headers, 'POST', $posts);
$results = mb_convert_encoding($html, 'UTF-8', 'EUC-JP');
echo($results);
}
/**
* データ形式の統一
**/
private function _marge_voices($values)
{
if (is_array($values)) {
foreach ($values as $type => $value) {
$voices = json_decode($value);
foreach ($voices as $key => $voice) {
$time = strtotime($voice->created_at);
$sort_times['time'] = $time;
$result['type'] = $type;
$result['time'] = $time;
$result['created_at'] = date('Y-m-d H:i:s', $time);
$result['text'] = $voice->text;
$results[] = $result;
}
}
}
if (is_array($result)) {
array_multisort($sort_times, SORT_DESC, $results);
json_encode($results);
return $results; }
}
/**
* twitter認証設定
**/
private function _twitter_auth()
{
$this->twitter_user_name = TWITTER_USER_NAME;
$this->twitter_email = TWITTER_EMAIL;
$this->twitter_password = TWITTER_PASS;
}
/**
* mixi認証設定
**/
private function _mixi_auth()
{
$this->mixi_id = MIXI_ID;
$this->mixi_email = MIXI_EMAIL;
$this->mixi_password = MIXI_PASS;
}
/**
* mixiログイン処理
**/
private function _mixi_login()
{
$this->_mixi_auth();
$posts = array(
'email' => $this->mixi_email,
'password' => $this->mixi_password,
'next_url' => 'http://mixi.jp/home.pl'
);
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
$url = 'http://mixi.jp/login.pl';
$this->_mixi_request($url, $headers, 'POST', $posts);
}
/**
* mixiボイスpost_key取得
**/
private function _get_mixi_voice_post_key($html)
{
if ($html) {
$html = mb_convert_encoding($html, 'UTF-8', 'EUC-JP');
}
$rows = explode("\n", $html);
if (is_array($rows)) {
foreach ($rows as $key => $row) {
$pattern = '|]+>(.*)]+>|U';
preg_match("{$pattern}", $row, $values);
preg_match('/post_key=(.+)&/', $row, $params);
if ($params) {
$post_key = $params[1];
if ($post_key) {
return $post_key;
}
}
}
}
}
/**
* mixiボイスパース
**/
private function _parse_mixi_voice($html)
{
if ($html) {
$html = mb_convert_encoding($html, 'UTF-8', 'EUC-JP');
}
$rows = explode("\n", $html);
if (is_array($rows)) {
foreach ($rows as $key => $row) {
$pattern = '|]+>(.*)]+>|U';
preg_match("{$pattern}", $row, $values);
$pattern_posttime = '';
if (preg_match("{$pattern_posttime}", $values[0])) {
$voice['created_at'] = $values[1];
$voice['type'] = 'mixi';
}
$pattern_body = '';
if (preg_match("{$pattern_body}", $values[0])) {
$voice['text'] = $values[1];
$voices[] = $voice;
$voice = null;
$values = null;
}
}
}
return $voices;
}
/**
* mixi共通リクエスト
**/
private function _mixi_request($url, $headers, $method, $posts=null) {
if (is_array($posts)) {
$content = http_build_query($posts, '', '&');
$content_length = strlen($content);
$headers[] = "Content-Length: {$content_length}";
$params['http']['content'] = $content;
}
$params['http']['method'] = $method;
$params['http']['header'] = implode("\r\n", $headers);
$context = stream_context_create($params);
$contents = file_get_contents($url, false, $context);
//cookie設定
$this->_set_cokkie_for_response_header($http_response_header);
return $contents;
}
private function _set_cokkie_for_response_header($http_response_header) {
if (is_array($http_response_header)) {
foreach ($http_response_header as $r) {
if (strpos($r, 'Set-Cookie') === false) {
continue;
}
$params = explode(' ', $r);
$this->cookies[] = str_replace(';', '', $params[1]);
}
if (is_array($this->cookies)) {
$this->cookie = implode('; ', $this->cookies);
}
}
}
/**
* twitter共通リクエスト
**/
private function _twitter_request($url, $posts=null)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if ($posts) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $posts);
}
curl_setopt($ch, CURLOPT_USERPWD, "{$this->twitter_email}:{$this->twitter_password}");
$results = curl_exec($ch);
curl_close($ch);
return $results;
}
// WSSE Authentication
function _mixi_wsse_authentication_header() {
$nonce = pack('H*', sha1(md5(time().rand().posix_getpid())));
$created = date('Y-m-d\TH:i:s\Z');
$digest = base64_encode(pack('H*', sha1($nonce . $created . $this->mixi_password)));
$wsse_format = 'UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"';
$wsse = sprintf($wsse_format, $this->mixi_email, $digest, base64_encode($nonce), $created);
$header = "X-WSSE: {$wsse}";
return $header;
}
}
自宅←→会社の作業での個人プロジェクト共有のお話
ファイル転送ソフトとかいい加減馬鹿らしいので、SVNをyoo-s.comに構築している。 と記事にするまでもないネタだったのだが・・・
http経由でソースをオール公開していたのだが、 個人設定情報も去年から丸見えだった!事に今日気づくw
mixiとtwitterはおろか、Googleアカウントまで乗っ取られるとこだった((_))
取り合えずBasic認証をかける。 やっぱライブラリ系以外のソース公開は無理だな。
■Apache設定
#vi /etc/apache2/mods-available/dav_svn.conf
DAV svn
SVNParentPath /var/svn
AuthType Basic
AuthName "Subversion Repository"
AuthUserFile /etc/apache2/dav_svn.passwd
AuthzSVNAccessFile /etc/apache2/dav_svn.authz
Require valid-user
■Basic認証設定 - ユーザファイル
#vi /etc/apache2dav_svn.authz
* = r ユーザ名 = rw
#htpasswd -c dav_svn.passwd ユーザ名