diff --git a/README.md b/README.md
index 399cdaf4..7d4e30c9 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,2 @@
# DemonEditor
-Enigma2 channel list editor for GNU/Linux
+Enigma2 channel and satellites list editor for GNU/Linux
diff --git a/main/eparser/__constants.py b/main/eparser/__constants.py
index 5b3ffa9f..49618ece 100644
--- a/main/eparser/__constants.py
+++ b/main/eparser/__constants.py
@@ -28,5 +28,5 @@ SYSTEM = {"0": "DVB-S", "1": "DVB-S2"}
MODULATION = {"0": "Auto", "1": "QPSK", "2": "8PSK", "3": "16APSK", "5": "32APSK"}
SERVICE_TYPE = {-2: "Unknown", 1: "TV", 2: "Radio", 3: "Data",
- 10: "Radio", 12: "Data", 22: "TV", 25: "TV",
+ 10: "Radio", 12: "Data", 22: "TV", 25: "TV (HD)",
136: "Data", 139: "Data"}
diff --git a/main/eparser/__init__.py b/main/eparser/__init__.py
index f97e5428..eeda3569 100644
--- a/main/eparser/__init__.py
+++ b/main/eparser/__init__.py
@@ -1,5 +1,5 @@
-from .lamedb import get_channels
-from .bouquets import get_bouquets, get_bouquet
+from .lamedb import get_channels, write_channels
+from .bouquets import get_bouquets, get_bouquet, write_bouquet
from .satxml import get_satellites, write_satellites, Satellite, Transponder
diff --git a/main/eparser/bouquets.py b/main/eparser/bouquets.py
index 140ea4a5..4a4c68ce 100644
--- a/main/eparser/bouquets.py
+++ b/main/eparser/bouquets.py
@@ -3,20 +3,30 @@ from collections import namedtuple
__BOUQUETS_PATH = "../data/"
-Bouquet = namedtuple("Bouquet", ["name", "type"])
+Bouquet = namedtuple("Bouquet", ["name", "type", "services"])
Bouquets = namedtuple("Bouquets", ["name", "bouquets"])
def get_bouquets(path):
- return [parse_bouquets(path, "bouquets.tv"), parse_bouquets(path, "bouquets.radio")]
+ return parse_bouquets(path, "bouquets.tv", "tv"), parse_bouquets(path, "bouquets.radio", "radio")
-def write_bouquets(path, channels):
- pass
+def write_bouquet(path, name, channels):
+ bouquet = ["#NAME {}\n".format(name)]
+ for ch in channels:
+ data_type = int(ch.data_id.split(":")[-2])
+ if data_type == 22:
+ data_type = 16
+ elif data_type == 25:
+ data_type = 19
+ bouquet.append("#SERVICE {}:0:{}:{}:0:0:0:\n".format(1, data_type, ch.fav_id))
+ with open(path + "_userbouquet.{}.tv".format(name), "w") as file:
+ file.writelines(bouquet)
-def get_bouquet(path, name, type):
- with open(path + "userbouquet.{}.{}".format(name, str(type))) as file:
+def get_bouquet(path, name, bq_type):
+ """ Parsing services ids from bouquet file """
+ with open(path + "userbouquet.{}.{}".format(name, bq_type)) as file:
chs_list = file.read()
ids = []
for ch in chs_list.split("#SERVICE")[1:]:
@@ -25,8 +35,8 @@ def get_bouquet(path, name, type):
return ids
-def parse_bouquets(path, name):
- with open(path + name) as file:
+def parse_bouquets(path, bq_name, bq_type):
+ with open(path + bq_name) as file:
lines = file.readlines()
bouquets = None
nm_sep = "#NAME"
@@ -34,8 +44,9 @@ def parse_bouquets(path, name):
if nm_sep in line:
_, _, name = line.partition(nm_sep)
bouquets = Bouquets(name.strip(), [])
- if bouquets is not None and "#SERVICE" in line:
- bouquets[1].append(line.split(".")[1])
+ if bouquets and "#SERVICE" in line:
+ name = line.split(".")[1]
+ bouquets[1].append(Bouquet(name=name, type=bq_type, services=get_bouquet(path, name, bq_type)))
return bouquets
diff --git a/main/eparser/lamedb.py b/main/eparser/lamedb.py
index 2b92ae35..257fdff2 100644
--- a/main/eparser/lamedb.py
+++ b/main/eparser/lamedb.py
@@ -14,6 +14,10 @@ def get_channels(path):
return parse(path)
+def write_channels(path, channels):
+ print(channels)
+
+
def parse(path):
""" Parsing lamedb """
with open(path, "r") as file:
diff --git a/main/ui/main_app_window.py b/main/ui/main_app_window.py
index 7e68202b..10e36f0e 100644
--- a/main/ui/main_app_window.py
+++ b/main/ui/main_app_window.py
@@ -1,7 +1,6 @@
from threading import Thread
-from main.eparser import get_channels, get_bouquets, get_bouquet
-from main.eparser.__constants import SERVICE_TYPE
+from main.eparser import get_channels, get_bouquets, write_bouquet, write_channels
from main.ftp import download_data, upload_data
from main.properties import get_config, write_config
from . import Gtk, Gdk
@@ -26,6 +25,7 @@ __bouquets_view = None
# Clearing only after the insertion!
__rows_buffer = []
__channels = {}
+__bouquets = {}
def on_about_app(item):
@@ -121,6 +121,11 @@ def on_delete(item):
model.remove(itr)
if model.get_name() == FAV_LIST_NAME:
update_fav_num_column(model)
+ if model.get_name() == SERVICE_LIST_NAME:
+ for row in rows:
+ # There are channels with the same parameters except for the name.
+ # None because it can have duplicates! Need fix
+ __channels.pop(row[-1], None)
return rows
@@ -222,11 +227,13 @@ def data_open(model):
__channels[ch.fav_id] = ch
model.append(ch)
if model_name == BOUQUETS_LIST_NAME:
- data = get_bouquets(data_path)
- for name, bouquets in data:
- parent = model.append(None, [name])
- for bouquet in bouquets:
- model.append(parent, [bouquet])
+ bouquets = get_bouquets(data_path)
+ for bouquet in bouquets:
+ parent = model.append(None, [bouquet.name, None])
+ for bt in bouquet.bouquets:
+ name, bt_type = bt.name, bt.type
+ model.append(parent, [name, bt_type])
+ __bouquets["{}:{}".format(name, bt_type)] = bt.services
except Exception as e:
__status_bar.push(1, getattr(e, "message", repr(e)))
@@ -239,12 +246,15 @@ def on_data_open(model):
def on_data_save(*args):
# Perhaps needs a dialog to choose what we need to save!!!
- if is_bouquet_selected() and __fav_view.is_focus(): # bouquets
+ bouquet_name = is_bouquet_selected()
+ path = __options["data_dir_path"]
+ if bouquet_name and __fav_view.is_focus(): # bouquets
fav_ids = []
- __fav_model.foreach(lambda model, path, itr: fav_ids.append(model.get(model.get_iter(path), 4)))
- print(fav_ids)
+ __fav_model.foreach(lambda model, p, itr: fav_ids.append(model.get(model.get_iter(p), 4)))
+ channels = [__channels[fav_id[0]] for fav_id in fav_ids]
+ write_bouquet(path, bouquet_name, channels)
elif __services_view.is_focus():
- pass
+ write_channels(path, __channels.values())
def on_services_selection(model, path, column):
@@ -259,22 +269,30 @@ def on_bouquets_selection(model, path, column):
__fav_model.clear()
if len(path) > 1:
delete_selection(__services_view)
- tree_iter = model.get_iter(path)
- name = model.get_value(tree_iter, 0)
- # 'tv' Temporary! It is necessary to implement a row type attribute.
- bq = get_bouquet(__options["data_dir_path"], name, SERVICE_TYPE[1].lower())
- for num, ch_id in enumerate(bq):
- channel = __channels.get(ch_id, None)
+ update_bouquet_channels(model, path)
+
+
+def update_bouquet_channels(model, path):
+ """ Updates list of bouquet channels """
+ tree_iter = model.get_iter(path)
+ key = "{}:{}".format(*model.get(tree_iter, 0, 1))
+ services = __bouquets[key]
+ for num, ch_id in enumerate(services):
+ channel = __channels.get(ch_id, None)
+ if channel:
__fav_model.append((num + 1, channel.service, channel.service_type, channel.pos, channel.fav_id))
def is_bouquet_selected():
- """ Checks whether the bouquet is selected """
+ """ Checks whether the bouquet is selected
+
+ returns name of selected bouquet or False
+ """
selection = __bouquets_view.get_selection()
model, path = selection.get_selected_rows()
- if len(path) < 1:
+ if len(path) < 1 or model.iter_has_child(model.get_iter(path)):
return False
- return not model.iter_has_child(model.get_iter(path))
+ return model.get_value(model.get_iter(path), 0)
def show_message_dialog(text):
diff --git a/main/ui/main_window.glade b/main/ui/main_window.glade
index 8f12d935..b28d0376 100644
--- a/main/ui/main_window.glade
+++ b/main/ui/main_window.glade
@@ -29,6 +29,8 @@
+
+
True
- False
+ True
@@ -969,22 +991,36 @@
True
+ autosize
Bouquets
True
-
+
0
+
+
+ True
+ autosize
+ Type
+
+
+
+ 1
+
+
+
+
True
- True
+ False
@@ -1043,7 +1079,7 @@
0.1 Pre-alpha
2017 Dmitriy Yefremov
- Enigma2 channel list editor for GNU/Linux
+ Enigma2 channel and satellites list editor for GNU/Linux
Dmitriy Yefremov
accessories-text-editor