前の記事に続き、Flickr.NETを使う。
今度はFlickr Uploaderを作ってみた。Flickr.NETには
・Flickr APIへの認証(read/write/delete権限の取得)
・ファイル名を指定してアップロード
などの機能が揃っているのでさくっと作れた。
できたもの => Archive
ドラッグアンドドロップした写真1枚をアップロードする
■oAuthでの認証のためのtoken発行
今回はAPI keyに加えて、secretも使ってfrobを作ってtokenの発行を行わないといけない。
まずkeyとsecretを取りに行く→Flickr Services
その辺の仕組みは1つ前の記事と、
・Flickr API の認証 – まちゅダイアリー (2005-11-01)
・s.h.log: Flickr::Uploadで写真をアップロード
を参考に。
■プログラムを書く
まずfrobを作る。あとで使うのでとっておく(2回作ると違う値ができてしまうので)
Flickr flickr = new Flickr();
flickr.ApiKey = “your-api-key”;
flickr.ApiSecret = “your-api-secret”;
String flickr_frob = flickr.AuthGetFrob(); // frobの作成
で、認証画面をwebブラウザで開いて「OK」ボタンを押してもらう
System.Diagnostics.Process.Start(flickr.AuthCalcUrl(flickr_frob, AuthLevel.Write)); // 認証画面をブラウザで開く
OK押してもらってから、さっき作ったfrobを使ってtokenを取りに行く。
try{
Auth auth = flickr.AuthGetToken(flickr_frob);
flickr.AuthToken = auth.Token; // token取得
}
catch (FlickrApiException ex)
{
Console.WriteLine(ex.Message);
}
無事tokenを取って、Flickrオブジェクトにセットできたら、ファイル名を指定すればアップロードできる。tagやtitleやdescriptionを適当に付けてみた。
Photo p = new Photo();
p.PhotoId = flickr.UploadPicture(“PhotoFileName”, “test photo”, “これはてすとです”, “test,uploadertest”);
p.UserId = auth.User.UserId;
System.Diagnostics.Process.Start(p.WebUrl);
uploadされた写真のphotoIdが返ってくるので、それを使ってWeb上でのURLを求めることも出来る。今回はまたブラウザで開いてみた。
UploadPictureメソッドはどうやら内部でThread.Sleep()を呼んでいるみたいなので、そのままThreadで実行すればマルチスレッド化できる。
uploadを途中で止めるメソッドが無いみたいだけど、途中で止めたい時はスレッドで実行してAbort()してしまえば止まった。
詳しくは今回作ったアプリのソース参照
手順を強制するGUIのコードは長くなりがちだな。認証前にuploadボタンを押せないようにしておくとか。2回認証しないようにするとか。
FormFlickrUpload.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;using FlickrNet;
namespace FlickrUploadTest
{
public partial class FormFlickrUpload : Form
{
private Flickr flickr;
private String flickr_apikey = “cce8e143a8b4fd19c1e4026909643c67”;
private String flickr_secret = “5b58a24a5826ce2a”;
private String flickr_frob;
private String fileName;
///
/// Uploadするファイル
///
public String FileName
{
get
{
return this.fileName;
}
set
{
if (!new FileInfo(value).Exists) return;
panelDD.BackgroundImage = Image.FromFile(value);
this.fileName = value;
buttonUpload.Enabled = true;
}
}
private Auth auth;
private Thread threadUpload;public FormFlickrUpload()
{
InitializeComponent();
buttonUpload.Enabled = false;
progressBar.Visible = false;
panelDD.AllowDrop = true;flickr = new Flickr();
flickr.ApiKey = flickr_apikey;
flickr.ApiSecret = flickr_secret;
flickr_frob = flickr.AuthGetFrob();System.Diagnostics.Process.Start(flickr.AuthCalcUrl(flickr_frob, AuthLevel.Write)); // 認証画面をブラウザで開く
flickr.OnUploadProgress += new Flickr.UploadProgressHandler(flickr_OnUploadProgress);
}private void buttonGetToken_Click(object sender, EventArgs e)
{
try
{
auth = flickr.AuthGetToken(flickr_frob);
flickr.AuthToken = auth.Token;
buttonGetToken.Visible = false;
groupBoxDrop.Text = “Drop Photo here”;
if (auth.User.Username != null) Text = “Flickr Upload Test – ” + auth.User.Username;
else Text = “Flickr Upload Test – ” + auth.User.UserId;
}
catch (FlickrApiException ex)
{
Console.WriteLine(ex.Message);
}
}#region Drag and Drop
private void panelDD_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.All;
else
e.Effect = DragDropEffects.None;
}private void panelDD_DragDrop(object sender, DragEventArgs e)
{
string[] items = (string[])e.Data.GetData(DataFormats.FileDrop, false);
FileName = items[0]; // 1つ目のファイル
}
#endregion#region Upload
private void buttonUpload_Click(object sender, EventArgs e)
{
if (FileName == “”) return;
buttonUpload.Enabled = false;
panelDD.AllowDrop = false;
progressBar.Visible = true;
progressBar.Maximum = (int)(new FileInfo(this.FileName).Length/1000);
try
{
Photo p = new Photo();
threadUpload = new Thread(delegate()
{
p.PhotoId = flickr.UploadPicture(fileName, “test photo”, “これはてすとです”, “test,uploadertest”);
p.UserId = auth.User.UserId;
System.Diagnostics.Process.Start(p.WebUrl);
this.Invoke((MethodInvoker)delegate()
{
buttonUpload.Enabled = true;
panelDD.AllowDrop = true;
progressBar.Visible = false;
});
});
threadUpload.Start();
}
catch (FlickrApiException ex)
{
Console.WriteLine(ex.Message);
buttonUpload.Enabled = true;
}
}void flickr_OnUploadProgress(object sender, UploadProgressEventArgs e)
{
if (e.UploadComplete) // アップロード完了
{
this.Invoke((MethodInvoker)delegate()
{
progressBar.Value = 0;
});
}
else
{
this.Invoke((MethodInvoker)delegate()
{
progressBar.Value = e.Bytes / 1000;
});
}
}
#endregionprivate void FormFlickrUpload_FormClosed(object sender, FormClosedEventArgs e)
{
if(threadUpload != null) threadUpload.Abort(); // スレッド強制終了
}}
}