Projet

Général

Profil

Télécharger (6,99 ko) Statistiques
| Branche: | Tag: | Révision:

root / extra / modules / msp_ui.py @ c182b1ab

1
import urllib
2
import urllib2
3
import urlparse
4
import json
5
import base64
6
import datetime
7

    
8
from quixote import get_publisher, get_request, redirect, get_response, get_session_manager, get_session
9
from quixote.directory import AccessControlled, Directory
10
from quixote.html import TemplateIO, htmltext
11

    
12
import qommon.form
13
from qommon.misc import http_post_request, http_get_page
14

    
15

    
16
class MSPDirectory(Directory):
17
    _q_exports = ['', 'pick', 'download']
18

    
19
    @property
20
    def msp_gateway_base_url(self):
21
        return get_publisher().get_site_option('msp')
22

    
23
    @property
24
    def authorize_url(self):
25
        return urlparse.urljoin(self.msp_gateway_base_url, 'authorize/')
26

    
27
    @property
28
    def access_token_url(self):
29
        return urlparse.urljoin(self.msp_gateway_base_url, 'access_token/')
30

    
31
    @property
32
    def documents_url(self):
33
        return urlparse.urljoin(self.msp_gateway_base_url, 'documents/')
34

    
35
    @property
36
    def document_url(self):
37
        return urlparse.urljoin(self.msp_gateway_base_url, 'documents/%s/')
38

    
39
    @property
40
    def client_id(self):
41
        return get_publisher().get_site_option('msp_client_id')
42

    
43
    @property
44
    def client_secret(self):
45
        return get_publisher().get_site_option('msp_client_secret')
46

    
47
    def fix_document(self, document):
48
        site_charset = get_publisher().site_charset
49
        for key, value in document.iteritems():
50
            # date are returned as millisecond POSIX timestamp,
51
            # it should be ISO-8601 instead
52
            if key.endswith('Date') and value is not None:
53
                document[key] = unicode(datetime.date.fromtimestamp(value // 1000))
54
                value = document[key] = document[key].replace(u'-', u'\u2011')
55
            if isinstance(value, unicode) and key != 'content':
56
                document[key] = value.encode(site_charset)
57

    
58
    def get_documents(self, access_token):
59
        response, status, content, auth_header = http_get_page(self.documents_url, {
60
            'Authorization': 'Bearer %s' % access_token,
61
        });
62
        documents = json.loads(content)
63
        for document in documents:
64
            self.fix_document(document)
65
        return documents
66

    
67
    def get_document(self, doc_id, access_token):
68
        response, status, content, auth_header = http_get_page(
69
                self.document_url % doc_id, 
70
                { 'Authorization': 'Bearer %s' % access_token, }
71
        );
72
        document = json.loads(content)
73
        self.fix_document(document)
74
        return document
75

    
76
    def authorize(self, self_url, scope):
77
        params = {
78
                'redirect_uri': self_url,
79
                'response_type': 'code',
80
                'scope': scope,
81
        }
82
        return redirect('%s?%s' % (
83
            self.authorize_url, urllib.urlencode(params)))
84

    
85
    def access_token(self, self_url, code):
86
        params = {
87
                'code': code,
88
                'client_id': self.client_id,
89
                'client_secret': self.client_secret,
90
                'grant_type': 'authorization_code',
91
                'redirect_uri': self_url,
92
        }
93
        response, status, data, auth_header = http_post_request(self.access_token_url,
94
                urllib.urlencode(params), { 'Content-Type': 'application/x-www-form-urlencoded' })
95
        return json.loads(data)['access_token']
96

    
97
    def pick (self):
98
        request = get_request()
99
        frontoffice_url = get_publisher().get_frontoffice_url()
100
        self_url = frontoffice_url
101
        self_url += '/msp/pick'
102
        self_url = self_url.replace('://', '://iframe-')
103

    
104
        if 'code' not in request.form and 'error' not in request.form:
105
            return self.authorize(self_url, 'LIST_DOCS')
106
        access_token = self.access_token(self_url, request.form['code'])
107
        return self.pick_display(access_token)
108

    
109
    def pick_display(self, access_token):
110
        r = TemplateIO(html=True)
111

    
112
        request = get_request()
113

    
114
        get_response().add_javascript(['jquery.js',
115
            'tablesorter/jquery.tablesorter.min.js'])
116
        get_response().add_javascript_code(
117
                 str('''$(function() { $("table.sortable").tablesorter(); });'''))
118
        get_response().add_css_include('../js/tablesorter/themes/blue/style.css')
119

    
120
        frontoffice_url = get_publisher().get_frontoffice_url()
121

    
122
        r += htmltext('<h2>%s</h2>') % _('Pick a file')
123

    
124
        if 'error' not in request.form:
125
            documents = self.get_documents(access_token)
126
            r += htmltext('<table id="msp-pick-file-table" class="sortable tablesorter">')
127
            r += htmltext('<thead>')
128
            r += htmltext('<tr>')
129
            r += htmltext('<th>%s</th>') % _('Filename')
130
            r += htmltext('<th>%s</th>') % _('Expiration date')
131
            r += htmltext('</tr>')
132
            r += htmltext('</thead>')
133
            r += htmltext('<tbody>')
134
            for document in documents:
135
                r += htmltext('<tr>')
136
                for key in ('name', 'expirationDate'):
137
                    r += htmltext('<td class="msp-pick-file-table-%s">' % key)
138
                    if key == 'name':
139
                        r += htmltext('<a href="%s/msp/download?doc_id=%s">' % \
140
                            (frontoffice_url, document['id']))
141
                    r += '%s' % (document[key] or '')
142
                    if key == 'name':
143
                        r += htmltext('</a>')
144
                    r += htmltext('</td>')
145
                r += htmltext('</tr>')
146
            r += htmltext('</tbody>')
147
            r += htmltext('</table>')
148
        else:
149
            r += htmltext('<p>%s</p>') % _('Unable to access your mon.Service-Public.fr documents')
150
        return r.getvalue()
151

    
152
    def set_token(self, token, title):
153
        get_response().add_javascript(['jquery.js'])
154
        get_response().page_template_key = 'iframe'
155
        r = TemplateIO(html=True)
156
        r += htmltext('<html><body>')
157
        r += htmltext('<pre>Token: %s</pre>') % token
158
        r += htmltext('<script>window.top.document.set_token("%s", "%s");</script>' % (
159
            token, title))
160
        r += htmltext('</body></html>')
161
        return r.getvalue()
162

    
163
    def download(self):
164
        request = get_request()
165
        assert 'doc_id' in request.form
166
        doc_id = request.form['doc_id']
167
        frontoffice_url = get_publisher().get_frontoffice_url()
168
        self_url = frontoffice_url
169
        self_url += '/msp/download?%s' % urllib.urlencode({'doc_id': doc_id})
170
        if 'code' not in request.form and 'error' not in request.form:
171
            return self.authorize(self_url, 'GET_DOC')
172
        if 'error' in request.form:
173
            return self.set_token('', '')
174
        else:
175
            access_token = self.access_token(self_url, request.form['code'])
176
            document = self.get_document(doc_id, access_token)
177
            download = qommon.form.PicklableUpload(document['name'],
178
                    content_type='application/pdf')
179
            download.__setstate__({
180
                'data': base64.b64decode(document['content']),
181
            })
182
            token = get_session().add_tempfile(download)
183
            return self.set_token(token, document['name'])
(22-22/30)