Mercurial > libervia-desktop-kivy
comparison cagou/plugins/plugin_wid_remote.py @ 312:772c170b47a9
Python3 port:
/!\ Cagou now runs with Python 3.6+
Port has been done in the same way as for backend (check backend commit b2d067339de3
message for details).
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 13 Aug 2019 19:14:22 +0200 |
parents | e2afbec1d178 |
children | e2b51663d8b8 |
comparison
equal
deleted
inserted
replaced
311:a0d978d3ce84 | 312:772c170b47a9 |
---|---|
39 from cagou import G | 39 from cagou import G |
40 from functools import partial | 40 from functools import partial |
41 | 41 |
42 | 42 |
43 PLUGIN_INFO = { | 43 PLUGIN_INFO = { |
44 "name": _(u"remote control"), | 44 "name": _("remote control"), |
45 "main": "RemoteControl", | 45 "main": "RemoteControl", |
46 "description": _(u"universal remote control"), | 46 "description": _("universal remote control"), |
47 "icon_symbol": u"signal", | 47 "icon_symbol": "signal", |
48 } | 48 } |
49 | 49 |
50 NOTE_TITLE = _(u"Media Player Remote Control") | 50 NOTE_TITLE = _("Media Player Remote Control") |
51 | 51 |
52 | 52 |
53 class RemoteItemWidget(ItemWidget): | 53 class RemoteItemWidget(ItemWidget): |
54 | 54 |
55 def __init__(self, device_jid, node, name, main_wid, **kw): | 55 def __init__(self, device_jid, node, name, main_wid, **kw): |
64 | 64 |
65 | 65 |
66 class MediaPlayerControlWidget(BoxLayout): | 66 class MediaPlayerControlWidget(BoxLayout): |
67 main_wid = properties.ObjectProperty() | 67 main_wid = properties.ObjectProperty() |
68 remote_item = properties.ObjectProperty() | 68 remote_item = properties.ObjectProperty() |
69 status = properties.OptionProperty(u"play", options=(u"play", u"pause", u"stop")) | 69 status = properties.OptionProperty("play", options=("play", "pause", "stop")) |
70 title = properties.StringProperty() | 70 title = properties.StringProperty() |
71 identity = properties.StringProperty() | 71 identity = properties.StringProperty() |
72 command = properties.DictProperty() | 72 command = properties.DictProperty() |
73 ui_tpl = properties.ObjectProperty() | 73 ui_tpl = properties.ObjectProperty() |
74 | 74 |
82 self.ui_tpl = ui_tpl | 82 self.ui_tpl = ui_tpl |
83 for prop in ('Title', 'Identity'): | 83 for prop in ('Title', 'Identity'): |
84 try: | 84 try: |
85 setattr(self, prop.lower(), ui_tpl.widgets[prop].value) | 85 setattr(self, prop.lower(), ui_tpl.widgets[prop].value) |
86 except KeyError: | 86 except KeyError: |
87 log.warning(_(u"Missing field: {name}").format(name=prop)) | 87 log.warning(_("Missing field: {name}").format(name=prop)) |
88 playback_status = self.ui_tpl.widgets['PlaybackStatus'].value | 88 playback_status = self.ui_tpl.widgets['PlaybackStatus'].value |
89 if playback_status == u"Playing": | 89 if playback_status == "Playing": |
90 self.status = u"pause" | 90 self.status = "pause" |
91 elif playback_status == u"Paused": | 91 elif playback_status == "Paused": |
92 self.status = u"play" | 92 self.status = "play" |
93 elif playback_status == u"Stopped": | 93 elif playback_status == "Stopped": |
94 self.status = u"play" | 94 self.status = "play" |
95 else: | 95 else: |
96 G.host.addNote( | 96 G.host.addNote( |
97 title=NOTE_TITLE, | 97 title=NOTE_TITLE, |
98 message=_(u"Unknown playback status: playback_status") | 98 message=_("Unknown playback status: playback_status") |
99 .format(playback_status=playback_status), | 99 .format(playback_status=playback_status), |
100 level=C.XMLUI_DATA_LVL_WARNING) | 100 level=C.XMLUI_DATA_LVL_WARNING) |
101 self.commands = {v:k for k,v in ui_tpl.widgets['command'].options} | 101 self.commands = {v:k for k,v in ui_tpl.widgets['command'].options} |
102 | 102 |
103 def adHocRunCb(self, xmlui_raw): | 103 def adHocRunCb(self, xmlui_raw): |
104 ui_tpl = template_xmlui.create(G.host, xmlui_raw) | 104 ui_tpl = template_xmlui.create(G.host, xmlui_raw) |
105 data = {xmlui.XMLUIPanel.escape(u"media_player"): self.remote_item.node, | 105 data = {xmlui.XMLUIPanel.escape("media_player"): self.remote_item.node, |
106 u"session_id": ui_tpl.session_id} | 106 "session_id": ui_tpl.session_id} |
107 G.host.bridge.launchAction( | 107 G.host.bridge.launchAction( |
108 ui_tpl.submit_id, data, self.profile, | 108 ui_tpl.submit_id, data, self.profile, |
109 callback=self.updateUI, | 109 callback=self.updateUI, |
110 errback=self.main_wid.errback) | 110 errback=self.main_wid.errback) |
111 | 111 |
112 def on_remote_item(self, __, remote): | 112 def on_remote_item(self, __, remote): |
113 NS_MEDIA_PLAYER = G.host.ns_map[u"mediaplayer"] | 113 NS_MEDIA_PLAYER = G.host.ns_map["mediaplayer"] |
114 G.host.bridge.adHocRun(unicode(remote.device_jid), NS_MEDIA_PLAYER, self.profile, | 114 G.host.bridge.adHocRun(str(remote.device_jid), NS_MEDIA_PLAYER, self.profile, |
115 callback=self.adHocRunCb, | 115 callback=self.adHocRunCb, |
116 errback=self.main_wid.errback) | 116 errback=self.main_wid.errback) |
117 | 117 |
118 def do_cmd(self, command): | 118 def do_cmd(self, command): |
119 try: | 119 try: |
120 cmd_value = self.commands[command] | 120 cmd_value = self.commands[command] |
121 except KeyError: | 121 except KeyError: |
122 G.host.addNote( | 122 G.host.addNote( |
123 title=NOTE_TITLE, | 123 title=NOTE_TITLE, |
124 message=_(u"{command} command is not managed").format(command=command), | 124 message=_("{command} command is not managed").format(command=command), |
125 level=C.XMLUI_DATA_LVL_WARNING) | 125 level=C.XMLUI_DATA_LVL_WARNING) |
126 else: | 126 else: |
127 data = {xmlui.XMLUIPanel.escape(u"command"): cmd_value, | 127 data = {xmlui.XMLUIPanel.escape("command"): cmd_value, |
128 u"session_id": self.ui_tpl.session_id} | 128 "session_id": self.ui_tpl.session_id} |
129 # hidden values are normally transparently managed by XMLUIPanel | 129 # hidden values are normally transparently managed by XMLUIPanel |
130 # but here we have to add them by hand | 130 # but here we have to add them by hand |
131 hidden = {xmlui.XMLUIPanel.escape(k):v | 131 hidden = {xmlui.XMLUIPanel.escape(k):v |
132 for k,v in self.ui_tpl.hidden.iteritems()} | 132 for k,v in self.ui_tpl.hidden.items()} |
133 data.update(hidden) | 133 data.update(hidden) |
134 G.host.bridge.launchAction( | 134 G.host.bridge.launchAction( |
135 self.ui_tpl.submit_id, data, self.profile, | 135 self.ui_tpl.submit_id, data, self.profile, |
136 callback=self.updateUI, | 136 callback=self.updateUI, |
137 errback=self.main_wid.errback) | 137 errback=self.main_wid.errback) |
138 | 138 |
139 | 139 |
140 class RemoteDeviceWidget(DeviceWidget): | 140 class RemoteDeviceWidget(DeviceWidget): |
141 | 141 |
142 def xmluiCb(self, data, cb_id, profile): | 142 def xmluiCb(self, data, cb_id, profile): |
143 if u'xmlui' in data: | 143 if 'xmlui' in data: |
144 xml_ui = xmlui.create( | 144 xml_ui = xmlui.create( |
145 G.host, data[u'xmlui'], callback=self.xmluiCb, profile=profile) | 145 G.host, data['xmlui'], callback=self.xmluiCb, profile=profile) |
146 if isinstance(xml_ui, xmlui.XMLUIDialog): | 146 if isinstance(xml_ui, xmlui.XMLUIDialog): |
147 self.main_wid.showRootWidget() | 147 self.main_wid.showRootWidget() |
148 xml_ui.show() | 148 xml_ui.show() |
149 else: | 149 else: |
150 xml_ui.setCloseCb(self.onClose) | 150 xml_ui.setCloseCb(self.onClose) |
151 self.main_wid.layout.add_widget(xml_ui) | 151 self.main_wid.layout.add_widget(xml_ui) |
152 else: | 152 else: |
153 if data: | 153 if data: |
154 log.warning(_(u"Unhandled data: {data}").format(data=data)) | 154 log.warning(_("Unhandled data: {data}").format(data=data)) |
155 self.main_wid.showRootWidget() | 155 self.main_wid.showRootWidget() |
156 | 156 |
157 def onClose(self, __, reason): | 157 def onClose(self, __, reason): |
158 if reason == C.XMLUI_DATA_CANCELLED: | 158 if reason == C.XMLUI_DATA_CANCELLED: |
159 self.main_wid.showRootWidget() | 159 self.main_wid.showRootWidget() |
165 xml_ui.setCloseCb(self.onClose) | 165 xml_ui.setCloseCb(self.onClose) |
166 self.main_wid.layout.add_widget(xml_ui) | 166 self.main_wid.layout.add_widget(xml_ui) |
167 | 167 |
168 def do_item_action(self, touch): | 168 def do_item_action(self, touch): |
169 self.main_wid.layout.clear_widgets() | 169 self.main_wid.layout.clear_widgets() |
170 G.host.bridge.adHocRun(unicode(self.entity_jid), u'', self.profile, | 170 G.host.bridge.adHocRun(str(self.entity_jid), '', self.profile, |
171 callback=self.adHocRunCb, errback=self.main_wid.errback) | 171 callback=self.adHocRunCb, errback=self.main_wid.errback) |
172 | 172 |
173 | 173 |
174 class DevicesLayout(FloatLayout): | 174 class DevicesLayout(FloatLayout): |
175 """Layout used to show devices""" | 175 """Layout used to show devices""" |
192 | 192 |
193 def errback(self, failure_): | 193 def errback(self, failure_): |
194 """Generic errback which add a warning note and go back to root widget""" | 194 """Generic errback which add a warning note and go back to root widget""" |
195 G.host.addNote( | 195 G.host.addNote( |
196 title=NOTE_TITLE, | 196 title=NOTE_TITLE, |
197 message=_(u"Can't use remote control: {reason}").format(reason=failure_), | 197 message=_("Can't use remote control: {reason}").format(reason=failure_), |
198 level=C.XMLUI_DATA_LVL_WARNING) | 198 level=C.XMLUI_DATA_LVL_WARNING) |
199 self.showRootWidget() | 199 self.showRootWidget() |
200 | 200 |
201 def key_input(self, window, key, scancode, codepoint, modifier): | 201 def key_input(self, window, key, scancode, codepoint, modifier): |
202 if key == 27: | 202 if key == 27: |
216 found.insert(0, remotes_data) | 216 found.insert(0, remotes_data) |
217 if len(found) == 2: | 217 if len(found) == 2: |
218 self.show_devices(found) | 218 self.show_devices(found) |
219 | 219 |
220 def adHocRemotesGetEb(self, failure_, found): | 220 def adHocRemotesGetEb(self, failure_, found): |
221 G.host.errback(failure_, title=_(u"discovery error"), | 221 G.host.errback(failure_, title=_("discovery error"), |
222 message=_(u"can't check remote controllers: {msg}")) | 222 message=_("can't check remote controllers: {msg}")) |
223 found.insert(0, []) | 223 found.insert(0, []) |
224 if len(found) == 2: | 224 if len(found) == 2: |
225 self.show_devices(found) | 225 self.show_devices(found) |
226 | 226 |
227 def get_remotes(self, found): | 227 def get_remotes(self, found): |
234 found.append(data) | 234 found.append(data) |
235 if len(found) == 2: | 235 if len(found) == 2: |
236 self.show_devices(found) | 236 self.show_devices(found) |
237 | 237 |
238 def _discoFindByFeaturesEb(self, failure_, found): | 238 def _discoFindByFeaturesEb(self, failure_, found): |
239 G.host.errback(failure_, title=_(u"discovery error"), | 239 G.host.errback(failure_, title=_("discovery error"), |
240 message=_(u"can't check devices: {msg}")) | 240 message=_("can't check devices: {msg}")) |
241 found.append(({}, {}, {})) | 241 found.append(({}, {}, {})) |
242 if len(found) == 2: | 242 if len(found) == 2: |
243 self.show_devices(found) | 243 self.show_devices(found) |
244 | 244 |
245 def discover_devices(self, found): | 245 def discover_devices(self, found): |
246 """Looks for devices handling file "File Information Sharing" and display them""" | 246 """Looks for devices handling file "File Information Sharing" and display them""" |
247 try: | 247 try: |
248 namespace = self.host.ns_map['commands'] | 248 namespace = self.host.ns_map['commands'] |
249 except KeyError: | 249 except KeyError: |
250 msg = _(u"can't find ad-hoc commands namespace, is the plugin running?") | 250 msg = _("can't find ad-hoc commands namespace, is the plugin running?") |
251 log.warning(msg) | 251 log.warning(msg) |
252 G.host.addNote(_(u"missing plugin"), msg, C.XMLUI_DATA_LVL_ERROR) | 252 G.host.addNote(_("missing plugin"), msg, C.XMLUI_DATA_LVL_ERROR) |
253 return | 253 return |
254 self.host.bridge.discoFindByFeatures( | 254 self.host.bridge.discoFindByFeatures( |
255 [namespace], [], False, True, True, True, False, self.profile, | 255 [namespace], [], False, True, True, True, False, self.profile, |
256 callback=partial(self._discoFindByFeaturesCb, found=found), | 256 callback=partial(self._discoFindByFeaturesCb, found=found), |
257 errback=partial(self._discoFindByFeaturesEb, found=found)) | 257 errback=partial(self._discoFindByFeaturesEb, found=found)) |
258 | 258 |
259 def show_devices(self, found): | 259 def show_devices(self, found): |
260 remotes_data, (entities_services, entities_own, entities_roster) = found | 260 remotes_data, (entities_services, entities_own, entities_roster) = found |
261 if remotes_data: | 261 if remotes_data: |
262 title = _(u"media players remote controls") | 262 title = _("media players remote controls") |
263 self.stack_layout.add_widget(CategorySeparator(text=title)) | 263 self.stack_layout.add_widget(CategorySeparator(text=title)) |
264 | 264 |
265 for remote_data in remotes_data: | 265 for remote_data in remotes_data: |
266 device_jid, node, name = remote_data | 266 device_jid, node, name = remote_data |
267 wid = RemoteItemWidget(device_jid, node, name, self) | 267 wid = RemoteItemWidget(device_jid, node, name, self) |
268 self.stack_layout.add_widget(wid) | 268 self.stack_layout.add_widget(wid) |
269 | 269 |
270 for entities_map, title in ((entities_services, | 270 for entities_map, title in ((entities_services, |
271 _(u'services')), | 271 _('services')), |
272 (entities_own, | 272 (entities_own, |
273 _(u'your devices')), | 273 _('your devices')), |
274 (entities_roster, | 274 (entities_roster, |
275 _(u'your contacts devices'))): | 275 _('your contacts devices'))): |
276 if entities_map: | 276 if entities_map: |
277 self.stack_layout.add_widget(CategorySeparator(text=title)) | 277 self.stack_layout.add_widget(CategorySeparator(text=title)) |
278 for entity_str, entity_ids in entities_map.iteritems(): | 278 for entity_str, entity_ids in entities_map.items(): |
279 entity_jid = jid.JID(entity_str) | 279 entity_jid = jid.JID(entity_str) |
280 item = RemoteDeviceWidget( | 280 item = RemoteDeviceWidget( |
281 self, entity_jid, Identities(entity_ids)) | 281 self, entity_jid, Identities(entity_ids)) |
282 self.stack_layout.add_widget(item) | 282 self.stack_layout.add_widget(item) |
283 if (not remotes_data and not entities_services and not entities_own | 283 if (not remotes_data and not entities_services and not entities_own |
284 and not entities_roster): | 284 and not entities_roster): |
285 self.stack_layout.add_widget(Label( | 285 self.stack_layout.add_widget(Label( |
286 size_hint=(1, 1), | 286 size_hint=(1, 1), |
287 halign='center', | 287 halign='center', |
288 text_size=self.size, | 288 text_size=self.size, |
289 text=_(u"No sharing device found"))) | 289 text=_("No sharing device found"))) |