Mercurial > libervia-backend
comparison src/plugins/plugin_comp_file_sharing.py @ 2514:4440ea7047bd
file sharing component: thumbnails integration first draft:
if an uploaded file is detected as an image, 2 thumbnails (small and medium size) are generated automatically.
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 02 Mar 2018 17:53:31 +0100 |
parents | 67cc54b01a12 |
children | 353880a5c363 |
comparison
equal
deleted
inserted
replaced
2513:2d3c9dcec384 | 2514:4440ea7047bd |
---|---|
25 from sat.tools.common import regex | 25 from sat.tools.common import regex |
26 from sat.tools import stream | 26 from sat.tools import stream |
27 from twisted.internet import defer | 27 from twisted.internet import defer |
28 import os | 28 import os |
29 import os.path | 29 import os.path |
30 import mimetypes | |
30 | 31 |
31 | 32 |
32 PLUGIN_INFO = { | 33 PLUGIN_INFO = { |
33 C.PI_NAME: "File sharing component", | 34 C.PI_NAME: "File sharing component", |
34 C.PI_IMPORT_NAME: "file_sharing", | 35 C.PI_IMPORT_NAME: "file_sharing", |
35 C.PI_MODES: [C.PLUG_MODE_COMPONENT], | 36 C.PI_MODES: [C.PLUG_MODE_COMPONENT], |
36 C.PI_TYPE: C.PLUG_TYPE_ENTRY_POINT, | 37 C.PI_TYPE: C.PLUG_TYPE_ENTRY_POINT, |
37 C.PI_PROTOCOLS: [], | 38 C.PI_PROTOCOLS: [], |
38 C.PI_DEPENDENCIES: ["FILE", "XEP-0234", "XEP-0260", "XEP-0261", "XEP-0329"], | 39 C.PI_DEPENDENCIES: ["FILE", "XEP-0234", "XEP-0260", "XEP-0261", "XEP-0264", "XEP-0329"], |
39 C.PI_RECOMMENDATIONS: [], | 40 C.PI_RECOMMENDATIONS: [], |
40 C.PI_MAIN: "FileSharing", | 41 C.PI_MAIN: "FileSharing", |
41 C.PI_HANDLER: "no", | 42 C.PI_HANDLER: "no", |
42 C.PI_DESCRIPTION: _(u"""Component hosting and sharing files""") | 43 C.PI_DESCRIPTION: _(u"""Component hosting and sharing files""") |
43 } | 44 } |
44 | 45 |
45 PROGRESS_ID_KEY = 'progress_id' | |
46 HASH_ALGO = u'sha-256' | 46 HASH_ALGO = u'sha-256' |
47 | 47 |
48 | 48 |
49 class FileSharing(object): | 49 class FileSharing(object): |
50 | 50 |
52 log.info(_(u"File Sharing initialization")) | 52 log.info(_(u"File Sharing initialization")) |
53 self.host = host | 53 self.host = host |
54 self._f = host.plugins['FILE'] | 54 self._f = host.plugins['FILE'] |
55 self._jf = host.plugins['XEP-0234'] | 55 self._jf = host.plugins['XEP-0234'] |
56 self._h = host.plugins['XEP-0300'] | 56 self._h = host.plugins['XEP-0300'] |
57 self._t = host.plugins['XEP-0264'] | |
57 host.trigger.add("FILE_getDestDir", self._getDestDirTrigger) | 58 host.trigger.add("FILE_getDestDir", self._getDestDirTrigger) |
58 host.trigger.add("XEP-0234_fileSendingRequest", self._fileSendingRequestTrigger, priority=1000) | 59 host.trigger.add("XEP-0234_fileSendingRequest", self._fileSendingRequestTrigger, priority=1000) |
59 self.files_path = host.getLocalPath(None, C.FILES_DIR, profile=False) | 60 self.files_path = host.getLocalPath(None, C.FILES_DIR, profile=False) |
60 | 61 |
61 def profileConnected(self, client): | 62 def profileConnected(self, client): |
66 if not os.path.exists(path): | 67 if not os.path.exists(path): |
67 os.makedirs(path) | 68 os.makedirs(path) |
68 | 69 |
69 @defer.inlineCallbacks | 70 @defer.inlineCallbacks |
70 def _fileTransferedCb(self, dummy, client, peer_jid, file_data, file_path): | 71 def _fileTransferedCb(self, dummy, client, peer_jid, file_data, file_path): |
72 name = file_data[u'name'] | |
73 extra = {} | |
74 | |
71 if file_data[u'hash_algo'] == HASH_ALGO: | 75 if file_data[u'hash_algo'] == HASH_ALGO: |
72 log.debug(_(u"Reusing already generated hash")) | 76 log.debug(_(u"Reusing already generated hash")) |
73 file_hash = file_data[u'hash_hasher'].hexdigest() | 77 file_hash = file_data[u'hash_hasher'].hexdigest() |
74 else: | 78 else: |
75 hasher = self._h.getHasher(HASH_ALGO) | 79 hasher = self._h.getHasher(HASH_ALGO) |
76 with open('file_path') as f: | 80 with open('file_path') as f: |
77 file_hash = yield self._h.calculateHash(f, hasher) | 81 file_hash = yield self._h.calculateHash(f, hasher) |
78 final_path = os.path.join(self.files_path, file_hash) | 82 final_path = os.path.join(self.files_path, file_hash) |
83 | |
79 if os.path.isfile(final_path): | 84 if os.path.isfile(final_path): |
80 log.debug(u"file [{file_hash}] already exists, we can remove temporary one".format(file_hash = file_hash)) | 85 log.debug(u"file [{file_hash}] already exists, we can remove temporary one".format(file_hash = file_hash)) |
81 os.unlink(file_path) | 86 os.unlink(file_path) |
82 else: | 87 else: |
83 os.rename(file_path, final_path) | 88 os.rename(file_path, final_path) |
84 log.debug(u"file [{file_hash}] moved to {files_path}".format(file_hash=file_hash, files_path=self.files_path)) | 89 log.debug(u"file [{file_hash}] moved to {files_path}".format(file_hash=file_hash, files_path=self.files_path)) |
90 | |
91 mime_type = file_data.get(u'mime_type') | |
92 if not mime_type or mime_type == u'application/octet-stream': | |
93 mime_type = mimetypes.guess_type(name)[0] | |
94 | |
95 if mime_type is not None and mime_type.startswith(u'image'): | |
96 thumbnails = extra.setdefault(C.KEY_THUMBNAILS, []) | |
97 for max_thumb_size in (self._t.SIZE_SMALL, self._t.SIZE_MEDIUM): | |
98 try: | |
99 thumb_size, thumb_id = yield self._t.generateThumbnail(final_path, | |
100 max_thumb_size, | |
101 # we keep thumbnails for 6 months | |
102 60*60*24*31*6) | |
103 except Exception as e: | |
104 log.warning(_(u"Can't create thumbnail: {reason}").format(reason=e)) | |
105 break | |
106 thumbnails.append({u'id': thumb_id, u'size': thumb_size}) | |
107 | |
85 self.host.memory.setFile(client, | 108 self.host.memory.setFile(client, |
86 name=file_data[u'name'], | 109 name=name, |
87 version=u'', | 110 version=u'', |
88 file_hash=file_hash, | 111 file_hash=file_hash, |
89 hash_algo=HASH_ALGO, | 112 hash_algo=HASH_ALGO, |
90 size=file_data[u'size'], | 113 size=file_data[u'size'], |
91 path=file_data.get(u'path'), | 114 path=file_data.get(u'path'), |
92 namespace=file_data.get(u'namespace'), | 115 namespace=file_data.get(u'namespace'), |
93 owner=peer_jid) | 116 mime_type=mime_type, |
117 owner=peer_jid, | |
118 extra=extra) | |
94 | 119 |
95 def _getDestDirTrigger(self, client, peer_jid, transfer_data, file_data, stream_object): | 120 def _getDestDirTrigger(self, client, peer_jid, transfer_data, file_data, stream_object): |
96 if not client.is_component: | 121 if not client.is_component: |
97 return True, None | 122 return True, None |
98 assert stream_object | 123 assert stream_object |
99 assert 'stream_object' not in transfer_data | 124 assert 'stream_object' not in transfer_data |
100 assert PROGRESS_ID_KEY in file_data | 125 assert C.KEY_PROGRESS_ID in file_data |
101 filename = file_data['name'] | 126 filename = file_data['name'] |
102 assert filename and not '/' in filename | 127 assert filename and not '/' in filename |
103 file_tmp_dir = self.host.getLocalPath(client, C.FILES_TMP_DIR, peer_jid.userhost(), component=True, profile=False) | 128 file_tmp_dir = self.host.getLocalPath(client, C.FILES_TMP_DIR, peer_jid.userhost(), component=True, profile=False) |
104 file_tmp_path = file_data['file_path'] = os.path.join(file_tmp_dir, file_data['name']) | 129 file_tmp_path = file_data['file_path'] = os.path.join(file_tmp_dir, file_data['name']) |
105 | 130 |