Skip to content

Commit

Permalink
repository/googledocs New repository plugin MDL-16383
Browse files Browse the repository at this point in the history
Google have now allowed documents to be downloaded via their API
(http://googledataapis.blogspot.com/2009/02/start-downloads.html) so
the google docs repo plugin could be finished.

At the moment i've set the export format hardcoded, hopefully we can allow the
repo api let the user choose later...
  • Loading branch information
poltawski committed Mar 8, 2009
1 parent d0d72b9 commit 6667f9e
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 6 deletions.
3 changes: 3 additions & 0 deletions lang/en_utf8/repository_googledocs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php
$string['repositoryname'] = 'Google Docs';
?>
53 changes: 47 additions & 6 deletions lib/googleapi.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ protected function request($url, $options = array()){
return $ret;
}

protected function multi($requests, $options = array()) {
if($this->token){
// Adds authorisation head to a request so that it can be authentcated
$this->setHeader('Authorization: '. $this->get_auth_header_name().'"'.$this->token.'"');
}

$ret = parent::multi($requests, $options);
// reset headers for next request
$this->header = array();
return $ret;
}

public function get_sessiontoken(){
return $this->token;
}
Expand Down Expand Up @@ -190,7 +202,8 @@ public static function get_auth_header_name(){
* http://code.google.com/apis/documents/docs/2.0/developers_guide_protocol.html
*/
class google_docs {
const REALM = 'http://docs.google.com/feeds/documents';
// need both docs and the spreadsheets realm
const REALM = 'http://docs.google.com/feeds/ http://spreadsheets.google.com/feeds/';
const DOCUMENTFEED_URL = 'http://docs.google.com/feeds/documents/private/full';
const USER_PREF_NAME = 'google_authsub_sesskey';

Expand Down Expand Up @@ -229,6 +242,7 @@ public static function delete_sesskey($userid){
*/
#FIXME
public function get_file_list($search = ''){
global $CFG;
$url = google_docs::DOCUMENTFEED_URL;

if($search){
Expand All @@ -238,14 +252,41 @@ public function get_file_list($search = ''){

$xml = new SimpleXMLElement($content);



$files = array();
foreach($xml->entry as $gdoc){

$files[] = array( 'title' => "$gdoc->title",
'url' => "{$gdoc->content['src']}",
'source' => "{$gdoc->content['src']}",
'date' => usertime(strtotime($gdoc->updated)),
);
// there doesn't seem to to be cleaner way of getting the id/type
// than spliting this..
if (preg_match('/^http:\/\/docs.google.com\/feeds\/documents\/private\/full\/([^%]*)%3A(.*)$/', $gdoc->id, $matches)){
$docid = $matches[2];

// FIXME: We're making hard-coded choices about format here.
// If the repo api can support it, we could let the user
// chose.
switch($matches[1]){
case 'document':
$title = $gdoc->title.'.rtf';
$source = 'http://docs.google.com/feeds/download/documents/Export?docID='.$docid.'&exportFormat=rtf';
break;
case 'presentation':
$title = $gdoc->title.'.ppt';
$source = 'http://docs.google.com/feeds/download/presentations/Export?docID='.$docid.'&exportFormat=ppt';
break;
case 'spreadsheet':
$title = $gdoc->title.'.xls';
$source = 'http://spreadsheets.google.com/feeds/download/spreadsheets/Export?key='.$docid.'&fmcmd=4';
break;
}

$files[] = array( 'title' => $title,
'url' => "{$gdoc->link[0]->attributes()->href}",
'source' => $source,
'date' => usertime(strtotime($gdoc->updated)),
'thumbnail' => $CFG->pixpath.'/f/'.mimeinfo('icon32', $title)
);
}
}

return $files;
Expand Down
Binary file added repository/googledocs/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
127 changes: 127 additions & 0 deletions repository/googledocs/repository.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php
/**
* Google Docs Plugin
*
* @author Dan Poltawski <talktodan@gmail.com>
* @version $Id$
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
*/

require_once($CFG->libdir.'/googleapi.php');

class repository_googledocs 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_docs::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_docs::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_docs::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_docs::REALM);
$ret['login'] = array($popup_btn);
return $ret;
}
}

public function get_listing($path='', $page = '') {
$gdocs = new google_docs(new google_authsub($this->subauthtoken));

$ret = array();
$ret['dynload'] = true;
$ret['list'] = $gdocs->get_file_list();
return $ret;
}

public function search($query){
$gdocs = new google_docs(new google_authsub($this->subauthtoken));

$ret = array();
$ret['dynload'] = true;
$ret['list'] = $gdocs->get_file_list($query);
return $ret;
}

public function logout(){
global $USER;

$token = google_docs::get_sesskey($USER->id);

$gauth = new google_authsub($token);
// revoke token from google
$gauth->revoke_session_token();

google_docs::delete_sesskey($USER->id);
$this->subauthtoken = '';

return parent::logout();
}

public function get_name(){
return get_string('repositoryname', 'repository_googledocs');
}

public function get_file($url, $file) {
global $CFG;


//FIXME: Why does every repo plugin.. do this mktemp file itself..

if (!file_exists($CFG->dataroot.'/repository/download')) {
mkdir($CFG->dataroot.'/repository/download/', 0777, true);
}

if(is_dir($CFG->dataroot.'/repository/download')) {
$dir = $CFG->dataroot.'/repository/download/';
}

if (empty($file)){
$file = time();
}

$fp = fopen($dir.$file, 'w');
$gdocs = new google_docs(new google_authsub($this->subauthtoken));
$gdocs->download_file($url, $fp);

return $dir.$file;
}


}
//Icon from: http://www.iconspedia.com/icon/google-2706.html

0 comments on commit 6667f9e

Please sign in to comment.