« 2011年12月 | トップページ | 2012年3月 »

2012年1月

2012年1月16日 (月)

DelphiでWindows Live(SkyDrive)・・・(3)

最後にいくつか補足しておきます。

まずは、ページングについて。Live SDKのREST APIではページングをサポートしてるのですが、公開したライブラリでもサポートしています。LiveClientオブジェクトのEnumerateXXX系のメソッドで、Pagingオブジェクト(IPagingインターフェース)を引数に取るメソッドがそうです。

PagingオブジェクトはTLive.CreatePagingメソッドで作成します。

ページングをする時、EnumerateXXX系で返されるIEnumerable<XXX>オブジェクトはIContinuableインターフェースを実装します。

IContinuableのPrevious、Nextプロパティで1つ前、1つ後のPagingオブジェクトが取得できるので、続きを取得するには、これらのPagingオブジェクトを使って取得できます。

例えば、10件ずつ、すべて取得するコードは次のようになります。

次は、IStreamについて。ファイルを作成したり、既存のファイルの中身を変更するためのメソッド、CreateFileやUpdateFileContent、また、ファイルの中身をダウンロードするためのGetFileContentメソッドは引数にIStreamを取ったり、返したりしますが、通常他のライブラリではTStreamを引数に取ったりするので、相互変換する必要があります。

TStreamからIStreamへの変換は、Classes.pasに定義されてる一度は目にしたことがあると思うTStreamAdapterを使えばいいのですが、その逆のIStreamからTStreamへの変換は、最初は逆はないのか??と思ってましたが、AxCtrls.pasにTOleStreamクラスが定義されてるので、これを使ったりしてください。

後は、プロキシとかのタイムアウトの設定なんですが、これは内部で使用しているWinInetのInternet(セッション?)ハンドルがLiveClientオブジェクトのInternetプロパティで取得できるので、後はWinInetの関数で設定してください。

2012年1月15日 (日)

DelphiでWindows Live(SkyDrive)・・・(2)

今回は前回までのログイン・認証を踏まえて、実際にSkyDriveにアクセスしてみる。
読み込むには、wl.skydriveスコープ、読み書きするにはwl.skydrive_updateスコープが必要なので指定しておいて下さい。

SkyDrive上のコンテンツはロカールファイルシステムと同じようにファイルやフォルダから構成され公開したライブラリではIResourceインターフェースを実装したResourceオブジェクトで表されます。LiveClientオブジェクトのSkyDriveを読み書きするためのメソッドは基本的にこのResourceオブジェクトを返します(例外がありますが・・・)。IResourceインターフェースは次のようになります。

ResourceTypeプロパティはリソースの種類を表します。

  • folder
  • album
  • file
  • audio
  • photo
  • video

の6種類あります(これらの定数はTResourceTypeクラスに定義)。まぁ、要するに、大別すると、fileとfolderに分けられ、fileであっても、画像ファイルならpicture、動画ファイルならvideoとなります。albumはfolderの特殊なケースです。fileかfolderかを判定するヘルパメソッドも容易してあります。

また、fileなら、IResourceインターフェースを継承したIFileResourceインターフェース、folderならIFolderResourceインターフェースも実装しているので、fileやfolderに特有の情報も取得できます。

同様に、IPhotoFileResourceやIVideoFileResourceとかもあるので、詳しくは、ソースを見てください。

各プロパティの意味はLive SDK REST API のFileやFolderオブジェクトなどの項を参照してください(ほとんどそのまま落とし込んでいるので・・)。

ここまでが基本で、実際に読み書きしてます。

例えば、ルートフォルダの中身を列挙する場合、まず、ルートフォルダの情報をLiveClientオブジェクトのGetRootFolderメソッドで取得します。Resourceオブジェクトで返されます。返されたResourceオブジェクトのIDを使い、LiveClientオブジェクトのEnumerateResourcesメソッドで列挙します。

IEnumerable<IResource>が返されるのでfor-inループで列挙して下さい。コードは例えば次のようになります。

これらと再帰を組み合わせれば、すべての中身を列挙できます。具体的にはLiveDemoアプリを参照。

また、フォルダを作成するには、親フォルダのIDや名前を指定して、CreateFolderメソッド、フォルダの名前などの変更やフォルダを削除するには、UpdateResource,DeleteReourceメソッドをターゲットのリソースのIDを指定して呼んで下さい。

同様に、ファイルを作成するには、CreateFileメソッドでアップロードするファイルの中身をIStreamで指定して呼んで下さい。

既に存在するファイルの中身を変更するには、UpdateFileContentメソッドを使います。この2つのメソッドだけIResourceを返しませんdashdash。ファイルのダウンロードはGetFileContentメソッドを使います。ファイル名の変更や削除はフォルダの場合と同じUpdateReource,DeleteResourceメソッドを使います(ちなみに、現状、REST APIを使ってアップロードできるファイルの種類はテキストファイル、Officeドキュメント、画像や動画の一部などにサーバーによってえらい制限されてますので、まじで使えん・・・dashdash)

他にもMoveResourceメソッドでファイル・フォルダなどの既存のリソースを移動できますが、CopyFileでは名前が示す通り、ファイルしかコピーできません。

具体的な使い方はLiveDemoアプリ見てくださいということで、ここでは手抜きします。

LiveDemoアプリの画面はこんな感じです(最初に、ClientIDなどを求められるので各自用意)。

Live2_0

右クリックでコンテキストメニューがでます。そこから例えば、「プロパティ」を選択すると、

Live2_1_2

また、ツリー上でドラッグ&ドロップよる、リソースの移動ができます。

まぁ、あくまでデモなのですべてではないですが、ファイルのアップロードやフォルダの作成など主要な操作はとりあえずカバーしてます。

というか、ほぼ似た作りのDropboxライブラリそして、放置されているPiyotterで使われてるTwitterライブラリもあるんだが、気が向いたら公開します(公開する場合、Demoアプリ作ったり、多少手直しが必要なので・・・だるいwobbly)。

DelphiでWindows Live(SkyDrive)

以前 にDelphi用のヘッダを公開した同期フレームワークMicrosoft Sync Frameworkを試すために、最初はDropboxと組み合わせて色々遊んでいたが、Dropbox APIの挙動で一部不満wobblyな部分があったので急遽、SkyDriveに変更したのだが、せっかくライブラリっぽく仕上げたので、公開してみる。

と、いっても最近のDelphiはクロスプラットフォーム開発環境にまっしぐらであるが、作ったライブラリは内部でWinInetを使って環境依存しまくりなのでdash。また、.NETはAsyncResult、TaskだのJavaはFutureだの非同期操作がまっさかりであるが、非同期操作はサポートしてないので(いい加減にしろよ、ウンコDelphi)・・・。特にSkyDriveのようにファイルのアップロード・ダウンロードなど巨大なデータをやり取りする場合、非同期操作のキャンセルができんとちょっと・・

まぁ、スレッドセーフには作ってあるので、自前でスレッド作って、同時にアクセスするのは問題ないんだが、肝心のキャンセルはできませんsad

ということで、ダウンロードは


から。

使用する場合は、LiveDemoフォルダ以外のユニットを全部プロジェクトに追加して下さい。
開発環境はDelphi2010です。XE,XE2ならまだしも2009は無理かも。ライブラリの動作環境は、Internet Explorer7以降が必要です。内部でのUrlの操作にIUriというものを使っているので。LiveDemoフォルダにLiveDemoアプリがありますが、こちらはVista以降が必要です。

事前準備として、Liveの基本的な知識はLive SDKのREST APIのドキュメントWindows Live Developer Center で学んでおいてください。Windows Liveのアカウントももちろん必要です(開発用のアカウントを作成する事をお勧めします)。後、アプリを自分で登録して、クライアントIDを発行してもらう必要がありますので。Registering Your Application with Windows Live を参考に登録してください。

まずは、主なユニットから

  • Live.pas
  • Live.Client.pas
  • Live.Protocol.Request.pas
  • Live.Protocol.Response.pas

Live.pasでLiveに関する基本的なインターフェースなどを定義しています。Live.Protocol.Request.pasとLive.Protocol.Response.pasで、LiveのREST APIの低レベルなラッパーを実装して、これらを使いLive.Client.pasで、LiveClientオブジェクトを実装しています。

通常は使用するユニットのuses節にLive.pasとLive.Client.pasの2つだけを追加すればいいはずです。この2つの中身を見れば分かると思いますが、すべてinterfaceベースですので、オブジェクトの破棄とか気にする必要はありません。

ということで簡単な使い方。

まず、TLive.CreateClientContextメソッドでクライアントアプリに関する情報を表すClientContextオブジェクト(IClientContextインターフェース)を作成します。

AClientID,AClientSecrentには発行されたクライアントIDとクライアントシークレットを指定します。クライアントシークレットはアプリ登録時に発行されますが、モバイルアプリとしてマークすればここでは、指定しなくてもよさそうです。RedirectUriにはアプリ登録時に指定したUriを指定します。登録時に指定していない場合というかデスクトップアプリの場合は指定しなくてよさげなのですが、その時はデスクトップアプリ用の特殊なリダイレクトUriであるhttps://oauth.live.com/desktopを指定して下さい。必要であれば、ALocaleにはTLocaleクラスで定義されてるロケールを。

次に、これを元にTLiveClientFactory.CreateClientメソッドでLiveClientオブジェクト(ILiveClientインターフェース)を作成します。

ここで、OAuth 2.0 を使って、ユーザーからユーザーの保護されたリソースにアクセスするための許可を取る必要があります。Windows LiveではOAuth 2.0で定義されたImplict grant、Authorization code grantと独自のgrantの計3つ?サポートされていますが、LiveClientオブジェクトはAuthorization code grantだけをサポートします。

まず、LiveClientオブジェクトのCreateAuthorizationUriメソッドでユーザーから認可を得るためのUriを求めます。

AScopesでスコープを指定します。OAuth 2.0ではスコープというもので、アクセスできる情報のレベルを制御できるようになっています。Windows Liveの場合、定義されているスコープの種類と意味はLive SDKのドキュメントのScopes and permissionsを参考に。

また、型がIEnumerable<string>になっていますが、これはヘルパメソッドを用意してあるので、自前で実装する必要はありません。

通常は、LiveDemoアプリのようにTWebBrowserコントロールをホストしたりして自動化するのですが、ここでは、手動でやりますので、求めたUriを自分でブラウザを起動して、開きます。

Windows Liveにログインしていなければ、まず、ログインページが表示されます。

Live1_0

ログインすると、アプリがユーザーの保護されたリソースにアクセスしてよいかを許可・拒否するページに移動します。

Live1_1

表示される中身は先ほど指定したスコープやロケールで変わります。上の画面ではロケールにTLocale.Japaneseを指定したので日本語で表示されています。ここでは、「はい」を選択して許可します。すると、先ほど指定したRedirectUriにブラウザがリダイレクトします。

RedirectUriにAuthorization codeが含まれてるので、それを抜き出し、LiveClientオブジェクトのLoginメソッドに渡してログインします。

成功すると認証に関する情報を表すAuthContextオブジェクト(IAuthContextインターフェース)が返されますが、ほっといていいでしょう(LiveClientオブジェクトのAuthContextプロパティにセットされるので)。以上をまとめると次のよう感じになります。

これで、やっと、SkyDriveにアクセスできるようになるのですが、長くなったので、次回に続く・・ということなんですが、OAuth 2.0に関してちょっと補足しておきます。

OAuth 2.0ではユーザーからの許可を取ると、クライアントアプリにAccess Token(AuthContextオブジェクトのAccessTokenプロパティ)というものが発行され、以後、クライアントアプリはこのAcesss Tokenを使ってユーザーの保護されたリソースにアクセスするのですが、発行されてからある期間(AuthContextオブジェクトのExpiresInプロパティ)すぎると失効したりします。

Windows Liveの場合、現状、3600秒つまり1時間でAccess Tokenが失効するっぽいので、失効したら再取得する必要があります。新しいAccess Tokenを取得するために上記のフローを繰り返すのではあんまりなので、OAuth 2.0にはRefresh Token(AuthContextオブジェクトのRefreshTokenプロパティ)という仕組みが用意され、これを使い簡単に新しいAccess Tokenを取得できます。Windows Liveの場合、要求するスコープにwl.offline_accessを含めるとRefresh TokenがAccess Tokenと共に発行されるようですので、必要ならばこのスコープを最初に指定しておいて下さい。

LiveClientオブジェクトでRefresh Tokenを使って、Access Tokenを再取得する場合は、LiveClientオブジェクトのRefreshAuthContextメソッドを呼んでください。

Refresh Tokenを使って、Access Tokenを取得するとき、以前に指定したスコープと同じかそれより狭い範囲のスコープの新しいAccess Tokenを取得できますが、通常はANewScopesパラメータにnilを指定すれば、以前と同じスコープのAcesss Tokenになるので、nilでいいでしょう。ちなみに、Windows Liveの場合、このRefresh Tokenの有効期間は1年くらいってどっかみたような・・

まぁ、自前でやるのはだるいので、LiveClientオブジェクトにはAutoLoginプロパティがあります。このプロパティがTrueの時、Refresh Tokenが発行されていて、現在のAccess Tokenが失効していそうなら(ファジーです)、自動で、再取得します。デフォルトはTrueです。PCの日付をある程度合わせておいてねup

« 2011年12月 | トップページ | 2012年3月 »

自作ソフトウェア

無料ブログはココログ

メモ