annotate sat/plugins/plugin_comp_file_sharing.py @ 3701:6d298323eed2

plugin comp file sharing: don't use Deferred in return value
author Goffi <goffi@goffi.org>
date Fri, 05 Nov 2021 18:11:24 +0100
parents 02e5e2385a30
children 09f5ac48ffe3
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
3677
02e5e2385a30 component (file-sharing): use `file-sharing` instead of `file_sharing`:
Goffi <goffi@goffi.org>
parents: 3532
diff changeset
3 # Libervia File Sharing component
3479
be6d91572633 date update
Goffi <goffi@goffi.org>
parents: 3367
diff changeset
4 # Copyright (C) 2009-2021 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
3528
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
28 from sat.core.i18n import _, D_
2504
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
3528
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
37 from sat.tools.common import utils
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
38 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
39 from twisted.internet import defer, reactor
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
40 from twisted.words.protocols.jabber import error
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
41 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
42 from wokkel import pubsub
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
43 from wokkel import generic
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
44
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
45
3136
9d0df638c8b4 dates update
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
46 log = getLogger(__name__)
9d0df638c8b4 dates update
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
47
9d0df638c8b4 dates update
Goffi <goffi@goffi.org>
parents: 3028
diff changeset
48
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 PLUGIN_INFO = {
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 C.PI_NAME: "File sharing component",
3677
02e5e2385a30 component (file-sharing): use `file-sharing` instead of `file_sharing`:
Goffi <goffi@goffi.org>
parents: 3532
diff changeset
51 C.PI_IMPORT_NAME: "file-sharing",
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 C.PI_MODES: [C.PLUG_MODE_COMPONENT],
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 C.PI_TYPE: C.PLUG_TYPE_ENTRY_POINT,
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 C.PI_PROTOCOLS: [],
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
55 C.PI_DEPENDENCIES: [
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
56 "FILE",
2929
e0429ff7f6b6 plugin comp file sharing: file sharing management first draft:
Goffi <goffi@goffi.org>
parents: 2771
diff changeset
57 "FILE_SHARING_MANAGEMENT",
3367
90aee1f2d07c component file sharing: added missing `owner` filtering in `_retrieveFiles`
Goffi <goffi@goffi.org>
parents: 3363
diff changeset
58 "XEP-0106",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
59 "XEP-0234",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
60 "XEP-0260",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
61 "XEP-0261",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
62 "XEP-0264",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
63 "XEP-0329",
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
64 "XEP-0363",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
65 ],
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 C.PI_RECOMMENDATIONS: [],
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 C.PI_MAIN: "FileSharing",
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
68 C.PI_HANDLER: C.BOOL_TRUE,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
69 C.PI_DESCRIPTION: _("""Component hosting and sharing files"""),
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
70 }
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
71
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
72 HASH_ALGO = "sha-256"
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
73 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
74 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
75 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
76 # 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
77 # 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
78 TMP_BUFFER_DIR = "@@tmp@@"
3528
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
79 OVER_QUOTA_TXT = D_(
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
80 "You are over quota, your maximum allowed size is {quota} and you are already using "
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
81 "{used_space}, you can't upload {file_size} more."
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
82 )
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
83
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
84 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
85 'NFKD',
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
86 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
87 ).encode('ascii','ignore')
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
88
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
89
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
90 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
91 isLeaf = True
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
92
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
93 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
94 request.setResponseCode(code)
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
95 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
96 brief = 'Bad Request'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
97 details = "Your request is invalid"
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
98 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
99 brief = 'Forbidden'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
100 details = "You're not allowed to use this resource"
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
101 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
102 brief = 'Not Found'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
103 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
104 else:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
105 brief = 'Error'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
106 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
107 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
108 log.warning(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
109 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
110 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
111 )
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
112
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
113 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
114
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
115 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
116 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
117 return 'inline'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
118 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
119 return 'inline'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
120 else:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
121 return 'attachment'
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
122
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
123 def render(self, request):
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
124 request.setHeader("Access-Control-Allow-Origin", "*")
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
125 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
126 request.setHeader(
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
127 "Access-Control-Allow-Headers",
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
128 "Content-Type, Range, Xmpp-File-Path, Xmpp-File-No-Http")
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
129 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
130 request.setHeader("Accept-Ranges", "bytes")
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
131
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
132 request.setHeader(
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
133 "Access-Control-Expose-Headers",
2ad14b834730 component file sharing: added `Access-Control-Expose-Headers` CORS header:
Goffi <goffi@goffi.org>
parents: 3331
diff changeset
134 "Date, Content-Length, Content-Range")
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
135 return super().render(request)
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
136
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
137 def render_OPTIONS(self, request):
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
138 request.setResponseCode(http.OK)
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
139 return b""
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
140
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
141 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
142 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
143 request.upload_data
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
144 except exceptions.DataError:
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
145 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
146
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
147 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
148 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
149
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
150 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
151 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
152 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
153 except exceptions.DataError:
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
154 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
155 request.finish()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
156 return
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
157 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
158 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
159 if not found_files:
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
160 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
161 request.finish()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
162 return
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
163 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
164 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
165
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
166 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
167 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
168 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
169 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
170 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
171 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
172 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
173 # 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
174 # 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
175 request.setHeader(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
176 'Content-Disposition',
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
177 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
178 )
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
179 # cf. https://xmpp.org/extensions/xep-0363.html#server
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
180 request.setHeader(
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
181 'Content-Security-Policy',
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
182 "default-src 'none'; frame-ancestors 'none';"
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
183 )
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
184 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
185 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
186 # 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
187 request.write(ret)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
188 request.finish()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
189
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
190 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
191 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
192 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
193
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
194 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
195 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
196 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
197 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
198 except AttributeError:
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
199 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
200 request.finish()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
201 return
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
202
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
203 # 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
204 # 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
205 request.content.close()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
206 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
207 request.content = None
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
208
3297
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
209 # the 2 following headers are not standard, but useful in the context of file
3677
02e5e2385a30 component (file-sharing): use `file-sharing` instead of `file_sharing`:
Goffi <goffi@goffi.org>
parents: 3532
diff changeset
210 # sharing with HTTP Upload: first one allow uploader to specify the path
3297
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
211 # 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
212 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
213 if path:
9d1c0feba048 comp file sharing: file paths are now quoted on upload to allow unicode
Goffi <goffi@goffi.org>
parents: 3297
diff changeset
214 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
215 else:
9d1c0feba048 comp file sharing: file paths are now quoted on upload to allow unicode
Goffi <goffi@goffi.org>
parents: 3297
diff changeset
216 path = "/uploads"
3297
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
217 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
218 public_id = None
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
219 else:
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
220 public_id = upload_id
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
221
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
222 file_data = {
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
223 "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
224 "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
225 "size": upload_request.size,
3297
91b5ae058c66 comp file sharing: handle upload with headers:
Goffi <goffi@goffi.org>
parents: 3296
diff changeset
226 "path": path
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
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
229 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
230 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
231 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
232 )
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
233
3296
da443cf946ad comp file sharing: CORS:
Goffi <goffi@goffi.org>
parents: 3291
diff changeset
234 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
235 request.finish()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
236
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
237
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
238 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
239
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
240 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
241 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
242 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
243
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
244 @property
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
245 def upload_data(self):
3677
02e5e2385a30 component (file-sharing): use `file-sharing` instead of `file_sharing`:
Goffi <goffi@goffi.org>
parents: 3532
diff changeset
246 """A tuple with upload_id and filename retrieved from requested path"""
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
247 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
248 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
249
3528
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
250 # self.path is not available if we are early in the request (e.g. when gotLength
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
251 # 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
252 # 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
253 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
254 # 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
255 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
256 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
257 __, 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
258 except ValueError:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
259 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
260 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
261 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
262
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
263 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
264 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
265
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
266 @property
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
267 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
268 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
269
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
270 @property
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
271 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
272 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
273
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
274 def refuseRequest(self):
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
275 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
276 self.content.close()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
277 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
278 self.channel._respondToBadRequestAndDisconnect()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
279
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
280 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
281 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
282 # 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
283 # 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
284 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
285 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
286 except exceptions.DataError as e:
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
287 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
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 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
290 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
291 except KeyError:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
292 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
293 return self.refuseRequest()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
294
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
295 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
296 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
297 return self.refuseRequest()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
298
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
299 timer.cancel()
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 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
302 log.warning(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
303 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
304 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
305 )
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
306 return self.refuseRequest()
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.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
309
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
310 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
311 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
312
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
313 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
314 else:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
315 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
316
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
317
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
318 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
319 requestFactory = FileSharingRequest
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 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
322 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
323 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
324 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
325 )
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
326 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
327 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
328 old_file.unlink()
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
329 super().__init__(HTTPFileServer())
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 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
332 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
333 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
334
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
335
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
336 class FileSharing:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
337
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
338 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
339 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
340 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
341
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
342 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
343 # 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
344 # 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
345 # 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
346 # 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
347 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
348 return
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
349 self.initialised = True
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
350 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
351 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
352 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
353 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
354 self._t = self.host.plugins["XEP-0264"]
3528
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
355 self._hu = self.host.plugins["XEP-0363"]
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
356 self._hu.registerHandler(self._onHTTPUpload)
3291
449dfbfcdbcc component file sharing: don't initialise the plugin if not component use it
Goffi <goffi@goffi.org>
parents: 3289
diff changeset
357 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
358 self.host.trigger.add(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
359 "XEP-0234_fileSendingRequest", self._fileSendingRequestTrigger, priority=1000
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
360 )
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
361 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
362 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
363 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
364 self.host.trigger.add(
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
365 "XEP-0329_compGetFilesFromNode_build_directory",
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
366 self._addDirectoryMetadataElts)
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
367 self.host.trigger.add(
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
368 "XEP-0329_parseResult_directory",
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
369 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
370 self.files_path = self.host.getLocalPath(None, C.FILES_DIR, profile=False)
3507
375449da79f6 comp file sharing: fix port type:
Goffi <goffi@goffi.org>
parents: 3479
diff changeset
371 self.http_port = int(self.host.memory.getConfig(
3677
02e5e2385a30 component (file-sharing): use `file-sharing` instead of `file_sharing`:
Goffi <goffi@goffi.org>
parents: 3532
diff changeset
372 '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
373 connection_type = self.host.memory.getConfig(
3677
02e5e2385a30 component (file-sharing): use `file-sharing` instead of `file_sharing`:
Goffi <goffi@goffi.org>
parents: 3532
diff changeset
374 'component file-sharing', 'http_upload_connection_type', 'https')
3289
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 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
376 raise exceptions.ConfigError(
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
377 '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
378 )
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
379 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
380 self.expected_uploads = {}
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
381 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
382 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
383 else:
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
384 options = tls.getOptionsFromConfig(
3677
02e5e2385a30 component (file-sharing): use `file-sharing` instead of `file_sharing`:
Goffi <goffi@goffi.org>
parents: 3532
diff changeset
385 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
386 tls.TLSOptionsCheck(options)
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
387 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
388 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
389
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
390 def getHandler(self, client):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
391 return Comments_handler(self)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
392
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
393 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
394 self.init()
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
395 public_base_url = self.host.memory.getConfig(
3677
02e5e2385a30 component (file-sharing): use `file-sharing` instead of `file_sharing`:
Goffi <goffi@goffi.org>
parents: 3532
diff changeset
396 'component file-sharing', 'http_upload_public_facing_url')
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
397 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
398 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
399 else:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
400 client._file_sharing_base_url = public_base_url
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
401 path = client.file_tmp_dir = os.path.join(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
402 self.host.memory.getConfig("", "local_dir"),
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
403 C.FILES_TMP_DIR,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
404 regex.pathEscape(client.profile),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
405 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
406 if not os.path.exists(path):
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
407 os.makedirs(path)
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
408
3528
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
409 def getQuota(self, client, entity):
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
410 """Return maximum size allowed for all files for entity"""
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
411 # TODO: handle special entities like admins
3677
02e5e2385a30 component (file-sharing): use `file-sharing` instead of `file_sharing`:
Goffi <goffi@goffi.org>
parents: 3532
diff changeset
412 quotas = self.host.memory.getConfig("component file-sharing", "quotas_json", {})
3528
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
413 entity_bare_s = entity.userhost()
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
414 try:
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
415 quota = quotas["jids"][entity_bare_s]
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
416 except KeyError:
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
417 quota = quotas.get("users")
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
418 return None if quota is None else utils.parseSize(quota)
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
419
3348
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
420 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
421 thumbnails = extra.setdefault(C.KEY_THUMBNAILS, [])
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
422 for max_thumb_size in self._t.SIZES:
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
423 try:
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
424 thumb_size, thumb_id = await self._t.generateThumbnail(
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
425 image_path,
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
426 max_thumb_size,
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
427 #  we keep thumbnails for 6 months
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
428 60 * 60 * 24 * 31 * 6,
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
429 )
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
430 except Exception as e:
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
431 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
432 break
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
433 thumbnails.append({"id": thumb_id, "size": thumb_size})
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
434
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
435 async def registerReceivedFile(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
436 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
437 """Post file reception tasks
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
438
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
439 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
440 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
441 """
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
442 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
443 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
444 extra = {}
2514
4440ea7047bd file sharing component: thumbnails integration first draft:
Goffi <goffi@goffi.org>
parents: 2504
diff changeset
445
3331
b1e9f17fbb5a comp file sharing: minor core re-organisation
Goffi <goffi@goffi.org>
parents: 3329
diff changeset
446 mime_type = file_data.get("mime_type")
b1e9f17fbb5a comp file sharing: minor core re-organisation
Goffi <goffi@goffi.org>
parents: 3329
diff changeset
447 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
448 mime_type = mimetypes.guess_type(name)[0]
b1e9f17fbb5a comp file sharing: minor core re-organisation
Goffi <goffi@goffi.org>
parents: 3329
diff changeset
449
b1e9f17fbb5a comp file sharing: minor core re-organisation
Goffi <goffi@goffi.org>
parents: 3329
diff changeset
450 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
451 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
452
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
453 if file_data.get("hash_algo") == HASH_ALGO:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
454 log.debug(_("Reusing already generated hash"))
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
455 file_hash = file_data["hash_hasher"].hexdigest()
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
456 else:
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
457 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
458 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
459 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
460 final_path = self.files_path/file_hash
2514
4440ea7047bd file sharing component: thumbnails integration first draft:
Goffi <goffi@goffi.org>
parents: 2504
diff changeset
461
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
462 if final_path.is_file():
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
463 log.debug(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
464 "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
465 file_hash=file_hash
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
466 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
467 )
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
468 file_path.unlink()
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
469 else:
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
470 file_path.rename(final_path)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
471 log.debug(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
472 "file [{file_hash}] moved to {files_path}".format(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
473 file_hash=file_hash, files_path=self.files_path
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
474 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
475 )
2514
4440ea7047bd file sharing component: thumbnails integration first draft:
Goffi <goffi@goffi.org>
parents: 2504
diff changeset
476
3331
b1e9f17fbb5a comp file sharing: minor core re-organisation
Goffi <goffi@goffi.org>
parents: 3329
diff changeset
477 if is_image:
3348
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
478 await self.generate_thumbnails(extra, final_path)
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
479 elif is_video:
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
480 with tempfile.TemporaryDirectory() as tmp_dir:
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
481 thumb_path = Path(tmp_dir) / "thumbnail.jpg"
2514
4440ea7047bd file sharing component: thumbnails integration first draft:
Goffi <goffi@goffi.org>
parents: 2504
diff changeset
482 try:
3348
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
483 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
484 except Exception as e:
3348
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
485 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
486 final_path=final_path, e=e))
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
487 else:
12c427156cac component file sharing: generate thumbnails for videos
Goffi <goffi@goffi.org>
parents: 3340
diff changeset
488 await self.generate_thumbnails(extra, thumb_path)
2514
4440ea7047bd file sharing component: thumbnails integration first draft:
Goffi <goffi@goffi.org>
parents: 2504
diff changeset
489
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
490 self.host.memory.setFile(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
491 client,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
492 name=name,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
493 version="",
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
494 file_hash=file_hash,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
495 hash_algo=HASH_ALGO,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
496 size=file_data["size"],
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
497 path=file_data.get("path"),
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
498 namespace=file_data.get("namespace"),
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
499 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
500 public_id=public_id,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
501 owner=peer_jid,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
502 extra=extra,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
503 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
504
3528
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
505 async def _getDestDirTrigger(
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
506 self, client, peer_jid, transfer_data, file_data, stream_object
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
507 ):
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
508 """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
509 if not client.is_component:
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
510 return True, None
3532
ab72b8ac3bd2 component file sharing: forbid jingle upload by entities which are not in allowed hosts
Goffi <goffi@goffi.org>
parents: 3528
diff changeset
511 # client._file_sharing_allowed_hosts is set in plugin XEP-0329
ab72b8ac3bd2 component file sharing: forbid jingle upload by entities which are not in allowed hosts
Goffi <goffi@goffi.org>
parents: 3528
diff changeset
512 if peer_jid.host not in client._file_sharing_allowed_hosts:
ab72b8ac3bd2 component file sharing: forbid jingle upload by entities which are not in allowed hosts
Goffi <goffi@goffi.org>
parents: 3528
diff changeset
513 raise error.StanzaError("forbidden")
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
514 assert stream_object
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
515 assert "stream_object" not in transfer_data
2514
4440ea7047bd file sharing component: thumbnails integration first draft:
Goffi <goffi@goffi.org>
parents: 2504
diff changeset
516 assert C.KEY_PROGRESS_ID in file_data
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
517 filename = file_data["name"]
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
518 assert filename and not "/" in filename
3528
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
519 quota = self.getQuota(client, peer_jid)
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
520 if quota is not None:
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
521 used_space = await self.host.memory.fileGetUsedSpace(client, peer_jid)
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
522
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
523 if (used_space + file_data["size"]) > quota:
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
524 raise error.StanzaError(
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
525 "not-acceptable",
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
526 text=OVER_QUOTA_TXT.format(
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
527 quota=utils.getHumanSize(quota),
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
528 used_space=utils.getHumanSize(used_space),
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
529 file_size=utils.getHumanSize(file_data['size'])
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
530 )
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
531 )
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
532 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
533 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
534 )
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
535 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
536 file_tmp_dir/filename)
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
537
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
538 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
539 lambda __: defer.ensureDeferred(
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
540 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
541 )
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
542 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
543
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
544 self._f.openFileWrite(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
545 client, file_tmp_path, transfer_data, file_data, stream_object
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
546 )
3701
6d298323eed2 plugin comp file sharing: don't use Deferred in return value
Goffi <goffi@goffi.org>
parents: 3677
diff changeset
547 return False, True
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
548
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
549 @defer.inlineCallbacks
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
550 def _retrieveFiles(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
551 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
552 ):
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
553 """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
554 peer_jid = session["peer_jid"]
3514
6d9c9e2dca0a component (file sharing): fix retrieving owner from jid when user part is not specified
Goffi <goffi@goffi.org>
parents: 3507
diff changeset
555 if session['local_jid'].user:
6d9c9e2dca0a component (file sharing): fix retrieving owner from jid when user part is not specified
Goffi <goffi@goffi.org>
parents: 3507
diff changeset
556 owner = client.getOwnerFromJid(session['local_jid'])
6d9c9e2dca0a component (file sharing): fix retrieving owner from jid when user part is not specified
Goffi <goffi@goffi.org>
parents: 3507
diff changeset
557 else:
6d9c9e2dca0a component (file sharing): fix retrieving owner from jid when user part is not specified
Goffi <goffi@goffi.org>
parents: 3507
diff changeset
558 owner = peer_jid
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
559 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
560 found_files = yield self.host.memory.getFiles(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
561 client,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
562 peer_jid=peer_jid,
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
563 name=file_data.get("name"),
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
564 file_hash=file_data.get("file_hash"),
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
565 hash_algo=file_data.get("hash_algo"),
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
566 path=file_data.get("path"),
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
567 namespace=file_data.get("namespace"),
3367
90aee1f2d07c component file sharing: added missing `owner` filtering in `_retrieveFiles`
Goffi <goffi@goffi.org>
parents: 3363
diff changeset
568 owner=owner,
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
569 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
570 except exceptions.NotFound:
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
571 found_files = None
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
572 except exceptions.PermissionError:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
573 log.warning(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
574 _("{peer_jid} is trying to access an unauthorized file: {name}").format(
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
575 peer_jid=peer_jid, name=file_data.get("name")
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
576 )
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
577 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
578 defer.returnValue(False)
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
579
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
580 if not found_files:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
581 log.warning(
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
582 _("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
583 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
584 defer.returnValue(False)
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
585
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
586 # we only use the first found file
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
587 found_file = found_files[0]
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
588 if found_file['type'] != C.FILE_TYPE_FILE:
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
589 raise TypeError("a file was expected, type is {type_}".format(
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
590 type_=found_file['type']))
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
591 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
592 file_path = self.files_path / file_hash
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
593 file_data["hash_hasher"] = hasher = self._h.getHasher(found_file["hash_algo"])
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
594 size = file_data["size"] = found_file["size"]
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
595 file_data["file_hash"] = file_hash
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
596 file_data["hash_algo"] = found_file["hash_algo"]
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
597
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
598 # 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
599 if "name" not in file_data:
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
600 file_elt.addElement("name", content=found_file["name"])
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
601 file_elt.addElement("size", content=str(size))
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
602 content_data["stream_object"] = stream.FileStreamObject(
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
603 self.host,
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
604 client,
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
605 file_path,
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
606 uid=self._jf.getProgressId(session, content_name),
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
607 size=size,
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
608 data_cb=lambda data: hasher.update(data),
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
609 )
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
610 defer.returnValue(True)
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
611
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
612 def _fileSendingRequestTrigger(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
613 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
614 ):
2504
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
615 if not client.is_component:
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
616 return True, None
67cc54b01a12 plugin file sharing component: first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
617 else:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
618 return (
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
619 False,
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
620 self._retrieveFiles(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
621 client, session, content_data, content_name, file_data, file_elt
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
622 ),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
623 )
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
624
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
625 ## HTTP Upload ##
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
626
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
627 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
628 try:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
629 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
630 except KeyError:
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
631 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
632
3528
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
633 async def _onHTTPUpload(self, client, request):
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
634 # 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
635 assert '/' not in request.filename
3359
000b6722bd35 plugin XEP-0329: added `FISCreateDir` method:
Goffi <goffi@goffi.org>
parents: 3348
diff changeset
636 # 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
637 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
638 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
639
3528
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
640 quota = self.getQuota(client, request.from_)
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
641 if quota is not None:
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
642 used_space = await self.host.memory.fileGetUsedSpace(client, request.from_)
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
643
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
644 if (used_space + request.size) > quota:
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
645 raise error.StanzaError(
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
646 "not-acceptable",
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
647 text=OVER_QUOTA_TXT.format(
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
648 quota=utils.getHumanSize(quota),
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
649 used_space=utils.getHumanSize(used_space),
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
650 file_size=utils.getHumanSize(request.size)
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
651 ),
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
652 appCondition = self._hu.getFileTooLargeElt(max(quota - used_space, 0))
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
653 )
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
654
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
655 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
656 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
657 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
658 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
659 url = urljoin(client._file_sharing_base_url, f"{upload_id}/{request.filename}")
3528
849374e59178 component file sharing: quotas implementation:
Goffi <goffi@goffi.org>
parents: 3514
diff changeset
660 slot = self._hu.Slot(
3289
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
661 put=url,
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
662 get=url,
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
663 headers=[],
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
664 )
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
665 return slot
9057713ab124 plugin comp file sharing: files can now be uploaded/downloaded via HTTP:
Goffi <goffi@goffi.org>
parents: 3136
diff changeset
666
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
667 ## metadata triggers ##
2528
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 _addFileMetadataElts(self, client, file_elt, extra_args):
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
670 # affiliation
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
671 affiliation = extra_args.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 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
674
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
675 # comments
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
676 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
677 comments_url = extra_args.pop("comments_url")
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
678 except KeyError:
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
679 return
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
680
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
681 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
682
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
683 try:
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
684 count = len(extra_args["extra"]["comments"])
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
685 except KeyError:
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
686 count = 0
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
687
3028
ab2696e34d29 Python 3 port:
Goffi <goffi@goffi.org>
parents: 2929
diff changeset
688 comment_elt["count"] = str(count)
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
689 return True
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
690
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
691 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
692 # affiliation
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
693 try:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
694 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
695 except StopIteration:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
696 pass
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
697 else:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
698 file_data["affiliation"] = str(affiliation_elt)
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
699
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
700 # comments
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
701 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
702 comments_elt = next(file_elt.elements(NS_COMMENTS, "comments"))
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
703 except StopIteration:
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
704 pass
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
705 else:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
706 file_data["comments_url"] = str(comments_elt)
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
707 file_data["comments_count"] = comments_elt["count"]
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
708 return True
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
709
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
710 def _addFileMetadata(
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
711 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
712 for file_data in files_data:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
713 file_data["comments_url"] = uri.buildXMPPUri(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
714 "pubsub",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
715 path=client.jid.full(),
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
716 node=COMMENT_NODE_PREFIX + file_data["id"],
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
717 )
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
718 return True
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
719
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
720 def _addDirectoryMetadataElts(
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
721 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
722 affiliation = file_data.get('affiliation')
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
723 if affiliation is not None:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
724 directory_elt.addElement(
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
725 (NS_FS_AFFILIATION, "affiliation"),
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
726 content=affiliation
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
727 )
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
728
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
729 def _getDirectoryMetadataElts(
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
730 self, client, elt, file_data):
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
731 try:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
732 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
733 except StopIteration:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
734 pass
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
735 else:
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
736 file_data['affiliation'] = str(affiliation_elt)
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
737
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
738
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
739 class Comments_handler(pubsub.PubSubService):
2528
65e278997715 component file sharing: comments metadata:
Goffi <goffi@goffi.org>
parents: 2527
diff changeset
740 """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
741
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
742 def __init__(self, plugin_parent):
3314
5887fb414758 component file sharing: add/parse affiliation when possible
Goffi <goffi@goffi.org>
parents: 3301
diff changeset
743 super(Comments_handler, self).__init__()
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
744 self.host = plugin_parent.host
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
745 self.plugin_parent = plugin_parent
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
746 self.discoIdentity = {
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
747 "category": "pubsub",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
748 "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
749 "name": "files commenting service",
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
750 }
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
751
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
752 def _getFileId(self, nodeIdentifier):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
753 if not nodeIdentifier.startswith(COMMENT_NODE_PREFIX):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
754 raise error.StanzaError("item-not-found")
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
755 file_id = nodeIdentifier[len(COMMENT_NODE_PREFIX) :]
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
756 if not file_id:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
757 raise error.StanzaError("item-not-found")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
758 return file_id
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
759
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
760 @defer.inlineCallbacks
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
761 def getFileData(self, requestor, nodeIdentifier):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
762 file_id = self._getFileId(nodeIdentifier)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
763 try:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
764 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
765 except (exceptions.NotFound, exceptions.PermissionError):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
766 # we don't differenciate between NotFound and PermissionError
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
767 # to avoid leaking information on existing files
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
768 raise error.StanzaError("item-not-found")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
769 if not files:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
770 raise error.StanzaError("item-not-found")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
771 if len(files) > 1:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
772 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
773 defer.returnValue(files[0])
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
774
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
775 def commentsUpdate(self, extra, new_comments, peer_jid):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
776 """update comments (replace or insert new_comments)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
777
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
778 @param extra(dict): extra data to update
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
779 @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
780 @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
781 """
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
782 current_comments = extra.setdefault("comments", [])
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
783 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
784 updated = []
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
785 # 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
786 # exist, in which case we must update
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
787 for idx, comment in enumerate(current_comments):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
788 comment_id = comment[0]
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
789 if comment_id in new_comments_by_id:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
790 # 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
791 if peer_jid and comment[1] != peer_jid:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
792 # 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
793 raise exceptions.PermissionError
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
794 # we replace old_comment with updated one
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
795 new_comment = new_comments_by_id[comment_id]
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
796 current_comments[idx] = new_comment
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
797 updated.append(new_comment)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
798
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
799 # 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
800 # the ones to insert
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
801 for comment in updated:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
802 new_comments.remove(comment)
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 current_comments.extend(new_comments)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
805
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
806 def commentsDelete(self, extra, comments):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
807 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
808 comments_dict = extra["comments"]
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
809 except KeyError:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
810 return
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
811 for comment in comments:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
812 try:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
813 comments_dict.remove(comment)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
814 except ValueError:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
815 continue
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
816
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
817 def _getFrom(self, item_elt):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
818 """retrieve published of an item
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
819
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
820 @param item_elt(domish.element): <item> element
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
821 @return (unicode): full jid as string
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
822 """
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
823 iq_elt = item_elt
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
824 while iq_elt.parent != None:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
825 iq_elt = iq_elt.parent
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
826 return iq_elt["from"]
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
827
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
828 @defer.inlineCallbacks
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
829 def publish(self, requestor, service, nodeIdentifier, items):
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
830 #  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
831 file_data = yield self.getFileData(requestor, nodeIdentifier)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
832 file_id = file_data["id"]
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
833 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
834 if requestor.userhostJID() == file_data["owner"]:
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
835 peer_jid = None
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
836 else:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
837 peer_jid = requestor.userhost()
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
838 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
839 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
840 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
841 except exceptions.PermissionError:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
842 raise error.StanzaError("not-authorized")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
843
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
844 @defer.inlineCallbacks
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
845 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
846 file_data = yield self.getFileData(requestor, nodeIdentifier)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
847 comments = file_data["extra"].get("comments", [])
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
848 if itemIdentifiers:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
849 defer.returnValue(
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
850 [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
851 )
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
852 else:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
853 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
854
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
855 @defer.inlineCallbacks
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
856 def retract(self, requestor, service, nodeIdentifier, itemIdentifiers):
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
857 file_data = yield self.getFileData(requestor, nodeIdentifier)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
858 file_id = file_data["id"]
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
859 try:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
860 comments = file_data["extra"]["comments"]
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
861 except KeyError:
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
862 raise error.StanzaError("item-not-found")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
863
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
864 to_remove = []
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
865 for comment in comments:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
866 comment_id = comment[0]
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
867 if comment_id in itemIdentifiers:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
868 to_remove.append(comment)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
869 itemIdentifiers.remove(comment_id)
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
870 if not itemIdentifiers:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
871 break
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
872
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
873 if itemIdentifiers:
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
874 # 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
875 raise error.StanzaError("item-not-found")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
876
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
877 if requestor.userhostJID() != file_data["owner"]:
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
878 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
879 raise error.StanzaError("not-authorized")
2527
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
880
a201194fc461 component file sharing: comments handling first draft:
Goffi <goffi@goffi.org>
parents: 2522
diff changeset
881 remove_cb = partial(self.commentsDelete, comments=to_remove)
2624
56f94936df1e code style reformatting using black
Goffi <goffi@goffi.org>
parents: 2562
diff changeset
882 yield self.host.memory.fileUpdate(file_id, "extra", remove_cb)