diff --git a/README.md b/README.md
index fdb6ca2c..632309e0 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,8 @@ Ctrl + X, C, V, Up, Down, PageUp, PageDown, S, T, E, L, H, Space; Insert, Delete
Insert - copies the selected channels from the main list to the bouquet or inserts (creates) a new bouquet.
Ctrl + X - only in bouquet list. Ctrl + C - only in services list.
Clipboard is "rubber". There is an accumulation before the insertion!
-Ctrl + E, F2 - edit/rename.
+Ctrl + E, F2 - edit.
+Ctrl + R - rename.
Ctrl + S, T, E in Satellites edit tool for create and edit satellite or transponder.
Ctrl + L - parental lock.
Ctrl + H - hide/skip.
diff --git a/app/eparser/ecommons.py b/app/eparser/ecommons.py
index a593d947..0755c1c5 100644
--- a/app/eparser/ecommons.py
+++ b/app/eparser/ecommons.py
@@ -34,7 +34,7 @@ class Type(Enum):
Cable = "c"
-class FLAG(Enum):
+class Flag(Enum):
""" Service flags """
KEEP = 1 # Do not automatically update the services parameters.
HIDE = 2
@@ -47,6 +47,20 @@ class FLAG(Enum):
return 2, 3, 6, 7, 10, 42, 43, 46, 47
+class Inversion(Enum):
+ Off = "0"
+ On = "1"
+ Auto = "2"
+
+
+class Pilot(Enum):
+ Off = "0"
+ On = "1"
+ Auto = "2"
+
+
+ROLL_OFF = {"0": "35%", "1": "25%", "2": "20%", "3": "Auto"}
+
POLARIZATION = {"0": "H", "1": "V", "2": "L", "3": "R"}
PLS_MODE = {"0": "Root", "1": "Gold", "2": "Combo"}
diff --git a/app/eparser/enigma/lamedb.py b/app/eparser/enigma/lamedb.py
index 2ff88f0c..a4054c2c 100644
--- a/app/eparser/enigma/lamedb.py
+++ b/app/eparser/enigma/lamedb.py
@@ -6,7 +6,7 @@
from app.commons import log
from app.ui import CODED_ICON, LOCKED_ICON, HIDE_ICON
from .blacklist import get_blacklist
-from ..ecommons import Service, POLARIZATION, SYSTEM, FEC, SERVICE_TYPE, FLAG
+from ..ecommons import Service, POLARIZATION, SYSTEM, FEC, SERVICE_TYPE, Flag
_HEADER = "eDVB services /4/"
_SEP = ":" # separator
@@ -101,7 +101,7 @@ def parse_services(services, transponders, path):
all_flags = ch[2].split(",")
coded = CODED_ICON if list(filter(lambda x: x.startswith("C:"), all_flags)) else None
flags = list(filter(lambda x: x.startswith("f:"), all_flags))
- hide = HIDE_ICON if flags and int(flags[0][2:]) in FLAG.hide_values() else None
+ hide = HIDE_ICON if flags and int(flags[0][2:]) in Flag.hide_values() else None
locked = LOCKED_ICON if fav_id in blacklist else None
package = list(filter(lambda x: x.startswith("p:"), all_flags))
@@ -128,7 +128,7 @@ def parse_services(services, transponders, path):
rate=tr[1],
pol=POLARIZATION[tr[2]],
fec=FEC[tr[3]],
- system=SYSTEM[tr[6]],
+ system="DVB-S2" if len(tr) > 7 else "DVB-S",
pos="{}.{}".format(tr[4][:-1], tr[4][-1:]),
data_id=ch[0],
fav_id=fav_id,
diff --git a/app/eparser/iptv.py b/app/eparser/iptv.py
index c40ed203..45e1cdce 100644
--- a/app/eparser/iptv.py
+++ b/app/eparser/iptv.py
@@ -1,21 +1,31 @@
+""" Module for m3u import """
+from app.properties import Profile
+from app.ui import IPTV_ICON
from .ecommons import BqServiceType, Service
+# url, description, urlkey, account, usrname, psw, s_type, iconsrc, iconsrc_b, group
+NEUTRINO_FAV_ID_FORMAT = "{}::{}::{}::{}::{}::{}::{}::{}::{}::{}"
+ENIGMA2_FAV_ID_FORMAT = " 1:0:1:0:0:0:0:0:0:0:{}:{}\n#DESCRIPTION: {}\n"
-def parse_m3u(path):
+
+def parse_m3u(path, profile):
with open(path) as file:
aggr = [None] * 10
channels = []
count = 0
name = None
+ fav_id = None
for line in file.readlines():
if line.startswith("#EXTINF"):
name = line[1 + line.index(","):].strip()
count += 1
elif count == 1:
count = 0
- fav_id = " 1:0:1:0:0:0:0:0:0:0:{}:{}\n#DESCRIPTION: {}\n".format(
- line.strip().replace(":", "%3a"), name, name, None)
- srv = Service(*aggr[0:3], name, *aggr[0:3], BqServiceType.IPTV.name, *aggr, fav_id, None)
+ if profile is Profile.ENIGMA_2:
+ fav_id = ENIGMA2_FAV_ID_FORMAT.format(line.strip().replace(":", "%3a"), name, name, None)
+ elif profile is Profile.NEUTRINO_MP:
+ fav_id = NEUTRINO_FAV_ID_FORMAT.format(line.strip(), "", 0, None, None, None, None, "", "", 1)
+ srv = Service(None, None, IPTV_ICON, name, *aggr[0:3], BqServiceType.IPTV.name, *aggr, fav_id, None)
channels.append(srv)
return channels
diff --git a/app/eparser/neutrino/bouquets.py b/app/eparser/neutrino/bouquets.py
index a6ff972c..2af40aab 100644
--- a/app/eparser/neutrino/bouquets.py
+++ b/app/eparser/neutrino/bouquets.py
@@ -1,23 +1,28 @@
import os
-from contextlib import suppress
from enum import Enum
from xml.dom.minidom import parse, Document
+from app.eparser.iptv import NEUTRINO_FAV_ID_FORMAT
from app.ui import LOCKED_ICON, HIDE_ICON
from ..ecommons import Bouquets, Bouquet, BouquetService, BqServiceType, PROVIDER
_FILE = "bouquets.xml"
_U_FILE = "ubouquets.xml"
+_W_FILE = "webtv.xml"
+
+_COMMENT = " File was created in DemonEditor. Enjoy watching! "
class BqType(Enum):
BOUQUET = "bouquet"
TV = "tv"
+ WEBTV = "webtv"
def get_bouquets(path):
return (parse_bouquets(path + _FILE, "Providers", BqType.BOUQUET.value),
- parse_bouquets(path + _U_FILE, "FAV", BqType.TV.value))
+ parse_bouquets(path + _U_FILE, "FAV", BqType.TV.value),
+ parse_webtv(path + _W_FILE, "WEBTV", BqType.WEBTV.value))
def parse_bouquets(file, name, bq_type):
@@ -61,22 +66,62 @@ def parse_bouquets(file, name, bq_type):
return bouquets
-def write_bouquets(path, bouquets):
- if len(bouquets) < 2:
- for f in path + _FILE, path + _U_FILE:
- with suppress(FileNotFoundError):
- os.remove(f)
+def parse_webtv(path, name, bq_type):
+ bouquets = Bouquets(name=name, type=bq_type, bouquets=[])
+ if not os.path.exists(path):
+ return bouquets
+ dom = parse(path)
+ services = []
+ for elem in dom.getElementsByTagName("webtv"):
+ if elem.hasAttributes():
+ title = elem.attributes["title"].value
+ url = elem.attributes["url"].value
+ description = elem.attributes.get("description")
+ description = description.value if description else description
+ urlkey = elem.attributes.get("urlkey", None)
+ urlkey = urlkey.value if urlkey else urlkey
+ account = elem.attributes.get("account", None)
+ account = account.value if account else account
+ usrname = elem.attributes.get("usrname", None)
+ usrname = usrname.value if usrname else usrname
+ psw = elem.attributes.get("psw", None)
+ psw = psw.value if psw else psw
+ s_type = elem.attributes.get("type", None)
+ s_type = s_type.value if s_type else s_type
+ iconsrc = elem.attributes.get("iconsrc", None)
+ iconsrc = iconsrc.value if iconsrc else iconsrc
+ iconsrc_b = elem.attributes.get("iconsrc_b", None)
+ iconsrc_b = iconsrc_b.value if iconsrc_b else iconsrc_b
+ group = elem.attributes.get("group", None)
+ group = group.value if group else group
+ fav_id = NEUTRINO_FAV_ID_FORMAT.format(url, description, urlkey, account, usrname, psw, s_type, iconsrc,
+ iconsrc_b, group)
+ srv = BouquetService(name=title,
+ type=BqServiceType.IPTV,
+ data=fav_id,
+ num=0)
+ services.append(srv)
+ bouquet = Bouquet(name="default", type=bq_type, services=services, locked=None, hidden=None)
+ bouquets[2].append(bouquet)
+
+ return bouquets
+
+
+def write_bouquets(path, bouquets):
for bq in bouquets:
bq_type = BqType(bq.type)
- write_bouquet(path + (_FILE if bq_type is BqType.BOUQUET else _U_FILE), bq)
+ if bq_type is BqType.WEBTV:
+ write_webtv(path + _W_FILE, bq)
+ else:
+ write_bouquet(path + (_FILE if bq_type is BqType.BOUQUET else _U_FILE), bq)
def write_bouquet(file, bouquet):
doc = Document()
root = doc.createElement("zapit")
doc.appendChild(root)
- comment = doc.createComment(" File was created in DemonEditor. Enjoy watching! ")
+ comment = doc.createComment(_COMMENT)
doc.appendChild(comment)
for bq in bouquet.bouquets:
@@ -102,5 +147,43 @@ def write_bouquet(file, bouquet):
doc.writexml(open(file, "w"), addindent=" ", newl="\n", encoding="UTF-8")
+def write_webtv(file, bouquet):
+ doc = Document()
+ root = doc.createElement("webtvs")
+ doc.appendChild(root)
+ comment = doc.createComment(_COMMENT)
+ doc.appendChild(comment)
+
+ for bq in bouquet.bouquets:
+ for srv in bq.services:
+ url, description, urlkey, account, usrname, psw, s_type, iconsrc, iconsrc_b, group = srv.fav_id.split("::")
+ srv_elem = doc.createElement("webtv")
+ srv_elem.setAttribute("title", srv.service)
+ srv_elem.setAttribute("url", url)
+
+ if description != "None":
+ srv_elem.setAttribute("description", description)
+ if urlkey != "None":
+ srv_elem.setAttribute("urlkey", urlkey)
+ if account != "None":
+ srv_elem.setAttribute("account", account)
+ if usrname != "None":
+ srv_elem.setAttribute("usrname", usrname)
+ if psw != "None":
+ srv_elem.setAttribute("psw", psw)
+ if s_type != "None":
+ srv_elem.setAttribute("type", s_type)
+ if iconsrc != "None":
+ srv_elem.setAttribute("iconsrc", iconsrc)
+ if iconsrc_b != "None":
+ srv_elem.setAttribute("iconsrc_b", iconsrc_b)
+ if group != "None":
+ srv_elem.setAttribute("group", group)
+
+ root.appendChild(srv_elem)
+
+ doc.writexml(open(file, "w"), addindent=" ", newl="\n", encoding="UTF-8")
+
+
if __name__ == "__main__":
pass
diff --git a/app/ftp.py b/app/ftp.py
index 7ddb2839..76697f0e 100644
--- a/app/ftp.py
+++ b/app/ftp.py
@@ -11,12 +11,16 @@ from app.properties import Profile
__DATA_FILES_LIST = ("tv", "radio", "lamedb", "blacklist", "whitelist", # enigma 2
"services.xml", "myservices.xml", "bouquets.xml", "ubouquets.xml") # neutrino
+_SATELLITES_XML_FILE = "satellites.xml"
+_WEBTV_XML_FILE = "webtv.xml"
+
class DownloadDataType(Enum):
ALL = 0
BOUQUETS = 1
SATELLITES = 2
PICONS = 3
+ WEBTV = 4
def download_data(*, properties, download_type=DownloadDataType.ALL, callback=None):
@@ -35,20 +39,21 @@ def download_data(*, properties, download_type=DownloadDataType.ALL, callback=No
name = str(file).strip()
if name.endswith(__DATA_FILES_LIST):
name = name.split()[-1]
- with open(save_path + name, "wb") as f:
- ftp.retrbinary("RETR " + name, f.write)
- # satellites.xml section
- if download_type is DownloadDataType.ALL or download_type is DownloadDataType.SATELLITES:
+ download_file(ftp, name, save_path)
+ # satellites.xml and webtv section
+ if download_type in (DownloadDataType.ALL, DownloadDataType.SATELLITES, DownloadDataType.WEBTV):
ftp.cwd(properties["satellites_xml_path"])
files.clear()
ftp.dir(files.append)
for file in files:
name = str(file).strip()
- xml_file = "satellites.xml"
- if name.endswith(xml_file):
- with open(save_path + xml_file, 'wb') as f:
- ftp.retrbinary("RETR " + xml_file, f.write)
+ if download_type in (DownloadDataType.ALL, DownloadDataType.SATELLITES):
+ if name.endswith(_SATELLITES_XML_FILE):
+ download_file(ftp, _SATELLITES_XML_FILE, save_path)
+ elif download_type in (DownloadDataType.ALL, DownloadDataType.WEBTV):
+ if name.endswith(_WEBTV_XML_FILE):
+ download_file(ftp, _WEBTV_XML_FILE, save_path)
if callback is not None:
callback()
@@ -71,9 +76,20 @@ def upload_data(*, properties, download_type=DownloadDataType.ALL, remove_unused
if download_type is DownloadDataType.ALL or download_type is DownloadDataType.SATELLITES:
ftp.cwd(properties["satellites_xml_path"])
- file_name = "satellites.xml"
- send = send_file(file_name, data_path, ftp)
- if download_type == DownloadDataType.SATELLITES:
+ send = send_file(_SATELLITES_XML_FILE, data_path, ftp)
+ if download_type is DownloadDataType.SATELLITES:
+ tn.send("init 3" if profile is Profile.ENIGMA_2 else "init 6")
+ if callback is not None:
+ callback()
+ return send
+
+ if profile is Profile.NEUTRINO_MP and download_type in (DownloadDataType.ALL, DownloadDataType.WEBTV):
+ ftp.cwd(properties["satellites_xml_path"])
+ send = send_file(_WEBTV_XML_FILE, data_path, ftp)
+ if download_type is DownloadDataType.WEBTV:
+ tn.send("init 6")
+ if callback is not None:
+ callback()
return send
if download_type is DownloadDataType.ALL or download_type is DownloadDataType.BOUQUETS:
@@ -88,7 +104,7 @@ def upload_data(*, properties, download_type=DownloadDataType.ALL, remove_unused
ftp.delete(name)
for file_name in os.listdir(data_path):
- if file_name == "satellites.xml":
+ if file_name == _SATELLITES_XML_FILE or file_name == _WEBTV_XML_FILE:
continue
if file_name.endswith(__DATA_FILES_LIST):
send_file(file_name, data_path, ftp)
@@ -123,6 +139,11 @@ def upload_data(*, properties, download_type=DownloadDataType.ALL, remove_unused
callback()
+def download_file(ftp, name, save_path):
+ with open(save_path + name, "wb") as f:
+ ftp.retrbinary("RETR " + name, f.write)
+
+
def send_file(file_name, path, ftp):
""" Opens the file in binary mode and transfers into receiver """
with open(path + file_name, "rb") as f:
diff --git a/app/ui/__init__.py b/app/ui/__init__.py
index cdd99b27..811757c8 100644
--- a/app/ui/__init__.py
+++ b/app/ui/__init__.py
@@ -15,6 +15,7 @@ LOCKED_ICON = theme.load_icon("system-lock-screen", 16, 0) if theme.lookup_icon(
"system-lock-screen", 16, 0) else _IMAGE_MISSING
HIDE_ICON = theme.load_icon("go-jump", 16, 0) if theme.lookup_icon("go-jump", 16, 0) else _IMAGE_MISSING
TV_ICON = theme.load_icon("tv-symbolic", 16, 0) if theme.lookup_icon("tv-symbolic", 16, 0) else _IMAGE_MISSING
+IPTV_ICON = theme.load_icon("emblem-shared", 16, 0) if theme.load_icon("emblem-shared", 16, 0) else None
if __name__ == "__main__":
pass
diff --git a/app/ui/dialogs.glade b/app/ui/dialogs.glade
index c0349d35..3a9a532f 100644
--- a/app/ui/dialogs.glade
+++ b/app/ui/dialogs.glade
@@ -9,7 +9,7 @@
system-help
normal
DemonEditor
- 0.2.3 Pre-alpha
+ 0.2.4 Pre-alpha
2018 Dmitriy Yefremov
dmitry.v.yefremov@gmail.com
@@ -220,7 +220,21 @@ dmitry.v.yefremov@gmail.com
-
+
+
+ False
+ True
+ 4
+
diff --git a/app/ui/download_dialog.py b/app/ui/download_dialog.py
index 6cce92e1..8d934db9 100644
--- a/app/ui/download_dialog.py
+++ b/app/ui/download_dialog.py
@@ -35,16 +35,19 @@ class DownloadDialog:
self._all_radio_button = builder.get_object("all_radio_button")
self._bouquets_radio_button = builder.get_object("bouquets_radio_button")
self._satellites_radio_button = builder.get_object("satellites_radio_button")
+ self._webtv_radio_button = builder.get_object("webtv_radio_button")
+ if profile is Profile.NEUTRINO_MP:
+ self._webtv_radio_button.set_visible(True)
# self._dialog.get_content_area().set_border_width(0)
@run_idle
def on_receive(self, item):
- self.download(True, d_type=self.get_download_type())
+ self.download(True, self.get_download_type())
@run_idle
def on_send(self, item):
if show_dialog(DialogType.QUESTION, self._dialog) != Gtk.ResponseType.CANCEL:
- self.download(d_type=self.get_download_type())
+ self.download(False, self.get_download_type())
def get_download_type(self):
download_type = DownloadDataType.ALL
@@ -52,6 +55,8 @@ class DownloadDialog:
download_type = DownloadDataType.BOUQUETS
elif self._satellites_radio_button.get_active():
download_type = DownloadDataType.SATELLITES
+ elif self._webtv_radio_button.get_active():
+ download_type = DownloadDataType.WEBTV
return download_type
def run(self):
@@ -65,7 +70,7 @@ class DownloadDialog:
@run_idle
@run_task
- def download(self, download=False, d_type=DownloadDataType.ALL):
+ def download(self, download, d_type):
""" Download/upload data from/to receiver """
try:
if download:
diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py
index 9e121750..c71947f5 100644
--- a/app/ui/main_app_window.py
+++ b/app/ui/main_app_window.py
@@ -7,10 +7,11 @@ import shutil
from app.commons import run_idle, log
from app.eparser import get_blacklist, write_blacklist, parse_m3u
from app.eparser import get_services, get_bouquets, write_bouquets, write_services, Bouquets, Bouquet, Service
-from app.eparser.ecommons import CAS, FLAG
+from app.eparser.ecommons import CAS, Flag
from app.eparser.enigma.bouquets import BqServiceType
+from app.eparser.neutrino.bouquets import BqType
from app.properties import get_config, write_config, Profile
-from . import Gtk, Gdk, UI_RESOURCES_PATH, LOCKED_ICON, HIDE_ICON
+from . import Gtk, Gdk, UI_RESOURCES_PATH, LOCKED_ICON, HIDE_ICON, IPTV_ICON
from .dialogs import show_dialog, DialogType, get_chooser_dialog
from .download_dialog import show_download_dialog
from .main_helper import edit_marker, insert_marker, move_items, edit, ViewTarget, set_flags, locate_in_services, \
@@ -18,6 +19,7 @@ from .main_helper import edit_marker, insert_marker, move_items, edit, ViewTarge
from .picons_dialog import PiconsDialog
from .satellites_dialog import show_satellites_dialog
from .settings_dialog import show_settings_dialog
+from .service_details_dialog import ServiceDetailsDialog
class MainAppWindow:
@@ -39,8 +41,9 @@ class MainAppWindow:
"fav_import_m3u_popup_item", "fav_insert_marker_popup_item", "fav_edit_popup_item",
"fav_locate_popup_item", "fav_picon_popup_item")
- _FAV_ONLY_ELEMENTS = ("import_m3u_tool_button", "fav_import_m3u_popup_item", "fav_insert_marker_popup_item",
- "fav_edit_marker_popup_item")
+ _FAV_ENIGMA_ELEMENTS = ("fav_insert_marker_popup_item", "fav_edit_marker_popup_item")
+
+ _FAV_M3U_ELEMENTS = ("import_m3u_tool_button", "fav_import_m3u_popup_item")
_LOCK_HIDE_ELEMENTS = ("locked_tool_button", "hide_tool_button")
@@ -99,7 +102,8 @@ class MainAppWindow:
"on_reference_picon": self.on_reference_picon,
"on_filter_toggled": self.on_filter_toggled,
"on_search_toggled": self.on_search_toggled,
- "on_search": self.on_search}
+ "on_search": self.on_search,
+ "on_services_data_edit": self.on_services_data_edit}
self.__options = get_config()
self.__profile = self.__options.get("profile")
@@ -524,7 +528,8 @@ class MainAppWindow:
# IPTV and MARKER services
s_type = srv.type
if s_type is BqServiceType.MARKER or s_type is BqServiceType.IPTV:
- srv = Service(*agr[0:3], srv.name, *agr[0:3], s_type.name, *agr, srv.num, fav_id, None)
+ icon = IPTV_ICON if s_type is BqServiceType.IPTV else None
+ srv = Service(*agr[0:2], icon, srv.name, *agr[0:3], s_type.name, *agr, srv.num, fav_id, None)
self.__services[fav_id] = srv
services.append(fav_id)
self.__bouquets["{}:{}".format(name, bt_type)] = services
@@ -703,8 +708,15 @@ class MainAppWindow:
self.on_locked(None)
elif ctrl and key == Gdk.KEY_h or key == Gdk.KEY_H:
self.on_hide(None)
- elif ctrl and key == Gdk.KEY_E or key == Gdk.KEY_e or key == Gdk.KEY_F2:
+ elif ctrl and key == Gdk.KEY_R or key == Gdk.KEY_r:
self.on_edit(view)
+ elif ctrl and key == Gdk.KEY_E or key == Gdk.KEY_e or key == Gdk.KEY_F2:
+ if model_name == self._BOUQUETS_LIST_NAME:
+ self.on_edit(view)
+ return
+ elif model_name == self._FAV_LIST_NAME:
+ self.on_locate_in_services(view)
+ self.on_services_data_edit(view)
elif key == Gdk.KEY_Left or key == Gdk.KEY_Right:
view.do_unselect_all(view)
@@ -714,7 +726,6 @@ class MainAppWindow:
open_data=self.open_data,
profile=Profile(self.__profile))
- @run_idle
def on_view_focus(self, view, focus_event):
profile = Profile(self.__profile)
model = get_base_model(view.get_model())
@@ -731,12 +742,21 @@ class MainAppWindow:
self.__tool_elements[elem].set_sensitive(not_empty)
else:
is_service = model_name == self._SERVICE_LIST_NAME
+ bq_selected = False
+ if model_name == self._FAV_LIST_NAME:
+ bq_selected = self.is_bouquet_selected()
+ if profile is Profile.NEUTRINO_MP and bq_selected:
+ name, bq_type = bq_selected.split(":")
+ bq_selected = BqType(bq_type) is BqType.WEBTV
+
for elem in self._FAV_ELEMENTS:
if elem in ("paste_tool_button", "paste_menu_item", "fav_paste_popup_item"):
self.__tool_elements[elem].set_sensitive(not is_service and self.__rows_buffer)
- elif elem in self._FAV_ONLY_ELEMENTS:
+ elif elem in self._FAV_ENIGMA_ELEMENTS:
if profile is Profile.ENIGMA_2:
- self.__tool_elements[elem].set_sensitive(self.is_bouquet_selected() and not is_service)
+ self.__tool_elements[elem].set_sensitive(bq_selected and not is_service)
+ elif elem in self._FAV_M3U_ELEMENTS:
+ self.__tool_elements[elem].set_sensitive(bq_selected and not is_service)
else:
self.__tool_elements[elem].set_sensitive(not_empty and not is_service)
for elem in self._SERVICE_ELEMENTS:
@@ -750,10 +770,10 @@ class MainAppWindow:
self.__tool_elements[elem].set_sensitive(not_empty)
def on_hide(self, item):
- self.set_service_flags(FLAG.HIDE)
+ self.set_service_flags(Flag.HIDE)
def on_locked(self, item):
- self.set_service_flags(FLAG.LOCK)
+ self.set_service_flags(Flag.LOCK)
def set_service_flags(self, flag):
profile = Profile(self.__profile)
@@ -766,9 +786,9 @@ class MainAppWindow:
elif profile is Profile.NEUTRINO_MP:
if bq_selected:
model, path = self.__bouquets_view.get_selection().get_selected()
- value = model.get_value(path, 1 if flag is FLAG.LOCK else 2)
- value = None if value else LOCKED_ICON if flag is FLAG.LOCK else HIDE_ICON
- model.set_value(path, 1 if flag is FLAG.LOCK else 2, value)
+ value = model.get_value(path, 1 if flag is Flag.LOCK else 2)
+ value = None if value else LOCKED_ICON if flag is Flag.LOCK else HIDE_ICON
+ model.set_value(path, 1 if flag is Flag.LOCK else 2, value)
@run_idle
def on_model_changed(self, model, path, itr=None):
@@ -811,7 +831,7 @@ class MainAppWindow:
show_dialog(DialogType.ERROR, self.__main_window, text="No m3u file is selected!")
return
- channels = parse_m3u(response)
+ channels = parse_m3u(response, Profile(self.__profile))
bq_selected = self.is_bouquet_selected()
if channels and bq_selected:
bq_services = self.__bouquets.get(bq_selected)
@@ -876,6 +896,11 @@ class MainAppWindow:
self.__services,
self.__bouquets)
+ @run_idle
+ def on_services_data_edit(self, item):
+ dialog = ServiceDetailsDialog(self.__main_window, self.__options, self.__services_view)
+ dialog.show()
+
@run_idle
def update_picons(self):
update_picons(self.__options.get(self.__profile).get("picons_dir_path"), self.__picons, self.__services_model)
diff --git a/app/ui/main_helper.py b/app/ui/main_helper.py
index a7cf51a2..c4dd2546 100644
--- a/app/ui/main_helper.py
+++ b/app/ui/main_helper.py
@@ -7,7 +7,7 @@ import shutil
from gi.repository import GdkPixbuf
from app.eparser import Service
-from app.eparser.ecommons import FLAG
+from app.eparser.ecommons import Flag
from app.eparser.enigma.bouquets import BqServiceType, to_bouquet_id
from . import Gtk, Gdk, HIDE_ICON, LOCKED_ICON
from .dialogs import show_dialog, DialogType, get_chooser_dialog
@@ -166,7 +166,7 @@ def set_flags(flag, services_view, fav_view, channels, blacklist):
model = get_base_model(model)
- if flag is FLAG.HIDE:
+ if flag is Flag.HIDE:
if target is ViewTarget.SERVICES:
set_hide(channels, model, paths)
else:
@@ -174,7 +174,7 @@ def set_flags(flag, services_view, fav_view, channels, blacklist):
srv_model = get_base_model(services_view.get_model())
srv_paths = [row.path for row in srv_model if row[18] in fav_ids]
set_hide(channels, srv_model, srv_paths)
- elif flag is FLAG.LOCK:
+ elif flag is Flag.LOCK:
set_lock(blacklist, channels, model, paths, target, services_model=get_base_model(services_view.get_model()))
return True
@@ -223,13 +223,13 @@ def set_hide(channels, model, paths):
value = int(flag[2:]) if flag else 0
if not hide:
- if value in FLAG.hide_values():
+ if value in Flag.hide_values():
continue # skip if already hidden
- value += FLAG.HIDE.value
+ value += Flag.HIDE.value
else:
- if value not in FLAG.hide_values():
+ if value not in Flag.hide_values():
continue # skip if already allowed to show
- value -= FLAG.HIDE.value
+ value -= Flag.HIDE.value
if value == 0 and index is not None:
del flags[index]
diff --git a/app/ui/main_window.glade b/app/ui/main_window.glade
index 74c50561..4ee4efb4 100644
--- a/app/ui/main_window.glade
+++ b/app/ui/main_window.glade
@@ -117,6 +117,11 @@
False
gtk-copy
+
+
+
+
+
+
+
-