Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
moodle
moodle
Commits
9fe33633
Commit
9fe33633
authored
Mar 16, 2017
by
Damyon Wiese
Browse files
MDL-58280 fileconverter_googledrive: Is born.
parent
6d14355c
Changes
11
Hide whitespace changes
Inline
Side-by-side
files/converter/googledrive/classes/converter.php
0 → 100644
View file @
9fe33633
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Class for converting files between different file formats using google drive.
*
* @package fileconverter_googledrive
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace
fileconverter_googledrive
;
defined
(
'MOODLE_INTERNAL'
)
||
die
();
use
stored_file
;
use
moodle_exception
;
use
moodle_url
;
use
\
core_files\conversion
;
/**
* Class for converting files between different formats using unoconv.
*
* @package fileconverter_googledrive
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class
converter
implements
\
core_files\converter_interface
{
private
static
$imports
=
[
'doc'
=>
'application/vnd.google-apps.document'
,
'docx'
=>
'application/vnd.google-apps.document'
,
'rtf'
=>
'application/vnd.google-apps.document'
,
'xls'
=>
'application/vnd.google-apps.spreadsheet'
,
'xlsx'
=>
'application/vnd.google-apps.spreadsheet'
,
'ppt'
=>
'application/vnd.google-apps.presentation'
,
'pptx'
=>
'application/vnd.google-apps.presentation'
];
private
static
$exports
=
[
'docx'
=>
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
,
'rtf'
=>
'application/rtf'
,
'xlsx'
=>
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
,
'pptx'
=>
'application/vnd.openxmlformats-officedocument.presentationml.presentation'
,
'pdf'
=>
'application/pdf'
,
'txt'
=>
'text/plain'
];
/**
* Convert a document to a new format and return a conversion object relating to the conversion in progress.
*
* @param conversion $conversion The file to be converted
* @param string $format The target file format
* @return this
*/
public
function
start_document_conversion
(
\
core_files\conversion
$conversion
)
{
global
$CFG
;
$file
=
$conversion
->
get_sourcefile
();
$format
=
$conversion
->
get
(
'targetformat'
);
$issuerid
=
get_config
(
'fileconverter_googledrive'
,
'issuerid'
);
if
(
empty
(
$issuerid
))
{
$conversion
->
set
(
'status'
,
conversion
::
STATUS_FAILED
);
return
$this
;
}
$issuer
=
\
core\oauth2\api
::
get_issuer
(
$issuerid
);
if
(
empty
(
$issuer
))
{
$conversion
->
set
(
'status'
,
conversion
::
STATUS_FAILED
);
return
$this
;
}
$client
=
\
core\oauth2\api
::
get_system_oauth_client
(
$issuer
);
$service
=
new
\
fileconverter_googledrive\rest
(
$client
);
$contenthash
=
$file
->
get_contenthash
();
$originalname
=
$file
->
get_filename
();
if
(
strpos
(
$originalname
,
'.'
)
===
false
)
{
$conversion
->
set
(
'status'
,
conversion
::
STATUS_FAILED
);
return
$this
;
}
$importextension
=
substr
(
$originalname
,
strrpos
(
$originalname
,
'.'
)
+
1
);
$importformat
=
self
::
$imports
[
$importextension
];
$exportformat
=
self
::
$exports
[
$format
];
$metadata
=
[
'name'
=>
$contenthash
,
'mimeType'
=>
$importformat
];
$filecontent
=
$file
->
get_content
();
$filesize
=
$file
->
get_filesize
();
$filemimetype
=
$file
->
get_mimetype
();
// Start resumable upload.
// First create empty file.
$params
=
[
'uploadType'
=>
'resumable'
,
'fields'
=>
'id,name'
];
$client
->
setHeader
(
'X-Upload-Content-Type: '
.
$filemimetype
);
$client
->
setHeader
(
'X-Upload-Content-Length: '
.
$filesize
);
$headers
=
$service
->
call
(
'upload'
,
$params
,
json_encode
(
$metadata
));
$uploadurl
;
// Google returns a location header with the location for the upload.
foreach
(
$headers
as
$header
)
{
if
(
strpos
(
$header
,
'Location:'
)
===
0
)
{
$uploadurl
=
trim
(
substr
(
$header
,
strpos
(
$header
,
':'
)
+
1
));
}
}
if
(
empty
(
$uploadurl
))
{
$conversion
->
set
(
'status'
,
conversion
::
STATUS_FAILED
);
return
$this
;
}
$params
=
[
'uploadurl'
=>
$uploadurl
];
$result
=
$service
->
call
(
'upload_content'
,
$params
,
$filecontent
,
$filemimetype
);
$fileid
=
$result
->
id
;
// Now export it again.
$params
=
[
'mimeType'
=>
$exportformat
];
$sourceurl
=
new
moodle_url
(
'https://www.googleapis.com/drive/v3/files/'
.
$fileid
.
'/export'
,
$params
);
$source
=
$sourceurl
->
out
(
false
);
$tmp
=
make_request_directory
();
$downloadto
=
$tmp
.
'/'
.
$fileid
.
'.'
.
$format
;
$options
=
[
'filepath'
=>
$downloadto
,
'timeout'
=>
15
,
'followlocation'
=>
true
,
'maxredirs'
=>
5
];
$success
=
$client
->
download_one
(
$source
,
null
,
$options
);
if
(
$success
)
{
$conversion
->
store_destfile_from_path
(
$downloadto
);
$conversion
->
set
(
'status'
,
conversion
::
STATUS_COMPLETE
);
$conversion
->
update
();
}
else
{
$conversion
->
set
(
'status'
,
conversion
::
STATUS_FAILED
);
}
// Cleanup.
$params
=
[
'fileid'
=>
$fileid
];
$service
->
call
(
'delete'
,
$params
);
return
$this
;
}
/**
* Generate and serve the test document.
*
* @return stored_file
*/
public
function
serve_test_document
()
{
global
$CFG
;
require_once
(
$CFG
->
libdir
.
'/filelib.php'
);
$filerecord
=
[
'contextid'
=>
\
context_system
::
instance
()
->
id
,
'component'
=>
'test'
,
'filearea'
=>
'fileconverter_googledrive'
,
'itemid'
=>
0
,
'filepath'
=>
'/'
,
'filename'
=>
'conversion_test.docx'
];
// Get the fixture doc file content and generate and stored_file object.
$fs
=
get_file_storage
();
$testdocx
=
$fs
->
get_file
(
$filerecord
[
'contextid'
],
$filerecord
[
'component'
],
$filerecord
[
'filearea'
],
$filerecord
[
'itemid'
],
$filerecord
[
'filepath'
],
$filerecord
[
'filename'
]);
if
(
!
$testdocx
)
{
$fixturefile
=
dirname
(
__DIR__
)
.
'/tests/fixtures/source.docx'
;
$testdocx
=
$fs
->
create_file_from_pathname
(
$filerecord
,
$fixturefile
);
}
$conversion
=
new
\
core_files\conversion
(
0
,
(
object
)
[
'targetformat'
=>
'pdf'
,
]);
$conversion
->
set_sourcefile
(
$testdocx
);
$conversion
->
create
();
// Convert the doc file to pdf and send it direct to the browser.
$this
->
start_document_conversion
(
$conversion
);
$testfile
=
$conversion
->
get_destfile
();
readfile_accel
(
$testfile
,
'application/pdf'
,
true
);
}
/**
* Poll an existing conversion for status update.
*
* @param conversion $conversion The file to be converted
* @return $this;
*/
public
function
poll_conversion_status
(
conversion
$conversion
)
{
return
$this
;
}
/**
* Whether the plugin is configured and requirements are met.
*
* @return bool
*/
public
static
function
are_requirements_met
()
{
$issuerid
=
get_config
(
'fileconverter_googledrive'
,
'issuerid'
);
if
(
empty
(
$issuerid
))
{
return
false
;
}
$issuer
=
\
core\oauth2\api
::
get_issuer
(
$issuerid
);
if
(
empty
(
$issuer
))
{
return
false
;
}
if
(
!
$issuer
->
is_system_account_connected
())
{
return
false
;
}
return
true
;
}
/**
* Whether a file conversion can be completed using this converter.
*
* @param string $from The source type
* @param string $to The destination type
* @return bool
*/
public
static
function
supports
(
$from
,
$to
)
{
// This is not a one-liner because of php 5.6.
$imports
=
self
::
$imports
;
$exports
=
self
::
$exports
;
return
isset
(
$imports
[
$from
])
&&
isset
(
$exports
[
$to
]);
}
/**
* A list of the supported conversions.
*
* @return string
*/
public
function
get_supported_conversions
()
{
return
implode
(
', '
,
[
'rtf'
,
'doc'
,
'xls'
,
'docx'
,
'xlsx'
,
'ppt'
,
'pptx'
,
'pdf'
]);
}
}
files/converter/googledrive/classes/rest.php
0 → 100644
View file @
9fe33633
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Google Drive Rest API.
*
* @package fileconverter_googledrive
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace
fileconverter_googledrive
;
defined
(
'MOODLE_INTERNAL'
)
||
die
();
/**
* Google Drive Rest API.
*
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class
rest
extends
\
core\oauth2\rest
{
/**
* Define the functions of the rest API.
*
* @return array Example:
* [ 'listFiles' => [ 'method' => 'get', 'endpoint' => 'http://...', 'args' => [ 'folder' => PARAM_STRING ] ] ]
*/
public
function
get_api_functions
()
{
return
[
'upload'
=>
[
'endpoint'
=>
'https://www.googleapis.com/upload/drive/v3/files'
,
'method'
=>
'post'
,
'args'
=>
[
'uploadType'
=>
PARAM_RAW
,
'fields'
=>
PARAM_RAW
],
'response'
=>
'headers'
],
'upload_content'
=>
[
'endpoint'
=>
'{uploadurl}'
,
'method'
=>
'put'
,
'args'
=>
[
'uploadurl'
=>
PARAM_URL
],
'response'
=>
'json'
],
'create'
=>
[
'endpoint'
=>
'https://www.googleapis.com/drive/v3/files'
,
'method'
=>
'post'
,
'args'
=>
[
'fields'
=>
PARAM_RAW
],
'response'
=>
'json'
],
'delete'
=>
[
'endpoint'
=>
'https://www.googleapis.com/drive/v3/files/{fileid}'
,
'method'
=>
'delete'
,
'args'
=>
[
'fileid'
=>
PARAM_RAW
],
'response'
=>
'json'
],
];
}
}
files/converter/googledrive/lang/en/fileconverter_googledrive.php
0 → 100644
View file @
9fe33633
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for plugin 'fileconverter_example'
*
* @package fileconverter_example
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined
(
'MOODLE_INTERNAL'
)
||
die
();
$string
[
'pluginname'
]
=
'Google Drive'
;
$string
[
'disabled'
]
=
'Disabled'
;
$string
[
'issuer'
]
=
'OAuth 2 Service'
;
$string
[
'issuer_help'
]
=
'The OAuth 2 service used to access google drive.'
;
$string
[
'test_converter'
]
=
'Test this converter is working properly.'
;
$string
[
'test_conversion'
]
=
'Test document conversion'
;
$string
[
'test_conversionready'
]
=
'This document converter is configured properly.'
;
$string
[
'test_conversionnotready'
]
=
'This document converter is not configured properly.'
;
files/converter/googledrive/lib.php
0 → 100644
View file @
9fe33633
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This plugin is used to convert documents with google drive.
*
* @package fileconverter_googledrive
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined
(
'MOODLE_INTERNAL'
)
||
die
();
/**
* Callback to get the required scopes for system account.
*
* @param \core\oauth2\issuer $issuer
* @return string
*/
function
fileconverter_googledrive_oauth2_system_scopes
(
\
core\oauth2\issuer
$issuer
)
{
if
(
$issuer
->
get
(
'id'
)
==
get_config
(
'fileconverter_googledrive'
,
'issuerid'
))
{
return
'https://www.googleapis.com/auth/drive'
;
}
return
''
;
}
files/converter/googledrive/settings.php
0 → 100644
View file @
9fe33633
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Link to the OAuth 2 service we will use.
*
* @package fileconverter_googledrive
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined
(
'MOODLE_INTERNAL'
)
||
die
();
if
(
$hassiteconfig
)
{
$options
=
[];
$issuers
=
\
core\oauth2\api
::
get_all_issuers
();
$options
[
''
]
=
get_string
(
'disabled'
,
'fileconverter_googledrive'
);
foreach
(
$issuers
as
$issuer
)
{
$options
[
$issuer
->
get
(
'id'
)]
=
s
(
$issuer
->
get
(
'name'
));
}
$settings
->
add
(
new
admin_setting_configselect
(
'fileconverter_googledrive/issuerid'
,
get_string
(
'issuer'
,
'fileconverter_googledrive'
),
get_string
(
'issuer_help'
,
'fileconverter_googledrive'
),
''
,
$options
));
$url
=
new
moodle_url
(
'/files/converter/googledrive/test.php'
);
$link
=
html_writer
::
link
(
$url
,
get_string
(
'test_converter'
,
'fileconverter_googledrive'
));
$settings
->
add
(
new
admin_setting_heading
(
'test_converter'
,
''
,
$link
));
}
files/converter/googledrive/test.php
0 → 100644
View file @
9fe33633
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Test that unoconv is configured correctly
*
* @package fileconverter_unoconv
* @copyright 2017 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require
(
__DIR__
.
'/../../../config.php'
);
require_once
(
$CFG
->
libdir
.
'/filelib.php'
);
$sendpdf
=
optional_param
(
'sendpdf'
,
0
,
PARAM_BOOL
);
$PAGE
->
set_url
(
new
moodle_url
(
'/files/converter/googledrive/test.php'
));
$PAGE
->
set_context
(
context_system
::
instance
());
require_login
();
require_capability
(
'moodle/site:config'
,
context_system
::
instance
());
$strheading
=
get_string
(
'test_conversion'
,
'fileconverter_googledrive'
);
$PAGE
->
navbar
->
add
(
get_string
(
'administrationsite'
));
$PAGE
->
navbar
->
add
(
get_string
(
'plugins'
,
'admin'
));
$PAGE
->
navbar
->
add
(
get_string
(
'pluginname'
,
'fileconverter_googledrive'
),
new
moodle_url
(
'/admin/settings.php'
,
array
(
'section'
=>
'fileconvertergoogledrive'
)));
$PAGE
->
navbar
->
add
(
$strheading
);
$PAGE
->
set_heading
(
$strheading
);
$PAGE
->
set_title
(
$strheading
);
$converter
=
new
\
fileconverter_googledrive\converter
();
if
(
$sendpdf
)
{
require_sesskey
();
$converter
->
serve_test_document
();
die
();
}
$result
=
$converter
->
are_requirements_met
();
if
(
$result
)
{
$msg
=
$OUTPUT
->
notification
(
get_string
(
'test_conversionready'
,
'fileconverter_googledrive'
),
'success'
);
$pdflink
=
new
moodle_url
(
$PAGE
->
url
,
array
(
'sendpdf'
=>
1
,
'sesskey'
=>
sesskey
()));
$msg
.
=
html_writer
::
link
(
$pdflink
,
get_string
(
'test_conversion'
,
'fileconverter_googledrive'
));
$msg
.
=
html_writer
::
empty_tag
(
'br'
);
}
else
{
$msg
=
$OUTPUT
->
notification
(
get_string
(
'test_conversionnotready'
,
'fileconverter_googledrive'
),
'warning'
);
}
$returl
=
new
moodle_url
(
'/admin/settings.php'
,
array
(
'section'
=>
'fileconvertergoogledrive'
));
$msg
.
=
$OUTPUT
->
continue_button
(
$returl
);
echo
$OUTPUT
->
header
();
echo
$OUTPUT
->
box
(
$msg
,
'generalbox'
);
echo
$OUTPUT
->
footer
();
files/converter/googledrive/tests/fixtures/source.docx
0 → 100644
View file @
9fe33633
File added
files/converter/googledrive/version.php
0 → 100644
View file @
9fe33633
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Version details
*
* @package fileconverter_googledrive
* @copyright 2017 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined
(
'MOODLE_INTERNAL'
)
||
die
();
$plugin
->
version
=
2017020600
;
// The current plugin version (Date: YYYYMMDDXX)
$plugin
->
requires
=
2016112900
;
// Requires this Moodle version
$plugin
->
component
=
'fileconverter_googledrive'
;
// Full name of the plugin (used for diagnostics).
lib/classes/oauth2/rest.php
View file @
9fe33633
...
...
@@ -39,7 +39,7 @@ require_once($CFG->libdir . '/filelib.php');
abstract
class
rest
{
/** @var curl $curl */
pr
ivate
$curl
;
pr
otected
$curl
;
/**
* Constructor.
...
...
@@ -66,7 +66,7 @@ abstract class rest {
* @param string $rawpost Optional param to include in the body of a post.
* @return string|object
*/
public
function
call
(
$functionname
,
$functionargs
,
$rawpost
=
false
)
{
public
function
call
(
$functionname
,
$functionargs
,
$rawpost
=
false
,
$contenttype
=
false
)
{
$functions
=
$this
->
get_api_functions
();
$supportedmethods
=
[
'get'
,
'put'
,
'post'
,
'patch'
,
'head'
,
'delete'
];
if
(
empty
(
$functions
[
$functionname
]))
{
...
...
@@ -106,7 +106,11 @@ abstract class rest {
$callargs
=
$rawpost
;
}
$this
->
curl
->
setHeader
(
'Content-type: application/json'
);
if
(
empty
(
$contenttype
))
{
$this
->
curl
->
setHeader
(
'Content-type: application/json'
);
}
else
{
$this
->
curl
->
setHeader
(
'Content-type: '
.
$contenttype
);
}
$response
=
$this
->
curl
->
$method
(
$endpoint
,
$callargs
);
if
(
$this
->
curl
->
errno
==
0
)
{
...
...
@@ -117,6 +121,8 @@ abstract class rest {
throw
new
rest_exception
(
$json
->
error
->
code
.
': '
.
$json
->
error
->
message
);
}
return
$json
;
}
else
if
(
$responsetype
==
'headers'
)
{
$response
=
$this
->
curl
->
get_raw_response
();
}
return
$response
;
}
else
{
...
...
lib/classes/plugin_manager.php
View file @
9fe33633
...
...
@@ -1757,7 +1757,7 @@ class core_plugin_manager {
),
'fileconverter'
=>
array
(
'unoconv'
'unoconv'