<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>橋本商会 &#187; Flickr</title>
	<atom:link href="http://shokai.org/blog/archives/tag/flickr/feed" rel="self" type="application/rss+xml" />
	<link>http://shokai.org/blog</link>
	<description>なんか作ったりした記録を忘れないうちに書くblog</description>
	<lastBuildDate>Sun, 20 May 2012 10:50:20 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com/" />
			<item>
		<title>Flickrダウンローダを作った</title>
		<link>http://shokai.org/blog/archives/4529</link>
		<comments>http://shokai.org/blog/archives/4529#comments</comments>
		<pubDate>Fri, 08 May 2009 18:29:31 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[Flickr]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://shokai.org/blog/?p=4529</guid>
		<description><![CDATA[Rubyで。ダウンロード部分はwgetに投げているのでUnix系でしか動かせないかもしれない。REXML::XPath使うのの勉強になった。 shokai / Flickr downloader / overview — [...]]]></description>
			<content:encoded><![CDATA[<p>
Rubyで。ダウンロード部分はwgetに投げているのでUnix系でしか動かせないかもしれない。REXML::XPath使うのの勉強になった。<br />
<br />
<a href="http://bitbucket.org/shokai/flickr-downloader/">shokai / Flickr downloader / overview — bitbucket.org</a><br />
<br />
タグ検索してユーザ指定したりもして（権限があれば）オリジナル画像を一括ダウンロードできる。<br />
<br />
<br />
実行例<br />
</p>
<blockquote><p>flickr-download beer,food 51753258@N00</p></blockquote>
<p>
で俺がbeerとfoodをタグを付けた写真が全部取ってこれて空腹を紛らわせれる。51753258@N00のところはユーザIDで、各ユーザぺージのRSSのURLを見ればわかる。<br />
<br />
<br />
オリジナル画像を手に入れるためにFlickr APIの<a href="http://bitbucket.org/shokai/flickr-downloader/src/4dd993a2dee3/FlickrAPI.rb">photos.searchとphotos.getInfoのラッパーを実装した</a></p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/4529/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flickrのcontactの写真をMediumサイズで全部見る</title>
		<link>http://shokai.org/blog/archives/4278</link>
		<comments>http://shokai.org/blog/archives/4278#comments</comments>
		<pubDate>Mon, 09 Mar 2009 08:46:43 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[Flickr]]></category>
		<category><![CDATA[YahooPipes]]></category>

		<guid isPermaLink="false">http://shokai.org/blog/?p=4278</guid>
		<description><![CDATA[Pipes: Flickr Auto Feedで新着500件のRSSを作ってGoogle Readerに読み込ませたら快適になった。サムネイルじゃないのでビデオもGoogle Reader内で見れる。 ステキなガジェット [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://pipes.yahoo.com/pipes/pipe.info?_id=0pbkgAe63BGE6AHSJZhxuA">Pipes: Flickr Auto Feed</a>で新着500件のRSSを作って<a href="http://reader.google.com/">Google Reader</a>に読み込ませたら快適になった。サムネイルじゃないのでビデオもGoogle Reader内で見れる。<br />
<br />
<br />
ステキなガジェットを作っている人をかたっぱしからFlickrのコンタクトに加えていたら、いつのまにか100人を超えていて、とんでもない量の新着写真が毎日来るようになった。<br />
たとえば今、2日ぶりに新着を見てみたら656枚の写真があった。<br />
<br />
<br />
<a href="http://www.flickr.com/photos/friends/">Flickr: From your Contacts</a>を見ると自分のコンタクトのアップロードした写真の一覧があるが、サムネイルなので何がなんだかわからなくて全然駄目。<br />
RSSも出ているけどこれもthumbサイズだし、なぜか新着20件しか取得できないので使い物にならない。普通のFlickrユーザは数十枚まとめてアップロードするので、すぐに新着が流れてしまって取りこぼしてしまう。<br />
<br />
本当はこのpipesをLDRで読みたいけど、PipesのRSSをLDRに登録してもPipes自体が重いからなのかFeedが来ない。なのでこれだけはGoogle Readerを使う事にした<br />
<br />
&#8212;&#8211;追記&#8212;&#8211;<br />
<a href="http://userscripts.org/scripts/show/12197">Google Reader Minimalistic for Greasemonkey</a>を使うと写真が画面に入りきるようになる</p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/4278/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GoogleEarth上でFlickrの位置情報付き写真を見れるサービスを作った</title>
		<link>http://shokai.org/blog/archives/1533</link>
		<comments>http://shokai.org/blog/archives/1533#comments</comments>
		<pubDate>Wed, 07 May 2008 19:31:39 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[Flickr]]></category>
		<category><![CDATA[GoogleEarth]]></category>
		<category><![CDATA[KML]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tech]]></category>

		<guid isPermaLink="false">http://shokai.org/blog/?p=1533</guid>
		<description><![CDATA[blogを書けなくて(MTが再構築できなくて)もう1ヶ月ぐらい前に作ったものになるけど、春休みにRuby on Railsのお勉強をしていて、その最終成果物としてGoogleEarth上でFlickrのGeoTag付き写 [...]]]></description>
			<content:encoded><![CDATA[<p>
<p>blogを書けなくて(MTが再構築できなくて)もう1ヶ月ぐらい前に作ったものになるけど、春休みにRuby on Railsのお勉強をしていて、その最終成果物として<a href="http://shokai.mag.keio.ac.jp/geophoto/">GoogleEarth上でFlickrのGeoTag付き写真を見れるサービス</a>を作ったのでまとめておく。</p>
<p>ついでに、緯度経度でFlickrの写真を検索できるAPIも公開してある。</p>
<p><a title="screen-capture.png by shokai, on Flickr" href="http://www.flickr.com/photos/shokai/2406826369/"><img src="http://farm4.static.flickr.com/3062/2406826369_dccc4835cf.jpg" alt="screen-capture.png" width="500" height="333" /></a></p>
<p>■実装方法<br /><br />
１．Flickrのタグ検索で、geotagが付いている写真を定期的にクロールしてきて、写真のURL、緯度経度をRailsのDBに溜める（photo modelに溜める）<br /><br />
２．GETパラメータで緯度経度をRailsに渡して、photo modelを検索する<br /><br />
３．検索結果をGoogleEarthで表示できるように、kml出力のViewを作る<br /><br />
４．GoogleEarthで視点が変わる毎にサーバーに問い合わせて、返ってきたkmlを表示するkmlを作る<br /><br />
５．mongrelでRailsを動かして、apache2のmod_proxy_balancerでRailsのURLをサブディレクトリに見せかける</p>
<p>こんな感じで。一番時間がかかったのが１のクローラの実装で、これは俺がRuby初心者すぎて2日ぐらいかかった。あとは、デンマーク行きの飛行機と帰りの空港からのバスでやったので5時間ぐらい。この辺は、データを溜めて、クライアントからのリクエストに基づいてフォーマットを決めて吐き出す部分が最初からできてるRailsのおかげ。</p>
<p>■１．geotag付き写真クローラ<br /><br />
まずFlickrはタグ検索ができるけど、数値じゃなくて「〜〜を含む文字列」としてしか検索できないので、例えば「北緯35度東経135度周辺の写真が欲しい」という時は使えない。なので、あらかじめメタデータを集めておいて、数値として範囲を指定して検索できるようにしておく。</p>
<p>geotagは小数点ありの値（geo:lat=35.2341など）なんだけど、普通にgeo:latやgeo:lonを含む写真一覧をFlickr APIから検索しても小数点無しのタグしか手に入らない。<br /><br />
小数点ありのタグを手に入れるために、Net::FlickrでFlickrAPIからタグ検索して、<br /><br />
→ <a href="http://d.hatena.ne.jp/shokai/20080312/1205309919">Net::Flickrで全public photoからタグ検索 &#8211; shokaiの日記</a><br /><br />
&#8220;geotagged&#8221;タグを含む写真をリストアップして、それから再度photo_idを使ってFlickrAPIのphotos.getInfoメソッドを使ってtagのraw attributeを見なければならなかった。<br /><br />
→ <a href="http://shokai.org/blog/archives/1507">s.h.log  RubyでFlickr APIのphotos.getInfoを呼ぶ</a></p>
<p>クローラ自体はRailsで実装されていなくて、ActiveRecordだけを使ってcronで1時間毎に実行されている。<br /><br />
→ <a href="http://shokai.org/blog/archives/1504">s.h.log  RailsなしでActiveRecordだけ使って、SQLiteを読み書きする</a><br /><br />
SQLiteのファイルがRailsと共有されているだけ。今回は、Rails側からの書き込みが無いので特に問題は起こらないだろうと判断した。</p>
<p>いまのところ10万枚の写真が集まった。SQLiteのファイルが欲しい人はあげます。</p>
<p>あと、クローラは連続でHTTPアクセスするとFlickrに悪い気がするので、適当にsleepを入れてみてるんだけど、そうすると実行に結構時間がかかる。これが、クローラを作って動かして直して作って…と繰り返す時に面倒だったが、和田さんに言われてscreenをデタッチ/アタッチするという技を覚えた。デタッチしておくと、sshを切断してもクローラが止まらなくて、アタッチしたら普通に続きからできる（もしくは結果が出てる）screenはクローラ作ってるときに重要。</p>
<p>■２．緯度経度をGETパラメータでRailsに渡して検索する</p>
</p>
<blockquote><p><p>photos.kml?lat=35&#038;lon=135&#038;size=thumb</p></p></blockquote>
<p>
<p>みたいな形式で、パラメータを渡してDBに溜めた写真を検索する。</p>
<p>→ <a href="http://d.hatena.ne.jp/shokai/20080408/1207638037">KMLを全部出すと多すぎたので、緯度経度を指定してその周囲の写真だけ出す &#8211; shokaiの日記</a><br /><br />
paramsで受け取れる。パラメータ名はシンボルになっているので注意。<br /><br />
controllerで、ActiveRecord::Baseのfind_by_sqlメソッドで普通に検索。（この方法だと四角い。PostgreSQLやMySQLの空間型を使えば丸くできるらしいがとりあえずSQLiteでやる）<br /><br />
そしてmodelの配列をViewに渡してやる。</p>
<p>■３．検索結果をGoogleEarthで表示できるように、kml出力のViewを作る<br /><br />
kml形式のviewを作る。views/photos/index.html.erb を参考にして、index.kml.erbを作ればok<br /><br />
mime-typeにkmlを追加しておく必要があった。<br /><br />
→ <a href="http://d.hatena.ne.jp/shokai/20080403/1207179775">flickrのgeotagついてる写真を収集してたので、kml出力するようにした &#8211; shokaiの日記</a></p>
<p>結果は巨大なkmlになるので、Rails標準搭載のWEBrickだときつい。でかいときはhttpサーバーをmongrelに換える。<br /><br />
→ <a href="http://d.hatena.ne.jp/shokai/20080331/1206925058">MongrelでRailsをデプロイ &#8211; shokaiの日記</a><br /><br />
→ <a href="http://d.hatena.ne.jp/shokai/20080331/1206926410">apache2のサブディレクトリをmongrelで起動してるrailsにプロキシする &#8211; shokaiの日記</a></p>
<p>■４．GoogleEarthで移動する毎に検索するkmlを作る<br /><br />
GoogleEarthの表示を作っているkmlは、静的な表示だけでなく、NetworkLinkタグで別のKMLの内容をURLを指定して読み込める。さらにViewRefleshModeをonStopにすると、画面の移動が止まった時に再読み込みできる。<br /><br />
再読込時に、視点の緯度経度を[lookatLat][lookatLon]で取得できるので、</p>
</p>
<blockquote><p><p>lat=[lookatLat]&amp;lon=[lookatLon]</p></p></blockquote>
<p>
<p>としてNetworkLinkで読み込むkmlのURLの後ろにくっつけてやる事で、GETパラメータになる。<br /><br />
→ <a href="http://d.hatena.ne.jp/shokai/20080408/1207638324">GoogleEarthで表示している場所の緯度経度から検索する &#8211; shokaiの日記</a></p>
<p>■５．mongrelでRailsを動かして、apache2のサブディレクトリに見えるようにする<br /><br />
デプロイ。<br /><br />
４まではMac OSX上でやって、ここからは<a href="http://d.hatena.ne.jp/shokai/20080218">大学院棟に置いたUbuntu</a>に移し替えた。RailsをSQLite+Mongrel環境で動かして、URLをapacheで隠すようにすると、Railsプロジェクトのディレクトリをそのまま移し替えるだけでほぼ動くので超楽。</p>
<p>→ <a href="http://d.hatena.ne.jp/shokai/20080408/1207647644">Flickrのgeotag写真を検索する &#8211; shokaiの日記</a><br /><br />
→ <a href="http://d.hatena.ne.jp/shokai/20080331/1206926410">apache2のサブディレクトリをmongrelで起動してるrailsにプロキシする &#8211; shokaiの日記</a><br /><br />
→ <a href="http://d.hatena.ne.jp/shokai/20080331/1206925058">MongrelでRailsをデプロイ &#8211; shokaiの日記</a><br /><br />
→ <a href="http://d.hatena.ne.jp/shokai/20080329/1206763523">Mongrel入れる &#8211; shokaiの日記</a></p>
<p>&#8212;&#8212;&#8212;&#8211;</p>
<p>こんな感じで、クローラの実装と、バックエンドのサービスとしてAPIを吐くためのRails、というのを覚えた。<br /><br />
今まで戦略的に「長い時間をかけたインタラクション」をするモノや、「データを共有した複数のモノと人とのインタラクション」を作る事を避けていたんだけど（ややこしくてプロトタイピングできないものは作らない方針なので）<br /><br />
Rails使うとサクサクとこのぐらいまではいけるようになったので、自分の得意なフィジカルなデバイス作成と合体させて何か新しい物を作る予定。</p>
</p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/1533/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>RubyでFlickr APIのphotos.getInfoを呼ぶ</title>
		<link>http://shokai.org/blog/archives/1507</link>
		<comments>http://shokai.org/blog/archives/1507#comments</comments>
		<pubDate>Mon, 17 Mar 2008 08:39:46 +0000</pubDate>
		<dc:creator>shokai</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[Flickr]]></category>
		<category><![CDATA[REXML]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://shlog.sakura.ne.jp/blog/?p=1507</guid>
		<description><![CDATA[Net::Flickrをインストールしたら、flickr.photos.getInfoメソッドが実装されてなかったので良い機会なので実装してみた。 flickr apiをrubyで使う &#8211; replore的日 [...]]]></description>
			<content:encoded><![CDATA[<p>
<p><a href="http://code.google.com/p/net-flickr/">Net::Flickr</a>をインストールしたら、<a href="http://flickr.com/services/api/flickr.photos.search.html">flickr.photos.getInfoメソッド</a>が実装されてなかったので良い機会なので実装してみた。<br /><br />
<a href="http://d.hatena.ne.jp/goinger/20070720/1184867418">flickr apiをrubyで使う &#8211; replore的日記</a>がとても参考になった。</p>
<p>FlickrAPIは普通にRESTなので、REXMLで取得してparseする。<br /><br />
今回自分で実装したのはgeotagまわりのため。FlickrのAPIの仕様でtagは小数点やハイフンが消されるので、その元の値を取るのにgetInfoメソッドが必要になる。Tagオブジェクトのrawからアクセスできるようにした。<br /><br />
使い方はphoto_idをコンストラクタに渡す。</p>
</p>
<blockquote><p><p>info = PhotoInfo.new(photo_id)<br /><br />
info.tags.each{ |tag|<br /><br />
puts tag.raw<br /><br />
}<br />
</p></p></blockquote>
<p>
<p>flickr-photos-getInfo.rb</p>
</p>
<blockquote><p><p>require&#8217;open-uri&#8217;<br /><br />
require&#8217;rexml/document&#8217;<br /><br />
require&#8217;cgi&#8217;</p>
<p>FLICKR_API_KEY=&#8217;your-api-key&#8217;</p>
<p>defflickr_call(method_name,arg_map={}.freeze)<br /><br />
args=arg_map.collect{|k,v|CGI.escape(k)<<'='<<CGI.escape(v)}.join('&#038;')<br /><br />
url=&#8221;http://www.flickr.com/services/rest/?api_key=%s&#038;method=%s&#038;%s&#8221;%<br /><br />
[FLICKR_API_KEY,method_name,args]<br /><br />
doc=REXML::Document.new(open(url).read)<br /><br />
end</p>
<p>classPhotoInfo<br /><br />
@xml_doc<br /><br />
definitialize(photo_id)<br /><br />
@xml_doc=flickr_call(&#8216;flickr.photos.getInfo&#8217;,'photo_id&#8217;=>photo_id)<br /><br />
end<br /><br />
deftags<br /><br />
tag_list=Array.new<br /><br />
REXML::XPath.each(@xml_doc,&#8217;//tag&#8217;){|tag|<br /><br />
tag_list<<Tag.new(<br /><br />
&#8216;id&#8217;=>REXML::XPath.first(tag,&#8217;attribute::id&#8217;),<br /><br />
&#8216;author&#8217;=>REXML::XPath.first(tag,&#8217;attribute::author&#8217;),<br /><br />
&#8216;raw&#8217;=>REXML::XPath.first(tag,&#8217;attribute::raw&#8217;),<br /><br />
&#8216;tag&#8217;=>tag.text<br /><br />
)<br /><br />
}<br /><br />
returntag_list<br /><br />
end<br /><br />
end</p>
<p>classTag<br /><br />
definitialize(args)<br /><br />
@id=args['id']<br /><br />
@author=args['author']<br /><br />
@raw=args['raw']<br /><br />
@tag=args['tag']<br /><br />
end<br /><br />
<br /><br />
defid<br /><br />
@id<br /><br />
end<br /><br />
<br /><br />
defauthor<br /><br />
@author.to_s<br /><br />
end<br /><br />
<br /><br />
defraw<br /><br />
@raw.to_s<br /><br />
end<br /><br />
<br /><br />
deftag<br /><br />
@tag.to_s<br /><br />
end<br /><br />
<br /><br />
defis_machine<br /><br />
if@tag=~/.+:.+=.+/<br /><br />
returntrue<br /><br />
else<br /><br />
returnfalse<br /><br />
end<br /><br />
end<br /><br />
<br /><br />
defis_geo<br /><br />
if@tag=~/geo:.+=.+/<br /><br />
returntrue<br /><br />
else<br /><br />
returnfalse<br /><br />
end<br /><br />
<br /><br />
end<br /><br />
end</p></p></blockquote>
<p>
</p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/1507/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# &#8211; Flickr.NETでFlickrアップローダ</title>
		<link>http://shokai.org/blog/archives/1482</link>
		<comments>http://shokai.org/blog/archives/1482#comments</comments>
		<pubDate>Sun, 13 Jan 2008 17:59:18 +0000</pubDate>
		<dc:creator>moblog</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Flickr]]></category>
		<category><![CDATA[Flickr.NET]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[VS2005]]></category>

		<guid isPermaLink="false">http://shlog.sakura.ne.jp/blog/?p=1482</guid>
		<description><![CDATA[前の記事に続き、Flickr.NETを使う。 今度はFlickr Uploaderを作ってみた。Flickr.NETには ・Flickr APIへの認証（read/write/delete権限の取得） ・ファイル名を指定 [...]]]></description>
			<content:encoded><![CDATA[<p>
<p><a href="http://web.sfc.keio.ac.jp/~shokai/archives/2008/01/cs-flickr-net-search-tag.html">前の記事</a>に続き、<a href="http://www.codeplex.com/FlickrNet">Flickr.NET</a>を使う。</p>
<p>今度はFlickr Uploaderを作ってみた。Flickr.NETには<br /><br />
・Flickr APIへの認証（read/write/delete権限の取得）<br /><br />
・ファイル名を指定してアップロード<br /><br />
などの機能が揃っているのでさくっと作れた。</p>
<p>できたもの => <a href="http://shokai.org/archive/cs2.0/0801_FlickrAPI/">Archive</a><br /><br />
ドラッグアンドドロップした写真1枚をアップロードする<br /><br />
<a title="uploader by shokai, on Flickr" href="http://www.flickr.com/photos/shokai/2189326366/"><img src="http://farm3.static.flickr.com/2021/2189326366_e924e883a6_o.png" alt="uploader" width="369" height="336" /></a></p>
<p>tagやtitleなどが適当に付いている<br /><br />
<a title="using Flickr.NET by shokai, on Flickr" href="http://www.flickr.com/photos/shokai/2188583024/"><img src="http://farm3.static.flickr.com/2019/2188583024_b8fa19bc1c.jpg" alt="using Flickr.NET" width="500" height="401" /></a></p>
<p>■oAuthでの認証のためのtoken発行<br /><br />
今回はAPI keyに加えて、secretも使ってfrobを作ってtokenの発行を行わないといけない。<br /><br />
まずkeyとsecretを取りに行く→<a href="http://flickr.com/services/api/keys/">Flickr Services</a><br /><br />
その辺の仕組みは<a href="http://web.sfc.keio.ac.jp/~shokai/archives/2008/01/cs-flickr-net-search-tag.html">1つ前の記事</a>と、<br /><br />
・<a href="http://www.machu.jp/diary/20051101.html#p01">Flickr API の認証 &#8211; まちゅダイアリー (2005-11-01)</a><br /><br />
・<a href="http://web.sfc.keio.ac.jp/~shokai/archives/2006/09/flickrupload.html">s.h.log: Flickr::Uploadで写真をアップロード</a><br /><br />
を参考に。</p>
<p>■プログラムを書く<br /><br />
まずfrobを作る。あとで使うのでとっておく（2回作ると違う値ができてしまうので）</p>
</p>
<blockquote><p><p>Flickr flickr = new Flickr();<br /><br />
flickr.ApiKey = &#8220;your-api-key&#8221;;<br /><br />
flickr.ApiSecret = &#8220;your-api-secret&#8221;;<br /><br />
String flickr_frob = flickr.AuthGetFrob(); // frobの作成</p></p></blockquote>
<p>
<p>で、認証画面をwebブラウザで開いて「OK」ボタンを押してもらう</p>
</p>
<blockquote><p><p>System.Diagnostics.Process.Start(flickr.AuthCalcUrl(flickr_frob, AuthLevel.Write)); // 認証画面をブラウザで開く</p></p></blockquote>
<p>
<p>OK押してもらってから、さっき作ったfrobを使ってtokenを取りに行く。</p>
</p>
<blockquote><p><p>try{<br /><br />
Auth auth = flickr.AuthGetToken(flickr_frob);<br /><br />
flickr.AuthToken = auth.Token; // token取得<br /><br />
}<br /><br />
catch (FlickrApiException ex)<br /><br />
{<br /><br />
Console.WriteLine(ex.Message);<br /><br />
}</p></p></blockquote>
<p>
<p>無事tokenを取って、Flickrオブジェクトにセットできたら、ファイル名を指定すればアップロードできる。tagやtitleやdescriptionを適当に付けてみた。</p>
</p>
<blockquote><p><p>Photo p = new Photo();<br /><br />
p.PhotoId = flickr.UploadPicture(&#8220;PhotoFileName&#8221;, &#8220;test photo&#8221;, &#8220;これはてすとです&#8221;, &#8220;test,uploadertest&#8221;);<br /><br />
p.UserId = auth.User.UserId;<br /><br />
System.Diagnostics.Process.Start(p.WebUrl);</p></p></blockquote>
<p>
<p>uploadされた写真のphotoIdが返ってくるので、それを使ってWeb上でのURLを求めることも出来る。今回はまたブラウザで開いてみた。</p>
<p>UploadPictureメソッドはどうやら内部でThread.Sleep()を呼んでいるみたいなので、そのままThreadで実行すればマルチスレッド化できる。<br /><br />
uploadを途中で止めるメソッドが無いみたいだけど、途中で止めたい時はスレッドで実行してAbort()してしまえば止まった。</p>
<p>詳しくは今回作ったアプリのソース参照</p>
<p><span id="more-1482"></span></p>
<p>手順を強制するGUIのコードは長くなりがちだな。認証前にuploadボタンを押せないようにしておくとか。2回認証しないようにするとか。<br /><br />
<a href="http://shokai.org/archive/cs2.0/0801_FlickrAPI/FlickrAPI/FlickrUploadTest/FormFlickrUpload.cs">FormFlickrUpload.cs</a></p>
</p>
<blockquote><p><p>using System;<br /><br />
using System.Collections.Generic;<br /><br />
using System.ComponentModel;<br /><br />
using System.Data;<br /><br />
using System.Drawing;<br /><br />
using System.Text;<br /><br />
using System.Windows.Forms;<br /><br />
using System.IO;<br /><br />
using System.Threading;</p>
<p>using FlickrNet;</p>
<p>namespace FlickrUploadTest<br /><br />
{<br /><br />
public partial class FormFlickrUpload : Form<br /><br />
{<br /><br />
private Flickr flickr;<br /><br />
private String flickr_apikey = &#8220;cce8e143a8b4fd19c1e4026909643c67&#8243;;<br /><br />
private String flickr_secret = &#8220;5b58a24a5826ce2a&#8221;;<br /><br />
private String flickr_frob;<br /><br />
private String fileName;<br /><br />
/// <summary><br /><br />
/// Uploadするファイル<br /><br />
/// </summary><br /><br />
public String FileName<br /><br />
{<br /><br />
get<br /><br />
{<br /><br />
return this.fileName;<br /><br />
}<br /><br />
set<br /><br />
{<br /><br />
if (!new FileInfo(value).Exists) return;<br /><br />
panelDD.BackgroundImage = Image.FromFile(value);<br /><br />
this.fileName = value;<br /><br />
buttonUpload.Enabled = true;<br /><br />
}<br /><br />
}<br /><br />
private Auth auth;<br /><br />
private Thread threadUpload;</p>
<p>public FormFlickrUpload()<br /><br />
{<br /><br />
InitializeComponent();<br /><br />
buttonUpload.Enabled = false;<br /><br />
progressBar.Visible = false;<br /><br />
panelDD.AllowDrop = true;</p>
<p>flickr = new Flickr();<br /><br />
flickr.ApiKey = flickr_apikey;<br /><br />
flickr.ApiSecret = flickr_secret;<br /><br />
flickr_frob = flickr.AuthGetFrob();</p>
<p>System.Diagnostics.Process.Start(flickr.AuthCalcUrl(flickr_frob, AuthLevel.Write)); // 認証画面をブラウザで開く</p>
<p>flickr.OnUploadProgress += new Flickr.UploadProgressHandler(flickr_OnUploadProgress);<br /><br />
}</p>
<p>private void buttonGetToken_Click(object sender, EventArgs e)<br /><br />
{<br /><br />
try<br /><br />
{<br /><br />
auth = flickr.AuthGetToken(flickr_frob);<br /><br />
flickr.AuthToken = auth.Token;<br /><br />
buttonGetToken.Visible = false;<br /><br />
groupBoxDrop.Text = &#8220;Drop Photo here&#8221;;<br /><br />
if (auth.User.Username != null) Text = &#8220;Flickr Upload Test &#8211; &#8221; + auth.User.Username;<br /><br />
else Text = &#8220;Flickr Upload Test &#8211; &#8221; + auth.User.UserId;<br /><br />
}<br /><br />
catch (FlickrApiException ex)<br /><br />
{<br /><br />
Console.WriteLine(ex.Message);<br /><br />
}<br /><br />
}</p>
<p>#region Drag and Drop<br /><br />
private void panelDD_DragEnter(object sender, DragEventArgs e)<br /><br />
{<br /><br />
if (e.Data.GetDataPresent(DataFormats.FileDrop))<br /><br />
e.Effect = DragDropEffects.All;<br /><br />
else<br /><br />
e.Effect = DragDropEffects.None;<br /><br />
}</p>
<p>private void panelDD_DragDrop(object sender, DragEventArgs e)<br /><br />
{<br /><br />
string[] items = (string[])e.Data.GetData(DataFormats.FileDrop, false);<br /><br />
FileName = items[0]; // 1つ目のファイル<br /><br />
}<br /><br />
#endregion</p>
<p>#region Upload<br /><br />
private void buttonUpload_Click(object sender, EventArgs e)<br /><br />
{<br /><br />
if (FileName == &#8220;&#8221;) return;<br /><br />
buttonUpload.Enabled = false;<br /><br />
panelDD.AllowDrop = false;<br /><br />
progressBar.Visible = true;<br /><br />
progressBar.Maximum = (int)(new FileInfo(this.FileName).Length/1000);<br /><br />
try<br /><br />
{<br /><br />
Photo p = new Photo();<br /><br />
threadUpload = new Thread(delegate()<br /><br />
{<br /><br />
p.PhotoId = flickr.UploadPicture(fileName, &#8220;test photo&#8221;, &#8220;これはてすとです&#8221;, &#8220;test,uploadertest&#8221;);<br /><br />
p.UserId = auth.User.UserId;<br /><br />
System.Diagnostics.Process.Start(p.WebUrl);<br /><br />
this.Invoke((MethodInvoker)delegate()<br /><br />
{<br /><br />
buttonUpload.Enabled = true;<br /><br />
panelDD.AllowDrop = true;<br /><br />
progressBar.Visible = false;<br /><br />
});<br /><br />
});<br /><br />
threadUpload.Start();<br /><br />
}<br /><br />
catch (FlickrApiException ex)<br /><br />
{<br /><br />
Console.WriteLine(ex.Message);<br /><br />
buttonUpload.Enabled = true;<br /><br />
}<br /><br />
}</p>
<p>void flickr_OnUploadProgress(object sender, UploadProgressEventArgs e)<br /><br />
{<br /><br />
if (e.UploadComplete) // アップロード完了<br /><br />
{<br /><br />
this.Invoke((MethodInvoker)delegate()<br /><br />
{<br /><br />
progressBar.Value = 0;<br /><br />
});<br /><br />
}<br /><br />
else<br /><br />
{<br /><br />
this.Invoke((MethodInvoker)delegate()<br /><br />
{<br /><br />
progressBar.Value = e.Bytes / 1000;<br /><br />
});<br /><br />
}<br /><br />
}<br /><br />
#endregion</p>
<p>private void FormFlickrUpload_FormClosed(object sender, FormClosedEventArgs e)<br /><br />
{<br /><br />
if(threadUpload != null) threadUpload.Abort(); // スレッド強制終了<br /><br />
}</p>
<p>}<br /><br />
}</p></p></blockquote>
<p>
</p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/1482/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C# &#8211; Flickr.NETでtag検索</title>
		<link>http://shokai.org/blog/archives/1481</link>
		<comments>http://shokai.org/blog/archives/1481#comments</comments>
		<pubDate>Sun, 13 Jan 2008 17:30:11 +0000</pubDate>
		<dc:creator>moblog</dc:creator>
				<category><![CDATA[未分類]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Flickr]]></category>
		<category><![CDATA[Flickr.NET]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[VS2005]]></category>

		<guid isPermaLink="false">http://shlog.sakura.ne.jp/blog/?p=1481</guid>
		<description><![CDATA[Flickr.NETという.NET Framework用のライブラリを使って、Flickr APIからタグ検索してみた。2年ぐらい前に使った時より、dllのファイルサイズが1.5倍に増えててた。 できたもの => Arc [...]]]></description>
			<content:encoded><![CDATA[<p>
<p><a href="http://www.codeplex.com/FlickrNet">Flickr.NET</a>という.NET Framework用のライブラリを使って、Flickr APIからタグ検索してみた。2年ぐらい前に使った時より、dllのファイルサイズが1.5倍に増えててた。</p>
<p>できたもの => <a href="http://shokai.org/archive/cs2.0/0801_FlickrAPI/">Archive</a><br /><br />
<a title="using Flickr.NET by shokai, on Flickr" href="http://www.flickr.com/photos/shokai/2188281686/"><img src="http://farm3.static.flickr.com/2350/2188281686_8713b5eb04_o.png" alt="using Flickr.NET" width="473" height="416" /></a></p>
<p>■dllを手に入れる<br /><br />
<a href="http://www.codeplex.com/FlickrNet">FlickrNet API Library &#8211; Home</a><br /><br />
[Release]から2.1.5をダウンロードしてきた。<br /><br />
んで、[参照の追加]でリンクして、</p>
</p>
<blockquote><p><p>using FlickrNet;</p></p></blockquote>
<p>
<p>する。</p>
<p>■API keyを手に入れる<br /><br />
<a href="http://flickr.com/services/api/keys/">Flickr Services</a>からAPI keyを手に入れないといけない。メールアドレスを登録してすぐ発行してもらえる。<br /><br />
今回は「デスクトップアプリ用」を選択。<br /><br />
（検索だけなら、secretとtokenを使ってoAuthで認証する必要は無い）</p>
<p>■プログラムを書く<br /><br />
<a href="http://www.flickr.com/services/api/">Flickr API</a>のラッパーなので、基本的な仕様はFlickr APIの方を見た方が良い。<br /><br />
今回は<a href="http://www.flickr.com/services/api/flickr.photos.search.html">flickr.photos.search</a>を叩いてみた。</p>
<p>まずFlickrというクラスが全ての根になっている</p>
</p>
<blockquote><p><p>using FlickrNet;<br /><br />
Flickr flickr = new Flickr(&#8220;your-api-key&#8221;);</p></p></blockquote>
<p>
<p>flickr.photos.searchでは色々なパラメータを渡すが、Flickr.NETではPhotoSearchOptionsクラスで集約されている。今回はタグだけでeveryoneから検索するのでこれだけだけど、もっと色々パラメータが指定できる。</p>
</p>
<blockquote><p><p>PhotoSearchOptions opt = new PhotoSearchOptions();<br /><br />
opt.Tags = &#8220;food, sfc&#8221;;<br /><br />
opt.TagMode = TagMode.AllTags;<br /><br />
Photos photos = flickr.PhotosSearch(opt); // 検索</p></p></blockquote>
<p>
<p>Photosクラスで返ってきた結果からURLを取り出して、表示する。<br /><br />
PictureBox.Imageにストリームから読み込ませるための関数 DownloadPicture(&#8220;URL&#8221;) を利用してダウンロードする。</p>
</p>
<blockquote><p><p>Photo p = photos.PhotoCollection[0]; // 1枚目<br /><br />
pictureBox.Image = Image.FromStream(flickr.DownloadPicture(p.MediumUrl));<br /><br />
textBoxPhotoUri.Text = p.WebUrl;</p></p></blockquote>
<p>
<p><span id="more-1481"></span></p>
<p>今回のメインクラス => <a href="http://shokai.org/archive/cs2.0/0801_FlickrAPI/FlickrAPI/FlickrDotNetTest/FormFlickrSearch.cs">FormFlickrSearch.cs</a></p>
</p>
<blockquote><p><p>using System;<br /><br />
using System.Collections.Generic;<br /><br />
using System.ComponentModel;<br /><br />
using System.Data;<br /><br />
using System.Drawing;<br /><br />
using System.Text;<br /><br />
using System.Windows.Forms;<br /><br />
using System.IO;<br /><br />
using System.Net;</p>
<p>using FlickrNet;</p>
<p>namespace FlickrDotNetTest<br /><br />
{<br /><br />
public partial class FormFlickrDotNetTest : Form<br /><br />
{<br /><br />
private Flickr flickr;<br /><br />
private String flickr_apikey = &#8220;17bd602a83ec433b0ed9fafd93549e1a&#8221;;<br /><br />
private Photos photos;<br /><br />
private int index;</p>
<p>public FormFlickrDotNetTest()<br /><br />
{<br /><br />
InitializeComponent();</p>
<p>buttonNext.Enabled = false;<br /><br />
buttonPrev.Enabled = false;<br /><br />
index = 0;</p>
<p>flickr = new Flickr(flickr_apikey);<br /><br />
}</p>
<p>public void reloadPhoto()<br /><br />
{<br /><br />
try<br /><br />
{<br /><br />
Photo p = photos.PhotoCollection[index];<br /><br />
pictureBoxResult.Image = Image.FromStream(flickr.DownloadPicture(p.MediumUrl));<br /><br />
textBoxPhotoUri.Text = p.WebUrl;<br /><br />
this.Text = &#8220;Flickr Search Test (&#8221; + index + &#8220;/&#8221; + photos.PhotoCollection.Length + &#8220;)&#8221;;<br /><br />
if (index < 1) buttonPrev.Enabled = false;<br /><br />
else buttonPrev.Enabled = true;<br /><br />
if (index >= photos.PhotoCollection.Length &#8211; 1) buttonNext.Enabled = false;<br /><br />
else buttonNext.Enabled = true;<br /><br />
}<br /><br />
catch (Exception ex)<br /><br />
{<br /><br />
Console.WriteLine(ex.Message);<br /><br />
}<br /><br />
}</p>
<p>private void buttonLoad_Click(object sender, EventArgs e)<br /><br />
{<br /><br />
buttonLoad.Enabled = false;<br /><br />
textBoxTags.Enabled = false;<br /><br />
PhotoSearchOptions opt = new PhotoSearchOptions();<br /><br />
opt.Tags = textBoxTags.Text;<br /><br />
opt.TagMode = TagMode.AllTags;<br /><br />
photos = flickr.PhotosSearch(opt);</p>
<p>index = 0;<br /><br />
reloadPhoto();<br /><br />
buttonLoad.Enabled = true;<br /><br />
textBoxTags.Enabled = true;<br /><br />
}</p>
<p>private void buttonPrev_Click(object sender, EventArgs e)<br /><br />
{<br /><br />
index&#8211;;<br /><br />
reloadPhoto();<br /><br />
}</p>
<p>private void buttonNext_Click(object sender, EventArgs e)<br /><br />
{<br /><br />
index++;<br /><br />
reloadPhoto();<br /><br />
}</p>
<p>private void textBoxTags_TextChanged(object sender, EventArgs e)<br /><br />
{<br /><br />
if (textBoxTags.Text == &#8220;&#8221;) buttonLoad.Enabled = false;<br /><br />
else buttonLoad.Enabled = true;<br /><br />
}<br /><br />
}<br /><br />
}</p></p></blockquote>
<p>
</p>
]]></content:encoded>
			<wfw:commentRss>http://shokai.org/blog/archives/1481/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

