|
import urllib
|
|
import urllib2
|
|
import urlparse
|
|
import json
|
|
import base64
|
|
import datetime
|
|
|
|
from quixote import get_publisher, get_request, redirect, get_response, get_session_manager, get_session
|
|
from quixote.directory import AccessControlled, Directory
|
|
|
|
import qommon.form
|
|
from qommon.misc import http_post_request, http_get_page
|
|
|
|
|
|
class MSPDirectory(Directory):
|
|
_q_exports = ['', 'pick', 'download']
|
|
|
|
@property
|
|
def msp_gateway_base_url(self):
|
|
return get_publisher().get_site_option('msp')
|
|
|
|
@property
|
|
def authorize_url(self):
|
|
return urlparse.urljoin(self.msp_gateway_base_url, 'authorize/')
|
|
|
|
@property
|
|
def access_token_url(self):
|
|
return urlparse.urljoin(self.msp_gateway_base_url, 'access_token/')
|
|
|
|
@property
|
|
def documents_url(self):
|
|
return urlparse.urljoin(self.msp_gateway_base_url, 'documents/')
|
|
|
|
@property
|
|
def document_url(self):
|
|
return urlparse.urljoin(self.msp_gateway_base_url, 'documents/%s/')
|
|
|
|
@property
|
|
def client_id(self):
|
|
return get_publisher().get_site_option('msp_client_id')
|
|
|
|
@property
|
|
def client_secret(self):
|
|
return get_publisher().get_site_option('msp_client_secret')
|
|
|
|
def fix_document(self, document):
|
|
site_charset = get_publisher().site_charset
|
|
for key, value in document.iteritems():
|
|
# date are returned as millisecond POSIX timestamp,
|
|
# it should be ISO-8601 instead
|
|
if key.endswith('Date') and value is not None:
|
|
document[key] = unicode(datetime.date.fromtimestamp(value // 1000))
|
|
value = document[key] = document[key].replace(u'-', u'\u2011')
|
|
if isinstance(value, unicode) and key != 'content':
|
|
document[key] = value.encode(site_charset)
|
|
|
|
def get_documents(self, access_token):
|
|
response, status, content, auth_header = http_get_page(self.documents_url, {
|
|
'Authorization': 'Bearer %s' % access_token,
|
|
});
|
|
documents = json.loads(content)
|
|
for document in documents:
|
|
self.fix_document(document)
|
|
return documents
|
|
|
|
def get_document(self, doc_id, access_token):
|
|
response, status, content, auth_header = http_get_page(
|
|
self.document_url % doc_id,
|
|
{ 'Authorization': 'Bearer %s' % access_token, }
|
|
);
|
|
document = json.loads(content)
|
|
self.fix_document(document)
|
|
return document
|
|
|
|
def authorize(self, self_url, scope):
|
|
params = {
|
|
'redirect_uri': self_url,
|
|
'response_type': 'code',
|
|
'scope': scope,
|
|
}
|
|
return redirect('%s?%s' % (
|
|
self.authorize_url, urllib.urlencode(params)))
|
|
|
|
def access_token(self, self_url, code):
|
|
params = {
|
|
'code': code,
|
|
'client_id': self.client_id,
|
|
'client_secret': self.client_secret,
|
|
'grant_type': 'authorization_code',
|
|
'redirect_uri': self_url,
|
|
}
|
|
response, status, data, auth_header = http_post_request(self.access_token_url,
|
|
urllib.urlencode(params), { 'Content-Type': 'application/x-www-form-urlencoded' })
|
|
return json.loads(data)['access_token']
|
|
|
|
def pick (self):
|
|
request = get_request()
|
|
frontoffice_url = get_publisher().get_frontoffice_url()
|
|
self_url = frontoffice_url
|
|
self_url += '/msp/pick'
|
|
self_url = self_url.replace('://', '://iframe-')
|
|
|
|
if 'code' not in request.form and 'error' not in request.form:
|
|
return self.authorize(self_url, 'LIST_DOCS')
|
|
access_token = self.access_token(self_url, request.form['code'])
|
|
return self.pick_display(access_token)
|
|
|
|
def pick_display [html] (self, access_token):
|
|
request = get_request()
|
|
|
|
get_response().add_javascript(['jquery.js',
|
|
'tablesorter/jquery.tablesorter.min.js'])
|
|
get_response().add_javascript_code(
|
|
str('''$(function() { $("table.sortable").tablesorter(); });'''))
|
|
get_response().add_css_include('../js/tablesorter/themes/blue/style.css')
|
|
|
|
frontoffice_url = get_publisher().get_frontoffice_url()
|
|
|
|
'<h2>%s</h2>' % _('Pick a file')
|
|
|
|
if 'error' not in request.form:
|
|
documents = self.get_documents(access_token)
|
|
'<table id="msp-pick-file-table" class="sortable tablesorter">'
|
|
'<thead>'
|
|
'<tr>'
|
|
'<th>%s</th>' % _('Filename')
|
|
'<th>%s</th>' % _('Expiration date')
|
|
'</tr>'
|
|
'</thead>'
|
|
'<tbody>'
|
|
for document in documents:
|
|
'<tr>'
|
|
for key in ('name', 'expirationDate'):
|
|
'<td class="msp-pick-file-table-%s">' % key
|
|
if key == 'name':
|
|
'<a href="%s/msp/download?doc_id=%s">' % \
|
|
(frontoffice_url, document['id'])
|
|
'%s' % (document[key] or '')
|
|
if key == 'name':
|
|
'</a>'
|
|
'</td>'
|
|
'</tr>'
|
|
'</tbody>'
|
|
'</table>'
|
|
else:
|
|
'<p>%s</p>' % _('Unable to access your mon.Service-Public.fr documents')
|
|
|
|
def set_token [html] (self, token, document):
|
|
get_response().add_javascript(['jquery.js'])
|
|
get_response().page_template_key = 'iframe'
|
|
'<html><body>'
|
|
'<pre>Token: %s</pre>' % token
|
|
'<script>window.top.document.set_token("%s", "%s");</script>' % (token, document['name'])
|
|
'</body></html>'
|
|
|
|
def download(self):
|
|
request = get_request()
|
|
assert 'doc_id' in request.form
|
|
doc_id = request.form['doc_id']
|
|
frontoffice_url = get_publisher().get_frontoffice_url()
|
|
self_url = frontoffice_url
|
|
self_url += '/msp/download?%s' % urllib.urlencode({'doc_id': doc_id})
|
|
if 'code' not in request.form and 'error' not in request.form:
|
|
return self.authorize(self_url, 'GET_DOC')
|
|
if 'error' in request.form:
|
|
return self.download_error()
|
|
else:
|
|
access_token = self.access_token(self_url, request.form['code'])
|
|
document = self.get_document(doc_id, access_token)
|
|
download = qommon.form.PicklableUpload(document['name'],
|
|
content_type='application/pdf')
|
|
download.__setstate__({
|
|
'data': base64.b64decode(document['content']),
|
|
})
|
|
token = get_session().add_tempfile(download)
|
|
return self.set_token(token, document)
|