diff --git a/app/eparser/iptv.py b/app/eparser/iptv.py
index c40ed203..342dbbd7 100644
--- a/app/eparser/iptv.py
+++ b/app/eparser/iptv.py
@@ -1,20 +1,29 @@
+""" Module for m3u import """
+from app.properties import Profile
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)
+ 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(*aggr[0:3], name, *aggr[0:3], BqServiceType.IPTV.name, *aggr, fav_id, None)
channels.append(srv)
diff --git a/app/eparser/neutrino/bouquets.py b/app/eparser/neutrino/bouquets.py
index ebfb2c4a..2af40aab 100644
--- a/app/eparser/neutrino/bouquets.py
+++ b/app/eparser/neutrino/bouquets.py
@@ -2,6 +2,7 @@ import os
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
@@ -76,7 +77,8 @@ def parse_webtv(path, name, bq_type):
if elem.hasAttributes():
title = elem.attributes["title"].value
url = elem.attributes["url"].value
- description = elem.attributes["description"].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)
@@ -93,8 +95,8 @@ def parse_webtv(path, name, bq_type):
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 = "{}::{}::{}::{}::{}::{}::{}::{}::{}::{}".format(url, description, urlkey, account, usrname,
- psw, s_type, iconsrc, iconsrc_b, 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,
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/dialogs.glade b/app/ui/dialogs.glade
index c0349d35..47c09607 100644
--- a/app/ui/dialogs.glade
+++ b/app/ui/dialogs.glade
@@ -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 5c2e5d2f..780ea65a 100644
--- a/app/ui/main_app_window.py
+++ b/app/ui/main_app_window.py
@@ -821,7 +821,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)