mirror of
https://github.com/DYefremov/DemonEditor.git
synced 2026-05-09 04:57:18 +02:00
Compare commits
11 Commits
3.9.1-b1
...
3.10.0-tes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70b9851324 | ||
|
|
2a3b558d83 | ||
|
|
21ea841f34 | ||
|
|
1db0ce3fc5 | ||
|
|
2804a9bc54 | ||
|
|
8976f42974 | ||
|
|
8330104f3c | ||
|
|
3ede2e2b07 | ||
|
|
dd796c0f88 | ||
|
|
f3a432c002 | ||
|
|
4c1cdc4850 |
@@ -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!
|
||||
|
||||
|
||||
@@ -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}]")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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. """
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Package: demon-editor
|
||||
Version: 3.9.1-Beta
|
||||
Version: 3.10.0-Beta
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Architecture: all
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user