リハビリがてらに、フォト蔵からflickrへと写真を移行するものを作ってみました。
flickrの有料アカウントを取得したので、もうフォト蔵を使うこともなさそうです。
(アルバム別ではなく)写真別に公開/非公開設定ができるflickrさんに惚れちゃいました(゚∀゚)ノ
gistにコードを置いておくのでよければお使いください~
(※一気に何枚もアップロードするのでパンクするかも)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class Http { | |
function post($url, $data, $option = array()) { | |
$option += array( | |
CURLOPT_POST => true, | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_POSTFIELDS => $data | |
); | |
$curl = curl_init($url); | |
curl_setopt_array($curl, $option); | |
$res = curl_exec($curl); | |
curl_close($curl); | |
return $this->_parseXML($res); | |
} | |
function get($url, $data = null, $option = array()) { | |
if (!is_null($data)) { | |
$url = $this->_createUrl($url, $data); | |
} | |
$option += array( | |
CURLOPT_RETURNTRANSFER => true | |
); | |
$curl = curl_init($url); | |
curl_setopt_array($curl, $option); | |
$res = curl_exec($curl); | |
curl_close($curl); | |
return $this->_parseXML($res); | |
} | |
function _createUrl($url, $data) { | |
$url .= '?'; | |
$params = array(); | |
foreach ($data as $key => $value) { | |
$params[] = $key.'='.$value; | |
} | |
$url .= implode('&', $params); | |
return $url; | |
} | |
function _parseXML($xml) { | |
return new SimpleXMLElement($xml); | |
} | |
} | |
class PhotoZou extends Http { | |
var $user = ''; | |
var $password = ''; | |
function __construct() { | |
$this->apiUrl = 'http://api.photozou.jp/rest/'; | |
$this->curlOption = array( | |
CURLOPT_USERPWD => $this->user.':'.$this->password, | |
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1 | |
); | |
} | |
function get($method, $data = null) { | |
return parent::get($this->apiUrl.$method, $data, $this->curlOption); | |
} | |
function post($method, $data = null) { | |
return parent::post($this->apiUrl.$method, $data, $this->curlOption); | |
} | |
} | |
class Flickr extends Http { | |
var $key = ''; | |
var $secret = ''; | |
var $baseUrl = 'http://api.flickr.com/services/'; | |
function __construct() { | |
$this->restUrl = $this->baseUrl.'rest/'; | |
$this->uploadUrl = $this->baseUrl.'upload/'; | |
$this->authUrl = $this->baseUrl.'auth/'; | |
} | |
function _getApiSig($data) { | |
ksort($data); | |
$auth_sig = ''; | |
foreach ($data as $key => $value) { | |
$auth_sig .= $key.$value; | |
} | |
return md5($this->secret.$auth_sig); | |
} | |
function rest($method, $data) { | |
$data['method'] = 'flickr.'.$method; | |
$data['api_key'] = $this->key; | |
if (isset($this->token)) { | |
$data['auth_token'] = $this->token; | |
} | |
$data['api_sig'] = $this->_getApiSig($data); | |
return parent::post($this->restUrl, $data); | |
} | |
function upload($photo, $data = array()) { | |
$data['api_key'] = $this->key; | |
if (isset($this->token)) { | |
$data['auth_token'] = $this->token; | |
} | |
$data['api_sig'] = $this->_getApiSig($data); | |
// 'photo' parameter should not be included in the signature | |
$data['photo'] = '@'.realpath($photo); | |
$res = parent::post($this->uploadUrl, $data); | |
return $data['async'] ? $res->ticketid : $res->photoid; | |
} | |
function auth() { | |
$params = array( | |
'api_key' => $this->key, | |
'perms' => 'write' | |
); | |
$params['api_sig'] = $this->_getApiSig($params); | |
$auth_url = parent::_createUrl($this->authUrl, $params); | |
header('Location: '.$auth_url); | |
exit(); | |
} | |
function getToken($frob) { | |
$res = $this->rest('auth.getToken', array( | |
'frob' => $frob | |
)); | |
$this->token = $res->auth->token; | |
} | |
} | |
if (isset($_GET['frob'])) { | |
// get token of flickr | |
$flickr = new Flickr(); | |
$flickr->getToken($_GET['frob']); | |
$photoZou = new PhotoZou(); | |
$z_albums = $photoZou->get('photo_album'); | |
foreach ($z_albums->info->album as $z_album) { | |
// !!!!!warning!!!!! | |
// album becomes public temporary | |
$photoZou->post('photo_edit_album', array( | |
'album_id' => $z_album->album_id, | |
'name' => $z_album->name, | |
'perm_type' => 'allow', | |
'perm_type2' => 'net' | |
)); | |
// get photo list | |
$z_photos = $photoZou->get('photo_list_public', array( | |
'type' => 'album', | |
'user_id' => $z_album->user_id, | |
'album_id' => $z_album->album_id, | |
'limit' => 1000 | |
)); | |
$f_is_async = ($z_album->photo_num < 100); | |
$f_responses = array(); | |
foreach ($z_photos->info->photo as $z_photo) { | |
// download photo | |
$path = './'.basename($z_photo->original_image_url); | |
$data = file_get_contents($z_photo->original_image_url); | |
file_put_contents($path, $data); | |
// upload to flickr | |
// if you also want to move description, you should get that of every photos | |
$tags = array(); | |
foreach ($z_photo->tags as $value) { | |
$tags[] = $value->tag; | |
} | |
$f_responses[] = $flickr->upload($path, array( | |
'title' => $z_photo->photo_title, | |
'tags' => implode(' ', $tags), | |
'is_public' => ($z_album->perm_type2 == 'net' ? 1 : 0), | |
'async' => ($f_is_async ? 1 : 0) | |
)); | |
// delete downloaded photo | |
unlink($path); | |
} | |
if ($f_is_async) { | |
$f_ticketids = $f_responses; | |
// upload check | |
$i = 0; | |
$wait = true; | |
while ($wait && ++$i <= intval($z_album->photo_num)*60) { | |
sleep(1); | |
$wait = false; | |
$res = $flickr->rest('photos.upload.checkTickets', array( | |
'tickets' => implode(',', $f_ticketids) | |
)); | |
foreach ($res->uploader->ticket as $ticket) { | |
if (isset($ticket['complete']) && $ticket['complete'] == '0') { | |
$wait = true; | |
} | |
} | |
} | |
$photo_ids = array(); | |
foreach ($res->uploader->ticket as $ticket) { | |
if (isset($ticket['complete']) && $ticket['complete'] == '1') { | |
$photo_ids[] = $ticket['photoid']; | |
} | |
} | |
} else { | |
$photo_ids = $f_responses; | |
} | |
// be sure to restore album's setting | |
$photoZou->post('photo_edit_album', array( | |
'album_id' => $z_album->album_id, | |
'name' => $z_album->name, | |
'perm_type' => $z_album->perm_type, | |
'perm_type2' => $z_album->perm_type2 | |
)); | |
// create set of flickr | |
$photoset = $flickr->rest('photosets.create', array( | |
'title' => $z_album->name, | |
'description' => $z_album->description, | |
'primary_photo_id' => $photo_ids[0] | |
)); | |
// move photos to set | |
foreach ($photo_ids as $id) { | |
$flickr->rest('photosets.addPhoto', array( | |
'photoset_id' => $photoset->photoset['id'], | |
'photo_id' => $id | |
)); | |
} | |
sleep(5); | |
} | |
} else { | |
// auth flickr | |
$flickr = new Flickr(); | |
$flickr->auth(); | |
} | |
exit(); |
流れ:
- Create an Appからアプリを作成して、API KeyとSecret Keyを取得
- フォト蔵 to Flickrを設置
- コードに自分のフォト蔵ID,Passを書く
- コードにFlickrのAPI Key,Secret Keyを書く
- Flickrアプリの管理ページからCallback URLを指定する。
- コードを実行(アクセス)してFlickrアプリの認証をし、移行開始
FlickrのAPI扱うのが面倒だった・・・(そのほうがセキュリティ上好ましいが)
ライブラリはあるので、一から自分で作るのは訓練目的以外では止めたほうがいいですねえ。
フォト蔵も、非公開アルバムの写真情報の取得ができないため、一旦アルバムを公開設定にした後に、再度非公開にするという作業が必要でした。
(非公開アルバムは一時的に公開設定となるためご注意ください。)