diff --git a/README.md b/README.md index 7d4e30c9..e82176a3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,19 @@ # DemonEditor -Enigma2 channel and satellites list editor for GNU/Linux +Enigma2 channel and satellites list editor for GNU/Linux. +Focused on the convenience of working in lists from the keyboard. +The mouse is also fully supported (Drag and Drop etc) + +Keyboard shortcuts currently supported: Ctrl + X, C, V, Up, Down, PageUp, PageDown, S, T, E; Insert, Delete, F2. +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! +F2 - rename the bouquet. +Ctrl + S, T, E in Satellites edit tool for create and edit satellite or transponder + +Terrestrial and cable channels at the moment are not supported! + +Tested only on OpenPLi based image with GM 990 Spark Reloaded receiver +in my preferred linux distro (Linux Mint 18.2 "Sonya" - MATE 64-bit)! + +Minimum requirements: Python >= 3.5.2 and GTK+ 3 with PyGObject bindings. diff --git a/app/ftp.py b/app/ftp.py index d9853a1f..0238e565 100644 --- a/app/ftp.py +++ b/app/ftp.py @@ -1,8 +1,9 @@ +import os +import socket +import time from enum import Enum from ftplib import FTP - -import os - +from telnetlib import Telnet __DATA_FILES_LIST = ("tv", "radio", "lamedb") @@ -14,7 +15,7 @@ class DownloadDataType(Enum): def download_data(*, properties, download_type=DownloadDataType.ALL): - with FTP(host=properties["host"], timeout=5) as ftp: + with FTP(host=properties["host"]) as ftp: ftp.login(user=properties["user"], passwd=properties["password"]) save_path = properties["data_dir_path"] files = [] @@ -27,8 +28,8 @@ def download_data(*, properties, download_type=DownloadDataType.ALL): 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) + 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: ftp.cwd(properties["satellites_xml_path"]) @@ -40,14 +41,20 @@ def download_data(*, properties, download_type=DownloadDataType.ALL): 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) + ftp.retrbinary("RETR " + xml_file, f.write) def upload_data(*, properties, download_type=DownloadDataType.ALL, remove_unused=False): data_path = properties["data_dir_path"] + host = properties["host"] + # telnet + tn = telnet(host=host) + next(tn) - with FTP(host=properties["host"], timeout=5) as ftp: + with FTP(host=host) as ftp: ftp.login(user=properties["user"], passwd=properties["password"]) + # terminate enigma + tn.send("init 4") if download_type is DownloadDataType.ALL or download_type is DownloadDataType.SATELLITES: ftp.cwd(properties["satellites_xml_path"]) @@ -70,7 +77,9 @@ def upload_data(*, properties, download_type=DownloadDataType.ALL, remove_unused for file_name in os.listdir(data_path): if file_name == "satellites.xml": continue - send_file(file_name, data_path, ftp) + file_name, send_file(file_name, data_path, ftp) + # resume enigma + tn.send("init 3") def send_file(file_name, path, ftp): @@ -79,3 +88,23 @@ def send_file(file_name, path, ftp): return ftp.storbinary("STOR " + file_name, f) +def telnet(host, port=23, user="root", password="root", timeout=2): + try: + tn = Telnet(host=host, port=port, timeout=timeout) + except socket.timeout: + print("socket timeout") + else: + time.sleep(1) + command = yield + tn.write("{}\r\n".format(command).encode("utf-8")) + time.sleep(timeout) + command = yield + time.sleep(timeout) + tn.write("{}\r\n".format(command).encode("utf-8")) + time.sleep(timeout) + tn.close() + yield + + +if __name__ == "__main__": + pass diff --git a/app/ui/main_app_window.py b/app/ui/main_app_window.py index e2582151..68486bec 100644 --- a/app/ui/main_app_window.py +++ b/app/ui/main_app_window.py @@ -349,6 +349,15 @@ class MainAppWindow: """ Iterate through model and updates values for Num column """ model.foreach(lambda store, pth, itr: store.set_value(itr, 0, int(pth[0]) + 1)) # iter , column, value + def update_bouquet_list(self): + """ Update bouquet after move items """ + bq_selected = self.is_bouquet_selected() + if bq_selected: + fav_bouquet = self.__bouquets[bq_selected] + fav_bouquet.clear() + for row in self.__fav_model: + fav_bouquet.append(row[4]) + def on_services_tree_view_drag_data_get(self, view, drag_context, data, info, time): """ DnD """ data.set_text(self.get_selection(view), -1) @@ -500,6 +509,7 @@ class MainAppWindow: self.move_items(key) elif model_name == self._FAV_LIST_NAME and key == Gdk.KEY_Control_L or key == Gdk.KEY_Control_R: self.update_fav_num_column(view.get_model()) + self.update_bouquet_list() elif key == Gdk.KEY_Insert: # Move items from app to fav list if model_name == self._SERVICE_LIST_NAME: