new variant of satellites download skeleton

This commit is contained in:
Dmitriy Yefremov
2018-04-25 17:26:29 +03:00
parent 7f096df998
commit f9239f0642
10 changed files with 879 additions and 907 deletions

View File

@@ -5,17 +5,17 @@ Experimental support of Neutrino-MP or others on the same basis (BPanther, etc).
Focused on the convenience of working in lists from the keyboard. The mouse is also fully supported (Drag and Drop etc)
### Keyboard shortcuts:
#### Ctrl + X, C, V, Up, Down, PageUp, PageDown, Home, End, S, T, E, L, H, Space; 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.
**Ctrl + X, C, V, Up, Down, PageUp, PageDown, Home, End, S, T, E, L, H, Space; 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!
Ctrl + E - edit.
Ctrl + R, F2 - rename.
Ctrl + S, T in Satellites edit tool for create satellite or transponder.
Ctrl + L - parental lock.
Ctrl + H - hide/skip.
Space - select/deselect.
Left/Right - remove selection.
*Ctrl + E* - edit.
*Ctrl + R, F2* - rename.
*Ctrl + S, T* in Satellites edit tool for create satellite or transponder.
*Ctrl + L* - parental lock.
*Ctrl + H* - hide/skip.
*Space* - select/deselect.
*Left/Right* - remove selection.
### Extra:
Multiple selections in lists only with Space key (as in file managers).
@@ -29,6 +29,6 @@ To create a simple debian package, you can use the build-deb.sh
Tests only in image based on OpenPLi or last BPanther(neutrino) images with GM 990 Spark Reloaded receiver
in my preferred linux distro (Last Linux Mint 18.* - MATE 64-bit)!
#### Terrestrial and cable channels at the moment are not supported!
**Terrestrial and cable channels at the moment are not supported!**

View File

@@ -5,9 +5,12 @@ import requests
from html.parser import HTMLParser
from app.commons import run_task
from app.eparser import Satellite, Transponder
class SatellitesParser(HTMLParser):
""" Parser for satellite html page. (https://www.lyngsat.com/*sat-name*.html) """
""" Parser for satellite html page. """
_HEADERS = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:45.0) Gecko/20100101 Firefox/59.02"}
@@ -56,18 +59,65 @@ class SatellitesParser(HTMLParser):
def error(self, message):
pass
def get_satellites(self):
@run_task
def get_satellites(self, callback):
self.reset()
request = requests.get(url=self._url, headers=self._HEADERS)
reason = request.reason
satellites = []
if reason == "OK":
self.feed(request.text)
if self._rows:
return list(filter(lambda x: all(x) and len(x) == 5, self._rows))
for sat in list(filter(lambda x: all(x) and len(x) == 5, self._rows)):
if callback(self.get_satellite(sat)):
break
else:
print(reason)
return satellites
def get_satellite(self, sat):
pos = "".join(c for c in sat[2] if c.isdigit() or c.isalpha() or c == ".")
return Satellite(name=sat[1] + " ({})".format(pos),
flags="0",
position=self.get_position(pos.replace(".", "")),
transponders=self.get_transponders(sat[0]))
def get_position(self, pos):
return "{}{}".format("-" if pos[-1] == "W" else "", pos[:-1])
def get_transponders(self, sat_url):
self._rows.clear()
url = "https://www.flysat.com/" + sat_url
request = requests.get(url=url, headers=self._HEADERS)
reason = request.reason
trs = []
if reason == "OK":
self.feed(request.text)
if self._rows:
zeros = "000"
for r in self._rows:
if len(r) < 3:
continue
data = r[2].split(" ")
if len(data) != 2:
continue
sr, fec = data
data = r[1].split(" ")
if len(data) < 3:
continue
freq, pol, tr_type = data[0], data[1], data[2]
tr_type = tr_type.split("/")
if len(tr_type) != 2:
continue
tr_type, mod = tr_type
mod = "QPSK" if tr_type == "DVB-S" else mod
trs.append(Transponder(freq + zeros, sr + zeros, pol, fec, tr_type, mod, None, None, None))
return trs
if __name__ == "__main__":
parser = SatellitesParser(url="https://www.flysat.com/satlist.php")
parser.get_satellites()
pass

View File

@@ -19,8 +19,7 @@ from .download_dialog import show_download_dialog
from .main_helper import edit_marker, insert_marker, move_items, rename, ViewTarget, set_flags, locate_in_services, \
scroll_to, get_base_model, update_picons, copy_picon_reference, assign_picon, remove_picon, \
is_only_one_item_selected, gen_bouquets, BqGenType
from .tools.picons_downloader import PiconsDialog
from .tools.satellites_downloader import SatellitesDownloaderDialog
from .picons_downloader import PiconsDialog
from .satellites_dialog import show_satellites_dialog
from .settings_dialog import show_settings_dialog
from .service_details_dialog import ServiceDetailsDialog, Action
@@ -105,7 +104,6 @@ class MainAppWindow:
"on_fav_popup": self.on_fav_popup,
"on_locate_in_services": self.on_locate_in_services,
"on_picons_loader_show": self.on_picons_loader_show,
"on_satellites_downloader_show": self.on_satellites_downloader_show,
"on_filter_changed": self.on_filter_changed,
"on_assign_picon": self.on_assign_picon,
"on_remove_picon": self.on_remove_picon,
@@ -931,10 +929,6 @@ class MainAppWindow:
dialog.show()
self.update_picons()
@run_idle
def on_satellites_downloader_show(self, item):
SatellitesDownloaderDialog(self._main_window, self._options).show()
@run_idle
def on_filter_toggled(self, toggle_button: Gtk.ToggleToolButton):
self._filter_info_bar.set_visible(toggle_button.get_active())

View File

@@ -122,11 +122,6 @@
<property name="can_focus">False</property>
<property name="stock">gtk-save-as</property>
</object>
<object class="GtkImage" id="image10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-goto-bottom</property>
</object>
<object class="GtkImage" id="image4">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -798,22 +793,6 @@
<signal name="activate" handler="on_satellite_editor_show" swapped="no"/>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="satellites_downloader_menu_item">
<property name="label" translatable="yes">Satellites downloader</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="image">image10</property>
<property name="use_stock">False</property>
<signal name="activate" handler="on_satellites_downloader_show" swapped="no"/>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem" id="tools_separatormenuitem1">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
<child>
<object class="GtkImageMenuItem" id="picons_downloader_menu_item">
<property name="label" translatable="yes">Picons downloader</property>

View File

@@ -839,271 +839,4 @@
<column type="gchararray"/>
</columns>
</object>
<object class="GtkListStore" id="satellites_list_store">
<columns>
<!-- column-name name -->
<column type="gchararray"/>
<!-- column-name pos -->
<column type="gchararray"/>
<!-- column-name type -->
<column type="gchararray"/>
<!-- column-name url -->
<column type="gchararray"/>
<!-- column-name selected -->
<column type="gboolean"/>
</columns>
</object>
<object class="GtkListStore" id="source_urls_list_store">
<columns>
<!-- column-name source -->
<column type="gchararray"/>
</columns>
<data>
<row>
<col id="0">FlySat</col>
</row>
</data>
</object>
<object class="GtkDialog" id="satellites_dialog">
<property name="width_request">480</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">Satellites download tool</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="destroy_with_parent">True</property>
<property name="type_hint">dialog</property>
<property name="skip_pager_hint">True</property>
<child internal-child="vbox">
<object class="GtkBox" id="satellites_dialog_vbox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="satellites_dialog_action_area">
<property name="can_focus">False</property>
<property name="layout_style">center</property>
<child>
<object class="GtkButton" id="button2">
<property name="label">gtk-close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="satelittes_dialog_main_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkBox" id="source_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="spacing">2</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Source:</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="source_combo_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="model">source_urls_list_store</property>
<property name="active">0</property>
<child>
<object class="GtkCellRendererText" id="source_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>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSeparator" id="sat_separator_2">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="satellites_tree_view_scrolledwindow">
<property name="height_request">150</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="satellites_tree_view">
<property name="height_request">100</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">satellites_list_store</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection2"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="satellite_column">
<property name="title" translatable="yes">Satellite</property>
<child>
<object class="GtkCellRendererText" id="satellite_name_cellrenderertext"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="satellite_pos_column">
<property name="title" translatable="yes">Position</property>
<child>
<object class="GtkCellRendererText" id="satellite_position_cellrenderertext"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="satellite_type_column">
<property name="title" translatable="yes">Type</property>
<child>
<object class="GtkCellRendererText" id="satellite_type_cellrenderertext"/>
<attributes>
<attribute name="text">2</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="sat_url_column">
<property name="title" translatable="yes">Url</property>
<child>
<object class="GtkCellRendererText" id="satellite_url_cellrenderertext"/>
<attributes>
<attribute name="text">3</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="sat_selected_column">
<property name="title" translatable="yes">Selected</property>
<child>
<object class="GtkCellRendererToggle" id="satellite_selected_cellrenderertoggle"/>
<attributes>
<attribute name="activatable">4</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkSeparator" id="sat_separator">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkToolbar" id="satellites_dialog_toolbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_arrow">False</property>
<child>
<object class="GtkToolButton" id="satellites_receive_toolbutton">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="is_important">True</property>
<property name="label" translatable="yes">Receive</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-goto-bottom</property>
<signal name="clicked" handler="on_satellites_receive" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="homogeneous">True</property>
</packing>
</child>
<style>
<class name="primary-toolbar"/>
</style>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkSeparator" id="sat_separator_3">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View File

@@ -38,7 +38,7 @@ class PiconsDialog:
builder = Gtk.Builder()
builder.set_translation_domain(TEXT_DOMAIN)
builder.add_objects_from_file(UI_RESOURCES_PATH + "tools.glade",
builder.add_objects_from_file(UI_RESOURCES_PATH + "picons_downloader.glade",
("picons_dialog", "receive_image", "providers_list_store"))
builder.connect_signals(handlers)
self._dialog = builder.get_object("picons_dialog")

File diff suppressed because it is too large Load Diff

View File

@@ -3,29 +3,30 @@ from math import fabs
from app.commons import run_idle
from app.eparser import get_satellites, write_satellites, Satellite, Transponder
from app.tools.satellites import SatellitesParser
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN, MOVE_KEYS
from .dialogs import show_dialog, DialogType, WaitDialog
from .main_helper import move_items, scroll_to
def show_satellites_dialog(transient, options):
dialog = SatellitesDialog(transient, options)
dialog.run()
dialog.destroy()
SatellitesDialog(transient, options).show()
class SatellitesDialog:
__slots__ = ["_dialog", "_data_path", "_stores", "_options", "_sat_view", "_wait_dialog"]
_aggr = [None for x in range(9)] # aggregate
def __init__(self, transient, options):
self._data_path = options.get("data_dir_path") + "satellites.xml"
self._options = options
self._download_task = False
handlers = {"on_open": self.on_open,
"on_remove": self.on_remove,
"on_save": self.on_save,
"on_update": self.on_update,
"on_receive": self.on_receive,
"on_cancel_receive": self.on_cancel_receive,
"on_up": self.on_up,
"on_down": self.on_down,
"on_popup_menu": self.on_popup_menu,
@@ -40,8 +41,8 @@ class SatellitesDialog:
builder = Gtk.Builder()
builder.set_translation_domain(TEXT_DOMAIN)
builder.add_objects_from_file(UI_RESOURCES_PATH + "satellites_dialog.glade",
("satellites_editor_dialog", "satellites_tree_store",
"popup_menu", "add_popup_menu", "add_menu_icon"))
("satellites_editor_dialog", "satellites_tree_store", "popup_menu",
"add_popup_menu", "add_menu_icon", "receive_menu_icon", "update_source_store"))
builder.connect_signals(handlers)
# Adding custom image for add_menu_tool_button
add_menu_tool_button = builder.get_object("add_menu_tool_button")
@@ -51,6 +52,7 @@ class SatellitesDialog:
self._dialog.set_transient_for(transient)
self._dialog.get_content_area().set_border_width(0) # The width of the border around the app dialog area!
self._sat_view = builder.get_object("satellites_editor_tree_view")
self._download_bar = builder.get_object("download_bar")
self._wait_dialog = WaitDialog(self._dialog)
# Setting the last size of the dialog window if it was saved
window_size = self._options.get("sat_editor_window_size", None)
@@ -63,10 +65,10 @@ class SatellitesDialog:
6: builder.get_object("mod_store")}
self.on_satellites_list_load(self._sat_view.get_model())
def run(self):
@run_idle
def show(self):
self._dialog.run()
def destroy(self):
self.on_cancel_receive()
self._dialog.destroy()
def on_resize(self, window):
@@ -75,7 +77,8 @@ class SatellitesDialog:
self._options["sat_editor_window_size"] = window.get_size()
def on_quit(self, item):
self.destroy()
self.on_cancel_receive()
self._dialog.destroy()
def on_open(self, model):
file_filter = Gtk.FileFilter()
@@ -147,10 +150,14 @@ class SatellitesDialog:
@run_idle
def append_data(self, model, satellites):
for name, flags, pos, transponders in satellites:
parent = model.append(None, [name, *self._aggr, flags, pos])
for transponder in transponders:
model.append(parent, ["Transponder:", *transponder, None, None])
for sat in satellites:
self.append_satellite(model, sat)
def append_satellite(self, model, sat):
name, flags, pos, transponders = sat
parent = model.append(None, [name, *self._aggr, flags, pos])
for transponder in transponders:
model.append(parent, ["Transponder:", *transponder, None, None])
def on_add(self, view):
""" Common adding """
@@ -279,6 +286,33 @@ class SatellitesDialog:
model.foreach(self.parse_data, satellites)
write_satellites(satellites, self._data_path)
def on_update(self, button: Gtk.ToggleToolButton):
self._download_bar.set_visible(button.get_active())
@run_idle
def on_receive(self, item):
if self._download_task:
show_dialog(DialogType.ERROR, self._dialog, "The task is already running!")
return
model = self._sat_view.get_model()
model.clear()
self._download_task = True
def callback(sat):
if self._download_task:
self.append_satellite(model, sat)
return False
else:
print("Canceled!")
return True
SatellitesParser(url="https://www.flysat.com/satlist.php").get_satellites(callback)
@run_idle
def on_cancel_receive(self, item=None):
self._download_task = False
@staticmethod
def parse_data(model, path, itr, sats):
if model.iter_has_child(itr):

View File

@@ -1,36 +0,0 @@
from app.commons import run_idle
from app.tools.satellites import SatellitesParser
from ..uicommons import Gtk, UI_RESOURCES_PATH, TEXT_DOMAIN
class SatellitesDownloaderDialog:
def __init__(self, transient, options):
handlers = {"on_satellites_receive": self.on_satellites_receive}
builder = Gtk.Builder()
builder.set_translation_domain(TEXT_DOMAIN)
builder.add_objects_from_file(UI_RESOURCES_PATH + "tools.glade",
("satellites_dialog", "source_urls_list_store", "satellites_list_store"))
builder.connect_signals(handlers)
self._dialog = builder.get_object("satellites_dialog")
self._dialog.set_transient_for(transient)
self._satellites_tree_view = builder.get_object("satellites_tree_view")
def show(self):
self._dialog.run()
self._dialog.destroy()
@run_idle
def on_satellites_receive(self, item):
parser = SatellitesParser(url="https://www.flysat.com/satlist.php")
sats = parser.get_satellites()
if sats:
model = self._satellites_tree_view.get_model()
model.clear()
for sat in sats:
model.append((sat[1], sat[2], sat[3], sat[0], False))
if __name__ == "__main__":
pass