From f67a79e86909dcb6f1643c5bf993c366f3e326d8 Mon Sep 17 00:00:00 2001 From: Dmitriy Yefremov Date: Tue, 16 Jan 2018 01:16:03 +0300 Subject: [PATCH] base implementation of picons parser --- app/picons/picons.py | 40 +++++++++++++++++++++++++------------- app/ui/picons_dialog.glade | 3 ++- app/ui/picons_dialog.py | 32 +++++++++++++++++++----------- 3 files changed, 49 insertions(+), 26 deletions(-) diff --git a/app/picons/picons.py b/app/picons/picons.py index 72d33e47..c7a50725 100644 --- a/app/picons/picons.py +++ b/app/picons/picons.py @@ -3,6 +3,7 @@ import shutil from collections import namedtuple from html.parser import HTMLParser +from app.commons import log from app.properties import Profile Provider = namedtuple("Provider", ["logo", "name", "url", "on_id", "selected"]) @@ -22,7 +23,7 @@ class PiconsParser(HTMLParser): self._is_th = False self._current_row = [] self._current_cell = [] - self.rows = [] + self.picons = [] def handle_starttag(self, tag, attrs): if tag == 'td': @@ -50,34 +51,44 @@ class PiconsParser(HTMLParser): elif tag == 'tr': row = self._current_row ln = len(row) - if ln == 10 and row[0].startswith("../logo/"): - self.rows.append((row[0], row[-4])) - elif ln == 11: - self.rows.append((row[0] if row[0].startswith("../logo/") else row[1], row[-4])) + if 9 < ln < 13: + url = None + if row[0].startswith("../logo/"): + url = row[0] + elif row[1].startswith("../logo/"): + url = row[1] + + ssid = row[-4] + if url and len(ssid) > 2: + self.picons.append(Picon(url, ssid, row[-3])) + self._current_row = [] def error(self, message): pass @staticmethod - def parse(open_path, picons_path, tmp_path): + def parse(open_path, picons_path, tmp_path, on_id): with open(open_path, encoding="utf-8", errors="replace") as f: parser = PiconsParser() parser.reset() parser.feed(f.read()) - rows = parser.rows - - if rows: + picons = parser.picons + if picons: os.makedirs(picons_path, exist_ok=True) - for r in rows: - shutil.copyfile(tmp_path + "www.lyngsat.com/" + r[0].lstrip("."), - picons_path + PiconsParser.format(r[1], Profile.ENIGMA_2)) + for p in picons: + try: + picon_file_name = picons_path + PiconsParser.format(p.ssid, on_id, p.v_pid, Profile.ENIGMA_2) + shutil.copyfile(tmp_path + "www.lyngsat.com/" + p.ref.lstrip("."), picon_file_name) + except (TypeError, ValueError) as e: + log("Picons format parse error: {} {} {}".format(p.ref, p.ssid, p.v_pid) + "\n" + str(e)) + print(e) @staticmethod - def format(ssid, profile: Profile): + def format(ssid, on_id, v_pid, profile: Profile): if profile is Profile.ENIGMA_2: tr_id = int(ssid[:-2] if len(ssid) < 4 else ssid[:2]) - return "1_0_1_{:X}_{:X}_{}_1680000_0_0_0.png".format(int(ssid), tr_id, "70") + return "1_0_{}_{:X}_{:X}_{:X}_1680000_0_0_0.png".format(1 if v_pid else 2, int(ssid), tr_id, int(on_id)) elif profile is Profile.NEUTRINO_MP: return "{:x}{}{:x}".format(int(ssid[:-2]), "0070", int(ssid)) else: @@ -134,6 +145,7 @@ class ProviderParser(HTMLParser): if len(row) == 12: on_id, sep, tid = str(row[-2]).partition("-") if tid and on_id not in self._ON_ID_BLACK_LIST and on_id not in self._ids: + row[-2] = on_id self.rows.append(row) self._ids.add(on_id) self._current_row = [] diff --git a/app/ui/picons_dialog.glade b/app/ui/picons_dialog.glade index 95f7cb89..2ad9a29d 100644 --- a/app/ui/picons_dialog.glade +++ b/app/ui/picons_dialog.glade @@ -23,7 +23,6 @@ False Picons download tool False - True True emblem-photos dialog @@ -80,6 +79,7 @@ True + False True network-transmit-receive-symbolic @@ -91,6 +91,7 @@ True + False True diff --git a/app/ui/picons_dialog.py b/app/ui/picons_dialog.py index 4ed0f6e6..667ddd8f 100644 --- a/app/ui/picons_dialog.py +++ b/app/ui/picons_dialog.py @@ -6,7 +6,7 @@ import time from gi.repository import GLib, GdkPixbuf from app.commons import run_idle, run_task -from app.picons.picons import PiconsParser, parse_providers +from app.picons.picons import PiconsParser, parse_providers, Provider from . import Gtk, Gdk, UI_RESOURCES_PATH from .main_helper import update_entry_data @@ -47,6 +47,7 @@ class PiconsDialog: self._info_bar = builder.get_object("info_bar") self._message_label = builder.get_object("info_bar_message_label") self._load_providers_tool_button = builder.get_object("load_providers_tool_button") + self._receive_tool_button = builder.get_object("receive_tool_button") # style self._style_provider = Gtk.CssProvider() self._style_provider.load_from_path(UI_RESOURCES_PATH + "style.css") @@ -82,12 +83,9 @@ class PiconsDialog: for p in providers: logo = self.get_pixbuf(p[0]) model.append((logo, p.name, p.url, p.on_id, p.selected)) + self.update_receive_button_state() def get_pixbuf(self, img_url): - # image = Gtk.Image() - # image.set_from_file(self._TMP_DIR + "www.lyngsat.com/" + img_url) - # image.size_allocate_with_baseline() - # return image.get_pixbuf() return GdkPixbuf.Pixbuf.new_from_file_at_scale(filename=self._TMP_DIR + "www.lyngsat.com/" + img_url, width=48, height=48, preserve_aspect_ratio=True) @@ -95,22 +93,24 @@ class PiconsDialog: def on_receive(self, item): self.start_download() + @run_task def start_download(self): self._expander.set_expanded(True) + + for prv in self.get_selected_providers(): + self.process_provider(Provider(*prv)) + + def process_provider(self, provider): + url = provider.url self.show_info_message("Please, wait...", Gtk.MessageType.INFO) - url = self._url_entry.get_text() self._current_process = subprocess.Popen(["wget", "-pkP", self._TMP_DIR, url], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) GLib.io_add_watch(self._current_process.stderr, GLib.IO_IN, self.write_to_buffer) - self.batch_rename(url) - - @run_task - def batch_rename(self, url): self._current_process.wait() path = self._TMP_DIR + self._BASE_URL + url[url.rfind("/") + 1:] - PiconsParser.parse(path, self._picons_path, self._TMP_DIR) + PiconsParser.parse(path, self._picons_path, self._TMP_DIR, provider.on_id) self.show_info_message("Done", Gtk.MessageType.INFO) def write_to_buffer(self, fd, condition): @@ -157,15 +157,25 @@ class PiconsDialog: def on_picons_dir_open(self, entry, icon, event_button): update_entry_data(entry, self._dialog, options={"data_dir_path": self._picons_path}) + @run_idle def on_selected_toggled(self, toggle, path): model = self._providers_tree_view.get_model() model.set_value(model.get_iter(path), 4, not toggle.get_active()) + self.update_receive_button_state() def on_url_changed(self, entry): suit = self._PATTERN.search(entry.get_text()) entry.set_name("GtkEntry" if suit else "digit-entry") self._load_providers_tool_button.set_sensitive(suit if suit else False) + @run_idle + def update_receive_button_state(self): + self._receive_tool_button.set_sensitive(len(self.get_selected_providers()) > 0) + + def get_selected_providers(self): + """ returns selected providers """ + return [r for r in self._providers_tree_view.get_model() if r[4]] + if __name__ == "__main__": pass