Compare commits

...

11 Commits

Author SHA1 Message Date
DYefremov
70b9851324 minor ui correction
* IPTV list config dialog adjustment for macOS
2024-05-17 22:52:46 +03:00
DYefremov
2a3b558d83 adjustment for LyngSat web source
* default values for ONID-TID if not present (#200)
2024-05-09 19:13:52 +03:00
DYefremov
21ea841f34 version update -> 3.10.0 2024-05-07 18:53:52 +03:00
DYefremov
1db0ce3fc5 README update 2024-05-07 18:42:01 +03:00
DYefremov
2804a9bc54 change playback keyboard shortcuts 2024-05-07 18:41:36 +03:00
DYefremov
8976f42974 enabled playback mode for the main services list (#198) 2024-05-07 17:56:00 +03:00
DYefremov
8330104f3c add last config load flag 2024-03-29 22:22:05 +03:00
DYefremov
3ede2e2b07 fix -> mark not present in bouquets (#197) 2024-03-29 20:35:48 +03:00
DYefremov
dd796c0f88 version update -> 3.9.2-b 2024-03-16 17:58:52 +03:00
DYefremov
f3a432c002 add optional keep for backup
* prevent *.xml deletion (#196)
2024-03-11 00:38:25 +03:00
DYefremov
4c1cdc4850 increase pos width for sat dialog 2024-03-06 20:53:14 +03:00
12 changed files with 71 additions and 37 deletions

View File

@@ -41,10 +41,7 @@ Experimental support of Neutrino-MP or others on the same basis (BPanther, etc).
* **Ctrl + Alt + R** - rename for bouquet.
* **Ctrl + S, T** in Satellites edit tool for create satellite or transponder.
* **Ctrl + L** - parental lock.
* **Ctrl + H** - hide/skip.
* **Ctrl + P** - start play IPTV or other stream in the bouquet list.
* **Ctrl + Z** - switch(**zap**) the channel(works when the HTTP API is enabled, Enigma2 only).
* **Ctrl + W** - switch to the channel and watch in the program.
* **Ctrl + H** - hide/skip.
* **Space** - select/deselect.
* **Left/Right** - remove selection.
* **Ctrl + Up, Down, PageUp, PageDown, Home, End**- move selected items in the list.
@@ -56,6 +53,9 @@ Experimental support of Neutrino-MP or others on the same basis (BPanther, etc).
* **Ctrl + Shift + F** - show/hide filter bar.
* **Ctrl + T** - show/hide built-in Telnet client.
* **Ctrl + Shift + L** - show/hide logging panel.
* **Shift + P** - start play IPTV or other stream in the bouquet list.
* **Shift + Z** - switch(**zap**) the channel(works when the HTTP API is enabled, Enigma2 only).
* **Shift + W** - switch to the channel and watch in the program.
For **multiple** selection with the mouse, press and hold the **Ctrl** key!

View File

@@ -443,9 +443,9 @@ class ServicesParser(HTMLParser):
self._POS_PAT = re.compile(r".*?(\d+\.\d°[EW]).*")
# LyngSat.
self._TR_PAT = re.compile((r".*?(\d+)\.?\d?\s+([RLHV]).*(DVB-S[2]?)/?(.*PSK)?\s"
self._TR_PAT = re.compile((r".*?(\d{4,5})\.?\d?\s+([RLHV]).*(DVB-S[2]?)/?(.*PSK)?\s"
r"?(T2-MI)?\s?(PLS\s+Multistream)?\s?"
r"SR-FEC:\s(\d+)-(\d/\d)\s+.*ONID-TID:\s+(\d+)-(\d+).*"))
r"SR-FEC:\s(\d+)-(\d+/\d+)\s+?(?:.*ONID-TID:\s+(\d+)-(\d+))?"))
self._MULTI_PAT = re.compile(r"PLS\s+(Root|Gold|Combo)+\s(\d+)?\s+(?:Stream\s(\d+))")
# KingOfSat.
@@ -635,12 +635,18 @@ class ServicesParser(HTMLParser):
if pos_found:
text = " ".join(c.text for c in r[1:])
td = re.match(self._TR_PAT, text)
if td:
freq, pol = int(td.group(1)), get_key_by_value(POLARIZATION, td.group(2))
sys, mod, sr, _fec, = td.group(3), td.group(4), td.group(7), td.group(8)
nid, tid = td.group(9), td.group(10)
sys, mod, fec, nsp, s2_flags, roll_off, pilot, inv = self.get_transponder_data(pos, _fec, sys, mod)
nid, tid = int(nid), int(tid)
# The ONID-TID values may not present!
_nid, _tid = td.group(9), td.group(10)
if _nid and _tid:
nid, tid = int(_nid), int(_tid)
else:
log((f"Values 'ONID-TID' for transponder [{self._t_url}] are not present."
" Default values are used."))
if td.group(5):
log(f"Detected T2-MI transponder! [{freq} {sr} {pol}]")

View File

@@ -41,6 +41,10 @@ from app.ui.dialogs import show_dialog, DialogType, get_builder
from app.ui.main_helper import append_text_to_tview, show_info_bar_message
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, KeyboardKey, MOD_MASK, HeaderBar
KEEP_DATA = {"satellites.xml",
"terrestrial.xml",
"cables.xml"}
class RestoreType(Enum):
BOUQUETS = 0
@@ -232,18 +236,19 @@ class BackupDialog:
self.restore(RestoreType.BOUQUETS)
def backup_data(path, backup_path, move=True):
def backup_data(path, backup_path, move=True, keep=None):
""" Creating data backup from a folder at the specified path
Returns full path to the compressed file.
"""
keep = keep or KEEP_DATA
backup_path = f"{backup_path}{datetime.now().strftime('%Y-%m-%d_%H-%M-%S')}{SEP}"
os.makedirs(os.path.dirname(backup_path), exist_ok=True)
os.makedirs(os.path.dirname(path), exist_ok=True)
# Backup files in data dir.
for file in filter(lambda f: os.path.isfile(os.path.join(path, f)), os.listdir(path)):
src, dst = os.path.join(path, file), backup_path + file
shutil.move(src, dst) if move else shutil.copy(src, dst)
shutil.move(src, dst) if move and file not in keep else shutil.copy(src, dst)
# Compressing to zip and delete remaining files.
zip_file = shutil.make_archive(backup_path.rstrip(SEP), "zip", backup_path)
shutil.rmtree(backup_path)

View File

@@ -40,7 +40,7 @@ Author: Dmitriy Yefremov
<property name="icon_name">system-help</property>
<property name="type_hint">normal</property>
<property name="program_name">DemonEditor</property>
<property name="version">3.9.1 Beta</property>
<property name="version">3.10.0 Beta</property>
<property name="copyright">2018-2024 Dmitriy Yefremov
</property>
<property name="comments" translatable="yes">Enigma2 channel and satellite list editor.</property>

View File

@@ -270,7 +270,7 @@ Author: Dmitriy Yefremov
</object>
<object class="GtkDialog" id="iptv_list_configuration_dialog">
<property name="use-header-bar">{use_header}</property>
<property name="width-request">400</property>
<property name="width-request">680</property>
<property name="can-focus">False</property>
<property name="title" translatable="yes">IPTV streams list configuration</property>
<property name="resizable">False</property>
@@ -513,9 +513,9 @@ Author: Dmitriy Yefremov
</child>
<child>
<object class="GtkEntry" id="list_namespace_entry">
<property name="width-request">120</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="hexpand">True</property>
<property name="can-focus">True</property>
<property name="width-chars">5</property>
<property name="max-width-chars">5</property>

View File

@@ -1722,7 +1722,7 @@ Author: Dmitriy Yefremov
<object class="GtkLabel" id="app_ver_label">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label">3.9.1 Beta</property>
<property name="label">3.10.0 Beta</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>

View File

@@ -77,6 +77,8 @@ from .xml.edit import SatellitesTool
class Application(Gtk.Application):
""" Main application class. """
VERSION = "3.10.0"
SERVICE_MODEL = "services_list_store"
FAV_MODEL = "fav_list_store"
BQ_MODEL = "bouquets_tree_store"
@@ -623,7 +625,7 @@ class Application(Gtk.Application):
self._main_window.set_wmclass("DemonEditor", "DemonEditor")
self._main_window.present()
self.init_profiles()
self.init_profiles(True)
gen = self.init_http_api()
GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
@@ -875,9 +877,9 @@ class Application(Gtk.Application):
self.set_accels_for_action("app.on_logs_show", ["<shift><primary>l"])
self.set_accels_for_action("win.filter", ["<shift><primary>f"])
def init_profiles(self):
def init_profiles(self, last_config=False):
self.update_profiles()
if self._settings.load_last_config:
if last_config and self._settings.load_last_config:
config = self._settings.get("last_config") or {}
if config.get("last_bouquet", None):
self.connect("data-load-done", self.open_last_bouquet)
@@ -2949,21 +2951,33 @@ class Application(Gtk.Application):
key = KeyboardKey(key_code)
ctrl = event.state & MOD_MASK
shift = event.state & Gdk.ModifierType.SHIFT_MASK
model_name, model = get_model_data(view)
if key is KeyboardKey.LEFT or key is KeyboardKey.RIGHT:
view.do_unselect_all(view)
elif ctrl and model_name == self.FAV_MODEL:
if key is KeyboardKey.P:
self.emit("fav-clicked", PlaybackMode.STREAM)
if key is KeyboardKey.W:
self.emit("fav-clicked", PlaybackMode.ZAP_PLAY)
if key is KeyboardKey.Z:
self.emit("fav-clicked", PlaybackMode.ZAP)
elif key is KeyboardKey.CTRL_L or key is KeyboardKey.CTRL_R:
if model_name == self.FAV_MODEL:
if ctrl and key in (KeyboardKey.CTRL_L, KeyboardKey.CTRL_R):
self.update_fav_num_column(model)
self.update_bouquet_list()
if shift:
if key is KeyboardKey.P:
self.emit("fav-clicked", PlaybackMode.STREAM)
if key is KeyboardKey.W:
self.emit("fav-clicked", PlaybackMode.ZAP_PLAY)
if key is KeyboardKey.Z:
self.emit("fav-clicked", PlaybackMode.ZAP)
elif model_name == self.SERVICE_MODEL:
if shift:
if key is KeyboardKey.P:
self.emit("srv-clicked", PlaybackMode.STREAM)
if key is KeyboardKey.W:
self.emit("srv-clicked", PlaybackMode.ZAP_PLAY)
if key is KeyboardKey.Z:
self.emit("srv-clicked", PlaybackMode.ZAP)
def on_view_focus(self, view, focus_event=None):
# Preventing focus lack for some cases.
if not focus_event and not view.is_focus():
@@ -4105,8 +4119,8 @@ class Application(Gtk.Application):
for index, row in enumerate(self._services_model):
fav_id = row[Column.SRV_FAV_ID]
if fav_id not in ids:
row[Column.SRV_BACKGROUND] = self._EXTRA_COLOR
bg = self.get_new_background(row[Column.SRV_CAS_FLAGS]) if fav_id in ids else self._EXTRA_COLOR
row[Column.SRV_BACKGROUND] = bg
if index % self.FAV_FACTOR == 0:
yield True

View File

@@ -2,7 +2,7 @@
#
# The MIT License (MIT)
#
# Copyright (c) 2018-2023 Dmitriy Yefremov
# Copyright (c) 2018-2024 Dmitriy Yefremov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -158,7 +158,14 @@ class PlayerBox(Gtk.Overlay):
return
ref = self._app.get_service_ref_data(srv)
self.zap(ref, self.play_current)
if mode is PlaybackMode.PLAY:
self.play_service(ref)
elif mode is PlaybackMode.ZAP:
self.zap(ref)
elif mode is PlaybackMode.ZAP_PLAY:
self.zap(ref, self.play_current)
elif mode is PlaybackMode.STREAM:
self._app.show_error_message("Not allowed in this context!")
def on_iptv_clicked(self, app, mode):
if not self._app.http_api:
@@ -439,15 +446,17 @@ class PlayerBox(Gtk.Overlay):
self.play(url) if url else self.on_error(None, "No reference is present!")
def on_play_service(self, item=None):
""" Playback without switching channel on the Box [returns current reference]"""
""" Playback without switching channel on the Box."""
ref, path = self.get_ref()
if not ref:
return
self.play_service(ref)
def play_service(self, ref):
s_type = self._app.app_settings.setting_type
req = HttpAPI.Request.STREAM if s_type is SettingsType.ENIGMA_2 else HttpAPI.Request.N_STREAM
self._app.http_api.send(req, ref, self.watch)
return ref
def on_zap(self, callback=None):
""" Switch(zap) the channel. """

View File

@@ -3,7 +3,7 @@
The MIT License (MIT)
Copyright (c) 2018-2023 Dmitriy Yefremov
Copyright (c) 2018-2024 Dmitriy Yefremov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -31,7 +31,7 @@ Author: Dmitriy Yefremov
<!-- interface-css-provider-path style.css -->
<!-- interface-license-type mit -->
<!-- interface-name DemonEditor -->
<!-- interface-copyright 2018-2023 Dmitriy Yefremov -->
<!-- interface-copyright 2018-2024 Dmitriy Yefremov -->
<!-- interface-authors Dmitriy Yefremov -->
<!-- n-columns=2 n-rows=4 -->
<object class="GtkGrid" id="cable_tr_box">
@@ -471,7 +471,7 @@ Author: Dmitriy Yefremov
<object class="GtkSpinButton" id="sat_position_button">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="width-chars">5</property>
<property name="width-chars">6</property>
<property name="secondary-icon-activatable">False</property>
<property name="secondary-icon-sensitive">False</property>
<property name="input-purpose">number</property>

View File

@@ -1,5 +1,5 @@
#!/bin/bash
VER="3.9.1_Beta"
VER="3.10.0_Beta"
B_PATH="dist/DemonEditor"
DEB_PATH="$B_PATH/usr/share/demoneditor"

View File

@@ -1,5 +1,5 @@
Package: demon-editor
Version: 3.9.1-Beta
Version: 3.10.0-Beta
Section: utils
Priority: optional
Architecture: all

View File

@@ -81,7 +81,7 @@ app = BUNDLE(coll,
'CFBundleGetInfoString': "Enigma2 channel and satellite editor",
'LSApplicationCategoryType': 'public.app-category.utilities',
'LSMinimumSystemVersion': '10.13',
'CFBundleShortVersionString': f"3.9.1.{BUILD_DATE} Beta",
'CFBundleShortVersionString': f"3.10.0.{BUILD_DATE} Beta",
'NSHumanReadableCopyright': u"Copyright © 2024, Dmitriy Yefremov",
'NSRequiresAquaSystemAppearance': 'false',
'NSHighResolutionCapable': 'true'