0001-remove-FileWithPreviewAndStrongboxWidget.patch
extra/auquotidien.py | ||
---|---|---|
14 | 14 |
import modules.formpage |
15 | 15 |
import modules.template |
16 | 16 |
import modules.root |
17 |
import modules.form |
|
18 | 17 |
import modules.payments |
19 | 18 |
import modules.connectors |
20 | 19 |
import modules.abelium_domino_ui |
... | ... | |
50 | 49 |
rdb.register_directory('settings', modules.admin.SettingsDirectory()) |
51 | 50 |
rdb.register_directory('categories', modules.categories_admin.CategoriesDirectory()) |
52 | 51 | |
53 |
import wcs.fields |
|
54 |
wcs.fields.FileField.widget_class = modules.form.FileWithPreviewAndStrongboxWidget |
|
55 | ||
56 | 52 |
import wcs.admin.settings |
57 | 53 |
wcs.admin.settings.SettingsDirectory.domino = modules.abelium_domino_ui.AbeliumDominoDirectory() |
58 | 54 |
wcs.admin.settings.SettingsDirectory._q_exports.append('domino') |
extra/modules/fargo_ui.py | ||
---|---|---|
1 |
import urllib |
|
2 |
import urlparse |
|
3 |
import json |
|
4 | ||
5 |
from quixote import get_publisher, get_request, redirect, get_response, get_session |
|
6 |
from quixote.directory import Directory |
|
7 |
from quixote.html import TemplateIO, htmltext |
|
8 | ||
9 |
import qommon.form |
|
10 | ||
11 | ||
12 |
class FargoDirectory(Directory): |
|
13 |
_q_exports = ['pick'] |
|
14 | ||
15 |
@property |
|
16 |
def fargo_url(self): |
|
17 |
return get_publisher().get_site_option('fargo_url') |
|
18 | ||
19 |
def pick (self): |
|
20 |
request = get_request() |
|
21 |
if 'cancel' in request.form: |
|
22 |
get_response().add_javascript(['jquery.js']) |
|
23 |
get_response().page_template_key = 'iframe' |
|
24 |
r = TemplateIO(html=True) |
|
25 |
r += htmltext('<html><body>') |
|
26 |
r += htmltext('<script>window.top.document.fargo_close_dialog();</script>') |
|
27 |
r += htmltext('</body></html>') |
|
28 |
return r.getvalue() |
|
29 |
elif 'url' in request.form: |
|
30 |
# Download file |
|
31 |
# FIXME: handle error cases |
|
32 |
url = request.form['url'] |
|
33 |
document = urllib.urlopen(request.form['url']).read() |
|
34 |
scheme, netloc, path, qs, frag = urlparse.urlsplit(url) |
|
35 |
path = map(None, path.split('/')) |
|
36 |
name = urllib.unquote(path[-1]) |
|
37 |
download = qommon.form.PicklableUpload(name, |
|
38 |
content_type='application/pdf') |
|
39 |
download.__setstate__({ |
|
40 |
'data': document, |
|
41 |
}) |
|
42 |
token = get_session().add_tempfile(download) |
|
43 |
return self.set_token(token, name) |
|
44 |
else: |
|
45 |
# Display file picker |
|
46 |
frontoffice_url = get_publisher().get_frontoffice_url() |
|
47 |
self_url = frontoffice_url |
|
48 |
self_url += '/fargo/pick' |
|
49 |
return redirect('%spick?pick=%s' % (self.fargo_url, |
|
50 |
urllib.quote(self_url))) |
|
51 | ||
52 |
def set_token(self, token, title): |
|
53 |
get_response().add_javascript(['jquery.js']) |
|
54 |
get_response().page_template_key = 'iframe' |
|
55 |
r = TemplateIO(html=True) |
|
56 |
r += htmltext('<html><body>') |
|
57 |
r += htmltext('<script>window.top.document.fargo_set_token(%s, %s);</script>' % ( |
|
58 |
json.dumps(token), json.dumps(title))) |
|
59 |
r += htmltext('</body></html>') |
|
60 |
return r.getvalue() |
extra/modules/form.py | ||
---|---|---|
1 |
from qommon.form import * |
|
2 | ||
3 | ||
4 |
class FileWithPreviewAndStrongboxWidget(FileWithPreviewWidget): |
|
5 |
def render_hint(self, hint): |
|
6 |
t = CompositeWidget.render_hint(self, hint) |
|
7 |
if not self.allow_portfolio_picking: |
|
8 |
return t |
|
9 |
root_url = get_publisher().get_root_url() |
|
10 |
if get_publisher().has_site_option('strongbox') and get_request().user and not self.preview: |
|
11 |
get_response().add_javascript(['../../aq/js/strongbox.js']) |
|
12 |
t += htmltext('''<p class="use-file-from-strongbox"><span |
|
13 |
data-url="%smyspace/strongbox/pick" |
|
14 |
rel="popup">%s</span></p>''') % ( |
|
15 |
root_url, _('Use file from strongbox')) |
|
16 |
if get_publisher().get_site_option('msp') is not None and not self.preview: |
|
17 |
get_response().add_javascript(['../../aq/js/msp.js']) |
|
18 |
t += htmltext('''<p class="use-file-from-msp"><span |
|
19 |
data-src="%smsp/pick" |
|
20 |
data-width="500" |
|
21 |
data-height="400" |
|
22 |
data-title="%s" |
|
23 |
rel="popup">%s</span></p>''') % ( |
|
24 |
root_url, _('Pick a file on mon.Service-Public.fr'), |
|
25 |
_('Use file from mon.Service-Public.fr')) |
|
26 |
if get_publisher().get_site_option('fargo_url') is not None and not self.preview: |
|
27 |
get_response().add_javascript(['fargo.js']) |
|
28 |
t += htmltext('''<p class="use-file-from-fargo"><span |
|
29 |
data-src="%sfargo/pick" |
|
30 |
data-width="500" |
|
31 |
data-height="400" |
|
32 |
data-title="%s" |
|
33 |
rel="popup">%s</span></p>''') % ( |
|
34 |
root_url, _('Pick a file from your dropbox'), |
|
35 |
_('Use file from my dropbox')) |
|
36 |
return t |
extra/modules/msp_ui.py | ||
---|---|---|
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']) |
extra/modules/myspace.py | ||
---|---|---|
28 | 28 |
from announces import AnnounceSubscription |
29 | 29 |
from strongbox import StrongboxItem, StrongboxType |
30 | 30 |
from payments import Invoice, Regie, is_payment_supported |
31 |
import msp_ui |
|
32 | 31 | |
33 | 32 |
class MyInvoicesDirectory(Directory): |
34 | 33 |
_q_exports = [''] |
... | ... | |
422 | 421 | |
423 | 422 |
class MyspaceDirectory(wcs.myspace.MyspaceDirectory): |
424 | 423 |
_q_exports = ['', 'profile', 'new', 'password', 'remove', 'drafts', 'forms', |
425 |
'announces', 'strongbox', 'invoices', 'json', 'msp']
|
|
424 |
'announces', 'strongbox', 'invoices', 'json'] |
|
426 | 425 | |
427 |
msp = msp_ui.MSPDirectory() |
|
428 | 426 |
strongbox = StrongboxDirectory() |
429 | 427 |
invoices = MyInvoicesDirectory() |
430 | 428 |
json = JsonDirectory() |
extra/modules/root.py | ||
---|---|---|
55 | 55 |
import qommon.ident.password |
56 | 56 |
import qommon.ident.idp |
57 | 57 | |
58 |
import msp_ui |
|
59 |
import fargo_ui |
|
60 | 58 | |
61 | 59 |
def category_get_homepage_position(self): |
62 | 60 |
if hasattr(self, 'homepage_position') and self.homepage_position: |
... | ... | |
771 | 769 |
'myspace', 'services', 'agenda', 'categories', 'user', |
772 | 770 |
('tmp-upload', 'tmp_upload'), 'json', '__version__', |
773 | 771 |
'themes', 'pages', 'payment', 'invoices', 'accesscode', 'roles', |
774 |
'msp', 'api', 'code', 'fargo', 'tryauth', 'auth', 'preview',
|
|
772 |
'api', 'code', 'tryauth', 'auth', 'preview',
|
|
775 | 773 |
('reload-top', 'reload_top')] |
776 | 774 | |
777 | 775 |
admin = admin.AdminRootDirectory() |
... | ... | |
784 | 782 |
saml = Saml2Directory() |
785 | 783 |
payment = PublicPaymentDirectory() |
786 | 784 |
invoices = InvoicesDirectory() |
787 |
msp = msp_ui.MSPDirectory() |
|
788 |
fargo = fargo_ui.FargoDirectory() |
|
789 | 785 |
code = wcs.forms.root.TrackingCodesDirectory() |
790 | 786 |
preview = AlternatePreviewDirectory() |
791 | 787 | |
792 |
- |