mirror of
https://github.com/DYefremov/DemonEditor.git
synced 2025-12-21 16:09:41 +01:00
ui prototype to support markers
This commit is contained in:
@@ -1,12 +1,21 @@
|
|||||||
""" Module for parsing bouquets """
|
""" Module for parsing bouquets """
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
_BOUQUETS_PATH = "../data/"
|
_BOUQUETS_PATH = "../data/"
|
||||||
_TV_ROOT_FILE_NAME = "bouquets.tv"
|
_TV_ROOT_FILE_NAME = "bouquets.tv"
|
||||||
_RADIO_ROOT_FILE_NAME = "bouquets.radio"
|
_RADIO_ROOT_FILE_NAME = "bouquets.radio"
|
||||||
|
|
||||||
|
|
||||||
|
class BqServiceType(Enum):
|
||||||
|
DEFAULT = "DEFAULT"
|
||||||
|
IPTV = "IPTV"
|
||||||
|
MARKER = "MARKER" # 64
|
||||||
|
|
||||||
|
|
||||||
Bouquet = namedtuple("Bouquet", ["name", "type", "services"])
|
Bouquet = namedtuple("Bouquet", ["name", "type", "services"])
|
||||||
Bouquets = namedtuple("Bouquets", ["name", "type", "bouquets"])
|
Bouquets = namedtuple("Bouquets", ["name", "type", "bouquets"])
|
||||||
|
BouquetService = namedtuple("BouquetService", ["name", "type", "data"])
|
||||||
|
|
||||||
|
|
||||||
def get_bouquets(path):
|
def get_bouquets(path):
|
||||||
@@ -35,8 +44,9 @@ def write_bouquet(path, name, bq_type, channels):
|
|||||||
for ch in channels:
|
for ch in channels:
|
||||||
if not ch: # if was duplicate
|
if not ch: # if was duplicate
|
||||||
continue
|
continue
|
||||||
if ch.service_type == "IPTV" or ch.service_type == "DESC":
|
|
||||||
bouquet.append("#SERVICE {}".format(ch.fav_id.split(":::")[1]))
|
if ch.service_type == BqServiceType.IPTV.name or ch.service_type == BqServiceType.MARKER.name:
|
||||||
|
bouquet.append("#SERVICE {}".format(ch.fav_id))
|
||||||
else:
|
else:
|
||||||
bouquet.append("#SERVICE {}\n".format(to_bouquet_id(ch)))
|
bouquet.append("#SERVICE {}\n".format(to_bouquet_id(ch)))
|
||||||
|
|
||||||
@@ -62,17 +72,18 @@ def get_bouquet(path, name, bq_type):
|
|||||||
""" Parsing services ids from bouquet file """
|
""" Parsing services ids from bouquet file """
|
||||||
with open(path + "userbouquet.{}.{}".format(name, bq_type)) as file:
|
with open(path + "userbouquet.{}.{}".format(name, bq_type)) as file:
|
||||||
chs_list = file.read()
|
chs_list = file.read()
|
||||||
ids = []
|
services = []
|
||||||
for ch in list(filter(lambda x: len(x) > 1, chs_list.split("#SERVICE")[1:])): # filtering ['']
|
for ch in list(filter(lambda x: len(x) > 1, chs_list.split("#SERVICE")[1:])): # filtering ['']
|
||||||
ch_data = ch.strip().split(":")
|
ch_data = ch.strip().split(":")
|
||||||
if ch_data[1] == "64":
|
if ch_data[1] == "64":
|
||||||
ids.append("{}:::{}:::{}".format("DECR", ch, ch_data[-1].split("\n")[0]))
|
services.append(BouquetService(ch_data[-1].split("\n")[0], BqServiceType.MARKER, ch))
|
||||||
elif "http" in ch:
|
elif "http" in ch:
|
||||||
ids.append("{}:::{}:::{}".format("IPTV", ch, ch_data[-1].split("\n")[0]))
|
services.append(BouquetService(ch_data[-1].split("\n")[0], BqServiceType.IPTV, ch))
|
||||||
else:
|
else:
|
||||||
ids.append("{}:{}:{}:{}".format(ch_data[3], ch_data[4], ch_data[5], ch_data[6]))
|
services.append(BouquetService(None, BqServiceType.DEFAULT,
|
||||||
|
"{}:{}:{}:{}".format(ch_data[3], ch_data[4], ch_data[5], ch_data[6])))
|
||||||
|
|
||||||
return ids
|
return services
|
||||||
|
|
||||||
|
|
||||||
def parse_bouquets(path, bq_name, bq_type):
|
def parse_bouquets(path, bq_name, bq_type):
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ def show_dialog(dialog_type: DialogType, transient, text=None, options=None, act
|
|||||||
|
|
||||||
if dialog_type is DialogType.INPUT:
|
if dialog_type is DialogType.INPUT:
|
||||||
entry = builder.get_object("input_entry")
|
entry = builder.get_object("input_entry")
|
||||||
entry.set_text(text)
|
entry.set_text(text if text else "")
|
||||||
response = dialog.run()
|
response = dialog.run()
|
||||||
txt = entry.get_text()
|
txt = entry.get_text()
|
||||||
dialog.destroy()
|
dialog.destroy()
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from app.commons import run_idle
|
|||||||
from app.eparser import get_blacklist, write_blacklist, to_bouquet_id, parse_m3u
|
from app.eparser import get_blacklist, write_blacklist, to_bouquet_id, parse_m3u
|
||||||
from app.eparser import get_channels, get_bouquets, write_bouquets, write_channels, Bouquets, Bouquet, Channel
|
from app.eparser import get_channels, get_bouquets, write_bouquets, write_channels, Bouquets, Bouquet, Channel
|
||||||
from app.eparser.__constants import CAS, FLAG
|
from app.eparser.__constants import CAS, FLAG
|
||||||
|
from app.eparser.bouquets import BqServiceType
|
||||||
from app.properties import get_config, write_config
|
from app.properties import get_config, write_config
|
||||||
from . import Gtk, Gdk, LOCKED_ICON, HIDE_ICON
|
from . import Gtk, Gdk, LOCKED_ICON, HIDE_ICON
|
||||||
from .dialogs import show_dialog, DialogType
|
from .dialogs import show_dialog, DialogType
|
||||||
@@ -25,7 +26,7 @@ class MainAppWindow:
|
|||||||
"bouquets_remove_popup_item", "fav_remove_popup_item")
|
"bouquets_remove_popup_item", "fav_remove_popup_item")
|
||||||
_FAV_ELEMENTS = ("up_tool_button", "down_tool_button", "cut_tool_button", "paste_tool_button", "cut_menu_item",
|
_FAV_ELEMENTS = ("up_tool_button", "down_tool_button", "cut_tool_button", "paste_tool_button", "cut_menu_item",
|
||||||
"paste_menu_item", "fav_cut_popup_item", "fav_paste_popup_item", "import_m3u_tool_button",
|
"paste_menu_item", "fav_cut_popup_item", "fav_paste_popup_item", "import_m3u_tool_button",
|
||||||
"fav_import_m3u_popup_item")
|
"fav_import_m3u_popup_item", "fav_insert_marker_popup_item")
|
||||||
_LOCK_HIDE_ELEMENTS = ("locked_tool_button", "hide_tool_button")
|
_LOCK_HIDE_ELEMENTS = ("locked_tool_button", "hide_tool_button")
|
||||||
__DYNAMIC_ELEMENTS = ("up_tool_button", "down_tool_button", "cut_tool_button", "copy_tool_button",
|
__DYNAMIC_ELEMENTS = ("up_tool_button", "down_tool_button", "cut_tool_button", "copy_tool_button",
|
||||||
"paste_tool_button", "to_fav_tool_button", "new_tool_button", "remove_tool_button",
|
"paste_tool_button", "to_fav_tool_button", "new_tool_button", "remove_tool_button",
|
||||||
@@ -34,7 +35,7 @@ class MainAppWindow:
|
|||||||
"fav_paste_popup_item", "bouquets_new_popup_item", "bouguets_edit_popup_item",
|
"fav_paste_popup_item", "bouquets_new_popup_item", "bouguets_edit_popup_item",
|
||||||
"services_remove_popup_item", "bouquets_remove_popup_item", "fav_remove_popup_item",
|
"services_remove_popup_item", "bouquets_remove_popup_item", "fav_remove_popup_item",
|
||||||
"locked_tool_button", "hide_tool_button", "import_m3u_tool_button",
|
"locked_tool_button", "hide_tool_button", "import_m3u_tool_button",
|
||||||
"fav_import_m3u_popup_item")
|
"fav_import_m3u_popup_item", "fav_insert_marker_popup_item", "fav_edit_marker_popup_item")
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
handlers = {"on_close_main_window": self.on_quit,
|
handlers = {"on_close_main_window": self.on_quit,
|
||||||
@@ -66,7 +67,10 @@ class MainAppWindow:
|
|||||||
"on_hide": self.on_hide,
|
"on_hide": self.on_hide,
|
||||||
"on_locked": self.on_locked,
|
"on_locked": self.on_locked,
|
||||||
"on_model_changed": self.on_model_changed,
|
"on_model_changed": self.on_model_changed,
|
||||||
"on_import_m3u": self.on_import_m3u}
|
"on_import_m3u": self.on_import_m3u,
|
||||||
|
"on_insert_marker": self.on_insert_marker,
|
||||||
|
"on_edit_marker": self.on_edit_marker,
|
||||||
|
"on_fav_popup": self.on_fav_popup}
|
||||||
|
|
||||||
self.__options = get_config()
|
self.__options = get_config()
|
||||||
# Used for copy/paste. When adding the previous data will not be deleted.
|
# Used for copy/paste. When adding the previous data will not be deleted.
|
||||||
@@ -100,6 +104,7 @@ class MainAppWindow:
|
|||||||
self.__tv_count_label = builder.get_object("tv_count_label")
|
self.__tv_count_label = builder.get_object("tv_count_label")
|
||||||
self.__radio_count_label = builder.get_object("radio_count_label")
|
self.__radio_count_label = builder.get_object("radio_count_label")
|
||||||
self.__data_count_label = builder.get_object("data_count_label")
|
self.__data_count_label = builder.get_object("data_count_label")
|
||||||
|
self.__fav_edit_marker_popup_item = builder.get_object("fav_edit_marker_popup_item")
|
||||||
builder.connect_signals(handlers)
|
builder.connect_signals(handlers)
|
||||||
self.init_drag_and_drop() # drag and drop
|
self.init_drag_and_drop() # drag and drop
|
||||||
self.__main_window.show()
|
self.__main_window.show()
|
||||||
@@ -454,18 +459,18 @@ class MainAppWindow:
|
|||||||
for bt in bouquet.bouquets:
|
for bt in bouquet.bouquets:
|
||||||
name, bt_type = bt.name, bt.type
|
name, bt_type = bt.name, bt.type
|
||||||
self.__bouquets_model.append(parent, [name, bt_type])
|
self.__bouquets_model.append(parent, [name, bt_type])
|
||||||
self.__bouquets["{}:{}".format(name, bt_type)] = bt.services
|
services = []
|
||||||
aggr = [None] * 8
|
agr = [None] * 8
|
||||||
# IPTV and DECR services
|
|
||||||
for srv in bt.services:
|
for srv in bt.services:
|
||||||
srv_ids = srv.split(":::")
|
f_id = srv.data
|
||||||
if srv_ids:
|
# IPTV and MARKER services
|
||||||
if srv_ids[0] == "DECR":
|
s_type = srv.type
|
||||||
self.__channels[srv] = Channel(*aggr[0:3], srv_ids[-1], *aggr[0:3], "DECR", *aggr, srv,
|
if s_type is BqServiceType.MARKER:
|
||||||
None)
|
self.__channels[f_id] = Channel(*agr[0:3], srv.name, *agr[0:3], s_type.name, *agr, f_id, None)
|
||||||
elif srv_ids[0] == "IPTV":
|
elif s_type is BqServiceType.IPTV:
|
||||||
self.__channels[srv] = Channel(*aggr[0:3], srv_ids[-1], *aggr[0:3], "IPTV", *aggr, srv,
|
self.__channels[f_id] = Channel(*agr[0:3], srv.name, *agr[0:3], srv.type.name, *agr, f_id, None)
|
||||||
None)
|
services.append(f_id)
|
||||||
|
self.__bouquets["{}:{}".format(name, bt_type)] = services
|
||||||
|
|
||||||
def append_services(self, data_path):
|
def append_services(self, data_path):
|
||||||
channels = get_channels(data_path)
|
channels = get_channels(data_path)
|
||||||
@@ -567,6 +572,7 @@ class MainAppWindow:
|
|||||||
|
|
||||||
return "{}:{}".format(*model.get(model.get_iter(path), 0, 1))
|
return "{}:{}".format(*model.get(model.get_iter(path), 0, 1))
|
||||||
|
|
||||||
|
@run_idle
|
||||||
def delete_selection(self, view, *args):
|
def delete_selection(self, view, *args):
|
||||||
""" Used for clear selection on given view(s) """
|
""" Used for clear selection on given view(s) """
|
||||||
for v in [view, *args]:
|
for v in [view, *args]:
|
||||||
@@ -753,6 +759,23 @@ class MainAppWindow:
|
|||||||
bq_services.append(ch.fav_id)
|
bq_services.append(ch.fav_id)
|
||||||
self.update_bouquet_channels(self.__fav_model, None, bq_selected)
|
self.update_bouquet_channels(self.__fav_model, None, bq_selected)
|
||||||
|
|
||||||
|
def on_insert_marker(self, view):
|
||||||
|
response = show_dialog(DialogType.INPUT, self.__main_window)
|
||||||
|
if response == Gtk.ResponseType.CANCEL:
|
||||||
|
return
|
||||||
|
|
||||||
|
def on_edit_marker(self, view):
|
||||||
|
model, paths = view.get_selection().get_selected_rows()
|
||||||
|
response = show_dialog(DialogType.INPUT, self.__main_window, text=model.get_value(model.get_iter(paths[0]), 2))
|
||||||
|
if response == Gtk.ResponseType.CANCEL:
|
||||||
|
return
|
||||||
|
|
||||||
|
@run_idle
|
||||||
|
def on_fav_popup(self, view, event):
|
||||||
|
model, paths = view.get_selection().get_selected_rows()
|
||||||
|
self.__fav_edit_marker_popup_item.set_sensitive(
|
||||||
|
len(paths) == 1 and model.get_value(model.get_iter(paths[0]), 5) == BqServiceType.MARKER.name)
|
||||||
|
|
||||||
|
|
||||||
def start_app():
|
def start_app():
|
||||||
MainAppWindow()
|
MainAppWindow()
|
||||||
|
|||||||
@@ -74,7 +74,22 @@
|
|||||||
<object class="GtkImage" id="image1">
|
<object class="GtkImage" id="image1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="icon_name">media-import-audio-cd</property>
|
<property name="icon_name">insert-object</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="icon_name">applications-utilities</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image5">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="icon_name">insert-text</property>
|
||||||
|
</object>
|
||||||
|
<object class="GtkImage" id="image6">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-edit</property>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkMenu" id="fav_popup_menu">
|
<object class="GtkMenu" id="fav_popup_menu">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
@@ -102,7 +117,37 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparatorMenuItem" id="separatormenuitem3">
|
<object class="GtkSeparatorMenuItem" id="fav_pupup_separator_1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="fav_insert_marker_popup_item">
|
||||||
|
<property name="label" translatable="yes">Insert marker</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image5</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="on_insert_marker" object="fav_tree_view" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImageMenuItem" id="fav_edit_marker_popup_item">
|
||||||
|
<property name="label" translatable="yes">Edit mаrker text</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="sensitive">False</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="image">image6</property>
|
||||||
|
<property name="use_stock">False</property>
|
||||||
|
<signal name="activate" handler="on_edit_marker" object="fav_tree_view" swapped="no"/>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSeparatorMenuItem" id="fav_pupup_separator_2">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
@@ -113,13 +158,14 @@
|
|||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="sensitive">False</property>
|
<property name="sensitive">False</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
<property name="image">image1</property>
|
<property name="image">image1</property>
|
||||||
<property name="use_stock">False</property>
|
<property name="use_stock">False</property>
|
||||||
<signal name="activate" handler="on_import_m3u" swapped="no"/>
|
<signal name="activate" handler="on_import_m3u" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkSeparatorMenuItem" id="separatormenuitem2">
|
<object class="GtkSeparatorMenuItem" id="fav_pupup_separator_3">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
</object>
|
</object>
|
||||||
@@ -136,11 +182,6 @@
|
|||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
<object class="GtkImage" id="image4">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">False</property>
|
|
||||||
<property name="icon_name">applications-utilities</property>
|
|
||||||
</object>
|
|
||||||
<object class="GtkImage" id="send_recive_image">
|
<object class="GtkImage" id="send_recive_image">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
@@ -676,7 +717,7 @@
|
|||||||
<property name="opacity">0.93999999999999995</property>
|
<property name="opacity">0.93999999999999995</property>
|
||||||
<property name="label" translatable="yes">IPTV</property>
|
<property name="label" translatable="yes">IPTV</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
<property name="icon_name">media-import-audio-cd</property>
|
<property name="icon_name">insert-object</property>
|
||||||
<signal name="clicked" handler="on_import_m3u" swapped="no"/>
|
<signal name="clicked" handler="on_import_m3u" swapped="no"/>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
@@ -1270,6 +1311,7 @@
|
|||||||
<property name="rubber_banding">True</property>
|
<property name="rubber_banding">True</property>
|
||||||
<property name="enable_grid_lines">both</property>
|
<property name="enable_grid_lines">both</property>
|
||||||
<property name="activate_on_single_click">True</property>
|
<property name="activate_on_single_click">True</property>
|
||||||
|
<signal name="button-press-event" handler="on_fav_popup" swapped="no"/>
|
||||||
<signal name="button-press-event" handler="on_view_popup_menu" object="fav_popup_menu" swapped="no"/>
|
<signal name="button-press-event" handler="on_view_popup_menu" object="fav_popup_menu" swapped="no"/>
|
||||||
<signal name="drag-data-get" handler="on_fav_tree_view_drag_data_get" swapped="no"/>
|
<signal name="drag-data-get" handler="on_fav_tree_view_drag_data_get" swapped="no"/>
|
||||||
<signal name="drag-data-received" handler="on_fav_tree_view_drag_data_received" swapped="no"/>
|
<signal name="drag-data-received" handler="on_fav_tree_view_drag_data_received" swapped="no"/>
|
||||||
@@ -1387,7 +1429,7 @@
|
|||||||
<object class="GtkImage" id="image2">
|
<object class="GtkImage" id="image2">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="stock">gtk-properties</property>
|
<property name="icon_name">document-properties</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
@@ -1509,7 +1551,7 @@
|
|||||||
<object class="GtkImage" id="image3">
|
<object class="GtkImage" id="image3">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">False</property>
|
<property name="can_focus">False</property>
|
||||||
<property name="stock">gtk-properties</property>
|
<property name="icon_name">document-properties</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
|
|||||||
Reference in New Issue
Block a user