annotate src/cagou/plugins/plugin_transfer_android_gallery.py @ 97:5d2289127bb7

menu (upload): better menu using dedicated widget: upload menu now use a decicated widget instead of context menu. The menu take half the size of the main window, and show each upload option as an icon. Use can select upload or P2P sending, and a short text message explains how the file will be transmitted.
author Goffi <goffi@goffi.org>
date Thu, 29 Dec 2016 23:47:07 +0100
parents src/cagou/plugins/plugin_upload_android_gallery.py@3dc526bb4a5a
children e89350dd3eca
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
88
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/python
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
2 # -*- coding: utf-8 -*-
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
3
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Cagou: desktop/mobile frontend for Salut à Toi XMPP client
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
5 # Copyright (C) 2016 Jérôme Poisson (goffi@goffi.org)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
6
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # This program is free software: you can redistribute it and/or modify
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
10 # (at your option) any later version.
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
11
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # This program is distributed in the hope that it will be useful,
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
15 # GNU Affero General Public License for more details.
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
16
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
19
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
20
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
21 from sat.core import log as logging
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 log = logging.getLogger(__name__)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
23 from sat.core.i18n import _
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 import sys
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 import tempfile
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
26 import os
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
27 import os.path
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 if sys.platform=="android":
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 from jnius import autoclass
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
30 from android import activity, mActivity
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
31
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 Intent = autoclass('android.content.Intent')
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 OpenableColumns = autoclass('android.provider.OpenableColumns')
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 PHOTO_GALLERY = 1
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 RESULT_OK = -1
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
36
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
37
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
38
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 PLUGIN_INFO = {
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
40 "name": _(u"photo"),
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
41 "main": "AndroidGallery",
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 "platforms": ('android',),
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 "external": True,
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
44 "description": _(u"upload a photo from photo gallery"),
97
5d2289127bb7 menu (upload): better menu using dedicated widget:
Goffi <goffi@goffi.org>
parents: 88
diff changeset
45 "icon_medium": u"{media}/icons/muchoslava/png/gallery_50.png",
88
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 }
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
47
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
48
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 class AndroidGallery(object):
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
50
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 def __init__(self, callback, cancel_cb):
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 self.callback = callback
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 self.cancel_cb = cancel_cb
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
54 activity.bind(on_activity_result=self.on_activity_result)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 intent = Intent()
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 intent.setType('image/*')
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
57 intent.setAction(Intent.ACTION_GET_CONTENT)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
58 mActivity.startActivityForResult(intent, PHOTO_GALLERY);
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
59
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
60 def on_activity_result(self, requestCode, resultCode, data):
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
61 # TODO: move file dump to a thread or use async callbacks during file writting
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
62 if requestCode == PHOTO_GALLERY and resultCode == RESULT_OK:
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
63 if data is None:
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
64 log.warning(u"No data found in activity result")
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
65 self.cancel_cb(self, None)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
66 return
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
67 uri = data.getData()
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
68
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
69 # we get filename in the way explained at https://developer.android.com/training/secure-file-sharing/retrieve-info.html
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
70 cursor = mActivity.getContentResolver().query(uri, None, None, None, None )
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
71 name_idx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
72 cursor.moveToFirst()
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
73 filename = cursor.getString(name_idx)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
74
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
75 # we save data in a temporary file that we send to callback
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
76 # the file will be removed once upload is done (or if an error happens)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
77 input_stream = mActivity.getContentResolver().openInputStream(uri)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
78 tmp_dir = tempfile.mkdtemp()
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
79 tmp_file = os.path.join(tmp_dir, filename)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
80 def cleaning():
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
81 os.unlink(tmp_file)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
82 os.rmdir(tmp_dir)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
83 log.debug(u'temporary file cleaned')
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
84 buff = bytearray(4096)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
85 with open(tmp_file, 'wb') as f:
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
86 while True:
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
87 ret = input_stream.read(buff, 0, 4096)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
88 if ret != -1:
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
89 f.write(buff)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
90 else:
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
91 break
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
92 input_stream.close()
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
93 self.callback(tmp_file, cleaning)
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
94 else:
3dc526bb4a5a upload: plugin android gallery, first draft:
Goffi <goffi@goffi.org>
parents:
diff changeset
95 self.cancel_cb(self, None)