name space for picons

This commit is contained in:
Dmitriy Yefremov
2018-02-04 18:09:37 +03:00
parent f19ab37bc8
commit cb40a8d0de
4 changed files with 65 additions and 84 deletions

View File

@@ -7,11 +7,11 @@ from app.commons import log
from app.properties import Profile
_ENIGMA2_PICON_NAME = "1_0_{}_{:X}_{:X}_{:X}_1680000_0_0_0.png"
_ENIGMA2_PICON_NAME = "1_0_{}_{:X}_{:X}_{:X}_{:X}0000_0_0_0.png"
_NEUTRINO_PICON_NAME = "{:x}{:04x}{:04x}.png"
Provider = namedtuple("Provider", ["logo", "name", "url", "on_id", "selected"])
Provider = namedtuple("Provider", ["logo", "name", "pos", "url", "on_id", "selected"])
Picon = namedtuple("Picon", ["ref", "ssid", "v_pid"])
@@ -73,7 +73,7 @@ class PiconsParser(HTMLParser):
pass
@staticmethod
def parse(open_path, picons_path, tmp_path, on_id, profile=Profile.ENIGMA_2):
def parse(open_path, picons_path, tmp_path, on_id, pos, profile=Profile.ENIGMA_2):
with open(open_path, encoding="utf-8", errors="replace") as f:
parser = PiconsParser()
parser.reset()
@@ -83,17 +83,17 @@ class PiconsParser(HTMLParser):
os.makedirs(picons_path, exist_ok=True)
for p in picons:
try:
picon_file_name = picons_path + PiconsParser.format(p.ssid, on_id, p.v_pid, profile)
picon_file_name = picons_path + PiconsParser.format(p.ssid, on_id, p.v_pid, pos, profile)
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, on_id, v_pid, profile: Profile):
def format(ssid, on_id, v_pid, pos, profile: Profile):
tr_id = int(ssid[:-2] if len(ssid) < 4 else ssid[:2])
if profile is Profile.ENIGMA_2:
return _ENIGMA2_PICON_NAME.format(1 if v_pid else 2, int(ssid), tr_id, int(on_id))
return _ENIGMA2_PICON_NAME.format(1 if v_pid else 2, int(ssid), tr_id, int(on_id), int(pos))
elif profile is Profile.NEUTRINO_MP:
return _NEUTRINO_PICON_NAME.format(tr_id, int(on_id), int(ssid))
else:
@@ -117,6 +117,8 @@ class ProviderParser(HTMLParser):
self._current_cell = []
self.rows = []
self._ids = set()
self._counter = 0
self._positon = None
def handle_starttag(self, tag, attrs):
if tag == 'td':
@@ -147,27 +149,39 @@ class ProviderParser(HTMLParser):
self._current_cell = []
elif tag == 'tr':
row = self._current_row
# Satellite position
self._counter = self._counter + 1
if self._counter == 12:
pos = str(row)
pos = pos[pos.rfind("at") + 2:]
self._positon = "".join(c for c in pos if c.isalnum() or c == ".")
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)
row[0] = self._positon
self._current_row = []
def error(self, message):
pass
def reset_counter(self):
self._counter = 0
def parse_providers(open_path):
with open(open_path, encoding="utf-8", errors="replace") as f:
parser = ProviderParser()
parser.reset()
parser.reset_counter()
parser.feed(f.read())
rows = parser.rows
if rows:
return [Provider(logo=r[2], name=r[5], url=r[6], on_id=r[-2], selected=True) for r in rows]
return [Provider(logo=r[2], name=r[5], pos=r[0], url=r[6], on_id=r[-2], selected=True) for r in rows]
if __name__ == "__main__":

View File

@@ -658,8 +658,8 @@ class MainAppWindow:
response = show_settings_dialog(self.__main_window, self.__options)
if response != Gtk.ResponseType.CANCEL:
profile = self.__options.get("profile")
if profile != self.__profile:
self.__status_bar.push(0, "Current IP: " + self.__options.get(profile).get("host"))
if profile != self.__profile:
self.__profile_label.set_text("Enigma 2 v.4" if Profile(profile) is Profile.ENIGMA_2 else "Neutrino-MP")
self.__profile = profile
self.clear_current_data()
@@ -837,8 +837,7 @@ class MainAppWindow:
locate_in_services(view, self.__services_view, self.__main_window)
def on_picons_loader_show(self, item):
pos = {r[16] for r in self.__services_model}
dialog = PiconsDialog(self.__main_window, self.__options.get(self.__profile), pos, Profile(self.__profile))
dialog = PiconsDialog(self.__main_window, self.__options.get(self.__profile), Profile(self.__profile))
dialog.show()
self.update_picons()

View File

@@ -9,6 +9,8 @@
<column type="GdkPixbuf"/>
<!-- column-name name -->
<column type="gchararray"/>
<!-- column-name pos -->
<column type="gchararray"/>
<!-- column-name url -->
<column type="gchararray"/>
<!-- column-name on_id -->
@@ -17,12 +19,6 @@
<column type="gboolean"/>
</columns>
</object>
<object class="GtkListStore" id="sat_position_list_store">
<columns>
<!-- column-name pos -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkDialog" id="picons_dialog">
<property name="width_request">480</property>
<property name="can_focus">False</property>
@@ -383,55 +379,6 @@
<property name="position">6</property>
</packing>
</child>
<child>
<object class="GtkBox" id="position_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">2</property>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">5</property>
<property name="label" translatable="yes">Satellite position: </property>
<property name="xalign">0.019999999552965164</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="position_combo_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">sat_position_list_store</property>
<property name="active">0</property>
<property name="id_column">0</property>
<child>
<object class="GtkCellRendererText" id="pos_cellrenderertext"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<style>
<class name="primary-toolbar"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">8</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="providers_scrolled_window">
<property name="height_request">150</property>
@@ -467,14 +414,29 @@
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="pos_column">
<property name="title" translatable="yes">Position</property>
<child>
<object class="GtkCellRendererText" id="pos_cellrenderertext1">
<property name="xalign">0.50999999046325684</property>
<property name="editable">True</property>
<signal name="edited" handler="on_position_edited" swapped="no"/>
</object>
<attributes>
<attribute name="text">2</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="url_column">
<property name="visible">False</property>
<property name="title" translatable="yes">Url</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext1"/>
<object class="GtkCellRendererText" id="url_cellrenderertext"/>
<attributes>
<attribute name="text">2</attribute>
<attribute name="text">3</attribute>
</attributes>
</child>
</object>
@@ -484,9 +446,9 @@
<property name="visible">False</property>
<property name="title" translatable="yes">ONID</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext2"/>
<object class="GtkCellRendererText" id="onid_cellrenderertext"/>
<attributes>
<attribute name="text">3</attribute>
<attribute name="text">4</attribute>
</attributes>
</child>
</object>
@@ -499,7 +461,7 @@
<signal name="toggled" handler="on_selected_toggled" swapped="no"/>
</object>
<attributes>
<attribute name="active">4</attribute>
<attribute name="active">5</attribute>
</attributes>
</child>
</object>
@@ -747,4 +709,10 @@
</object>
</child>
</object>
<object class="GtkListStore" id="sat_position_list_store">
<columns>
<!-- column-name pos -->
<column type="gchararray"/>
</columns>
</object>
</interface>

View File

@@ -15,7 +15,7 @@ from .main_helper import update_entry_data
class PiconsDialog:
def __init__(self, transient, options, sat_positions, profile=Profile.ENIGMA_2):
def __init__(self, transient, options, profile=Profile.ENIGMA_2):
self._TMP_DIR = tempfile.gettempdir() + "/"
self._BASE_URL = "www.lyngsat.com/packages/"
self._PATTERN = re.compile("^https://www\.lyngsat\.com/[\w-]+\.html$")
@@ -31,12 +31,12 @@ class PiconsDialog:
"on_info_bar_close": self.on_info_bar_close,
"on_picons_dir_open": self.on_picons_dir_open,
"on_selected_toggled": self.on_selected_toggled,
"on_url_changed": self.on_url_changed}
"on_url_changed": self.on_url_changed,
"on_position_edited": self.on_position_edited}
builder = Gtk.Builder()
builder.add_objects_from_file(UI_RESOURCES_PATH + "picons_dialog.glade",
("picons_dialog", "receive_image", "providers_list_store",
"sat_position_list_store"))
("picons_dialog", "receive_image", "providers_list_store"))
builder.connect_signals(handlers)
self._dialog = builder.get_object("picons_dialog")
self._dialog.set_transient_for(transient)
@@ -58,10 +58,6 @@ class PiconsDialog:
self._resize_no_radio_button = builder.get_object("resize_no_radio_button")
self._resize_220_132_radio_button = builder.get_object("resize_220_132_radio_button")
self._resize_100_60_radio_button = builder.get_object("resize_100_60_radio_button")
self._position_combo_box = builder.get_object("position_combo_box")
self._sat_position_list_store = builder.get_object("sat_position_list_store")
for pos in sat_positions:
self._sat_position_list_store.append((pos,))
# style
self._style_provider = Gtk.CssProvider()
self._style_provider.load_from_path(UI_RESOURCES_PATH + "style.css")
@@ -98,8 +94,7 @@ class PiconsDialog:
providers = parse_providers(self._TMP_DIR + url[url.find("w"):])
if providers:
for p in providers:
logo = self.get_pixbuf(p[0])
model.append((logo, p.name, p.url, p.on_id, p.selected))
model.append((self.get_pixbuf(p[0]), p.name, p.pos, p.url, p.on_id, p.selected))
self.update_receive_button_state()
def get_pixbuf(self, img_url):
@@ -124,8 +119,8 @@ class PiconsDialog:
break
self.process_provider(Provider(*prv))
def process_provider(self, provider):
url = provider.url
def process_provider(self, prv):
url = prv.url
self.show_info_message("Please, wait...", Gtk.MessageType.INFO)
self._current_process = subprocess.Popen(["wget", "-pkP", self._TMP_DIR, url],
stdout=subprocess.PIPE,
@@ -134,7 +129,8 @@ class PiconsDialog:
GLib.io_add_watch(self._current_process.stderr, GLib.IO_IN, self.write_to_buffer)
self._current_process.wait()
path = self._TMP_DIR + self._BASE_URL + url[url.rfind("/") + 1:]
PiconsParser.parse(path, self._picons_path, self._TMP_DIR, provider.on_id, self.get_picons_format())
pos = "".join(c for c in prv.pos if c.isdigit())
PiconsParser.parse(path, self._picons_path, self._TMP_DIR, prv.on_id, pos, self.get_picons_format())
self.resize(self._picons_path)
self.show_info_message("Done", Gtk.MessageType.INFO)
@@ -211,7 +207,7 @@ class PiconsDialog:
@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())
model.set_value(model.get_iter(path), 5, not toggle.get_active())
self.update_receive_button_state()
def on_url_changed(self, entry):
@@ -219,6 +215,10 @@ class PiconsDialog:
entry.set_name("GtkEntry" if suit else "digit-entry")
self._load_providers_tool_button.set_sensitive(suit if suit else False)
def on_position_edited(self, render, path, value):
model = self._providers_tree_view.get_model()
model.set_value(model.get_iter(path), 2, value)
@run_idle
def update_receive_button_state(self):
self._receive_tool_button.set_sensitive(len(self.get_selected_providers()) > 0)