Files
DemonEditor/app/ui/transmitter.py

175 lines
6.8 KiB
Python
Raw Normal View History

2020-02-15 12:51:16 +03:00
from pathlib import Path
2019-11-05 23:04:21 +03:00
from urllib.parse import urlparse
2020-01-28 15:08:57 +03:00
2020-02-15 12:51:16 +03:00
import gi
2019-11-24 21:58:32 +03:00
from gi.repository import GLib
2020-01-28 15:08:57 +03:00
2020-02-15 12:51:16 +03:00
from app.commons import log
2019-11-05 23:04:21 +03:00
from app.connections import HttpRequestType
2019-11-24 21:58:32 +03:00
from app.tools.yt import YouTube
2020-02-15 12:51:16 +03:00
from app.ui.iptv import get_yt_icon
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH
2019-11-05 23:04:21 +03:00
class LinksTransmitter:
2020-01-28 15:08:57 +03:00
""" The main class for the "send to" function.
It used for direct playback of media links by the enigma2 media player.
"""
__STREAM_PREFIX = "4097:0:1:0:0:0:0:0:0:0:"
2019-11-05 23:04:21 +03:00
2019-11-24 21:58:32 +03:00
def __init__(self, http_api, app_window):
2019-11-05 23:04:21 +03:00
handlers = {"on_popup_menu": self.on_popup_menu,
"on_status_icon_activate": self.on_status_icon_activate,
2020-02-15 12:51:16 +03:00
"on_url_changed": self.on_url_changed,
"on_url_activate": self.on_url_activate,
2019-11-05 23:04:21 +03:00
"on_drag_data_received": self.on_drag_data_received,
2020-01-28 15:08:57 +03:00
"on_previous": self.on_previous,
"on_next": self.on_next,
"on_stop": self.on_stop,
"on_clear": self.on_clear,
2020-02-15 12:51:16 +03:00
"on_play": self.on_play}
2019-11-05 23:04:21 +03:00
self._http_api = http_api
2019-11-24 21:58:32 +03:00
self._app_window = app_window
2020-02-15 12:51:16 +03:00
self._is_status_icon = True
2019-11-05 23:04:21 +03:00
builder = Gtk.Builder()
builder.add_from_file(UI_RESOURCES_PATH + "transmitter.glade")
builder.connect_signals(handlers)
self._main_window = builder.get_object("main_window")
self._url_entry = builder.get_object("url_entry")
2020-01-28 15:08:57 +03:00
self._tool_bar = builder.get_object("tool_bar")
2020-02-15 12:51:16 +03:00
self._popup_menu = builder.get_object("staus_popup_menu")
self._restore_menu_item = builder.get_object("restore_menu_item")
self._status_active = None
self._status_passive = None
try:
gi.require_version("AppIndicator3", "0.1")
from gi.repository import AppIndicator3
except (ImportError, ValueError) as e:
log("{}: Load library error: {}".format(__class__.__name__, e))
self._tray = builder.get_object("status_icon")
else:
self._is_status_icon = False
self._status_active = AppIndicator3.IndicatorStatus.ACTIVE
self._status_passive = AppIndicator3.IndicatorStatus.PASSIVE
category = AppIndicator3.IndicatorCategory.APPLICATION_STATUS
2020-04-27 12:51:10 +03:00
path = Path(UI_RESOURCES_PATH + "/icons/hicolor/scalable/apps/demon-editor.svg")
path = str(path.resolve()) if path.is_file() else "demon-editor"
2020-02-15 12:51:16 +03:00
self._tray = AppIndicator3.Indicator.new("DemonEditor", path, category)
self._tray.set_status(self._status_active)
self._tray.set_secondary_activate_target(builder.get_object("show_menu_item"))
self._tray.set_menu(self._popup_menu)
2019-11-05 23:04:21 +03:00
2019-12-04 23:06:38 +03:00
style_provider = Gtk.CssProvider()
style_provider.load_from_path(UI_RESOURCES_PATH + "style.css")
self._url_entry.get_style_context().add_provider_for_screen(Gdk.Screen.get_default(), style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_USER)
2019-11-05 23:04:21 +03:00
def show(self, show):
2020-02-15 12:51:16 +03:00
if self._is_status_icon:
self._tray.set_visible(show)
elif self._status_active:
self._tray.set_status(self._status_active if show else self._status_passive)
2019-11-05 23:04:21 +03:00
if not show:
2019-11-24 21:58:32 +03:00
self.hide()
def hide(self):
self._main_window.hide()
2019-11-05 23:04:21 +03:00
def on_popup_menu(self, menu, button, time):
menu.popup(None, None, None, None, button, time)
def on_status_icon_activate(self, window):
visible = window.get_visible()
window.hide() if visible else window.show()
2019-11-24 21:58:32 +03:00
self._app_window.present() if visible else self._app_window.iconify()
2019-11-05 23:04:21 +03:00
2020-02-15 12:51:16 +03:00
def on_url_changed(self, entry):
entry.set_name("GtkEntry" if self.is_url(entry.get_text()) else "digit-entry")
2019-11-05 23:04:21 +03:00
2020-02-15 12:51:16 +03:00
def on_url_activate(self, entry):
gen = self.activate_url(entry.get_text())
GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
2019-11-05 23:04:21 +03:00
2019-12-04 23:06:38 +03:00
def on_drag_data_received(self, entry, drag_context, x, y, data, info, time):
url = data.get_text()
GLib.idle_add(entry.set_text, url)
gen = self.activate_url(url)
2019-11-24 21:58:32 +03:00
GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
2019-11-05 23:04:21 +03:00
def activate_url(self, url):
2019-12-04 23:06:38 +03:00
self._url_entry.set_name("GtkEntry")
2020-02-15 12:51:16 +03:00
self._url_entry.set_icon_from_stock(Gtk.EntryIconPosition.SECONDARY, None)
2019-12-04 23:06:38 +03:00
2020-02-15 12:51:16 +03:00
if self.is_url(url):
2020-01-28 15:08:57 +03:00
self._tool_bar.set_sensitive(False)
2019-11-24 21:58:32 +03:00
yt_id = YouTube.get_yt_id(url)
yield True
if yt_id:
self._url_entry.set_icon_from_pixbuf(Gtk.EntryIconPosition.SECONDARY, get_yt_icon("youtube", 32))
links, title = YouTube.get_yt_link(yt_id)
yield True
if links:
url = links[sorted(links, key=lambda x: int(x.rstrip("p")), reverse=True)[0]]
2019-12-04 23:06:38 +03:00
else:
2020-01-28 15:08:57 +03:00
self.on_done(links)
2019-12-04 23:06:38 +03:00
return
2019-11-24 21:58:32 +03:00
else:
self._url_entry.set_icon_from_stock(Gtk.EntryIconPosition.SECONDARY, None)
2020-01-28 15:08:57 +03:00
self._http_api.send(HttpRequestType.PLAY, url, self.on_done, self.__STREAM_PREFIX)
2019-11-24 21:58:32 +03:00
yield True
2020-01-28 15:08:57 +03:00
def on_done(self, res):
2019-11-24 21:58:32 +03:00
""" Play callback """
2020-01-08 21:33:24 +03:00
res = res.get("e2state", None) if res else res
2019-12-04 23:06:38 +03:00
self._url_entry.set_name("GtkEntry" if res else "digit-entry")
2020-01-28 15:08:57 +03:00
GLib.idle_add(self._tool_bar.set_sensitive, True)
def on_previous(self, item):
self._http_api.send(HttpRequestType.PLAYER_PREV, None, self.on_done)
def on_next(self, item):
self._http_api.send(HttpRequestType.PLAYER_NEXT, None, self.on_done)
def on_play(self, item):
self._http_api.send(HttpRequestType.PLAYER_PLAY, None, self.on_done)
def on_stop(self, item):
self._http_api.send(HttpRequestType.PLAYER_STOP, None, self.on_done)
def on_clear(self, item):
""" Remove added links in the playlist. """
GLib.idle_add(self._tool_bar.set_sensitive, False)
self._http_api.send(HttpRequestType.PLAYER_LIST, None, self.clear_playlist)
def clear_playlist(self, res):
GLib.idle_add(self._tool_bar.set_sensitive, not res)
2020-02-15 12:51:16 +03:00
if "error_code" in res:
log("Error clearing playlist. There may be no http connection.")
self.on_done(res)
return
2020-01-28 15:08:57 +03:00
for ref in res:
GLib.idle_add(self._tool_bar.set_sensitive, False)
self._http_api.send(HttpRequestType.PLAYER_REMOVE,
ref.get("e2servicereference", ""),
self.on_done,
self.__STREAM_PREFIX)
2019-11-05 23:04:21 +03:00
2020-02-15 12:51:16 +03:00
@staticmethod
def is_url(text):
""" Simple url checking. """
result = urlparse(text)
return result.scheme and result.netloc
2019-11-05 23:04:21 +03:00
if __name__ == "__main__":
pass