added epg display in control panel

This commit is contained in:
DYefremov
2020-11-07 18:38:40 +03:00
parent 8910b6d68b
commit f3beec141c
7 changed files with 565 additions and 451 deletions

View File

@@ -56,6 +56,11 @@ class HttpRequestType(Enum):
POWER = "powerstate?newstate="
REMOTE = "remotecontrol?command="
VOL = "vol?set=set"
# EPG
EPG = "epgservice?sRef="
# Timer
TIMER = ""
TIMER_LIST = "timerlist"
# Screenshot
GRUB = "grab?format=jpg&"
@@ -398,7 +403,7 @@ class HttpAPI:
elif req_type is HttpRequestType.GRUB:
data = None # Must be disabled for token-based security.
url = "{}/{}{}".format(self._main_url, req_type.value, ref)
elif req_type in (HttpRequestType.REMOTE, HttpRequestType.POWER, HttpRequestType.VOL):
elif req_type in (HttpRequestType.REMOTE, HttpRequestType.POWER, HttpRequestType.VOL, HttpRequestType.EPG):
url += ref
def done_callback(f):
@@ -452,6 +457,12 @@ def get_response(req_type, url, data=None):
elif req_type is HttpRequestType.PLAYER_LIST:
return [{el.tag: el.text for el in el.iter()} for el in
ETree.fromstring(f.read().decode("utf-8")).iter("e2file")]
elif req_type is HttpRequestType.EPG:
return {"event_list": [{el.tag: el.text for el in el.iter()} for el in
ETree.fromstring(f.read().decode("utf-8")).iter("e2event")]}
elif req_type is HttpRequestType.TIMER_LIST:
return {"timer_list": [{el.tag: el.text for el in el.iter()} for el in
ETree.fromstring(f.read().decode("utf-8")).iter("e2timer")]}
else:
return {el.tag: el.text for el in ETree.fromstring(f.read().decode("utf-8")).iter()}
except HTTPError as e:

View File

@@ -49,174 +49,32 @@ Author: Dmitriy Yefremov
<property name="can_focus">False</property>
<property name="stock">gtk-go-forward</property>
</object>
<object class="GtkPopoverMenu" id="power_menu">
<object class="GtkImage" id="reboot_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="power_menu_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">10</property>
<property name="margin_right">10</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkModelButton" id="standby_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_standby</property>
<property name="text" translatable="yes">Standby</property>
<property name="centered">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkModelButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_wake_up</property>
<property name="text" translatable="yes">Wake Up</property>
<property name="centered">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkModelButton" id="reboot_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_reboot</property>
<property name="text" translatable="yes">Reboot</property>
<property name="centered">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkModelButton" id="restart_gui_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_restart_gui</property>
<property name="text" translatable="yes">Restart GUI</property>
<property name="centered">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkModelButton" id="shutdown_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_shutdown</property>
<property name="text" translatable="yes">Shutdown</property>
<property name="centered">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
</object>
<packing>
<property name="submenu">main</property>
<property name="position">1</property>
</packing>
</child>
<property name="pixel_size">16</property>
<property name="icon_name">view-refresh</property>
<property name="icon_size">1</property>
</object>
<object class="GtkPopoverMenu" id="screenshots_menu">
<object class="GtkImage" id="restart_gui_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="screenshots_menu_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">10</property>
<property name="margin_right">10</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkModelButton" id="screenshot_button_all">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_screenshot_all</property>
<property name="text" translatable="yes">All</property>
<property name="centered">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkModelButton" id="screenshot_button_video">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_screenshot_video</property>
<property name="text" translatable="yes">Video</property>
<property name="centered">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkModelButton" id="screenshot_button_osd">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_screenshot_osd</property>
<property name="text" translatable="yes">OSD</property>
<property name="centered">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="submenu">main</property>
<property name="position">1</property>
</packing>
</child>
<property name="pixel_size">16</property>
<property name="icon_name">window-new</property>
<property name="icon_size">1</property>
</object>
<object class="GtkImage" id="shutdown_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">16</property>
<property name="icon_name">application-exit</property>
</object>
<object class="GtkImage" id="standby_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">16</property>
<property name="icon_name">system-log-out</property>
<property name="icon_size">1</property>
</object>
<object class="GtkImage" id="up_image">
<property name="visible">True</property>
@@ -228,19 +86,29 @@ Author: Dmitriy Yefremov
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkBox" id="main_box">
<property name="width_request">245</property>
<object class="GtkImage" id="wake_up_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">16</property>
<property name="icon_name">document-revert</property>
<property name="icon_size">1</property>
</object>
<object class="GtkBox" id="main_box">
<property name="width_request">320</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">2</property>
<property name="margin_right">2</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkStackSwitcher" id="stack_switcher">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin_left">10</property>
<property name="margin_right">10</property>
<property name="margin_top">10</property>
<property name="margin_top">5</property>
<property name="stack">stack</property>
</object>
<packing>
@@ -253,90 +121,146 @@ Author: Dmitriy Yefremov
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">10</property>
<property name="margin_right">10</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="transition_type">crossfade</property>
<signal name="notify::visible-child" handler="on_visible_tool" swapped="no"/>
<child>
<object class="GtkBox" id="remote_box">
<object class="GtkFrame" id="remote_frame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<property name="label_xalign">0</property>
<property name="shadow_type">out</property>
<child>
<object class="GtkButtonBox" id="header_button_box">
<object class="GtkBox" id="remote_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="margin_top">10</property>
<property name="homogeneous">True</property>
<property name="layout_style">expand</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkMenuButton" id="power_menu_button">
<object class="GtkFrame" id="power_frame">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Power</property>
<property name="popover">power_menu</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="margin_top">5</property>
<property name="label_xalign">0.5</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkImage">
<object class="GtkButtonBox" id="power_button_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">system-log-out</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="homogeneous">True</property>
<property name="layout_style">expand</property>
<child>
<object class="GtkButton" id="standby_button">
<property name="width_request">32</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Standby</property>
<property name="action_name">app.on_standby</property>
<property name="image">standby_image</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="wake_up_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Wake Up</property>
<property name="action_name">app.on_wake_up</property>
<property name="image">wake_up_image</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="reboot_butto">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Reboot</property>
<property name="action_name">app.on_reboot</property>
<property name="image">reboot_image</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="restart_gui_butto">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Restart GUI</property>
<property name="action_name">app.on_restart_gui</property>
<property name="image">restart_gui_image</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="shutdown_butto">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Shutdown</property>
<property name="action_name">app.on_shutdown</property>
<property name="image">shutdown_image</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkMenuButton" id="screenshots_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Screenshot</property>
<property name="popover">screenshots_menu</property>
<child>
<object class="GtkImage" id="screenshots_menu_button_image">
<child type="label">
<object class="GtkLabel" id="power_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">zoom-best-fit</property>
<property name="label" translatable="yes">Power</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="control_frame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="label_xalign">0</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkBox" id="control_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">25</property>
<property name="margin_right">25</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkGrid" id="control_grid">
<property name="visible">True</property>
@@ -442,8 +366,6 @@ Author: Dmitriy Yefremov
<property name="valign">center</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="homogeneous">True</property>
<property name="layout_style">expand</property>
<child>
@@ -481,176 +403,258 @@ Author: Dmitriy Yefremov
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="screenshot_check_button">
<property name="label" translatable="yes">Grab screenshot</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">center</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkVolumeButton" id="volume_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="receives_default">True</property>
<property name="orientation">vertical</property>
<property name="adjustment">volume_adjustment</property>
<property name="icons">audio-volume-muted-symbolic
<child>
<object class="GtkCheckButton" id="screenshot_check_button">
<property name="label" translatable="yes">Grab screenshot</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="halign">center</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkVolumeButton" id="volume_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="receives_default">True</property>
<property name="orientation">vertical</property>
<property name="adjustment">volume_adjustment</property>
<property name="icons">audio-volume-muted-symbolic
audio-volume-high-symbolic
audio-volume-low-symbolic
audio-volume-medium-symbolic</property>
<signal name="value-changed" handler="on_volume_changed" swapped="no"/>
<child internal-child="plus_button">
<object class="GtkButton">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">center</property>
<signal name="value-changed" handler="on_volume_changed" swapped="no"/>
<child internal-child="plus_button">
<object class="GtkButton">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="relief">none</property>
</object>
</child>
<child internal-child="minus_button">
<object class="GtkButton">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="relief">none</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="color_buttons_grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="column_spacing">5</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkButton" id="green_button">
<property name="label" translatable="yes">G</property>
<property name="name">status-bar-button</property>
<property name="height_request">24</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_green</property>
<style>
<class name="green-button"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="yellow_button">
<property name="label" translatable="yes">Y</property>
<property name="name">status-bar-button</property>
<property name="height_request">24</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_yellow</property>
<style>
<class name="yellow-button"/>
</style>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="blue_button">
<property name="label" translatable="yes">B</property>
<property name="name">status-bar-button</property>
<property name="height_request">24</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_blue</property>
<style>
<class name="blue-button"/>
</style>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="red_button">
<property name="label" translatable="yes">R</property>
<property name="name">status-bar-button</property>
<property name="height_request">24</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_red</property>
<style>
<class name="red-button"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="scrennshot_frame">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">center</property>
<property name="relief">none</property>
<property name="label_xalign">0.5</property>
<property name="shadow_type">none</property>
<child>
<object class="GtkButtonBox" id="screenshot_button_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">5</property>
<property name="margin_bottom">5</property>
<property name="layout_style">expand</property>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">All</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="valign">center</property>
<property name="action_name">app.on_screenshot_all</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Video</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="valign">center</property>
<property name="action_name">app.on_screenshot_video</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">OSD</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="valign">center</property>
<property name="action_name">app.on_screenshot_osd</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="screenshot_labe">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Screenshot</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child internal-child="minus_button">
<object class="GtkButton">
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="screenshot_image">
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="stock">gtk-missing-image</property>
<property name="icon_size">6</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="color_buttons_grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="column_spacing">5</property>
<property name="column_homogeneous">True</property>
<child>
<object class="GtkButton" id="green_button">
<property name="name">status-bar-button</property>
<property name="height_request">24</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_green</property>
<style>
<class name="green-button"/>
</style>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="yellow_button">
<property name="name">status-bar-button</property>
<property name="height_request">24</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_yellow</property>
<style>
<class name="yellow-button"/>
</style>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="blue_button">
<property name="name">status-bar-button</property>
<property name="height_request">24</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_blue</property>
<style>
<class name="blue-button"/>
</style>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="red_button">
<property name="name">status-bar-button</property>
<property name="height_request">24</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="action_name">app.on_red</property>
<style>
<class name="red-button"/>
</style>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkImage" id="screenshot_image">
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="margin_top">10</property>
<property name="stock">gtk-missing-image</property>
<property name="icon_size">6</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">6</property>
</packing>
<child type="label_item">
<placeholder/>
</child>
</object>
<packing>
@@ -664,52 +668,28 @@ audio-volume-medium-symbolic</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkListBox" id="epg_list_box">
<object class="GtkScrolledWindow" id="epg_view_scrolled_window">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkViewport" id="epg_view_port">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkListBox" id="epg_list_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<signal name="button-press-event" handler="on_epg_press" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButtonBox" id="epg_button_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">expand</property>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">Add</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton">
<property name="label" translatable="yes">button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
<property name="position">0</property>
</packing>
</child>
</object>
@@ -720,14 +700,27 @@ audio-volume-medium-symbolic</property>
</packing>
</child>
<child>
<object class="GtkBox" id="timer_box">
<object class="GtkBox" id="timers_box">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
<object class="GtkListBox">
<object class="GtkScrolledWindow" id="timers_screlled_window">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkViewport" id="timers_viewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkListBox" id="timers_list_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
@@ -736,7 +729,7 @@ audio-volume-medium-symbolic</property>
</packing>
</child>
<child>
<object class="GtkButtonBox" id="epg_button_box1">
<object class="GtkButtonBox" id="timers_button_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="homogeneous">True</property>
@@ -789,8 +782,8 @@ audio-volume-medium-symbolic</property>
</child>
</object>
<packing>
<property name="name">timer</property>
<property name="title" translatable="yes">Timer</property>
<property name="name">timers</property>
<property name="title" translatable="yes">Timers</property>
<property name="position">2</property>
</packing>
</child>
@@ -805,10 +798,9 @@ audio-volume-medium-symbolic</property>
<object class="GtkBox" id="remote_signal_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">10</property>
<property name="margin_right">10</property>
<property name="margin_left">5</property>
<property name="margin_right">5</property>
<property name="margin_top">10</property>
<property name="margin_bottom">5</property>
<property name="orientation">vertical</property>
<property name="spacing">5</property>
<child>
@@ -927,7 +919,7 @@ audio-volume-medium-symbolic</property>
</packing>
</child>
<style>
<class name="app-notification"/>
<class name="control-box"/>
</style>
</object>
</interface>

View File

@@ -1,21 +1,66 @@
""" Receiver control module via HTTP API. """
import os
from datetime import datetime
from enum import Enum
from gi.repository import GLib
from .uicommons import Gtk, UI_RESOURCES_PATH
from ..commons import run_task, run_with_delay, log
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH
from ..commons import run_task, run_with_delay, log, run_idle
from ..connections import HttpRequestType, HttpAPI
class ControlBox(Gtk.HBox):
class Tool(Enum):
""" The currently displayed tool. """
REMOTE = "control"
EPG = "epg"
TIMERS = "timers"
class EpgRow(Gtk.HBox):
def __init__(self, event: dict, **properties):
super().__init__(**properties)
self._ev_id = event.get("e2eventid", "")
self._ref = event.get("e2eventservicereference", "")
self.set_orientation(Gtk.Orientation.VERTICAL)
title_label = Gtk.Label(event.get("e2eventtitle", ""))
description = Gtk.Label()
description.set_markup("<i>{}</i>".format(event.get("e2eventdescription", "")))
description.set_line_wrap(True)
description.set_max_width_chars(25)
start = int(event.get("e2eventstart", "0"))
start_time = datetime.fromtimestamp(start)
end_time = datetime.fromtimestamp(start + int(event.get("e2eventduration", "0")))
time_label = Gtk.Label()
time_label.set_margin_top(5)
time_str = "{} - {}".format(start_time.strftime("%A, %H:%M"), end_time.strftime("%H:%M"))
time_label.set_markup("<b>{}</b>".format(time_str))
self.add(time_label)
self.add(title_label)
self.add(description)
sep = Gtk.Separator()
sep.set_margin_top(5)
self.add(sep)
self.set_spacing(5)
self.show_all()
def __init__(self, app, http_api, settings, *args, **kwargs):
super().__init__(*args, **kwargs)
self._http_api = http_api
self._settings = settings
self._update_epg = False
self._app = app
handlers = {"on_volume_changed": self.on_volume_changed}
handlers = {"on_visible_tool": self.on_visible_tool,
"on_volume_changed": self.on_volume_changed,
"on_epg_press": self.on_epg_press}
builder = Gtk.Builder()
builder.add_from_file(UI_RESOURCES_PATH + "control.glade")
@@ -23,13 +68,24 @@ class ControlBox(Gtk.HBox):
self.add(builder.get_object("main_box"))
self._screenshot_image = builder.get_object("screenshot_image")
self._screenshots_button = builder.get_object("screenshots_button")
self._screenshot_button_box = builder.get_object("screenshot_button_box")
self._screenshot_check_button = builder.get_object("screenshot_check_button")
self._screenshot_check_button.bind_property("active", self._screenshot_image, "visible")
self._snr_value_label = builder.get_object("snr_value_label")
self._ber_value_label = builder.get_object("ber_value_label")
self._agc_value_label = builder.get_object("agc_value_label")
self._volume_button = builder.get_object("volume_button")
self._epg_list_box = builder.get_object("epg_list_box")
self._timers_list_box = builder.get_object("timers_list_box")
self._app._control_revealer.bind_property("visible", self, "visible")
builder.get_object("stack_switcher").set_visible(settings.is_enable_experimental)
builder.get_object("epg_box").set_visible(settings.is_enable_experimental)
self.init_actions(app)
self.connect("hide", self.on_hide)
self.show()
def init_actions(self, app):
# Remote controller actions
app.set_action("on_up", lambda a, v: self.on_remote_action(HttpAPI.Remote.UP))
app.set_action("on_down", lambda a, v: self.on_remote_action(HttpAPI.Remote.DOWN))
@@ -53,7 +109,19 @@ class ControlBox(Gtk.HBox):
app.set_action("on_screenshot_video", self.on_screenshot_video)
app.set_action("on_screenshot_osd", self.on_screenshot_osd)
self.show()
@property
def update_epg(self):
return self._update_epg
def on_visible_tool(self, stack, param):
tool = self.Tool(stack.get_visible_child_name())
self._update_epg = tool is self.Tool.EPG
if tool is self.Tool.TIMERS:
self.update_timer_list()
def on_hide(self, item):
self._update_epg = False
# ***************** Remote controller ********************* #
@@ -97,11 +165,16 @@ class ControlBox(Gtk.HBox):
from gi.repository import GdkPixbuf
loader = GdkPixbuf.PixbufLoader.new_with_type("jpeg")
loader.set_size(200, 120)
loader.write(data)
pix = loader.get_pixbuf()
loader.close()
GLib.idle_add(self._screenshot_image.set_from_pixbuf, pix)
loader.set_size(280, 165)
try:
loader.write(data)
pix = loader.get_pixbuf()
except GLib.Error:
pass # NOP
else:
GLib.idle_add(self._screenshot_image.set_from_pixbuf, pix)
finally:
loader.close()
def on_screenshot_all(self, action, value=None):
self._http_api.send(HttpRequestType.GRUB, "mode=all" if self._http_api.is_owif else "d=",
@@ -123,7 +196,7 @@ class ControlBox(Gtk.HBox):
img = data.get("img_data", None)
if img:
is_darwin = self._settings.is_darwin
GLib.idle_add(self._screenshots_button.set_sensitive, is_darwin)
GLib.idle_add(self._screenshot_button_box.set_sensitive, is_darwin)
path = os.path.expanduser("~/Desktop") if is_darwin else None
try:
@@ -135,7 +208,7 @@ class ControlBox(Gtk.HBox):
cmd = ["open" if is_darwin else "xdg-open", tf.name]
subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
finally:
GLib.idle_add(self._screenshots_button.set_sensitive, True)
GLib.idle_add(self._screenshot_button_box.set_sensitive, True)
def on_power_action(self, action):
self._http_api.send(HttpRequestType.POWER, action, lambda resp: log("Power status changed..."))
@@ -145,4 +218,30 @@ class ControlBox(Gtk.HBox):
self._ber_value_label.set_text(str(sig.get("e2ber", None) or "0").strip())
self._agc_value_label.set_text(sig.get("e2acg", "0 %").strip())
# ************************ EPG **************************** #
def on_service_changed(self, ref):
self._app._wait_dialog.show()
self._http_api.send(HttpRequestType.EPG, ref, self.update_epg_data)
@run_idle
def update_epg_data(self, epg):
list(map(self._epg_list_box.remove, (r for r in self._epg_list_box)))
list(map(lambda e: self._epg_list_box.add(self.EpgRow(e)), epg.get("event_list", [])))
self._app._wait_dialog.hide()
def on_epg_press(self, list_box: Gtk.ListBox, event: Gdk.EventButton):
if event.get_event_type() == Gdk.EventType.DOUBLE_BUTTON_PRESS and len(list_box) > 0:
pass
# *********************** Timers *************************** #
def update_timer_list(self):
self._app._wait_dialog.show()
self._http_api.send(HttpRequestType.TIMER_LIST, "", self.update_timers_data)
@run_idle
def update_timers_data(self, timers):
timers = timers.get("timer_list", [])
list(map(self._timers_list_box.remove, (r for r in self._timers_list_box)))
self._app._wait_dialog.hide()

View File

@@ -176,6 +176,7 @@ Author: Dmitriy Yefremov
<object class="GtkBox" id="box4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">2</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkSpinner" id="spinner">
@@ -212,10 +213,10 @@ Author: Dmitriy Yefremov
<property name="position">1</property>
</packing>
</child>
<style>
<class name="app-notification"/>
</style>
</object>
</child>
<style>
<class name="app-notification"/>
</style>
</object>
</interface>

View File

@@ -90,6 +90,7 @@ class Application(Gtk.Application):
"on_tree_view_key_release": self.on_tree_view_key_release,
"on_bouquets_selection": self.on_bouquets_selection,
"on_satellite_editor_show": self.on_satellite_editor_show,
"on_fav_selection": self.on_fav_selection,
"on_services_selection": self.on_services_selection,
"on_fav_cut": self.on_fav_cut,
"on_bouquets_cut": self.on_bouquets_cut,
@@ -250,7 +251,7 @@ class Application(Gtk.Application):
self._signal_level_bar.bind_property("visible", builder.get_object("record_button"), "visible")
self._receiver_info_box.bind_property("visible", self._http_status_image, "visible", 4)
self._receiver_info_box.bind_property("visible", self._signal_box, "visible")
# Remote controller
# Control
self._control_button = builder.get_object("control_button")
self._receiver_info_box.bind_property("visible", self._control_button, "visible")
self._control_revealer = builder.get_object("control_revealer")
@@ -1641,6 +1642,13 @@ class Application(Gtk.Application):
self._data_hash = self.get_data_hash()
yield True
def on_fav_selection(self, model, path, column):
if self._control_box and self._control_box.update_epg:
ref = self.get_service_ref(path)
if not ref:
return
self._control_box.on_service_changed(ref)
def on_services_selection(self, model, path, column):
self.update_service_bar(model, path)

View File

@@ -2409,6 +2409,7 @@ Author: Dmitriy Yefremov
<signal name="key-press-event" handler="on_tree_view_key_press" swapped="no"/>
<signal name="key-release-event" handler="on_tree_view_key_release" swapped="no"/>
<signal name="query-tooltip" handler="on_fav_view_query_tooltip" swapped="no"/>
<signal name="row-activated" handler="on_fav_selection" object="fav_list_store" swapped="no"/>
<child internal-child="selection">
<object class="GtkTreeSelection" id="fav_selection">
<property name="mode">multiple</property>
@@ -3133,11 +3134,9 @@ Author: Dmitriy Yefremov
</child>
<child>
<object class="GtkRevealer" id="control_revealer">
<property name="width_request">240</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="transition_type">crossfade</property>
<property name="transition_duration">500</property>
<child>
<placeholder/>
</child>

View File

@@ -7,6 +7,10 @@
margin: 1px;
}
.control-box {
padding: 5px;
}
.red-button {
background-color: red;
}