annotate sat/plugins/plugin_comp_file_sharing.py @ 3446:d2298ed6de7f

docker (pubsub): install latest version of `postgresql-client` with PostgreSQL own Debian repos.
author Goffi <goffi@goffi.org>
date Thu, 10 Dec 2020 10:28:05 +0100
parents 90aee1f2d07c
children be6d91572633
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
1 #!/usr/bin/env python3
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # SAT plugin for parrot mode (experimental)
3136
9d0df638c8b4 dates update
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
4 # Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org)
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
19 import os
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
20 import os.path
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
21 import mimetypes
3348
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
22 import tempfile
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
23 from functools import partial
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
24 import shortuuid
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
25 import unicodedata
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
26 from urllib.parse import urljoin, urlparse, quote, unquote
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
27 from pathlib import Path
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 from sat.core.i18n import _
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 from sat.core.constants import Const as C
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 from sat.core import exceptions
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 from sat.core.log import getLogger
3331
b1e9f17fbb5a comp file sharing: minor core re-organisation
Goffi <goffi@goffi.org>
parents: 3329
diff changeset
32 from sat.tools import stream
3348
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
33 from sat.tools import video
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 from sat.tools.common import regex
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
35 from sat.tools.common import uri
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
36 from sat.tools.common import files_utils
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
37 from sat.tools.common import tls
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
38 from twisted.internet import defer, reactor
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
39 from twisted.words.protocols.jabber import error
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
40 from twisted.web import server, resource, static, http
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
41 from wokkel import pubsub
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
42 from wokkel import generic
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
43
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
44
3136
9d0df638c8b4 dates update
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
45 log = getLogger(__name__)
9d0df638c8b4 dates update
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
46
9d0df638c8b4 dates update
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
47
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 PLUGIN_INFO = {
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 C.PI_NAME: "File sharing component",
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 C.PI_IMPORT_NAME: "file_sharing",
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 C.PI_MODES: [C.PLUG_MODE_COMPONENT],
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 C.PI_TYPE: C.PLUG_TYPE_ENTRY_POINT,
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 C.PI_PROTOCOLS: [],
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
54 C.PI_DEPENDENCIES: [
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
55 "FILE",
2929
e0429ff7f6b6 plugin comp file sharing: file sharing management first draft:
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
56 "FILE_SHARING_MANAGEMENT",
3367
90aee1f2d07c component file sharing: added missing `owner` filtering in `_retrieveFiles`
Goffi <goffi@goffi.org>
parents: 3363
diff changeset
57 "XEP-0106",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
58 "XEP-0234",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
59 "XEP-0260",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
60 "XEP-0261",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
61 "XEP-0264",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
62 "XEP-0329",
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
63 "XEP-0363",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
64 ],
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 C.PI_RECOMMENDATIONS: [],
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 C.PI_MAIN: "FileSharing",
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
67 C.PI_HANDLER: C.BOOL_TRUE,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
68 C.PI_DESCRIPTION: _("""Component hosting and sharing files"""),
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 }
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
70
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
71 HASH_ALGO = "sha-256"
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
72 NS_COMMENTS = "org.salut-a-toi.comments"
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
73 NS_FS_AFFILIATION = "org.salut-a-toi.file-sharing-affiliation"
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
74 COMMENT_NODE_PREFIX = "org.salut-a-toi.file_comments/"
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
75 # Directory used to buffer request body (i.e. file in case of PUT) we use more than one @
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
76 # there, to be sure than it's not conflicting with a JID
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
77 TMP_BUFFER_DIR = "@@tmp@@"
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
78
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
79 server.version = unicodedata.normalize(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
80 'NFKD',
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
81 f"{C.APP_NAME} file sharing {C.APP_VERSION}"
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
82 ).encode('ascii','ignore')
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
83
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
84
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
85 class HTTPFileServer(resource.Resource):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
86 isLeaf = True
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
87
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
88 def errorPage(self, request, code):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
89 request.setResponseCode(code)
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
90 if code == http.BAD_REQUEST:
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
91 brief = 'Bad Request'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
92 details = "Your request is invalid"
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
93 elif code == http.FORBIDDEN:
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
94 brief = 'Forbidden'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
95 details = "You're not allowed to use this resource"
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
96 elif code == http.NOT_FOUND:
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
97 brief = 'Not Found'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
98 details = "No resource found at this URL"
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
99 else:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
100 brief = 'Error'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
101 details = "This resource can't be used"
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
102 log.error(f"Unexpected return code used: {code}")
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
103 log.warning(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
104 f'Error returned while trying to access url {request.uri.decode()}: '
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
105 f'"{brief}" ({code}): {details}'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
106 )
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
107
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
108 return resource.ErrorPage(code, brief, details).render(request)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
109
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
110 def getDispositionType(self, media_type, media_subtype):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
111 if media_type in ('image', 'video'):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
112 return 'inline'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
113 elif media_type == 'application' and media_subtype == 'pdf':
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
114 return 'inline'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
115 else:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
116 return 'attachment'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
117
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
118 def render(self, request):
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
119 request.setHeader("Access-Control-Allow-Origin", "*")
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
120 request.setHeader("Access-Control-Allow-Methods", "OPTIONS, HEAD, GET, PUT")
3340
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
121 request.setHeader(
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
122 "Access-Control-Allow-Headers",
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
123 "Content-Type, Range, Xmpp-File-Path, Xmpp-File-No-Http")
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
124 request.setHeader("Access-Control-Allow-Credentials", "true")
3340
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
125 request.setHeader("Accept-Ranges", "bytes")
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
126
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
127 request.setHeader(
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
128 "Access-Control-Expose-Headers",
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
129 "Date, Content-Length, Content-Range")
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
130 return super().render(request)
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
131
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
132 def render_OPTIONS(self, request):
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
133 request.setResponseCode(http.OK)
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
134 return b""
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
135
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
136 def render_GET(self, request):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
137 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
138 request.upload_data
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
139 except exceptions.DataError:
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
140 return self.errorPage(request, http.NOT_FOUND)
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
141
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
142 defer.ensureDeferred(self.renderGet(request))
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
143 return server.NOT_DONE_YET
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
144
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
145 async def renderGet(self, request):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
146 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
147 upload_id, filename = request.upload_data
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
148 except exceptions.DataError:
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
149 request.write(self.errorPage(request, http.FORBIDDEN))
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
150 request.finish()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
151 return
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
152 found_files = await request.file_sharing.host.memory.getFiles(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
153 client=None, peer_jid=None, perms_to_check=None, public_id=upload_id)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
154 if not found_files:
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
155 request.write(self.errorPage(request, http.NOT_FOUND))
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
156 request.finish()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
157 return
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
158 if len(found_files) > 1:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
159 log.error(f"more that one files found for public id {upload_id!r}")
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
160
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
161 found_file = found_files[0]
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
162 file_path = request.file_sharing.files_path/found_file['file_hash']
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
163 file_res = static.File(file_path)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
164 file_res.type = f'{found_file["media_type"]}/{found_file["media_subtype"]}'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
165 file_res.encoding = file_res.contentEncodings.get(Path(found_file['name']).suffix)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
166 disp_type = self.getDispositionType(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
167 found_file['media_type'], found_file['media_subtype'])
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
168 # the URL is percent encoded, and not all browsers/tools unquote the file name,
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
169 # thus we add a content disposition header
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
170 request.setHeader(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
171 'Content-Disposition',
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
172 f"{disp_type}; filename*=UTF-8''{quote(found_file['name'])}"
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
173 )
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
174 # cf. https://xmpp.org/extensions/xep-0363.html#server
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
175 request.setHeader(
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
176 'Content-Security-Policy',
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
177 "default-src 'none'; frame-ancestors 'none';"
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
178 )
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
179 ret = file_res.render(request)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
180 if ret != server.NOT_DONE_YET:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
181 # HEAD returns directly the result (while GET use a produced)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
182 request.write(ret)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
183 request.finish()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
184
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
185 def render_PUT(self, request):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
186 defer.ensureDeferred(self.renderPut(request))
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
187 return server.NOT_DONE_YET
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
188
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
189 async def renderPut(self, request):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
190 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
191 client, upload_request = request.upload_request_data
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
192 upload_id, filename = request.upload_data
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
193 except AttributeError:
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
194 request.write(self.errorPage(request, http.BAD_REQUEST))
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
195 request.finish()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
196 return
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
197
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
198 # at this point request is checked and file is buffered, we can store it
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
199 # we close the content here, before registering the file
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
200 request.content.close()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
201 tmp_file_path = Path(request.content.name)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
202 request.content = None
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
203
3297
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
204 # the 2 following headers are not standard, but useful in the context of file
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
205 # sharing with HTTP Upload: first one allow uploaded to specify the path
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
206 # and second one will disable public exposure of the file through HTTP
3301
9d1c0feba048 comp file sharing: file paths are now quoted on upload to allow unicode
Goffi <goffi@goffi.org>
parents: 3297
diff changeset
207 path = request.getHeader("Xmpp-File-Path")
9d1c0feba048 comp file sharing: file paths are now quoted on upload to allow unicode
Goffi <goffi@goffi.org>
parents: 3297
diff changeset
208 if path:
9d1c0feba048 comp file sharing: file paths are now quoted on upload to allow unicode
Goffi <goffi@goffi.org>
parents: 3297
diff changeset
209 path = unquote(path)
9d1c0feba048 comp file sharing: file paths are now quoted on upload to allow unicode
Goffi <goffi@goffi.org>
parents: 3297
diff changeset
210 else:
9d1c0feba048 comp file sharing: file paths are now quoted on upload to allow unicode
Goffi <goffi@goffi.org>
parents: 3297
diff changeset
211 path = "/uploads"
3297
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
212 if request.getHeader("Xmpp-File-No-Http") is not None:
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
213 public_id = None
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
214 else:
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
215 public_id = upload_id
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
216
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
217 file_data = {
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
218 "name": unquote(upload_request.filename),
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
219 "mime_type": upload_request.content_type,
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
220 "size": upload_request.size,
3297
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
221 "path": path
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
222 }
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
223
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
224 await request.file_sharing.registerReceivedFile(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
225 client, upload_request.from_, file_data, tmp_file_path,
3297
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
226 public_id=public_id,
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
227 )
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
228
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
229 request.setResponseCode(http.CREATED)
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
230 request.finish()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
231
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
232
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
233 class FileSharingRequest(server.Request):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
234
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
235 def __init__(self, *args, **kwargs):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
236 super().__init__(*args, **kwargs)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
237 self._upload_data = None
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
238
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
239 @property
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
240 def upload_data(self):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
241 """A tuple with upload_id and filename retrieve from requested path"""
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
242 if self._upload_data is not None:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
243 return self._upload_data
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
244
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
245 # self.path is not available if we are easly in the request (e.g. when gotLength
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
246 # is called), in which case channel._path must be used. On the other hand, when
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
247 # render_[VERB] is called, only self.path is available
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
248 path = self.channel._path if self.path is None else self.path
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
249 # we normalise the path
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
250 path = urlparse(path.decode()).path
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
251 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
252 __, upload_id, filename = path.split('/')
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
253 except ValueError:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
254 raise exceptions.DataError("no enought path elements")
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
255 if len(upload_id) < 10:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
256 raise exceptions.DataError(f"invalid upload ID received for a PUT: {upload_id!r}")
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
257
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
258 self._upload_data = (upload_id, filename)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
259 return self._upload_data
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
260
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
261 @property
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
262 def file_sharing(self):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
263 return self.channel.site.file_sharing
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
264
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
265 @property
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
266 def file_tmp_dir(self):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
267 return self.channel.site.file_tmp_dir
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
268
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
269 def refuseRequest(self):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
270 if self.content is not None:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
271 self.content.close()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
272 self.content = open(os.devnull, 'w+b')
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
273 self.channel._respondToBadRequestAndDisconnect()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
274
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
275 def gotLength(self, length):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
276 if self.channel._command.decode().upper() == 'PUT':
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
277 # for PUT we check early if upload_id is fine, to avoid buffering a file we'll refuse
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
278 # we buffer the file in component's TMP_BUFFER_DIR, so we just have to rename it at the end
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
279 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
280 upload_id, filename = self.upload_data
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
281 except exceptions.DataError as e:
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
282 log.warning(f"Invalid PUT request, we stop here: {e}")
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
283 return self.refuseRequest()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
284 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
285 client, upload_request, timer = self.file_sharing.expected_uploads.pop(upload_id)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
286 except KeyError:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
287 log.warning(f"unknown (expired?) upload ID received for a PUT: {upload_id!r}")
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
288 return self.refuseRequest()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
290 if not timer.active:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
291 log.warning(f"upload id {upload_id!r} used for a PUT, but it is expired")
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
292 return self.refuseRequest()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
293
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
294 timer.cancel()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
295
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
296 if upload_request.filename != filename:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
297 log.warning(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
298 f"invalid filename for PUT (upload id: {upload_id!r}, URL: {self.channel._path.decode()}). Original "
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
299 f"{upload_request.filename!r} doesn't match {filename!r}"
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
300 )
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
301 return self.refuseRequest()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
302
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
303 self.upload_request_data = (client, upload_request)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
304
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
305 file_tmp_path = files_utils.get_unique_name(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
306 self.file_tmp_dir/upload_id)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
307
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
308 self.content = open(file_tmp_path, 'w+b')
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
309 else:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
310 return super().gotLength(length)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
311
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
312
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
313 class FileSharingSite(server.Site):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
314 requestFactory = FileSharingRequest
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
315
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
316 def __init__(self, file_sharing):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
317 self.file_sharing = file_sharing
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
318 self.file_tmp_dir = file_sharing.host.getLocalPath(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
319 None, C.FILES_TMP_DIR, TMP_BUFFER_DIR, component=True, profile=False
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
320 )
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
321 for old_file in self.file_tmp_dir.iterdir():
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
322 log.debug(f"purging old buffer file at {old_file}")
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
323 old_file.unlink()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
324 super().__init__(HTTPFileServer())
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
325
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
326 def getContentFile(self, length):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
327 file_tmp_path = self.file_tmp_dir/shortuuid.uuid()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
328 return open(file_tmp_path, 'w+b')
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
329
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
330
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
331 class FileSharing:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
332
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
333 def __init__(self, host):
3291
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
334 self.host = host
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
335 self.initialised = False
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
336
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
337 def init(self):
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
338 # we init once on first component connection,
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
339 # there is not need to init this plugin if not component use it
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
340 # TODO: this plugin should not be loaded at all if no component uses it
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
341 # and should be loaded dynamically as soon as a suitable profile is created
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
342 if self.initialised:
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
343 return
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
344 self.initialised = True
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
345 log.info(_("File Sharing initialization"))
3291
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
346 self._f = self.host.plugins["FILE"]
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
347 self._jf = self.host.plugins["XEP-0234"]
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
348 self._h = self.host.plugins["XEP-0300"]
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
349 self._t = self.host.plugins["XEP-0264"]
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
350 self.host.plugins["XEP-0363"].registerHandler(self._onHTTPUpload)
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
351 self.host.trigger.add("FILE_getDestDir", self._getDestDirTrigger)
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
352 self.host.trigger.add(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
353 "XEP-0234_fileSendingRequest", self._fileSendingRequestTrigger, priority=1000
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
354 )
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
355 self.host.trigger.add("XEP-0234_buildFileElement", self._addFileMetadataElts)
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
356 self.host.trigger.add("XEP-0234_parseFileElement", self._getFileMetadataElts)
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
357 self.host.trigger.add("XEP-0329_compGetFilesFromNode", self._addFileMetadata)
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
358 self.host.trigger.add(
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
359 "XEP-0329_compGetFilesFromNode_build_directory",
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
360 self._addDirectoryMetadataElts)
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
361 self.host.trigger.add(
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
362 "XEP-0329_parseResult_directory",
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
363 self._getDirectoryMetadataElts)
3291
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
364 self.files_path = self.host.getLocalPath(None, C.FILES_DIR, profile=False)
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
365 self.http_port = self.host.memory.getConfig(
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
366 'component file_sharing', 'http_upload_port', 8888)
3291
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
367 connection_type = self.host.memory.getConfig(
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
368 'component file_sharing', 'http_upload_connection_type', 'https')
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
369 if connection_type not in ('http', 'https'):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
370 raise exceptions.ConfigError(
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
371 'bad http_upload_connection_type, you must use one of "http" or "https"'
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
372 )
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
373 self.server = FileSharingSite(self)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
374 self.expected_uploads = {}
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
375 if connection_type == 'http':
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
376 reactor.listenTCP(self.http_port, self.server)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
377 else:
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
378 options = tls.getOptionsFromConfig(
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
379 self.host.memory.config, "component file_sharing")
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
380 tls.TLSOptionsCheck(options)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
381 context_factory = tls.getTLSContextFactory(options)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
382 reactor.listenSSL(self.http_port, self.server, context_factory)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
383
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
384 def getHandler(self, client):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
385 return Comments_handler(self)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
386
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
387 def profileConnecting(self, client):
3291
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
388 self.init()
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
389 public_base_url = self.host.memory.getConfig(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
390 'component file_sharing', 'http_upload_public_facing_url')
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
391 if public_base_url is None:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
392 client._file_sharing_base_url = f"https://{client.host}:{self.http_port}"
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
393 else:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
394 client._file_sharing_base_url = public_base_url
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
395 path = client.file_tmp_dir = os.path.join(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
396 self.host.memory.getConfig("", "local_dir"),
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
397 C.FILES_TMP_DIR,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
398 regex.pathEscape(client.profile),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
399 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
400 if not os.path.exists(path):
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
401 os.makedirs(path)
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
402
3348
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
403 async def generate_thumbnails(self, extra: dict, image_path: Path):
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
404 thumbnails = extra.setdefault(C.KEY_THUMBNAILS, [])
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
405 for max_thumb_size in self._t.SIZES:
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
406 try:
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
407 thumb_size, thumb_id = await self._t.generateThumbnail(
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
408 image_path,
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
409 max_thumb_size,
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
410 #  we keep thumbnails for 6 months
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
411 60 * 60 * 24 * 31 * 6,
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
412 )
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
413 except Exception as e:
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
414 log.warning(_("Can't create thumbnail: {reason}").format(reason=e))
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
415 break
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
416 thumbnails.append({"id": thumb_id, "size": thumb_size})
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
417
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
418 async def registerReceivedFile(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
419 self, client, peer_jid, file_data, file_path, public_id=None, extra=None):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
420 """Post file reception tasks
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
421
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
422 once file is received, this method create hash/thumbnails if necessary
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
423 move the file to the right location, and create metadata entry in database
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
424 """
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
425 name = file_data["name"]
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
426 if extra is None:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
427 extra = {}
2514
4440ea7047bd file sharing component: thumbnails integration first draft:
Goffi <goffi@goffi.org>
parents: 2504
diff changeset
428
3331
b1e9f17fbb5a comp file sharing: minor core re-organisation
Goffi <goffi@goffi.org>
parents: 3329
diff changeset
429 mime_type = file_data.get("mime_type")
b1e9f17fbb5a comp file sharing: minor core re-organisation
Goffi <goffi@goffi.org>
parents: 3329
diff changeset
430 if not mime_type or mime_type == "application/octet-stream":
b1e9f17fbb5a comp file sharing: minor core re-organisation
Goffi <goffi@goffi.org>
parents: 3329
diff changeset
431 mime_type = mimetypes.guess_type(name)[0]
b1e9f17fbb5a comp file sharing: minor core re-organisation
Goffi <goffi@goffi.org>
parents: 3329
diff changeset
432
b1e9f17fbb5a comp file sharing: minor core re-organisation
Goffi <goffi@goffi.org>
parents: 3329
diff changeset
433 is_image = mime_type is not None and mime_type.startswith("image")
3348
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
434 is_video = mime_type is not None and mime_type.startswith("video")
3331
b1e9f17fbb5a comp file sharing: minor core re-organisation
Goffi <goffi@goffi.org>
parents: 3329
diff changeset
435
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
436 if file_data.get("hash_algo") == HASH_ALGO:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
437 log.debug(_("Reusing already generated hash"))
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
438 file_hash = file_data["hash_hasher"].hexdigest()
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
439 else:
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
440 hasher = self._h.getHasher(HASH_ALGO)
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
441 with file_path.open('rb') as f:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
442 file_hash = await self._h.calculateHash(f, hasher)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
443 final_path = self.files_path/file_hash
2514
4440ea7047bd file sharing component: thumbnails integration first draft:
Goffi <goffi@goffi.org>
parents: 2504
diff changeset
444
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
445 if final_path.is_file():
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
446 log.debug(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
447 "file [{file_hash}] already exists, we can remove temporary one".format(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
448 file_hash=file_hash
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
449 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
450 )
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
451 file_path.unlink()
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
452 else:
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
453 file_path.rename(final_path)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
454 log.debug(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
455 "file [{file_hash}] moved to {files_path}".format(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
456 file_hash=file_hash, files_path=self.files_path
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
457 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
458 )
2514
4440ea7047bd file sharing component: thumbnails integration first draft:
Goffi <goffi@goffi.org>
parents: 2504
diff changeset
459
3331
b1e9f17fbb5a comp file sharing: minor core re-organisation
Goffi <goffi@goffi.org>
parents: 3329
diff changeset
460 if is_image:
3348
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
461 await self.generate_thumbnails(extra, final_path)
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
462 elif is_video:
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
463 with tempfile.TemporaryDirectory() as tmp_dir:
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
464 thumb_path = Path(tmp_dir) / "thumbnail.jpg"
2514
4440ea7047bd file sharing component: thumbnails integration first draft:
Goffi <goffi@goffi.org>
parents: 2504
diff changeset
465 try:
3348
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
466 await video.get_thumbnail(final_path, thumb_path)
2514
4440ea7047bd file sharing component: thumbnails integration first draft:
Goffi <goffi@goffi.org>
parents: 2504
diff changeset
467 except Exception as e:
3348
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
468 log.warning(_("Can't get thumbnail for {final_path}: {e}").format(
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
469 final_path=final_path, e=e))
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
470 else:
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
471 await self.generate_thumbnails(extra, thumb_path)
2514
4440ea7047bd file sharing component: thumbnails integration first draft:
Goffi <goffi@goffi.org>
parents: 2504
diff changeset
472
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
473 self.host.memory.setFile(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
474 client,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
475 name=name,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
476 version="",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
477 file_hash=file_hash,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
478 hash_algo=HASH_ALGO,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
479 size=file_data["size"],
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
480 path=file_data.get("path"),
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
481 namespace=file_data.get("namespace"),
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
482 mime_type=mime_type,
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
483 public_id=public_id,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
484 owner=peer_jid,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
485 extra=extra,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
486 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
487
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
488 def _getDestDirTrigger(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
489 self, client, peer_jid, transfer_data, file_data, stream_object
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
490 ):
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
491 """This trigger accept file sending request, and store file locally"""
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
492 if not client.is_component:
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
493 return True, None
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
494 assert stream_object
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
495 assert "stream_object" not in transfer_data
2514
4440ea7047bd file sharing component: thumbnails integration first draft:
Goffi <goffi@goffi.org>
parents: 2504
diff changeset
496 assert C.KEY_PROGRESS_ID in file_data
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
497 filename = file_data["name"]
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
498 assert filename and not "/" in filename
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
499 file_tmp_dir = self.host.getLocalPath(
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
500 None, C.FILES_TMP_DIR, peer_jid.userhost(), component=True, profile=False
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
501 )
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
502 file_tmp_path = file_data['file_path'] = files_utils.get_unique_name(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
503 file_tmp_dir/filename)
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
504
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
505 transfer_data["finished_d"].addCallback(
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
506 lambda __: defer.ensureDeferred(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
507 self.registerReceivedFile(client, peer_jid, file_data, file_tmp_path)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
508 )
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
509 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
510
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
511 self._f.openFileWrite(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
512 client, file_tmp_path, transfer_data, file_data, stream_object
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
513 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
514 return False, defer.succeed(True)
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
515
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
516 @defer.inlineCallbacks
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
517 def _retrieveFiles(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
518 self, client, session, content_data, content_name, file_data, file_elt
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
519 ):
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
520 """This method retrieve a file on request, and send if after checking permissions"""
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
521 peer_jid = session["peer_jid"]
3367
90aee1f2d07c component file sharing: added missing `owner` filtering in `_retrieveFiles`
Goffi <goffi@goffi.org>
parents: 3363
diff changeset
522 owner = client.getOwnerFromJid(session['local_jid'])
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
523 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
524 found_files = yield self.host.memory.getFiles(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
525 client,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
526 peer_jid=peer_jid,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
527 name=file_data.get("name"),
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
528 file_hash=file_data.get("file_hash"),
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
529 hash_algo=file_data.get("hash_algo"),
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
530 path=file_data.get("path"),
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
531 namespace=file_data.get("namespace"),
3367
90aee1f2d07c component file sharing: added missing `owner` filtering in `_retrieveFiles`
Goffi <goffi@goffi.org>
parents: 3363
diff changeset
532 owner=owner,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
533 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
534 except exceptions.NotFound:
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
535 found_files = None
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
536 except exceptions.PermissionError:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
537 log.warning(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
538 _("{peer_jid} is trying to access an unauthorized file: {name}").format(
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
539 peer_jid=peer_jid, name=file_data.get("name")
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
540 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
541 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
542 defer.returnValue(False)
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
543
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
544 if not found_files:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
545 log.warning(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
546 _("no matching file found ({file_data})").format(file_data=file_data)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
547 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
548 defer.returnValue(False)
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
549
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
550 # we only use the first found file
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
551 found_file = found_files[0]
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
552 if found_file['type'] != C.FILE_TYPE_FILE:
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
553 raise TypeError("a file was expected, type is {type_}".format(
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
554 type_=found_file['type']))
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
555 file_hash = found_file["file_hash"]
3363
e3bdfecaf1b0 component file sharing: fix used of `self.files_path` in `_retrieveFiles`
Goffi <goffi@goffi.org>
parents: 3359
diff changeset
556 file_path = self.files_path / file_hash
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
557 file_data["hash_hasher"] = hasher = self._h.getHasher(found_file["hash_algo"])
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
558 size = file_data["size"] = found_file["size"]
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
559 file_data["file_hash"] = file_hash
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
560 file_data["hash_algo"] = found_file["hash_algo"]
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
561
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
562 # we complete file_elt so peer can have some details on the file
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
563 if "name" not in file_data:
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
564 file_elt.addElement("name", content=found_file["name"])
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
565 file_elt.addElement("size", content=str(size))
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
566 content_data["stream_object"] = stream.FileStreamObject(
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
567 self.host,
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
568 client,
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
569 file_path,
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
570 uid=self._jf.getProgressId(session, content_name),
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
571 size=size,
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
572 data_cb=lambda data: hasher.update(data),
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
573 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
574 defer.returnValue(True)
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
575
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
576 def _fileSendingRequestTrigger(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
577 self, client, session, content_data, content_name, file_data, file_elt
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
578 ):
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
579 if not client.is_component:
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
580 return True, None
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
581 else:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
582 return (
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
583 False,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
584 self._retrieveFiles(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
585 client, session, content_data, content_name, file_data, file_elt
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
586 ),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
587 )
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
588
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
589 ## HTTP Upload ##
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
590
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
591 def _purge_slot(self, upload_id):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
592 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
593 del self.expected_uploads[upload_id]
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
594 except KeyError:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
595 log.error(f"trying to purge an inexisting upload slot ({upload_id})")
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
596
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
597 def _onHTTPUpload(self, client, request):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
598 # filename should be already cleaned, but it's better to double check
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
599 assert '/' not in request.filename
3359
000b6722bd35 plugin XEP-0329: added `FISCreateDir` method:
Goffi <goffi@goffi.org>
parents: 3348
diff changeset
600 # client._file_sharing_allowed_hosts is set in plugin XEP-0329
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
601 if request.from_.host not in client._file_sharing_allowed_hosts:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
602 raise error.StanzaError("forbidden")
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
603
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
604 upload_id = shortuuid.ShortUUID().random(length=30)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
605 assert '/' not in upload_id
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
606 timer = reactor.callLater(30, self._purge_slot, upload_id)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
607 self.expected_uploads[upload_id] = (client, request, timer)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
608 url = urljoin(client._file_sharing_base_url, f"{upload_id}/{request.filename}")
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
609 slot = self.host.plugins["XEP-0363"].Slot(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
610 put=url,
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
611 get=url,
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
612 headers=[],
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
613 )
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
614 return slot
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
615
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
616 ## metadata triggers ##
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
617
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
618 def _addFileMetadataElts(self, client, file_elt, extra_args):
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
619 # affiliation
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
620 affiliation = extra_args.get('affiliation')
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
621 if affiliation is not None:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
622 file_elt.addElement((NS_FS_AFFILIATION, "affiliation"), content=affiliation)
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
623
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
624 # comments
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
625 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
626 comments_url = extra_args.pop("comments_url")
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
627 except KeyError:
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
628 return
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
629
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
630 comment_elt = file_elt.addElement((NS_COMMENTS, "comments"), content=comments_url)
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
631
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
632 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
633 count = len(extra_args["extra"]["comments"])
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
634 except KeyError:
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
635 count = 0
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
636
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
637 comment_elt["count"] = str(count)
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
638 return True
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
639
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
640 def _getFileMetadataElts(self, client, file_elt, file_data):
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
641 # affiliation
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
642 try:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
643 affiliation_elt = next(file_elt.elements(NS_FS_AFFILIATION, "affiliation"))
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
644 except StopIteration:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
645 pass
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
646 else:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
647 file_data["affiliation"] = str(affiliation_elt)
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
648
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
649 # comments
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
650 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
651 comments_elt = next(file_elt.elements(NS_COMMENTS, "comments"))
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
652 except StopIteration:
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
653 pass
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
654 else:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
655 file_data["comments_url"] = str(comments_elt)
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
656 file_data["comments_count"] = comments_elt["count"]
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
657 return True
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
658
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
659 def _addFileMetadata(
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
660 self, client, iq_elt, iq_result_elt, owner, node_path, files_data):
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
661 for file_data in files_data:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
662 file_data["comments_url"] = uri.buildXMPPUri(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
663 "pubsub",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
664 path=client.jid.full(),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
665 node=COMMENT_NODE_PREFIX + file_data["id"],
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
666 )
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
667 return True
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
668
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
669 def _addDirectoryMetadataElts(
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
670 self, client, file_data, directory_elt, owner, node_path):
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
671 affiliation = file_data.get('affiliation')
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
672 if affiliation is not None:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
673 directory_elt.addElement(
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
674 (NS_FS_AFFILIATION, "affiliation"),
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
675 content=affiliation
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
676 )
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
677
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
678 def _getDirectoryMetadataElts(
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
679 self, client, elt, file_data):
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
680 try:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
681 affiliation_elt = next(elt.elements((NS_FS_AFFILIATION, "affiliation")))
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
682 except StopIteration:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
683 pass
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
684 else:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
685 file_data['affiliation'] = str(affiliation_elt)
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
686
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
687
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
688 class Comments_handler(pubsub.PubSubService):
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
689 """This class is a minimal Pubsub service handling virtual nodes for comments"""
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
690
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
691 def __init__(self, plugin_parent):
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
692 super(Comments_handler, self).__init__()
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
693 self.host = plugin_parent.host
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
694 self.plugin_parent = plugin_parent
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
695 self.discoIdentity = {
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
696 "category": "pubsub",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
697 "type": "virtual", # FIXME: non standard, here to avoid this service being considered as main pubsub one
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
698 "name": "files commenting service",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
699 }
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
700
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
701 def _getFileId(self, nodeIdentifier):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
702 if not nodeIdentifier.startswith(COMMENT_NODE_PREFIX):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
703 raise error.StanzaError("item-not-found")
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
704 file_id = nodeIdentifier[len(COMMENT_NODE_PREFIX) :]
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
705 if not file_id:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
706 raise error.StanzaError("item-not-found")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
707 return file_id
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
708
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
709 @defer.inlineCallbacks
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
710 def getFileData(self, requestor, nodeIdentifier):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
711 file_id = self._getFileId(nodeIdentifier)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
712 try:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
713 files = yield self.host.memory.getFiles(self.parent, requestor, file_id)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
714 except (exceptions.NotFound, exceptions.PermissionError):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
715 # we don't differenciate between NotFound and PermissionError
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
716 # to avoid leaking information on existing files
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
717 raise error.StanzaError("item-not-found")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
718 if not files:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
719 raise error.StanzaError("item-not-found")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
720 if len(files) > 1:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
721 raise error.InternalError("there should be only one file")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
722 defer.returnValue(files[0])
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
723
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
724 def commentsUpdate(self, extra, new_comments, peer_jid):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
725 """update comments (replace or insert new_comments)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
726
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
727 @param extra(dict): extra data to update
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
728 @param new_comments(list[tuple(unicode, unicode, unicode)]): comments to update or insert
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
729 @param peer_jid(unicode, None): bare jid of the requestor, or None if request is done by owner
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
730 """
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
731 current_comments = extra.setdefault("comments", [])
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
732 new_comments_by_id = {c[0]: c for c in new_comments}
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
733 updated = []
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
734 # we now check every current comment, to see if one id in new ones
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
735 # exist, in which case we must update
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
736 for idx, comment in enumerate(current_comments):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
737 comment_id = comment[0]
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
738 if comment_id in new_comments_by_id:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
739 # a new comment has an existing id, update is requested
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
740 if peer_jid and comment[1] != peer_jid:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
741 # requestor has not the right to modify the comment
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
742 raise exceptions.PermissionError
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
743 # we replace old_comment with updated one
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
744 new_comment = new_comments_by_id[comment_id]
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
745 current_comments[idx] = new_comment
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
746 updated.append(new_comment)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
747
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
748 # we now remove every updated comments, to only keep
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
749 # the ones to insert
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
750 for comment in updated:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
751 new_comments.remove(comment)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
752
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
753 current_comments.extend(new_comments)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
754
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
755 def commentsDelete(self, extra, comments):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
756 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
757 comments_dict = extra["comments"]
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
758 except KeyError:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
759 return
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
760 for comment in comments:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
761 try:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
762 comments_dict.remove(comment)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
763 except ValueError:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
764 continue
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
765
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
766 def _getFrom(self, item_elt):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
767 """retrieve published of an item
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
768
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
769 @param item_elt(domish.element): <item> element
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
770 @return (unicode): full jid as string
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
771 """
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
772 iq_elt = item_elt
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
773 while iq_elt.parent != None:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
774 iq_elt = iq_elt.parent
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
775 return iq_elt["from"]
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
776
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
777 @defer.inlineCallbacks
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
778 def publish(self, requestor, service, nodeIdentifier, items):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
779 #  we retrieve file a first time to check authorisations
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
780 file_data = yield self.getFileData(requestor, nodeIdentifier)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
781 file_id = file_data["id"]
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
782 comments = [(item["id"], self._getFrom(item), item.toXml()) for item in items]
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
783 if requestor.userhostJID() == file_data["owner"]:
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
784 peer_jid = None
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
785 else:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
786 peer_jid = requestor.userhost()
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
787 update_cb = partial(self.commentsUpdate, new_comments=comments, peer_jid=peer_jid)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
788 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
789 yield self.host.memory.fileUpdate(file_id, "extra", update_cb)
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
790 except exceptions.PermissionError:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
791 raise error.StanzaError("not-authorized")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
792
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
793 @defer.inlineCallbacks
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
794 def items(self, requestor, service, nodeIdentifier, maxItems, itemIdentifiers):
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
795 file_data = yield self.getFileData(requestor, nodeIdentifier)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
796 comments = file_data["extra"].get("comments", [])
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
797 if itemIdentifiers:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
798 defer.returnValue(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
799 [generic.parseXml(c[2]) for c in comments if c[0] in itemIdentifiers]
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
800 )
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
801 else:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
802 defer.returnValue([generic.parseXml(c[2]) for c in comments])
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
803
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
804 @defer.inlineCallbacks
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
805 def retract(self, requestor, service, nodeIdentifier, itemIdentifiers):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
806 file_data = yield self.getFileData(requestor, nodeIdentifier)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
807 file_id = file_data["id"]
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
808 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
809 comments = file_data["extra"]["comments"]
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
810 except KeyError:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
811 raise error.StanzaError("item-not-found")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
812
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
813 to_remove = []
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
814 for comment in comments:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
815 comment_id = comment[0]
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
816 if comment_id in itemIdentifiers:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
817 to_remove.append(comment)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
818 itemIdentifiers.remove(comment_id)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
819 if not itemIdentifiers:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
820 break
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
821
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
822 if itemIdentifiers:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
823 # not all items have been to_remove, we can't continue
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
824 raise error.StanzaError("item-not-found")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
825
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
826 if requestor.userhostJID() != file_data["owner"]:
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
827 if not all([c[1] == requestor.userhost() for c in to_remove]):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
828 raise error.StanzaError("not-authorized")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
829
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
830 remove_cb = partial(self.commentsDelete, comments=to_remove)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
831 yield self.host.memory.fileUpdate(file_id, "extra", remove_cb)