From 83b510875dfc82400f046d59d7ef33f84d4d173d Mon Sep 17 00:00:00 2001 From: poltawski Date: Sun, 30 Nov 2008 17:37:06 +0000 Subject: [PATCH] repository: New Picasa Web Albums Plugin MDL-17473 --- lang/en_utf8/repository_picasa.php | 3 + lib/googleapi.php | 114 +++++++++++++++++++++++++ repository/picasa/icon.png | Bin 0 -> 4954 bytes repository/picasa/repository.class.php | 101 ++++++++++++++++++++++ 4 files changed, 218 insertions(+) create mode 100644 lang/en_utf8/repository_picasa.php create mode 100644 repository/picasa/icon.png create mode 100644 repository/picasa/repository.class.php diff --git a/lang/en_utf8/repository_picasa.php b/lang/en_utf8/repository_picasa.php new file mode 100644 index 0000000000..57ae63166a --- /dev/null +++ b/lang/en_utf8/repository_picasa.php @@ -0,0 +1,3 @@ + diff --git a/lib/googleapi.php b/lib/googleapi.php index 69ba61a6d6..a1f48ccc3a 100644 --- a/lib/googleapi.php +++ b/lib/googleapi.php @@ -285,6 +285,9 @@ class google_picasa { const REALM = 'http://picasaweb.google.com/data/'; const USER_PREF_NAME = 'google_authsub_sesskey_picasa'; const UPLOAD_LOCATION = 'http://picasaweb.google.com/data/feed/api/user/default/albumid/default'; + const ALBUM_PHOTO_LIST = 'http://picasaweb.google.com/data/feed/api/user/default/albumid/'; + const PHOTO_SEARCH_URL = 'http://picasaweb.google.com/data/feed/api/user/default?kind=photo&q='; + const LIST_ALBUMS_URL = 'http://picasaweb.google.com/data/feed/api/user/default'; private $google_curl = null; @@ -332,6 +335,117 @@ class google_picasa { return false; } } + + /** + * Returns list of photos for file picker. + * If top level then returns list of albums, otherwise + * photos within an album. + * + * @param string $path The path to files (assumed to be albumid) + * @return mixed $files A list of files for the file picker + */ + public function get_file_list($path = ''){ + if(!$path){ + return $this->get_albums(); + }else{ + return $this->get_album_photos($path); + } + } + + /** + * Returns list of photos in album specified + * + * @param int $albumid Photo album to list photos from + * @return mixed $files A list of files for the file picker + */ + public function get_album_photos($albumid){ + $albumcontent = $this->google_curl->get(google_picasa::ALBUM_PHOTO_LIST.$albumid); + + return $this->get_photo_details($albumcontent); + } + + /** + * Does text search on the users photos and returns + * matches in format for picasa api + * + * @param string $query Search terms + * @return mixed $files A list of files for the file picker + */ + public function do_photo_search($query){ + $content = $this->google_curl->get(google_picasa::PHOTO_SEARCH_URL.htmlentities($query)); + + return $this->get_photo_details($content); + } + + /** + * Gets all the users albums and returns them as a list of folders + * for the file picker + * + * @return mixes $files Array in the format get_listing uses for folders + */ + public function get_albums(){ + $content = $this->google_curl->get(google_picasa::LIST_ALBUMS_URL); + $xml = new SimpleXMLElement($content); + + $files = array(); + + foreach($xml->entry as $album){ + $gphoto = $album->children('http://schemas.google.com/photos/2007'); + + $mediainfo = $album->children('http://search.yahoo.com/mrss/'); + //hacky... + $thumbnailinfo = $mediainfo->group->thumbnail[0]->attributes(); + + $files[] = array( 'title' => (string) $gphoto->name, + 'date' => userdate($gphoto->timestamp), + 'size' => (int) $gphoto->bytesUsed, + 'path' => (string) $gphoto->id, + 'thumbnail' => (string) $thumbnailinfo['url'], + 'thumbnail_width' => (int) $thumbnailinfo['width'], + 'thumbnail_height' => (int) $thumbnailinfo['height'], + 'children' => array(), + ); + + } + + return $files; + } + + /** + * Recieves XML from a picasa list of photos and returns + * array in format for file picker. + * + * @param string $rawxml XML from picasa api + * @return mixed $files A list of files for the file picker + */ + public function get_photo_details($rawxml){ + + $xml = new SimpleXMLElement($rawxml); + + $files = array(); + + foreach($xml->entry as $photo){ + $gphoto = $photo->children('http://schemas.google.com/photos/2007'); + + $mediainfo = $photo->children('http://search.yahoo.com/mrss/'); + $fullinfo = $mediainfo->group->content->attributes(); + //hacky... + $thumbnailinfo = $mediainfo->group->thumbnail[0]->attributes(); + + $files[] = array('title' => (string) $mediainfo->group->title, + 'date' => userdate($gphoto->timestamp), + 'size' => (int) $gphoto->size, + 'path' => $gphoto->albumid.'/'.$gphoto->id, + 'thumbnail' => (string) $thumbnailinfo['url'], + 'thumbnail_width' => (int) $thumbnailinfo['width'], + 'thumbnail_height' => (int) $thumbnailinfo['height'], + 'source' => (string) $fullinfo['url'], + ); + } + + return $files; + } + } /** diff --git a/repository/picasa/icon.png b/repository/picasa/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..97b70cf86c92763dda7b6b2f4eba92058c4d60e8 GIT binary patch literal 4954 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 + * @version $Id$ + * @license http://www.gnu.org/copyleft/gpl.html GNU Public License + */ + +require_once($CFG->libdir.'/googleapi.php'); + +class repository_picasa extends repository { + private $subauthtoken = ''; + + public function __construct($repositoryid, $context = SITEID, $options = array()) { + global $USER; + parent::__construct($repositoryid, $context, $options); + + // TODO: I wish there was somewhere we could explicitly put this outside of constructor.. + $googletoken = optional_param('token', false, PARAM_RAW); + if($googletoken){ + $gauth = new google_authsub(false, $googletoken); // will throw exception if fails + google_picasa::set_sesskey($gauth->get_sessiontoken(), $USER->id); + } + + # fixme - we are not checking login before all functions in the repo api.. eg search + # MDL-17474 + $this->check_login(); + } + + public function check_login() { + global $USER; + + $sesskey = google_picasa::get_sesskey($USER->id); + + if($sesskey){ + try{ + $gauth = new google_authsub($sesskey); + $this->subauthtoken = $sesskey; + return true; + }catch(Exception $e){ + // sesskey is not valid, delete store and re-auth + google_picasa::delete_sesskey($USER->id); + } + } + + return false; + } + + public function print_login($ajax = true){ + global $CFG; + if($ajax){ + $ret = array(); + $popup_btn = new stdclass; + $popup_btn->type = 'popup'; + $returnurl = $CFG->wwwroot.'/repository/ws.php?callback=yes&repo_id='.$this->id; + $popup_btn->url = google_authsub::login_url($returnurl, google_picasa::REALM); + $ret['login'] = array($popup_btn); + return $ret; + } + } + + public function get_listing($path='') { + $picasa = new google_picasa(new google_authsub($this->subauthtoken)); + + $ret = array(); + $ret['dynload'] = true; + $ret['list'] = $picasa->get_file_list($path); + return $ret; + } + + public function search($query){ + $picasa = new google_picasa(new google_authsub($this->subauthtoken)); + + $ret = array(); + $ret['list'] = $picasa->do_photo_search($query); + return $ret; + } + + public function logout(){ + global $USER; + + $token = google_picasa::get_sesskey($USER->id); + + $gauth = new google_authsub($token); + // revoke token from google + $gauth->revoke_session_token(); + + google_picasa::delete_sesskey($USER->id); + $this->subauthtoken = ''; + + return parent::logout(); + } + + public function get_name(){ + return get_string('repositoryname', 'repository_picasa'); + } +} + +// Icon for this plugin retrieved from http://www.iconspedia.com/icon/picasa-2711.html +// Where the license is said documented to be Free -- 2.39.5