mirror of
https://github.com/DYefremov/DemonEditor.git
synced 2026-05-08 19:16:27 +02:00
Compare commits
158 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38ceb6f65d | ||
|
|
33fe78911a | ||
|
|
3552415054 | ||
|
|
a2ec6f1e1f | ||
|
|
5f90d07853 | ||
|
|
d88548eece | ||
|
|
9ead5b3918 | ||
|
|
1a376e6922 | ||
|
|
eb29f2e1b2 | ||
|
|
bfaab7b2fb | ||
|
|
3e6a7f8a42 | ||
|
|
aff34d7627 | ||
|
|
8ef0a451ff | ||
|
|
8678f02fd6 | ||
|
|
a0a64606cd | ||
|
|
6574296278 | ||
|
|
d8414f56ee | ||
|
|
bb9499392b | ||
|
|
069ea9348f | ||
|
|
8c932c8913 | ||
|
|
562501dda8 | ||
|
|
79583869e4 | ||
|
|
5c9abcee21 | ||
|
|
e8377ed174 | ||
|
|
16f8df0238 | ||
|
|
dab772e25c | ||
|
|
37791a5537 | ||
|
|
eb55cc76be | ||
|
|
f728a01963 | ||
|
|
8aae503e35 | ||
|
|
fe499d6c94 | ||
|
|
cd2c820324 | ||
|
|
b4c5af4c04 | ||
|
|
f239957ca2 | ||
|
|
3b835e6f34 | ||
|
|
4ab3d2d0e1 | ||
|
|
3781686213 | ||
|
|
0247aeed52 | ||
|
|
3d34539c16 | ||
|
|
0a06b36f60 | ||
|
|
ea1d536c6c | ||
|
|
5087266693 | ||
|
|
3e617e329c | ||
|
|
1ab0b3d3f0 | ||
|
|
cb3f2d71d1 | ||
|
|
62bcb64640 | ||
|
|
300ea3b6d9 | ||
|
|
3ae1901757 | ||
|
|
2b63a59c91 | ||
|
|
ec69bae2a6 | ||
|
|
c07e0b606b | ||
|
|
61745df2a7 | ||
|
|
146c59e0db | ||
|
|
c7c0a4055b | ||
|
|
6c7d39889d | ||
|
|
9d9626d065 | ||
|
|
9bf7a10bf1 | ||
|
|
9659514feb | ||
|
|
f39ddd4315 | ||
|
|
90bd9e0211 | ||
|
|
48f419fec0 | ||
|
|
b993eba2df | ||
|
|
dbab024778 | ||
|
|
7999fc6893 | ||
|
|
b2eecf6cd9 | ||
|
|
919e1c66ba | ||
|
|
3fc5a3fd68 | ||
|
|
345ebc0983 | ||
|
|
8e14e78847 | ||
|
|
856b09bb4b | ||
|
|
c303cd3683 | ||
|
|
097bb82af2 | ||
|
|
e780448be5 | ||
|
|
732076e60e | ||
|
|
6bcbb48993 | ||
|
|
2b80704063 | ||
|
|
215010e2a4 | ||
|
|
d9a035d399 | ||
|
|
f9008c62d0 | ||
|
|
6c28ce29a9 | ||
|
|
6ac88317cc | ||
|
|
332b2342cd | ||
|
|
3703ab4427 | ||
|
|
a1586944b7 | ||
|
|
22f93c0b89 | ||
|
|
803b26ea02 | ||
|
|
d86a566668 | ||
|
|
a1011c7516 | ||
|
|
40df14ace8 | ||
|
|
96f9e4cca8 | ||
|
|
cd1a3c5df2 | ||
|
|
9f9db9257e | ||
|
|
f748fae549 | ||
|
|
c303162c09 | ||
|
|
6d4434c652 | ||
|
|
a92b7526eb | ||
|
|
c33f95e0b5 | ||
|
|
7bfeef9d73 | ||
|
|
506207f2e5 | ||
|
|
f9ef03b827 | ||
|
|
b5dabf65c7 | ||
|
|
3fb3d04161 | ||
|
|
d76e379542 | ||
|
|
d046bd7c28 | ||
|
|
bc2ec7fff1 | ||
|
|
e3c3f20da7 | ||
|
|
2254164f40 | ||
|
|
2ae4ac6383 | ||
|
|
80cd4c89b0 | ||
|
|
3df6fd7d0e | ||
|
|
f3243c9e40 | ||
|
|
528df9602b | ||
|
|
cd83539855 | ||
|
|
ecc17fa4b2 | ||
|
|
4c555bb7f4 | ||
|
|
e2592bb87a | ||
|
|
631564b22c | ||
|
|
a8bc81fb13 | ||
|
|
fecb77090d | ||
|
|
692495283c | ||
|
|
5ee6615d6f | ||
|
|
4e34057d16 | ||
|
|
f16b47ebf1 | ||
|
|
3ac16cb7af | ||
|
|
2b3c357657 | ||
|
|
5658a3cfc3 | ||
|
|
06c3cb6c42 | ||
|
|
b60bb6b3b1 | ||
|
|
b3648a2dae | ||
|
|
04efdab63a | ||
|
|
966dd13c23 | ||
|
|
2f6450f2b4 | ||
|
|
0db2080e2b | ||
|
|
4210c44ee9 | ||
|
|
9d7fef36c2 | ||
|
|
303d4d6107 | ||
|
|
9ac847ce19 | ||
|
|
d2c7c297b1 | ||
|
|
995def4be8 | ||
|
|
0f08ba67e7 | ||
|
|
499c1aa104 | ||
|
|
348b0743b4 | ||
|
|
769445fafe | ||
|
|
61af6e50ce | ||
|
|
4fd7295762 | ||
|
|
b0ad01da6c | ||
|
|
4320adc46d | ||
|
|
e2ec359327 | ||
|
|
dc773339ab | ||
|
|
e5f8ebbf37 | ||
|
|
ea9ce5dfaf | ||
|
|
b137a790a0 | ||
|
|
9ef776d8ab | ||
|
|
e5b726cbe6 | ||
|
|
fcfac6c20b | ||
|
|
e7a4b06945 | ||
|
|
3fe84f82f9 | ||
|
|
3eee824160 |
34
README.md
34
README.md
@@ -4,7 +4,9 @@
|
||||
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:
|
||||
* **Insert** - copies the selected channels from the main list to the bouquet or inserts (creates) a new bouquet.
|
||||
* **Ctrl + Insert** - copies the selected channels from the main list to the the bouquet beginning
|
||||
or inserts (creates) a new bouquet.
|
||||
* **Ctrl + BackSpace** - copies the selected channels from the main list to the bouquet end.
|
||||
* **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.
|
||||
@@ -12,23 +14,37 @@ Clipboard is **"rubber"**. There is an accumulation before the insertion!
|
||||
* **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 + 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.
|
||||
* **Space** - select/deselect.
|
||||
* **Left/Right** - remove selection.
|
||||
* **Ctrl + Up, Down, PageUp, PageDown, Home, End** - move selected items in the list.
|
||||
### Extra:
|
||||
* **Ctrl + Up, Down, PageUp, PageDown, Home, End** - move selected items in the list.
|
||||
|
||||
### Extra:
|
||||
* Multiple selections in lists only with Space key (as in file managers).
|
||||
* Ability to import IPTV into bouquet (Neutrino WEBTV) from m3u files.
|
||||
* Ability to download picons and update satellites (transponders) from web.
|
||||
* Preview (playing) IPTV or other streams directly from the bouquet list(should be installed VLC).
|
||||
* Preview (playing) IPTV or other streams directly from the bouquet list(should be installed VLC).
|
||||
|
||||
### Minimum requirements:
|
||||
Python >= 3.5.2 and GTK+ >= 3.16 with PyGObject bindings.
|
||||
#### Note.
|
||||
To create a simple debian package, you can use the build-deb.sh
|
||||
Python >= 3.5.2 and GTK+ >= 3.16 with PyGObject bindings.
|
||||
|
||||
### Launching
|
||||
To start the program, in most cases it is enough to download the archive, unpack and run it by
|
||||
double clicking on DemonEditor.desktop in the root directory, or launching from the console
|
||||
with the command: ```./start.py```
|
||||
Extra folders can be deleted, excluding the *app* folder and root files like *DemonEditor.desktop* and *start.py*!
|
||||
|
||||
### Note.
|
||||
To create a simple **debian package**, you can use the *build-deb.sh.*
|
||||
|
||||
Tests only with openATV image and Formuler F1 receiver in my preferred Linux distros
|
||||
(latest Linux Mint 18.* and 19 MATE 64-bit)!
|
||||
|
||||
**Terrestrial and cable channels at the moment are not supported!**
|
||||
**Terrestrial(DVB-T/T2) and cable(DVB-C) channels are only supported for Enigma2!**
|
||||
|
||||
Main supported **lamedb** format is version **4**. Versions **3** and **5** has only experimental support!
|
||||
For version **3** is only read mode available. When saving, version **4** format is used instead!
|
||||
|
||||
|
||||
|
||||
2
_config.yml
Normal file
2
_config.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
theme: jekyll-theme-cayman
|
||||
show_downloads: true
|
||||
343
app/connections.py
Normal file
343
app/connections.py
Normal file
@@ -0,0 +1,343 @@
|
||||
import json
|
||||
import os
|
||||
import socket
|
||||
import time
|
||||
import urllib
|
||||
from enum import Enum
|
||||
from ftplib import FTP, error_perm
|
||||
from telnetlib import Telnet
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.parse import urlencode
|
||||
from urllib.request import urlopen, HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener, install_opener
|
||||
|
||||
from app.commons import log
|
||||
from app.properties import Profile
|
||||
|
||||
_BQ_FILES_LIST = ("tv", "radio", # enigma 2
|
||||
"myservices.xml", "bouquets.xml", "ubouquets.xml") # neutrino
|
||||
|
||||
_DATA_FILES_LIST = ("lamedb", "lamedb5", "services.xml", "blacklist", "whitelist",)
|
||||
|
||||
_SAT_XML_FILE = "satellites.xml"
|
||||
_WEBTV_XML_FILE = "webtv.xml"
|
||||
|
||||
|
||||
class DownloadType(Enum):
|
||||
ALL = 0
|
||||
BOUQUETS = 1
|
||||
SATELLITES = 2
|
||||
PICONS = 3
|
||||
WEBTV = 4
|
||||
|
||||
|
||||
class HttpRequestType(Enum):
|
||||
ZAP = "zap?sRef="
|
||||
INFO = "about"
|
||||
SIGNAL = "tunersignal"
|
||||
STREAM = "streamcurrentm3u"
|
||||
|
||||
|
||||
class TestException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def download_data(*, properties, download_type=DownloadType.ALL, callback=None):
|
||||
with FTP(host=properties["host"], user=properties["user"], passwd=properties["password"]) as ftp:
|
||||
ftp.encoding = "utf-8"
|
||||
callback("FTP OK.\n")
|
||||
save_path = properties["data_dir_path"]
|
||||
os.makedirs(os.path.dirname(save_path), exist_ok=True)
|
||||
files = []
|
||||
# bouquets section
|
||||
if download_type is DownloadType.ALL or download_type is DownloadType.BOUQUETS:
|
||||
ftp.cwd(properties["services_path"])
|
||||
ftp.dir(files.append)
|
||||
file_list = _BQ_FILES_LIST + _DATA_FILES_LIST if download_type is DownloadType.ALL else _BQ_FILES_LIST
|
||||
for file in files:
|
||||
name = str(file).strip()
|
||||
if name.endswith(file_list):
|
||||
name = name.split()[-1]
|
||||
download_file(ftp, name, save_path, callback)
|
||||
# satellites.xml and webtv section
|
||||
if download_type in (DownloadType.ALL, DownloadType.SATELLITES, DownloadType.WEBTV):
|
||||
ftp.cwd(properties["satellites_xml_path"])
|
||||
files.clear()
|
||||
ftp.dir(files.append)
|
||||
|
||||
for file in files:
|
||||
name = str(file).strip()
|
||||
if download_type in (DownloadType.ALL, DownloadType.SATELLITES) and name.endswith(_SAT_XML_FILE):
|
||||
download_file(ftp, _SAT_XML_FILE, save_path, callback)
|
||||
if download_type in (DownloadType.ALL, DownloadType.WEBTV) and name.endswith(_WEBTV_XML_FILE):
|
||||
download_file(ftp, _WEBTV_XML_FILE, save_path, callback)
|
||||
|
||||
if callback is not None:
|
||||
callback("\nDone.\n")
|
||||
|
||||
|
||||
def upload_data(*, properties, download_type=DownloadType.ALL, remove_unused=False, profile=Profile.ENIGMA_2,
|
||||
callback=None, done_callback=None, use_http=False):
|
||||
data_path = properties["data_dir_path"]
|
||||
host = properties["host"]
|
||||
base_url = "http://{}:{}/api/".format(host, properties.get("http_port", "80"))
|
||||
tn, ht = None, None # telnet, http
|
||||
|
||||
try:
|
||||
if profile is Profile.ENIGMA_2 and use_http:
|
||||
ht = http(properties.get("http_user", ""), properties.get("http_password", ""), base_url, callback)
|
||||
next(ht)
|
||||
message = ""
|
||||
if download_type is DownloadType.BOUQUETS:
|
||||
message = "User bouquets will be updated!"
|
||||
elif download_type is DownloadType.ALL:
|
||||
message = "All user data will be reloaded!"
|
||||
elif download_type is DownloadType.SATELLITES:
|
||||
message = "Satellites.xml file will be updated!"
|
||||
|
||||
params = urlencode({"text": message, "type": 2, "timeout": 5})
|
||||
url = base_url + "message?{}".format(params)
|
||||
ht.send(url)
|
||||
|
||||
if download_type is DownloadType.ALL:
|
||||
time.sleep(5)
|
||||
ht.send(base_url + "/powerstate?newstate=0")
|
||||
time.sleep(2)
|
||||
else:
|
||||
# telnet
|
||||
tn = telnet(host=host, user=properties.get("telnet_user", "root"),
|
||||
password=properties.get("telnet_password", ""),
|
||||
timeout=properties.get("telnet_timeout", 5))
|
||||
next(tn)
|
||||
# terminate enigma or neutrino
|
||||
tn.send("init 4")
|
||||
|
||||
with FTP(host=host, user=properties["user"], passwd=properties["password"]) as ftp:
|
||||
ftp.encoding = "utf-8"
|
||||
callback("FTP OK.\n")
|
||||
sat_xml_path = properties["satellites_xml_path"]
|
||||
services_path = properties["services_path"]
|
||||
|
||||
if download_type is DownloadType.SATELLITES:
|
||||
upload_xml(ftp, data_path, sat_xml_path, _SAT_XML_FILE, callback)
|
||||
|
||||
if profile is Profile.NEUTRINO_MP and download_type is DownloadType.WEBTV:
|
||||
upload_xml(ftp, data_path, sat_xml_path, _WEBTV_XML_FILE, callback)
|
||||
|
||||
if download_type is DownloadType.BOUQUETS:
|
||||
ftp.cwd(services_path)
|
||||
upload_bouquets(ftp, data_path, remove_unused, callback)
|
||||
|
||||
if download_type is DownloadType.ALL:
|
||||
upload_xml(ftp, data_path, sat_xml_path, _SAT_XML_FILE, callback)
|
||||
if profile is Profile.NEUTRINO_MP:
|
||||
upload_xml(ftp, data_path, sat_xml_path, _WEBTV_XML_FILE, callback)
|
||||
|
||||
ftp.cwd(services_path)
|
||||
upload_bouquets(ftp, data_path, remove_unused, callback)
|
||||
upload_files(ftp, data_path, _DATA_FILES_LIST, callback)
|
||||
|
||||
if download_type is DownloadType.PICONS:
|
||||
upload_picons(ftp, properties.get("picons_dir_path"), properties.get("picons_path"))
|
||||
|
||||
if tn and not use_http:
|
||||
# resume enigma or restart neutrino
|
||||
tn.send("init 3" if profile is Profile.ENIGMA_2 else "init 6")
|
||||
elif ht and use_http:
|
||||
if download_type is DownloadType.BOUQUETS:
|
||||
ht.send(base_url + "/servicelistreload?mode=2")
|
||||
elif download_type is DownloadType.ALL:
|
||||
ht.send(base_url + "/servicelistreload?mode=0")
|
||||
ht.send(base_url + "/powerstate?newstate=4")
|
||||
|
||||
if done_callback is not None:
|
||||
done_callback()
|
||||
finally:
|
||||
if tn:
|
||||
tn.close()
|
||||
if ht:
|
||||
ht.close()
|
||||
|
||||
|
||||
def upload_bouquets(ftp, data_path, remove_unused, callback):
|
||||
if remove_unused:
|
||||
remove_unused_bouquets(ftp, callback)
|
||||
upload_files(ftp, data_path, _BQ_FILES_LIST, callback)
|
||||
|
||||
|
||||
def upload_files(ftp, data_path, file_list, callback):
|
||||
for file_name in os.listdir(data_path):
|
||||
if file_name == _SAT_XML_FILE or file_name == _WEBTV_XML_FILE:
|
||||
continue
|
||||
if file_name.endswith(file_list):
|
||||
send_file(file_name, data_path, ftp, callback)
|
||||
|
||||
|
||||
def remove_unused_bouquets(ftp, callback):
|
||||
files = []
|
||||
ftp.dir(files.append)
|
||||
for file in files:
|
||||
name = str(file).strip()
|
||||
if name.endswith(("tv", "radio", "bouquets.xml", "ubouquets.xml")):
|
||||
name = name.split()[-1]
|
||||
callback("Deleting file: {}. Status: {}\n".format(name, ftp.delete(name)))
|
||||
|
||||
|
||||
def upload_xml(ftp, data_path, xml_path, xml_file, callback):
|
||||
""" Used for transfer satellites.xml or webtv.xml files """
|
||||
ftp.cwd(xml_path)
|
||||
send_file(xml_file, data_path, ftp, callback)
|
||||
|
||||
|
||||
def upload_picons(ftp, src, dest):
|
||||
try:
|
||||
ftp.cwd(dest)
|
||||
except error_perm as e:
|
||||
if str(e).startswith("550"):
|
||||
ftp.mkd(dest) # if not exist
|
||||
ftp.cwd(dest)
|
||||
files = []
|
||||
ftp.dir(files.append)
|
||||
picons_suf = (".jpg", ".png")
|
||||
for file in files:
|
||||
name = str(file).strip()
|
||||
if name.endswith(picons_suf):
|
||||
name = name.split()[-1]
|
||||
ftp.delete(name)
|
||||
for file_name in os.listdir(src):
|
||||
if file_name.endswith(picons_suf):
|
||||
send_file(file_name, src, ftp)
|
||||
|
||||
|
||||
def download_file(ftp, name, save_path, callback):
|
||||
with open(save_path + name, "wb") as f:
|
||||
callback("Downloading file: {}. Status: {}\n".format(name, str(ftp.retrbinary("RETR " + name, f.write))))
|
||||
|
||||
|
||||
def send_file(file_name, path, ftp, callback):
|
||||
""" Opens the file in binary mode and transfers into receiver """
|
||||
with open(path + file_name, "rb") as f:
|
||||
callback("Uploading file: {}. Status: {}\n".format(file_name, str(ftp.storbinary("STOR " + file_name, f))))
|
||||
|
||||
|
||||
def http(user, password, url, callback):
|
||||
init_auth(user, password, url)
|
||||
while True:
|
||||
url = yield
|
||||
with urlopen(url, timeout=5) as f:
|
||||
msg = json.loads(f.read().decode("utf-8")).get("message", None)
|
||||
if msg:
|
||||
callback("HTTP: {}\n".format(msg))
|
||||
|
||||
|
||||
def telnet(host, port=23, user="", password="", timeout=5):
|
||||
try:
|
||||
tn = Telnet(host=host, port=port, timeout=timeout)
|
||||
except socket.timeout:
|
||||
log("telnet error: socket timeout")
|
||||
else:
|
||||
time.sleep(1)
|
||||
command = yield
|
||||
if user != "":
|
||||
tn.read_until(b"login: ")
|
||||
tn.write(user.encode("utf-8") + b"\n")
|
||||
time.sleep(timeout)
|
||||
if password != "":
|
||||
tn.read_until(b"Password: ")
|
||||
tn.write(password.encode("utf-8") + b"\n")
|
||||
time.sleep(timeout)
|
||||
tn.write("{}\r\n".format(command).encode("utf-8"))
|
||||
time.sleep(timeout)
|
||||
command = yield
|
||||
time.sleep(timeout)
|
||||
tn.write("{}\r\n".format(command).encode("utf-8"))
|
||||
time.sleep(timeout)
|
||||
yield
|
||||
|
||||
|
||||
# ***************** http api *******************#
|
||||
|
||||
def http_request(host, port, user, password):
|
||||
base_url = "http://{}:{}/api/".format(host, port)
|
||||
init_auth(user, password, base_url)
|
||||
while True:
|
||||
req_type, ref = yield
|
||||
url = base_url
|
||||
if req_type is HttpRequestType.ZAP:
|
||||
url = base_url + "zap?sRef={}".format(urllib.parse.quote(ref))
|
||||
elif req_type is HttpRequestType.INFO:
|
||||
url = base_url + HttpRequestType.INFO.value
|
||||
elif req_type is HttpRequestType.SIGNAL:
|
||||
url = base_url + HttpRequestType.SIGNAL.value
|
||||
elif req_type is HttpRequestType.STREAM:
|
||||
url = base_url + HttpRequestType.STREAM.value
|
||||
|
||||
try:
|
||||
with urlopen(url, timeout=5) as f:
|
||||
if req_type is HttpRequestType.STREAM:
|
||||
yield f.read().decode("utf-8")
|
||||
else:
|
||||
yield json.loads(f.read().decode("utf-8"))
|
||||
except (URLError, HTTPError):
|
||||
yield None
|
||||
|
||||
|
||||
# ***************** Connections testing *******************#
|
||||
|
||||
|
||||
def test_ftp(host, port, user, password, timeout=5):
|
||||
try:
|
||||
with FTP(host=host, user=user, passwd=password, timeout=timeout) as ftp:
|
||||
return ftp.getwelcome()
|
||||
except (error_perm, ConnectionRefusedError, OSError) as e:
|
||||
raise TestException(e)
|
||||
|
||||
|
||||
def test_http(host, port, user, password, timeout=5):
|
||||
try:
|
||||
params = urlencode({"text": "Connection test", "type": 2, "timeout": timeout})
|
||||
url = "http://{}:{}/api/message?{}".format(host, port, params)
|
||||
# authentication
|
||||
init_auth(user, password, url)
|
||||
|
||||
with urlopen(url, timeout=5) as f:
|
||||
return json.loads(f.read().decode("utf-8")).get("message", "")
|
||||
except (URLError, HTTPError) as e:
|
||||
raise TestException(e)
|
||||
|
||||
|
||||
def init_auth(user, password, url):
|
||||
""" Init authentication """
|
||||
pass_mgr = HTTPPasswordMgrWithDefaultRealm()
|
||||
pass_mgr.add_password(None, url, user, password)
|
||||
auth_handler = HTTPBasicAuthHandler(pass_mgr)
|
||||
opener = build_opener(auth_handler)
|
||||
install_opener(opener)
|
||||
|
||||
|
||||
def test_telnet(host, port, user, password, timeout=5):
|
||||
try:
|
||||
gen = telnet_test(host, port, user, password, timeout)
|
||||
res = next(gen)
|
||||
print(res)
|
||||
res = next(gen)
|
||||
return res
|
||||
except (socket.timeout, OSError) as e:
|
||||
raise TestException(e)
|
||||
|
||||
|
||||
def telnet_test(host, port, user, password, timeout):
|
||||
tn = Telnet(host=host, port=port, timeout=timeout)
|
||||
time.sleep(1)
|
||||
tn.read_until(b"login: ", timeout=2)
|
||||
tn.write(user.encode("utf-8") + b"\n")
|
||||
time.sleep(timeout)
|
||||
tn.read_until(b"Password: ", timeout=2)
|
||||
tn.write(password.encode("utf-8") + b"\n")
|
||||
time.sleep(timeout)
|
||||
yield tn.read_very_eager()
|
||||
tn.close()
|
||||
yield "Done"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
@@ -30,7 +30,7 @@ Transponder = namedtuple("Transponder", ["frequency", "symbol_rate", "polarizati
|
||||
class TrType(Enum):
|
||||
""" Transponders type """
|
||||
Satellite = "s"
|
||||
Terestrial = "t"
|
||||
Terrestrial = "t"
|
||||
Cable = "c"
|
||||
|
||||
|
||||
@@ -98,6 +98,12 @@ class Pilot(Enum):
|
||||
Auto = "2"
|
||||
|
||||
|
||||
class SystemCable(Enum):
|
||||
""" System of cable service """
|
||||
ANNEX_A = "0"
|
||||
ANNEX_C = "1"
|
||||
|
||||
|
||||
ROLL_OFF = {"0": "35%", "1": "25%", "2": "20%", "3": "Auto"}
|
||||
|
||||
POLARIZATION = {"0": "H", "1": "V", "2": "L", "3": "R"}
|
||||
@@ -110,7 +116,7 @@ FEC = {"0": "Auto", "1": "1/2", "2": "2/3", "3": "3/4", "4": "5/6", "5": "7/8",
|
||||
"25": "3/5", "26": "4/5", "27": "9/10", "28": "Auto"}
|
||||
|
||||
FEC_DEFAULT = {"0": "Auto", "1": "1/2", "2": "2/3", "3": "3/4", "4": "5/6", "5": "7/8", "6": "8/9", "7": "3/5",
|
||||
"8": "4/5", "9": "9/10"}
|
||||
"8": "4/5", "9": "9/10", "10": "6/7", "15": "None"}
|
||||
|
||||
SYSTEM = {"0": "DVB-S", "1": "DVB-S2"}
|
||||
|
||||
@@ -119,6 +125,26 @@ MODULATION = {"0": "Auto", "1": "QPSK", "2": "8PSK", "4": "16APSK", "5": "32APSK
|
||||
SERVICE_TYPE = {"-2": "Data", "1": "TV", "2": "Radio", "3": "Data", "10": "Radio", "22": "TV (H264)",
|
||||
"25": "TV (HD)", "31": "TV (UHD)"}
|
||||
|
||||
# Terrestrial
|
||||
BANDWIDTH = {"0": "8MHz", "1": "7MHz", "2": "6MHz", "3": "Auto", "4": "5MHz", "5": "1/712MHz", "6": "10MHz"}
|
||||
|
||||
T_MODULATION = {"0": "QPSK", "1": "QAM16", "2": "QAM64", "3": "Auto", "4": "QAM256"}
|
||||
|
||||
TRANSMISSION_MODE = {"0": "2k", "1": "8k", "2": "Auto", "3": "4k", "4": "1k", "5": "16k", "6": "32k"}
|
||||
|
||||
GUARD_INTERVAL = {"0": "1/32", "1": "1/16", "2": "1/8", "3": "1/4", "4": "Auto", "5": "1/128", "6": "19/128",
|
||||
"7": "19/256"}
|
||||
|
||||
HIERARCHY = {"0": "None", "1": "1", "2": "2", "3": "4", "4": "Auto"}
|
||||
|
||||
T_FEC = {"0": "1/2", "1": "2/3", "2": "3/4", "3": "5/6", "4": "7/8", "5": "Auto", "6": "6/7", "7": "8/9"}
|
||||
|
||||
T_SYSTEM = {"0": "DVB-T", "1": "DVB-T2", "-1": "DVB-T/T2"}
|
||||
|
||||
# Cable
|
||||
C_MODULATION = {"0": "Auto", "1": "QAM16", "2": "QAM32", "3": "QAM64", "4": "QAM128", "5": "QAM256"}
|
||||
|
||||
# CAS
|
||||
CAS = {"C:2600": "BISS", "C:0b00": "Conax", "C:0b01": "Conax", "C:0b02": "Conax", "C:0baa": "Conax", "C:0602": "Irdeto",
|
||||
"C:0604": "Irdeto", "C:0606": "Irdeto", "C:0608": "Irdeto", "C:0622": "Irdeto", "C:0626": "Irdeto",
|
||||
"C:0664": "Irdeto", "C:0614": "Irdeto", "C:0692": "Irdeto", "C:1801": "Nagravision", "C:0500": "Viaccess",
|
||||
|
||||
@@ -5,6 +5,7 @@ from app.eparser.ecommons import BqServiceType, BouquetService, Bouquets, Bouque
|
||||
|
||||
_TV_ROOT_FILE_NAME = "bouquets.tv"
|
||||
_RADIO_ROOT_FILE_NAME = "bouquets.radio"
|
||||
_DEFAULT_BOUQUET_NAME = "favourites"
|
||||
|
||||
|
||||
def get_bouquets(path):
|
||||
@@ -22,7 +23,11 @@ def write_bouquets(path, bouquets):
|
||||
line.append("#NAME {}\n".format(bqs.name))
|
||||
|
||||
for bq in bqs.bouquets:
|
||||
bq_name = re.sub(pattern, "_", bq.name)
|
||||
bq_name = bq.name
|
||||
if bq_name == "Favourites (TV)" or bq_name == "Favourites (Radio)":
|
||||
bq_name = _DEFAULT_BOUQUET_NAME
|
||||
else:
|
||||
bq_name = re.sub(pattern, "_", bq.name)
|
||||
line.append(srv_line.format(bq_name, bq.type))
|
||||
write_bouquet(path + "userbouquet.{}.{}".format(bq_name, bq.type), bq.name, bq.services)
|
||||
|
||||
@@ -65,17 +70,19 @@ def get_bouquet(path, name, bq_type):
|
||||
for ch in srvs[1:]:
|
||||
ch_data = ch.strip().split(":")
|
||||
if ch_data[1] == "64":
|
||||
services.append(BouquetService(ch_data[-1].split("\n")[0], BqServiceType.MARKER, ch, ch_data[2]))
|
||||
marker_data = ch.split("#DESCRIPTION", 1)
|
||||
services.append(BouquetService(marker_data[1].strip(), BqServiceType.MARKER, ch, ch_data[2]))
|
||||
elif "http" in ch:
|
||||
services.append(BouquetService(ch_data[-1].split("\n")[0], BqServiceType.IPTV, ch, 0))
|
||||
stream_data = ch.split("#DESCRIPTION", 1)
|
||||
services.append(BouquetService(stream_data[-1].strip(":").strip(), BqServiceType.IPTV, ch, 0))
|
||||
else:
|
||||
fav_id = "{}:{}:{}:{}".format(ch_data[3], ch_data[4], ch_data[5], ch_data[6])
|
||||
name = None
|
||||
if len(ch_data) == 12:
|
||||
name, desc = str(ch_data[-1]).split("\n#DESCRIPTION")
|
||||
services.append(BouquetService(name, BqServiceType.DEFAULT, fav_id, 0))
|
||||
services.append(BouquetService(name, BqServiceType.DEFAULT, fav_id.upper(), 0))
|
||||
|
||||
return srvs[0].strip("#NAME").strip(), services
|
||||
return srvs[0].lstrip("#NAME").strip(), services
|
||||
|
||||
|
||||
def parse_bouquets(path, bq_name, bq_type):
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
""" This module used for parsing and write lamedb file
|
||||
""" This module used for parsing and write lamedb file """
|
||||
import re
|
||||
|
||||
Currently implemented only for satellite channels!!!
|
||||
"""
|
||||
from app.commons import log
|
||||
from app.ui.uicommons import CODED_ICON, LOCKED_ICON, HIDE_ICON
|
||||
from .blacklist import get_blacklist
|
||||
from ..ecommons import Service, POLARIZATION, FEC, SERVICE_TYPE, Flag
|
||||
from ..ecommons import Service, POLARIZATION, FEC, SERVICE_TYPE, Flag, T_FEC, TrType, FEC_DEFAULT, T_SYSTEM
|
||||
|
||||
_HEADER = "eDVB services /{}/"
|
||||
_SEP = ":" # separator
|
||||
@@ -82,6 +81,32 @@ def parse(path, version=4):
|
||||
raise SyntaxError("Unsupported version of the format.")
|
||||
|
||||
|
||||
def parse_v3(services, transponders, path):
|
||||
""" Parsing version 3 """
|
||||
for t in transponders:
|
||||
tr = transponders[t].lower()
|
||||
tr_type = tr[0:1]
|
||||
if tr_type == "c":
|
||||
tr += ":0:0:0"
|
||||
elif tr_type == "t":
|
||||
tr += ":0:0"
|
||||
else:
|
||||
tr_data = tr.split(_SEP)
|
||||
len_data = len(tr_data)
|
||||
if len_data == 6:
|
||||
tr_data.append("0")
|
||||
elif len_data == 9:
|
||||
tr_data.insert(6, "0")
|
||||
tr_data.append("0")
|
||||
tr_data.append("2")
|
||||
|
||||
tr = _SEP.join(tr_data)
|
||||
|
||||
transponders[t] = tr
|
||||
|
||||
return parse_services(services, transponders, path)
|
||||
|
||||
|
||||
def parse_v4(path):
|
||||
""" Parsing version 4 """
|
||||
with open(path + _FILE_NAME, "r", encoding="utf-8", errors="replace") as file:
|
||||
@@ -91,14 +116,20 @@ def parse_v4(path):
|
||||
log("lamedb parse error: " + str(e))
|
||||
else:
|
||||
transponders, sep, services = data.partition("transponders") # 1 step
|
||||
if not transponders.endswith("/4/\n"):
|
||||
msg = "lamedb parsing error: unsupported format.\n Only version 4 is supported!"
|
||||
pattern = re.compile("/[34]/$")
|
||||
match = re.search(pattern, transponders)
|
||||
if not match:
|
||||
msg = "lamedb parsing error: unsupported format."
|
||||
log(msg)
|
||||
raise SyntaxError(msg)
|
||||
|
||||
transponders, sep, services = services.partition("services") # 2 step
|
||||
services, sep, _ = services.partition("\nend") # 3 step
|
||||
|
||||
return parse_services(services.split("\n"), parse_transponders(transponders.split("/")), path)
|
||||
if match.group() == "/3/":
|
||||
return parse_v3(services.split("\n"), parse_transponders(transponders.split("/")), path)
|
||||
|
||||
return parse_services(services.split("\n"), parse_transponders(transponders.split("/")), path)
|
||||
|
||||
|
||||
def parse_v5(path):
|
||||
@@ -139,18 +170,34 @@ def parse_transponders(arg):
|
||||
|
||||
|
||||
def parse_services(services, transponders, path):
|
||||
""" Parsing channels """
|
||||
channels = []
|
||||
""" Parsing services """
|
||||
services_list = []
|
||||
blacklist = str(get_blacklist(path))
|
||||
srv = split(services, 3)
|
||||
if srv[0][0] == "": # remove first empty element
|
||||
srv.remove(srv[0])
|
||||
srvs = split(services, 3)
|
||||
if srvs[0][0] == "": # remove first empty element
|
||||
srvs.remove(srvs[0])
|
||||
|
||||
for ch in srv:
|
||||
data = str(ch[0]).split(_SEP)
|
||||
for srv in srvs:
|
||||
data_id = str(srv[0]).lower() # lower is for lamedb ver.3
|
||||
data = data_id.split(_SEP)
|
||||
sp = "0"
|
||||
tid = data[2]
|
||||
nid = data[3]
|
||||
# For lamedb ver.3
|
||||
is_v3 = False
|
||||
if len(tid) < 4:
|
||||
is_v3 = True
|
||||
tid = "{:0>4}".format(tid)
|
||||
data[2] = tid
|
||||
if len(nid) < 4:
|
||||
is_v3 = True
|
||||
nid = "{:0>4}".format(nid)
|
||||
data[3] = nid
|
||||
if is_v3:
|
||||
data[0] = "{:0>4}".format(data[0])
|
||||
data_id = _SEP.join(data)
|
||||
|
||||
srv_type = int(data[4])
|
||||
transponder_id = "{}:{}:{}".format(data[1], tid, nid)
|
||||
transponder = transponders.get(transponder_id, None)
|
||||
|
||||
@@ -160,9 +207,9 @@ def parse_services(services, transponders, path):
|
||||
onid = str(data[1]).lstrip(sp).upper()
|
||||
# For comparison in bouquets. Needed in upper case!!!
|
||||
fav_id = "{}:{}:{}:{}".format(ssid, tid, nid, onid)
|
||||
picon_id = "1_0_{}_{}_{}_{}_{}_0_0_0.png".format(1, ssid, tid, nid, onid)
|
||||
picon_id = "1_0_{:X}_{}_{}_{}_{}_0_0_0.png".format(srv_type, ssid, tid, nid, onid)
|
||||
|
||||
all_flags = ch[2].split(",")
|
||||
all_flags = srv[2].split(",")
|
||||
coded = CODED_ICON if list(filter(lambda x: x.startswith("C:"), all_flags)) else None
|
||||
flags = list(filter(lambda x: x.startswith("f:"), all_flags))
|
||||
hide = HIDE_ICON if flags and Flag.is_hide(int(flags[0][2:])) else None
|
||||
@@ -173,35 +220,51 @@ def parse_services(services, transponders, path):
|
||||
|
||||
if transponder is not None:
|
||||
tr_type, sp, tr = str(transponder).partition(" ")
|
||||
# Skipping terrestrial and cable channels
|
||||
if tr_type in "tc":
|
||||
continue
|
||||
|
||||
tr_type = TrType(tr_type)
|
||||
tr = tr.split(_SEP)
|
||||
service_type = SERVICE_TYPE.get(data[4], SERVICE_TYPE["-2"])
|
||||
# removing all non printable symbols!
|
||||
srv_name = "".join(c for c in ch[1] if c.isprintable())
|
||||
channels.append(Service(flags_cas=ch[2],
|
||||
transponder_type=tr_type,
|
||||
coded=coded,
|
||||
service=srv_name,
|
||||
locked=locked,
|
||||
hide=hide,
|
||||
package=package,
|
||||
service_type=service_type,
|
||||
picon=None,
|
||||
picon_id=picon_id,
|
||||
ssid=data[0],
|
||||
freq=tr[0],
|
||||
rate=tr[1],
|
||||
pol=POLARIZATION[tr[2]],
|
||||
fec=FEC[tr[3]],
|
||||
system="DVB-S2" if len(tr) > 7 else "DVB-S",
|
||||
pos="{}.{}".format(tr[4][:-1], tr[4][-1:]),
|
||||
data_id=ch[0],
|
||||
fav_id=fav_id,
|
||||
transponder=transponder))
|
||||
return channels
|
||||
srv_name = "".join(c for c in srv[1] if c.isprintable())
|
||||
pol = None
|
||||
fec = None
|
||||
system = None
|
||||
pos = None
|
||||
|
||||
if tr_type is TrType.Satellite:
|
||||
pol = POLARIZATION.get(tr[2], None)
|
||||
fec = FEC.get(tr[3], None)
|
||||
system = "DVB-S2" if len(tr) > 7 else "DVB-S"
|
||||
pos = "{}.{}".format(tr[4][:-1], tr[4][-1:])
|
||||
if tr_type is TrType.Terrestrial:
|
||||
system = T_SYSTEM.get(tr[9], None)
|
||||
pos = "T"
|
||||
fec = T_FEC.get(tr[3], None)
|
||||
elif tr_type is TrType.Cable:
|
||||
system = "DVB-C"
|
||||
pos = "C"
|
||||
fec = FEC_DEFAULT.get(tr[4])
|
||||
|
||||
services_list.append(Service(flags_cas=srv[2],
|
||||
transponder_type=tr_type.value,
|
||||
coded=coded,
|
||||
service=srv_name,
|
||||
locked=locked,
|
||||
hide=hide,
|
||||
package=package,
|
||||
service_type=service_type,
|
||||
picon=None,
|
||||
picon_id=picon_id,
|
||||
ssid=data[0],
|
||||
freq=tr[0],
|
||||
rate=tr[1],
|
||||
pol=pol,
|
||||
fec=fec,
|
||||
system=system,
|
||||
pos=pos,
|
||||
data_id=data_id,
|
||||
fav_id=fav_id,
|
||||
transponder=transponder))
|
||||
return services_list
|
||||
|
||||
|
||||
def split(itr, size):
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
""" Module for IPTV and streams support """
|
||||
import urllib.request
|
||||
from enum import Enum
|
||||
|
||||
from app.properties import Profile
|
||||
@@ -8,6 +9,7 @@ from .ecommons import BqServiceType, Service
|
||||
# url, description, urlkey, account, usrname, psw, s_type, iconsrc, iconsrc_b, group
|
||||
NEUTRINO_FAV_ID_FORMAT = "{}::{}::{}::{}::{}::{}::{}::{}::{}::{}"
|
||||
ENIGMA2_FAV_ID_FORMAT = " {}:0:{}:{:X}:{:X}:{:X}:{:X}:0:0:0:{}:{}\n#DESCRIPTION: {}\n"
|
||||
MARKER_FORMAT = " 1:64:{}:0:0:0:0:0:0:0::{}\n#DESCRIPTION {}\n"
|
||||
|
||||
|
||||
class StreamType(Enum):
|
||||
@@ -18,25 +20,35 @@ class StreamType(Enum):
|
||||
def parse_m3u(path, profile):
|
||||
with open(path) as file:
|
||||
aggr = [None] * 10
|
||||
channels = []
|
||||
count = 0
|
||||
services = []
|
||||
groups = set()
|
||||
counter = 0
|
||||
name = None
|
||||
fav_id = None
|
||||
for line in file.readlines():
|
||||
if line.startswith("#EXTINF"):
|
||||
name = line[1 + line.index(","):].strip()
|
||||
count += 1
|
||||
elif count == 1:
|
||||
count = 0
|
||||
elif line.startswith("#EXTGRP") and profile is Profile.ENIGMA_2:
|
||||
grp_name = line.strip("#EXTGRP:").strip()
|
||||
if grp_name not in groups:
|
||||
groups.add(grp_name)
|
||||
fav_id = MARKER_FORMAT.format(counter, grp_name, grp_name)
|
||||
counter += 1
|
||||
mr = Service(None, None, None, grp_name, *aggr[0:3], BqServiceType.MARKER.name, *aggr, fav_id, None)
|
||||
services.append(mr)
|
||||
elif not line.startswith("#"):
|
||||
url = line.strip()
|
||||
if profile is Profile.ENIGMA_2:
|
||||
fav_id = ENIGMA2_FAV_ID_FORMAT.format(StreamType.NONE_TS.value, 1, 0, 0, 0, 0,
|
||||
line.strip().replace(":", "%3a"), name, name, None)
|
||||
url = urllib.request.quote(line.strip())
|
||||
stream_type = StreamType.NONE_TS.value
|
||||
fav_id = ENIGMA2_FAV_ID_FORMAT.format(stream_type, 1, 0, 0, 0, 0, url, name, name, None)
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
fav_id = NEUTRINO_FAV_ID_FORMAT.format(line.strip(), "", 0, None, None, None, None, "", "", 1)
|
||||
srv = Service(None, None, IPTV_ICON, name, *aggr[0:3], BqServiceType.IPTV.name, *aggr, fav_id, None)
|
||||
channels.append(srv)
|
||||
fav_id = NEUTRINO_FAV_ID_FORMAT.format(url, "", 0, None, None, None, None, "", "", 1)
|
||||
if name and url:
|
||||
srv = Service(None, None, IPTV_ICON, name, *aggr[0:3], BqServiceType.IPTV.name, *aggr, fav_id, None)
|
||||
services.append(srv)
|
||||
|
||||
return channels
|
||||
return services
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
179
app/ftp.py
179
app/ftp.py
@@ -1,179 +0,0 @@
|
||||
import os
|
||||
import socket
|
||||
import time
|
||||
from enum import Enum
|
||||
from ftplib import FTP, error_perm
|
||||
from telnetlib import Telnet
|
||||
|
||||
from app.commons import log, run_task
|
||||
from app.properties import Profile
|
||||
|
||||
__DATA_FILES_LIST = ("tv", "radio", "lamedb", "lamedb5", "blacklist", "whitelist", # enigma 2
|
||||
"services.xml", "myservices.xml", "bouquets.xml", "ubouquets.xml") # neutrino
|
||||
|
||||
_SAT_XML_FILE = "satellites.xml"
|
||||
_WEBTV_XML_FILE = "webtv.xml"
|
||||
|
||||
|
||||
class DownloadType(Enum):
|
||||
ALL = 0
|
||||
BOUQUETS = 1
|
||||
SATELLITES = 2
|
||||
PICONS = 3
|
||||
WEBTV = 4
|
||||
|
||||
|
||||
def download_data(*, properties, download_type=DownloadType.ALL, callback=None):
|
||||
with FTP(host=properties["host"]) as ftp:
|
||||
ftp.login(user=properties["user"], passwd=properties["password"])
|
||||
ftp.encoding = "utf-8"
|
||||
save_path = properties["data_dir_path"]
|
||||
os.makedirs(os.path.dirname(save_path), exist_ok=True)
|
||||
files = []
|
||||
# bouquets section
|
||||
if download_type is DownloadType.ALL or download_type is DownloadType.BOUQUETS:
|
||||
ftp.cwd(properties["services_path"])
|
||||
ftp.dir(files.append)
|
||||
|
||||
for file in files:
|
||||
name = str(file).strip()
|
||||
if name.endswith(__DATA_FILES_LIST):
|
||||
name = name.split()[-1]
|
||||
download_file(ftp, name, save_path)
|
||||
# satellites.xml and webtv section
|
||||
if download_type in (DownloadType.ALL, DownloadType.SATELLITES, DownloadType.WEBTV):
|
||||
ftp.cwd(properties["satellites_xml_path"])
|
||||
files.clear()
|
||||
ftp.dir(files.append)
|
||||
|
||||
for file in files:
|
||||
name = str(file).strip()
|
||||
if download_type in (DownloadType.ALL, DownloadType.SATELLITES) and name.endswith(_SAT_XML_FILE):
|
||||
download_file(ftp, _SAT_XML_FILE, save_path)
|
||||
if download_type in (DownloadType.ALL, DownloadType.WEBTV) and name.endswith(_WEBTV_XML_FILE):
|
||||
download_file(ftp, _WEBTV_XML_FILE, save_path)
|
||||
|
||||
if callback is not None:
|
||||
callback()
|
||||
|
||||
|
||||
@run_task
|
||||
def upload_data(*, properties, download_type=DownloadType.ALL, remove_unused=False, profile=Profile.ENIGMA_2,
|
||||
callback=None):
|
||||
data_path = properties["data_dir_path"]
|
||||
host = properties["host"]
|
||||
# telnet
|
||||
tn = telnet(host=host, user=properties.get("telnet_user", "root"), password=properties.get("telnet_password", ""),
|
||||
timeout=properties.get("telnet_timeout", 5))
|
||||
next(tn)
|
||||
# terminate enigma or neutrino
|
||||
tn.send("init 4")
|
||||
|
||||
with FTP(host=host) as ftp:
|
||||
ftp.login(user=properties["user"], passwd=properties["password"])
|
||||
ftp.encoding = "utf-8"
|
||||
|
||||
if download_type is DownloadType.ALL or download_type is DownloadType.SATELLITES:
|
||||
ftp.cwd(properties["satellites_xml_path"])
|
||||
send = send_file(_SAT_XML_FILE, data_path, ftp)
|
||||
if download_type is DownloadType.SATELLITES:
|
||||
tn.send("init 3" if profile is Profile.ENIGMA_2 else "init 6")
|
||||
if callback is not None:
|
||||
callback()
|
||||
return send
|
||||
|
||||
if profile is Profile.NEUTRINO_MP and download_type in (DownloadType.ALL, DownloadType.WEBTV):
|
||||
ftp.cwd(properties["satellites_xml_path"])
|
||||
send = send_file(_WEBTV_XML_FILE, data_path, ftp)
|
||||
if download_type is DownloadType.WEBTV:
|
||||
tn.send("init 6")
|
||||
if callback is not None:
|
||||
callback()
|
||||
return send
|
||||
|
||||
if download_type is DownloadType.ALL or download_type is DownloadType.BOUQUETS:
|
||||
ftp.cwd(properties["services_path"])
|
||||
if remove_unused:
|
||||
files = []
|
||||
ftp.dir(files.append)
|
||||
for file in files:
|
||||
name = str(file).strip()
|
||||
if name.endswith(__DATA_FILES_LIST):
|
||||
name = name.split()[-1]
|
||||
ftp.delete(name)
|
||||
|
||||
for file_name in os.listdir(data_path):
|
||||
if file_name == _SAT_XML_FILE or file_name == _WEBTV_XML_FILE:
|
||||
continue
|
||||
if file_name.endswith(__DATA_FILES_LIST):
|
||||
send_file(file_name, data_path, ftp)
|
||||
|
||||
if download_type is DownloadType.PICONS:
|
||||
picons_dir_path = properties.get("picons_dir_path")
|
||||
picons_path = properties.get("picons_path")
|
||||
try:
|
||||
ftp.cwd(picons_path)
|
||||
except error_perm as e:
|
||||
if str(e).startswith("550"):
|
||||
ftp.mkd(picons_path) # if not exist
|
||||
ftp.cwd(picons_path)
|
||||
|
||||
files = []
|
||||
ftp.dir(files.append)
|
||||
picons_suf = (".jpg", ".png")
|
||||
|
||||
for file in files:
|
||||
name = str(file).strip()
|
||||
if name.endswith(picons_suf):
|
||||
name = name.split()[-1]
|
||||
ftp.delete(name)
|
||||
for file_name in os.listdir(picons_dir_path):
|
||||
if file_name.endswith(picons_suf):
|
||||
send_file(file_name, picons_dir_path, ftp)
|
||||
|
||||
# resume enigma or restart neutrino
|
||||
tn.send("init 3" if profile is Profile.ENIGMA_2 else "init 6")
|
||||
|
||||
if callback is not None:
|
||||
callback()
|
||||
|
||||
|
||||
def download_file(ftp, name, save_path):
|
||||
with open(save_path + name, "wb") as f:
|
||||
ftp.retrbinary("RETR " + name, f.write)
|
||||
|
||||
|
||||
def send_file(file_name, path, ftp):
|
||||
""" Opens the file in binary mode and transfers into receiver """
|
||||
with open(path + file_name, "rb") as f:
|
||||
return ftp.storbinary("STOR " + file_name, f)
|
||||
|
||||
|
||||
def telnet(host, port=23, user="", password="", timeout=5):
|
||||
try:
|
||||
tn = Telnet(host=host, port=port, timeout=timeout)
|
||||
except socket.timeout:
|
||||
log("telnet error: socket timeout")
|
||||
else:
|
||||
time.sleep(1)
|
||||
command = yield
|
||||
if user != "":
|
||||
tn.read_until(b"login: ")
|
||||
tn.write(user.encode("utf-8") + b"\n")
|
||||
time.sleep(timeout)
|
||||
if password != "":
|
||||
tn.read_until(b"Password: ")
|
||||
tn.write(password.encode("utf-8") + b"\n")
|
||||
time.sleep(timeout)
|
||||
tn.write("{}\r\n".format(command).encode("utf-8"))
|
||||
time.sleep(timeout)
|
||||
command = yield
|
||||
time.sleep(timeout)
|
||||
tn.write("{}\r\n".format(command).encode("utf-8"))
|
||||
time.sleep(timeout)
|
||||
tn.close()
|
||||
yield
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
@@ -39,28 +39,25 @@ def write_config(config):
|
||||
def get_default_settings():
|
||||
return {
|
||||
Profile.ENIGMA_2.value: {
|
||||
"host": "127.0.0.1", "port": "21",
|
||||
"user": "root", "password": "root",
|
||||
"telnet_user": "", "telnet_password": "",
|
||||
"telnet_port": "21", "telnet_timeout": 5,
|
||||
"services_path": "/etc/enigma2/",
|
||||
"user_bouquet_path": "/etc/enigma2/",
|
||||
"satellites_xml_path": "/etc/tuxbox/",
|
||||
"picons_path": "/usr/share/enigma2/picon",
|
||||
"data_dir_path": DATA_PATH + "enigma2/",
|
||||
"picons_dir_path": DATA_PATH + "enigma2/picons/",
|
||||
"v5_support": False},
|
||||
"host": "127.0.0.1", "port": "21", "user": "root", "password": "root",
|
||||
"http_user": "root", "http_password": "", "http_port": "80", "http_timeout": 5,
|
||||
"telnet_user": "root", "telnet_password": "", "telnet_port": "23", "telnet_timeout": 5,
|
||||
"services_path": "/etc/enigma2/", "user_bouquet_path": "/etc/enigma2/",
|
||||
"satellites_xml_path": "/etc/tuxbox/", "data_dir_path": DATA_PATH + "enigma2/",
|
||||
"picons_path": "/usr/share/enigma2/picon", "picons_dir_path": DATA_PATH + "enigma2/picons/",
|
||||
"backup_dir_path": DATA_PATH + "enigma2/backup/",
|
||||
"backup_before_save": True, "backup_before_downloading": True,
|
||||
"v5_support": False, "http_api_support": False,
|
||||
"use_colors": True, "new_color": "rgb(255,230,204)", "extra_color": "rgb(179,230,204)"},
|
||||
Profile.NEUTRINO_MP.value: {
|
||||
"host": "127.0.0.1", "port": "21",
|
||||
"user": "root", "password": "root",
|
||||
"telnet_user": "root", "telnet_password": "",
|
||||
"telnet_port": "21", "telnet_timeout": 1,
|
||||
"services_path": "/var/tuxbox/config/zapit/",
|
||||
"user_bouquet_path": "/var/tuxbox/config/zapit/",
|
||||
"satellites_xml_path": "/var/tuxbox/config/",
|
||||
"picons_path": "/usr/share/tuxbox/neutrino/icons/logo/",
|
||||
"data_dir_path": DATA_PATH + "neutrino/",
|
||||
"picons_dir_path": DATA_PATH + "neutrino/picons/"},
|
||||
"host": "127.0.0.1", "port": "21", "user": "root", "password": "root",
|
||||
"http_user": "", "http_password": "", "http_port": "80", "http_timeout": 2,
|
||||
"telnet_user": "root", "telnet_password": "", "telnet_port": "23", "telnet_timeout": 1,
|
||||
"services_path": "/var/tuxbox/config/zapit/", "user_bouquet_path": "/var/tuxbox/config/zapit/",
|
||||
"satellites_xml_path": "/var/tuxbox/config/", "data_dir_path": DATA_PATH + "neutrino/",
|
||||
"picons_path": "/usr/share/tuxbox/neutrino/icons/logo/", "picons_dir_path": DATA_PATH + "neutrino/picons/",
|
||||
"backup_dir_path": DATA_PATH + "neutrino/backup/",
|
||||
"backup_before_save": True, "backup_before_downloading": True},
|
||||
"profile": Profile.ENIGMA_2.value}
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from app.commons import run_task
|
||||
from app.tools import vlc
|
||||
|
||||
|
||||
@@ -15,13 +16,14 @@ class Player:
|
||||
_VLC_INSTANCE = vlc.Instance("--quiet --no-xlib").media_player_new()
|
||||
return _VLC_INSTANCE
|
||||
|
||||
@run_task
|
||||
def play(self, mrl=None):
|
||||
if not self._is_playing:
|
||||
if mrl:
|
||||
self._player.set_mrl(mrl)
|
||||
self._player.play()
|
||||
self._is_playing = True
|
||||
if mrl:
|
||||
self._player.set_mrl(mrl)
|
||||
self._player.play()
|
||||
self._is_playing = True
|
||||
|
||||
@run_task
|
||||
def stop(self):
|
||||
if self._is_playing:
|
||||
self._player.stop()
|
||||
@@ -30,6 +32,7 @@ class Player:
|
||||
def pause(self):
|
||||
self._player.pause()
|
||||
|
||||
@run_task
|
||||
def release(self):
|
||||
if self._player:
|
||||
self._is_playing = False
|
||||
|
||||
@@ -6,25 +6,26 @@ import shutil
|
||||
from collections import namedtuple
|
||||
from html.parser import HTMLParser
|
||||
|
||||
from app.commons import log, run_task
|
||||
from app.commons import run_task
|
||||
from app.properties import Profile
|
||||
|
||||
_ENIGMA2_PICON_KEY = "{:X}:{:X}:{:X}0000"
|
||||
_ENIGMA2_PICON_KEY = "{:X}:{:X}:{}"
|
||||
_NEUTRINO_PICON_KEY = "{:x}{:04x}{:04x}.png"
|
||||
|
||||
Provider = namedtuple("Provider", ["logo", "name", "pos", "url", "on_id", "selected"])
|
||||
Provider = namedtuple("Provider", ["logo", "name", "pos", "url", "on_id", "ssid", "single", "selected"])
|
||||
Picon = namedtuple("Picon", ["ref", "ssid", "v_pid"])
|
||||
|
||||
|
||||
class PiconsParser(HTMLParser):
|
||||
""" Parser for package html page. (https://www.lyngsat.com/packages/*provider-name*.html) """
|
||||
|
||||
def __init__(self, entities=False, separator=' '):
|
||||
def __init__(self, entities=False, separator=' ', single=None):
|
||||
|
||||
HTMLParser.__init__(self)
|
||||
|
||||
self._parse_html_entities = entities
|
||||
self._separator = separator
|
||||
self._single = single
|
||||
self._is_td = False
|
||||
self._is_th = False
|
||||
self._current_row = []
|
||||
@@ -57,16 +58,20 @@ class PiconsParser(HTMLParser):
|
||||
elif tag == 'tr':
|
||||
row = self._current_row
|
||||
ln = len(row)
|
||||
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]))
|
||||
if self._single and ln == 4 and row[0].startswith("../../logo/"):
|
||||
self.picons.append(Picon(row[0].strip("../"), "0", "0"))
|
||||
else:
|
||||
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 = []
|
||||
|
||||
@@ -74,9 +79,15 @@ class PiconsParser(HTMLParser):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def parse(open_path, picons_path, tmp_path, on_id, pos, picon_ids, profile=Profile.ENIGMA_2):
|
||||
def parse(open_path, picons_path, tmp_path, provider, picon_ids, profile=Profile.ENIGMA_2):
|
||||
with open(open_path, encoding="utf-8", errors="replace") as f:
|
||||
parser = PiconsParser()
|
||||
on_id, pos, ssid, single = provider.on_id, provider.pos, provider.ssid, provider.single
|
||||
neg_pos = pos.endswith("W")
|
||||
pos = int("".join(c for c in pos if c.isdigit()))
|
||||
# For negative (West) positions 3600 - numeric position value!!!
|
||||
if neg_pos:
|
||||
pos = 3600 - pos
|
||||
parser = PiconsParser(single=single)
|
||||
parser.reset()
|
||||
parser.feed(f.read())
|
||||
picons = parser.picons
|
||||
@@ -84,19 +95,25 @@ class PiconsParser(HTMLParser):
|
||||
os.makedirs(picons_path, exist_ok=True)
|
||||
for p in picons:
|
||||
try:
|
||||
name = PiconsParser.format(p.ssid, on_id, p.v_pid, pos, picon_ids, profile)
|
||||
if single:
|
||||
on_id, freq = on_id.strip().split("::")
|
||||
namespace = "{:X}{:X}".format(int(pos), int(freq))
|
||||
else:
|
||||
namespace = "{:X}0000".format(int(pos))
|
||||
name = PiconsParser.format(ssid if single else p.ssid, on_id, namespace, picon_ids, profile)
|
||||
p_name = picons_path + (name if name else os.path.basename(p.ref))
|
||||
shutil.copyfile(tmp_path + "www.lyngsat.com/" + p.ref.lstrip("."), p_name)
|
||||
except (TypeError, ValueError) as e:
|
||||
log("Picons format parse error: {}".format(p) + "\n" + str(e))
|
||||
print(e)
|
||||
msg = "Picons format parse error: {}".format(p) + "\n" + str(e)
|
||||
# log(msg)
|
||||
print(msg)
|
||||
|
||||
@staticmethod
|
||||
def format(ssid, on_id, v_pid, pos, picon_ids, profile: Profile):
|
||||
tr_id = int(ssid[:-2] if len(ssid) < 4 else ssid[:2])
|
||||
def format(ssid, on_id, namespace, picon_ids, profile: Profile):
|
||||
if profile is Profile.ENIGMA_2:
|
||||
return picon_ids.get(_ENIGMA2_PICON_KEY.format(int(ssid), int(on_id), int(pos)), None)
|
||||
return picon_ids.get(_ENIGMA2_PICON_KEY.format(int(ssid), int(on_id), namespace), None)
|
||||
elif profile is Profile.NEUTRINO_MP:
|
||||
tr_id = int(ssid[:-2] if len(ssid) < 4 else ssid[:2])
|
||||
return _NEUTRINO_PICON_KEY.format(tr_id, int(on_id), int(ssid))
|
||||
else:
|
||||
return "{}.png".format(ssid)
|
||||
@@ -106,6 +123,8 @@ class ProviderParser(HTMLParser):
|
||||
""" Parser for satellite html page. (https://www.lyngsat.com/*sat-name*.html) """
|
||||
|
||||
_POSITION_PATTERN = re.compile("at\s\d+\..*(?:E|W)']")
|
||||
_ONID_TID_PATTERN = re.compile("^\d+-\d+.*")
|
||||
_TRANSPONDER_FREQUENCY_PATTERN = re.compile("^\d+ [HVLR]+")
|
||||
_DOMAIN = "https://www.lyngsat.com"
|
||||
_TV_DOMAIN = _DOMAIN + "/tvchannels/"
|
||||
_RADIO_DOMAIN = _DOMAIN + "/radiochannels/"
|
||||
@@ -114,12 +133,13 @@ class ProviderParser(HTMLParser):
|
||||
def __init__(self, entities=False, separator=' '):
|
||||
|
||||
HTMLParser.__init__(self)
|
||||
self.convert_charrefs = False
|
||||
|
||||
self._ON_ID_BLACK_LIST = ("65535", "?", "0", "1")
|
||||
self._parse_html_entities = entities
|
||||
self._separator = separator
|
||||
self._is_td = False
|
||||
self._is_th = False
|
||||
self._is_onid_tid = False
|
||||
self._is_provider = False
|
||||
self._current_row = []
|
||||
self._current_cell = []
|
||||
@@ -127,6 +147,8 @@ class ProviderParser(HTMLParser):
|
||||
self._ids = set()
|
||||
self._prv_names = set()
|
||||
self._positon = None
|
||||
self._on_id = None
|
||||
self._freq = None
|
||||
|
||||
def handle_starttag(self, tag, attrs):
|
||||
if tag == 'td':
|
||||
@@ -140,11 +162,20 @@ class ProviderParser(HTMLParser):
|
||||
url = attrs[0][1]
|
||||
if url.startswith((self._PKG_DOMAIN, self._TV_DOMAIN, self._RADIO_DOMAIN)):
|
||||
self._current_row.append(url)
|
||||
if tag == "font" and len(attrs) == 1:
|
||||
atr = attrs[0]
|
||||
if len(atr) == 2 and atr[1] == "darkgreen":
|
||||
self._is_onid_tid = True
|
||||
|
||||
def handle_data(self, data):
|
||||
""" Save content to a cell """
|
||||
if self._is_td or self._is_th:
|
||||
self._current_cell.append(data.strip())
|
||||
if self._is_onid_tid:
|
||||
m = self._ONID_TID_PATTERN.match(data)
|
||||
if m:
|
||||
self._on_id, tid = m.group().split("-")
|
||||
self._is_onid_tid = False
|
||||
|
||||
def handle_endtag(self, tag):
|
||||
if tag == 'td':
|
||||
@@ -165,18 +196,38 @@ class ProviderParser(HTMLParser):
|
||||
self._positon = "".join(c for c in str(pos) if c.isdigit() or c in ".EW")
|
||||
|
||||
len_row = len(r)
|
||||
if len_row > 2:
|
||||
m = self._TRANSPONDER_FREQUENCY_PATTERN.match(r[1])
|
||||
if m:
|
||||
self._freq = m.group().split()[0]
|
||||
|
||||
if len_row == 12:
|
||||
# Providers
|
||||
name = r[5]
|
||||
self._prv_names.add(name)
|
||||
on_id, sep, tid = str(r[-2]).partition("-")
|
||||
if tid and on_id not in self._ON_ID_BLACK_LIST and on_id not in self._ids:
|
||||
r[-2] = on_id
|
||||
self._ids.add(on_id)
|
||||
r[0] = self._positon
|
||||
if name + on_id not in self._prv_names:
|
||||
self._prv_names.add(name + on_id)
|
||||
self.rows.append(Provider(logo=r[2], name=name, pos=r[0], url=r[6], on_id=r[-2], selected=True))
|
||||
m = self._ONID_TID_PATTERN.match(str(r[-2]))
|
||||
if m:
|
||||
on_id, tid = m.group().split("-")
|
||||
if on_id not in self._ids:
|
||||
r[-2] = on_id
|
||||
self._ids.add(on_id)
|
||||
r[0] = self._positon
|
||||
if name + on_id not in self._prv_names:
|
||||
self._prv_names.add(name + on_id)
|
||||
self.rows.append(Provider(logo=r[2], name=name, pos=self._positon, url=r[6], on_id=on_id,
|
||||
ssid=None, single=False, selected=True))
|
||||
elif 6 < len_row < 10:
|
||||
# Single services
|
||||
name, url, ssid = None, None, None
|
||||
if r[0].startswith("http"):
|
||||
name, url, ssid = r[1], r[0], r[4]
|
||||
elif r[1].startswith("http"):
|
||||
name, url, ssid = r[2], r[1], r[5]
|
||||
|
||||
if name and url:
|
||||
on_id = "{}::{}".format(self._on_id if self._on_id else "1", self._freq)
|
||||
self.rows.append(Provider(logo=None, name=name, pos=self._positon, url=url, on_id=on_id,
|
||||
ssid=ssid, single=True, selected=False))
|
||||
|
||||
self._current_row = []
|
||||
|
||||
|
||||
@@ -76,12 +76,17 @@ class SatellitesParser(HTMLParser):
|
||||
self._source = source
|
||||
|
||||
for src in SatelliteSource.get_sources(self._source):
|
||||
request = requests.get(url=src, headers=self._HEADERS)
|
||||
reason = request.reason
|
||||
if reason == "OK":
|
||||
self.feed(request.text)
|
||||
try:
|
||||
request = requests.get(url=src, headers=self._HEADERS)
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
print(repr(e))
|
||||
return []
|
||||
else:
|
||||
print(reason)
|
||||
reason = request.reason
|
||||
if reason == "OK":
|
||||
self.feed(request.text)
|
||||
else:
|
||||
print(reason)
|
||||
|
||||
if self._rows:
|
||||
if self._source is SatelliteSource.FLYSAT:
|
||||
@@ -197,8 +202,4 @@ class SatellitesParser(HTMLParser):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = SatellitesParser(source=SatelliteSource.LYNGSAT)
|
||||
satts = parser.get_satellites_list(SatelliteSource.LYNGSAT)
|
||||
if satts:
|
||||
# list(map(print, satts))
|
||||
print("Parsed: ", len(satts))
|
||||
pass
|
||||
|
||||
207
app/ui/backup.py
Normal file
207
app/ui/backup.py
Normal file
@@ -0,0 +1,207 @@
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import time
|
||||
import zipfile
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
|
||||
from app.commons import run_idle
|
||||
from app.properties import Profile
|
||||
from app.ui.dialogs import show_dialog, DialogType
|
||||
from app.ui.main_helper import append_text_to_tview
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, KeyboardKey
|
||||
|
||||
|
||||
class RestoreType(Enum):
|
||||
BOUQUETS = 0
|
||||
ALL = 1
|
||||
|
||||
|
||||
class BackupDialog:
|
||||
def __init__(self, transient, options, profile, callback):
|
||||
handlers = {"on_restore_bouquets": self.on_restore_bouquets,
|
||||
"on_restore_all": self.on_restore_all,
|
||||
"on_remove": self.on_remove,
|
||||
"on_view_popup_menu": self.on_view_popup_menu,
|
||||
"on_info_button_toggled": self.on_info_button_toggled,
|
||||
"on_info_bar_close": self.on_info_bar_close,
|
||||
"on_cursor_changed": self.on_cursor_changed,
|
||||
"on_resize": self.on_resize,
|
||||
"on_key_release": self.on_key_release}
|
||||
|
||||
builder = Gtk.Builder()
|
||||
builder.set_translation_domain("demon-editor")
|
||||
builder.add_from_file(UI_RESOURCES_PATH + "backup_dialog.glade")
|
||||
builder.connect_signals(handlers)
|
||||
|
||||
self._options = options.get(profile.value)
|
||||
self._data_path = self._options.get("data_dir_path", "")
|
||||
self._backup_path = self._options.get("backup_dir_path", self._data_path + "backup/")
|
||||
self._profile = profile
|
||||
self._open_data_callback = callback
|
||||
self._dialog_window = builder.get_object("dialog_window")
|
||||
self._dialog_window.set_transient_for(transient)
|
||||
self._model = builder.get_object("main_list_store")
|
||||
self._main_view = builder.get_object("main_view")
|
||||
self._text_view = builder.get_object("text_view")
|
||||
self._text_view_scrolled_window = builder.get_object("text_view_scrolled_window")
|
||||
self._info_check_button = builder.get_object("info_check_button")
|
||||
self._info_bar = builder.get_object("info_bar")
|
||||
self._message_label = builder.get_object("message_label")
|
||||
# Setting the last size of the dialog window if it was saved
|
||||
window_size = self._options.get("backup_tool_window_size", None)
|
||||
if window_size:
|
||||
self._dialog_window.resize(*window_size)
|
||||
|
||||
self.init_data()
|
||||
|
||||
def show(self):
|
||||
self._dialog_window.show()
|
||||
|
||||
def init_data(self):
|
||||
try:
|
||||
files = os.listdir(self._backup_path)
|
||||
except FileNotFoundError as e:
|
||||
self.show_info_message(str(e), Gtk.MessageType.ERROR)
|
||||
else:
|
||||
for file in filter(lambda x: x.endswith(".zip"), files):
|
||||
self._model.append((file.rstrip(".zip"), False))
|
||||
|
||||
def on_restore_bouquets(self, item):
|
||||
self.restore(RestoreType.BOUQUETS)
|
||||
|
||||
def on_restore_all(self, item):
|
||||
self.restore(RestoreType.ALL)
|
||||
|
||||
def on_remove(self, item):
|
||||
model, paths = self._main_view.get_selection().get_selected_rows()
|
||||
if not paths:
|
||||
show_dialog(DialogType.ERROR, self._dialog_window, "No selected item!")
|
||||
return
|
||||
|
||||
if show_dialog(DialogType.QUESTION, self._dialog_window) == Gtk.ResponseType.CANCEL:
|
||||
return
|
||||
|
||||
itrs_to_delete = []
|
||||
try:
|
||||
for itr in map(model.get_iter, paths):
|
||||
file_name = model.get_value(itr, 0)
|
||||
os.remove("{}{}{}".format(self._backup_path, file_name, ".zip"))
|
||||
itrs_to_delete.append(itr)
|
||||
except FileNotFoundError as e:
|
||||
self.show_info_message(str(e), Gtk.MessageType.ERROR)
|
||||
else:
|
||||
list(map(model.remove, itrs_to_delete))
|
||||
|
||||
def on_view_popup_menu(self, menu, event):
|
||||
if event.get_event_type() == Gdk.EventType.BUTTON_PRESS and event.button == Gdk.BUTTON_SECONDARY:
|
||||
menu.popup(None, None, None, None, event.button, event.time)
|
||||
|
||||
def on_info_button_toggled(self, button):
|
||||
active = button.get_active()
|
||||
self._text_view_scrolled_window.set_visible(active)
|
||||
if active:
|
||||
self.on_cursor_changed(self._main_view)
|
||||
|
||||
@run_idle
|
||||
def show_info_message(self, text, message_type):
|
||||
self._info_bar.set_visible(True)
|
||||
self._info_bar.set_message_type(message_type)
|
||||
self._message_label.set_text(text)
|
||||
|
||||
def on_info_bar_close(self, bar=None, resp=None):
|
||||
self._info_bar.set_visible(False)
|
||||
|
||||
def on_cursor_changed(self, view):
|
||||
if not self._info_check_button.get_active():
|
||||
return
|
||||
|
||||
model, paths = view.get_selection().get_selected_rows()
|
||||
if paths:
|
||||
try:
|
||||
file_name = self._backup_path + model.get_value(model.get_iter(paths[0]), 0) + ".zip"
|
||||
created = time.ctime(os.path.getctime(file_name))
|
||||
self._text_view.get_buffer().set_text(
|
||||
"Created: {}\n********** Files: **********\n".format(created))
|
||||
with zipfile.ZipFile(file_name) as zip_file:
|
||||
for name in zip_file.namelist():
|
||||
append_text_to_tview(name + "\n", self._text_view)
|
||||
except FileNotFoundError as e:
|
||||
self.show_info_message(str(e), Gtk.MessageType.ERROR)
|
||||
|
||||
def restore(self, restore_type):
|
||||
model, paths = self._main_view.get_selection().get_selected_rows()
|
||||
if not paths:
|
||||
show_dialog(DialogType.ERROR, self._dialog_window, "No selected item!")
|
||||
return
|
||||
|
||||
if len(paths) > 1:
|
||||
show_dialog(DialogType.ERROR, self._dialog_window, "Please, select only one item!")
|
||||
return
|
||||
|
||||
if show_dialog(DialogType.QUESTION, self._dialog_window) == Gtk.ResponseType.CANCEL:
|
||||
return
|
||||
|
||||
file_name = model.get_value(model.get_iter(paths[0]), 0)
|
||||
full_file_name = self._backup_path + file_name + ".zip"
|
||||
|
||||
try:
|
||||
if restore_type is RestoreType.ALL:
|
||||
clear_data_path(self._data_path)
|
||||
shutil.unpack_archive(full_file_name, self._data_path)
|
||||
elif restore_type is RestoreType.BOUQUETS:
|
||||
tmp_dir = tempfile.gettempdir() + "/" + file_name
|
||||
cond = (".tv", ".radio") if self._profile is Profile.ENIGMA_2 else "bouquets.xml"
|
||||
shutil.unpack_archive(full_file_name, tmp_dir)
|
||||
for file in filter(lambda f: f.endswith(cond), os.listdir(self._data_path)):
|
||||
os.remove(os.path.join(self._data_path, file))
|
||||
for file in filter(lambda f: f.endswith(cond), os.listdir(tmp_dir)):
|
||||
shutil.move(os.path.join(tmp_dir, file), self._data_path + file)
|
||||
shutil.rmtree(tmp_dir)
|
||||
except FileNotFoundError as e:
|
||||
self.show_info_message(str(e), Gtk.MessageType.ERROR)
|
||||
else:
|
||||
self.show_info_message("Done!", Gtk.MessageType.INFO)
|
||||
self._open_data_callback(self._data_path)
|
||||
|
||||
def on_resize(self, window):
|
||||
if self._options:
|
||||
self._options["backup_tool_window_size"] = window.get_size()
|
||||
|
||||
def on_key_release(self, view, event):
|
||||
""" Handling keystrokes """
|
||||
key_code = event.hardware_keycode
|
||||
if not KeyboardKey.value_exist(key_code):
|
||||
return
|
||||
key = KeyboardKey(key_code)
|
||||
ctrl = event.state & Gdk.ModifierType.CONTROL_MASK
|
||||
|
||||
if key is KeyboardKey.DELETE:
|
||||
self.on_remove(view)
|
||||
elif ctrl and key is KeyboardKey.E:
|
||||
self.restore(RestoreType.ALL)
|
||||
elif ctrl and key is KeyboardKey.R:
|
||||
self.restore(RestoreType.BOUQUETS)
|
||||
|
||||
|
||||
def backup_data(path, backup_path):
|
||||
""" Creating data backup from a folder at the specified path """
|
||||
backup_path = "{}{}/".format(backup_path, datetime.now().strftime("%Y-%m-%d_%H-%M-%S"))
|
||||
os.makedirs(os.path.dirname(backup_path), exist_ok=True)
|
||||
# backup files in data dir(skipping dirs and satellites.xml)
|
||||
for file in filter(lambda f: f != "satellites.xml" and os.path.isfile(os.path.join(path, f)), os.listdir(path)):
|
||||
shutil.move(os.path.join(path, file), backup_path + file)
|
||||
# compressing to zip and delete remaining files
|
||||
shutil.make_archive(backup_path, "zip", backup_path)
|
||||
shutil.rmtree(backup_path)
|
||||
|
||||
|
||||
def clear_data_path(path):
|
||||
""" Clearing data at the specified path excluding satellites.xml file """
|
||||
for file in filter(lambda f: f != "satellites.xml" and os.path.isfile(os.path.join(path, f)), os.listdir(path)):
|
||||
os.remove(os.path.join(path, file))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
355
app/ui/backup_dialog.glade
Normal file
355
app/ui/backup_dialog.glade
Normal file
@@ -0,0 +1,355 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 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
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Author: Dmitriy Yefremov
|
||||
|
||||
-->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.16"/>
|
||||
<!-- interface-license-type mit -->
|
||||
<!-- interface-name DemonEditor -->
|
||||
<!-- interface-description Enigma2 channel and satellites list editor for GNU/Linux. -->
|
||||
<!-- interface-copyright 2018 Dmitriy Yefremov -->
|
||||
<!-- interface-authors Dmitriy Yefremov -->
|
||||
<object class="GtkListStore" id="main_list_store">
|
||||
<columns>
|
||||
<!-- column-name date -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name selected -->
|
||||
<column type="gboolean"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkWindow" id="dialog_window">
|
||||
<property name="width_request">560</property>
|
||||
<property name="height_request">320</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="icon_name">document-revert</property>
|
||||
<property name="gravity">center</property>
|
||||
<signal name="check-resize" handler="on_resize" swapped="no"/>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header_bar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Backups</property>
|
||||
<property name="spacing">2</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="header_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="restore_bouquets_header_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Restore bouquets</property>
|
||||
<signal name="clicked" handler="on_restore_bouquets" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="restore_bouquets_header_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">document-revert</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="restore_all_header_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Restore all</property>
|
||||
<signal name="clicked" handler="on_restore_all" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="restore_all_header_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">edit-select-all</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<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">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="remove_header_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Remove</property>
|
||||
<signal name="clicked" handler="on_remove" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="remove_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">user-trash</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="info_check_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">False</property>
|
||||
<signal name="toggled" handler="on_info_button_toggled" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="info_check_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-dialog-info</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="main_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkPaned" id="main_paned">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="wide_handle">True</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="main_view_scrolled_window">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="main_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hexpand">True</property>
|
||||
<property name="model">main_list_store</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<property name="search_column">0</property>
|
||||
<property name="rubber_banding">True</property>
|
||||
<property name="activate_on_single_click">True</property>
|
||||
<signal name="button-press-event" handler="on_view_popup_menu" object="popup_menu" swapped="no"/>
|
||||
<signal name="cursor-changed" handler="on_cursor_changed" swapped="no"/>
|
||||
<signal name="key-release-event" handler="on_key_release" swapped="no"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="main_view_selection">
|
||||
<property name="mode">multiple</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="backup_date_column">
|
||||
<property name="title" translatable="yes">Backup</property>
|
||||
<property name="clickable">True</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<property name="reorderable">True</property>
|
||||
<property name="sort_column_id">0</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="date_render">
|
||||
<property name="xpad">10</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="text_view_scrolled_window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="text_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="pixels_above_lines">5</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="left_margin">10</property>
|
||||
<property name="right_margin">10</property>
|
||||
<property name="indent">10</property>
|
||||
<property name="cursor_visible">False</property>
|
||||
<property name="accepts_tab">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="resize">True</property>
|
||||
<property name="shrink">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkInfoBar" id="info_bar">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<signal name="response" handler="on_info_bar_close" swapped="no"/>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">6</property>
|
||||
<property name="layout_style">end</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">16</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="message_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">message</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</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>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkImage" id="restore_popup_menu_item_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-revert-to-saved</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="restore_popup_menu_item_image2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-select-all</property>
|
||||
</object>
|
||||
<object class="GtkMenu" id="popup_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="restore_bouquets_popup_menu_item">
|
||||
<property name="label" translatable="yes">Restore bouquets</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">restore_popup_menu_item_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_restore_bouquets" swapped="no"/>
|
||||
<accelerator key="r" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="restore_all_popup_menu_item">
|
||||
<property name="label" translatable="yes">Restore all</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">restore_popup_menu_item_image2</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_restore_all" swapped="no"/>
|
||||
<accelerator key="e" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="popup_menu_separator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="remove_popup_menu_item">
|
||||
<property name="label">gtk-remove</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_remove" swapped="no"/>
|
||||
<accelerator key="Delete" signal="activate"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -40,15 +40,16 @@ 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">0.4.0 Pre-alpha</property>
|
||||
<property name="version">0.4.3 Pre-alpha</property>
|
||||
<property name="copyright">2018 Dmitriy Yefremov
|
||||
</property>
|
||||
<property name="comments" translatable="yes">Enigma2 channel and satellites list editor for GNU/Linux</property>
|
||||
<property name="website">https://github.com/DYefremov/DemonEditor</property>
|
||||
<property name="website">https://dyefremov.github.io/DemonEditor/</property>
|
||||
<property name="license" translatable="yes">Это приложение распространяется без каких-либо гарантий.
|
||||
Подробнее в <a href="http://opensource.org/licenses/mit-license.php">The MIT License (MIT)</a>.</property>
|
||||
<property name="authors">Dmitriy Yefremov
|
||||
</property>
|
||||
<property name="translator_credits" translatable="yes">translator-credits</property>
|
||||
<property name="logo_icon_name">accessories-text-editor</property>
|
||||
<property name="wrap_license">True</property>
|
||||
<property name="license_type">mit-x11</property>
|
||||
@@ -74,388 +75,6 @@ Author: Dmitriy Yefremov
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkDialog" id="download_dialog">
|
||||
<property name="width_request">320</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="default_width">320</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="icon_name">mail-send-receive</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="width_request">85</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Receive</property>
|
||||
<signal name="clicked" handler="on_receive" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="receive_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-goto-bottom</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="title">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">FTP-transfer</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton">
|
||||
<property name="width_request">85</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Send</property>
|
||||
<signal name="clicked" handler="on_send" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="send_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-goto-top</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">cancel_download_dialog_button</action-widget>
|
||||
</action-widgets>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="download_dialog_vbox">
|
||||
<property name="width_request">320</property>
|
||||
<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="doawload_dialog_action_area">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="cancel_download_dialog_button">
|
||||
<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>
|
||||
</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="download_dialog_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="download_dialog_grid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Receive</property>
|
||||
<property name="column_spacing">2</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label9">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="label" translatable="yes">Receiver IP:</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="host_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="max_width_chars">10</property>
|
||||
<property name="text">127.0.0.1</property>
|
||||
<property name="caps_lock_warning">False</property>
|
||||
<property name="primary_icon_name">network-transmit-receive-symbolic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label11">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="label" translatable="yes">Current data path:</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="data_path_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="text">data/</property>
|
||||
<property name="caps_lock_warning">False</property>
|
||||
<property name="primary_icon_name">folder-open-symbolic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="download_dialog_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label_xalign">0.019999999552965164</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="download_dialogbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label10">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="all_radio_button">
|
||||
<property name="label" translatable="yes">All</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">satellites_radio_button</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="bouquets_radio_button">
|
||||
<property name="label" translatable="yes">Bouquets</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">satellites_radio_button</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="satellites_radio_button">
|
||||
<property name="label" translatable="yes">Satellites</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">all_radio_button</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="webtv_radio_button">
|
||||
<property name="label" translatable="yes">WebTV</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">all_radio_button</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="download_dialog_data_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Data:</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="box1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="remove_unused_check_button">
|
||||
<property name="label" translatable="yes">Remove unused bouquets</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="separator4">
|
||||
<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">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkInfoBar" id="info_bar">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<signal name="response" handler="on_info_bar_close" swapped="no"/>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="infobar-action_area1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">expand</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox" id="infobar-content_area1">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">16</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="info_bar_message_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Info</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">cancel_download_dialog_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkMessageDialog" id="error_dialog">
|
||||
<property name="width_request">320</property>
|
||||
<property name="can_focus">False</property>
|
||||
|
||||
694
app/ui/download_dialog.glade
Normal file
694
app/ui/download_dialog.glade
Normal file
@@ -0,0 +1,694 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 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
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Author: Dmitriy Yefremov
|
||||
|
||||
-->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.16"/>
|
||||
<!-- interface-license-type mit -->
|
||||
<!-- interface-name DemonEditor -->
|
||||
<!-- interface-description Enigma2 channel and satellites list editor for GNU/Linux. -->
|
||||
<!-- interface-copyright 2018 Dmitriy Yefremov -->
|
||||
<!-- interface-authors Dmitriy Yefremov -->
|
||||
<object class="GtkWindow" id="download_dialog_window">
|
||||
<property name="width_request">500</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="icon_name">mail-send-receive</property>
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="skip_pager_hint">True</property>
|
||||
<property name="gravity">center</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header_bar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">5</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="header_left_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="receive_button">
|
||||
<property name="width_request">48</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Receive</property>
|
||||
<signal name="clicked" handler="on_receive" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="receive_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-goto-bottom</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="send_button">
|
||||
<property name="width_request">48</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Send</property>
|
||||
<signal name="clicked" handler="on_send" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="send_button_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-goto-top</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="title">
|
||||
<object class="GtkBox" id="header_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">2</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="header_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">FTP-transfer</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="header_data_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label10">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="xalign">0</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="all_radio_button">
|
||||
<property name="label" translatable="yes">All</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">satellites_radio_button</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="bouquets_radio_button">
|
||||
<property name="label" translatable="yes">Bouquets</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">satellites_radio_button</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="satellites_radio_button">
|
||||
<property name="label" translatable="yes">Satellites</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">all_radio_button</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="webtv_radio_button">
|
||||
<property name="label" translatable="yes">WebTV</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
<property name="group">all_radio_button</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="options_button">
|
||||
<property name="width_request">48</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Options</property>
|
||||
<signal name="clicked" handler="on_preferences" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-properties</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="main_dialog_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">1</property>
|
||||
<property name="margin_right">1</property>
|
||||
<property name="margin_bottom">1</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="main_settings_box_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="label_xalign">0.019999999552965164</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="main_settings_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="main_settings_bo">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="row_spacing">2</property>
|
||||
<property name="column_spacing">2</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="ip_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Receiver IP:</property>
|
||||
<property name="xalign">0.10000000149011612</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="host_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="max_width_chars">10</property>
|
||||
<property name="text">127.0.0.1</property>
|
||||
<property name="caps_lock_warning">False</property>
|
||||
<property name="primary_icon_name">network-transmit-receive-symbolic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="data_path_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Current data path:</property>
|
||||
<property name="xalign">0.10000000149011612</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="data_path_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="text">data/</property>
|
||||
<property name="caps_lock_warning">False</property>
|
||||
<property name="primary_icon_name">folder-open-symbolic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">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="GtkBox" id="extra_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="remove_unused_check_button">
|
||||
<property name="label" translatable="yes">Remove unused bouquets</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="use_http_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="use_http_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Use HTTP</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="use_http_switch">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Use http to reload data in the receiver.</property>
|
||||
<property name="active">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label_item">
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame" id="settings_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="label_xalign">0.019999999552965164</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkGrid" id="settings_grid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="row_spacing">2</property>
|
||||
<property name="column_spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="login_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Login:</property>
|
||||
<property name="xalign">0.10000000149011612</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="login_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="text">root</property>
|
||||
<property name="caps_lock_warning">False</property>
|
||||
<property name="primary_icon_name">avatar-default-symbolic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="password_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Password:</property>
|
||||
<property name="xalign">0.10000000149011612</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="password_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="invisible_char">●</property>
|
||||
<property name="text">root</property>
|
||||
<property name="primary_icon_name">emblem-readonly</property>
|
||||
<property name="input_purpose">password</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="port_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Port:</property>
|
||||
<property name="xalign">0.10000000149011612</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="port_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="width_chars">8</property>
|
||||
<property name="max_width_chars">8</property>
|
||||
<property name="text" translatable="yes">21</property>
|
||||
<property name="caps_lock_warning">False</property>
|
||||
<property name="primary_icon_name">network-workgroup-symbolic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="timeout_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="width_chars">8</property>
|
||||
<property name="max_width_chars">8</property>
|
||||
<property name="caps_lock_warning">False</property>
|
||||
<property name="primary_icon_name">alarm-symbolic</property>
|
||||
<property name="input_purpose">digits</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">3</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="timeout_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Timeout:</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">3</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkBox" id="settings_buttons_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="ftp_radio_button">
|
||||
<property name="label" translatable="yes">FTP</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="active">True</property>
|
||||
<property name="draw_indicator">False</property>
|
||||
<property name="group">telnet_radio_button</property>
|
||||
<signal name="toggled" handler="on_settings_button" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="http_radio_button">
|
||||
<property name="label" translatable="yes">HTTP</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">False</property>
|
||||
<property name="group">telnet_radio_button</property>
|
||||
<signal name="toggled" handler="on_settings_button" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkRadioButton" id="telnet_radio_button">
|
||||
<property name="label" translatable="yes">Telnet</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="draw_indicator">False</property>
|
||||
<property name="group">ftp_radio_button</property>
|
||||
<signal name="toggled" handler="on_settings_button" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkExpander" id="expander">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin_left">1</property>
|
||||
<property name="margin_right">1</property>
|
||||
<property name="margin_bottom">1</property>
|
||||
<property name="resize_toplevel">True</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="scrolled_window">
|
||||
<property name="height_request">120</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTextView" id="text_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="left_margin">5</property>
|
||||
<property name="right_margin">5</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="expander_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Extra:</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkInfoBar" id="info_bar">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">1</property>
|
||||
<property name="margin_right">1</property>
|
||||
<property name="margin_bottom">1</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<signal name="response" handler="on_info_bar_close" swapped="no"/>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<property name="layout_style">expand</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">16</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="info_bar_message_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Info</property>
|
||||
</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">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
@@ -1,52 +1,82 @@
|
||||
from gi.repository import GLib
|
||||
|
||||
from app.commons import run_idle, run_task
|
||||
from app.ftp import download_data, DownloadType, upload_data
|
||||
from app.properties import Profile
|
||||
from app.connections import download_data, DownloadType, upload_data
|
||||
from app.properties import Profile, get_config
|
||||
from app.ui.backup import backup_data
|
||||
from app.ui.main_helper import append_text_to_tview
|
||||
from app.ui.settings_dialog import show_settings_dialog
|
||||
from .uicommons import Gtk, UI_RESOURCES_PATH, TEXT_DOMAIN
|
||||
from .dialogs import show_dialog, DialogType, get_message
|
||||
|
||||
|
||||
def show_download_dialog(transient, options, open_data, profile=Profile.ENIGMA_2):
|
||||
dialog = DownloadDialog(transient, options, open_data, profile)
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
|
||||
class DownloadDialog:
|
||||
def __init__(self, transient, properties, open_data, profile):
|
||||
def __init__(self, transient, properties, open_data_callback, profile=Profile.ENIGMA_2):
|
||||
self._profile_properties = properties.get(profile.value)
|
||||
self._properties = properties
|
||||
self._open_data = open_data
|
||||
self._open_data_callback = open_data_callback
|
||||
self._profile = profile
|
||||
|
||||
handlers = {"on_receive": self.on_receive,
|
||||
"on_send": self.on_send,
|
||||
"on_settings_button": self.on_settings_button,
|
||||
"on_preferences": self.on_preferences,
|
||||
"on_info_bar_close": self.on_info_bar_close}
|
||||
|
||||
builder = Gtk.Builder()
|
||||
builder.set_translation_domain(TEXT_DOMAIN)
|
||||
builder.add_objects_from_file(UI_RESOURCES_PATH + "dialogs.glade", ("download_dialog",))
|
||||
builder.add_from_file(UI_RESOURCES_PATH + "download_dialog.glade")
|
||||
builder.connect_signals(handlers)
|
||||
|
||||
self._dialog = builder.get_object("download_dialog")
|
||||
self._dialog.set_transient_for(transient)
|
||||
self._current_property = "FTP"
|
||||
self._dialog_window = builder.get_object("download_dialog_window")
|
||||
self._dialog_window.set_transient_for(transient)
|
||||
self._info_bar = builder.get_object("info_bar")
|
||||
self._message_label = builder.get_object("info_bar_message_label")
|
||||
self._host_entry = builder.get_object("host_entry").set_text(properties["host"])
|
||||
self._data_path_entry = builder.get_object("data_path_entry").set_text(properties["data_dir_path"])
|
||||
self._text_view = builder.get_object("text_view")
|
||||
self._expander = builder.get_object("expander")
|
||||
|
||||
self._host_entry = builder.get_object("host_entry")
|
||||
self._data_path_entry = builder.get_object("data_path_entry")
|
||||
self._remove_unused_check_button = builder.get_object("remove_unused_check_button")
|
||||
self._all_radio_button = builder.get_object("all_radio_button")
|
||||
self._bouquets_radio_button = builder.get_object("bouquets_radio_button")
|
||||
self._satellites_radio_button = builder.get_object("satellites_radio_button")
|
||||
self._webtv_radio_button = builder.get_object("webtv_radio_button")
|
||||
self._login_entry = builder.get_object("login_entry")
|
||||
self._password_entry = builder.get_object("password_entry")
|
||||
self._host_entry = builder.get_object("host_entry")
|
||||
self._port_entry = builder.get_object("port_entry")
|
||||
self._timeout_entry = builder.get_object("timeout_entry")
|
||||
self._settings_buttons_box = builder.get_object("settings_buttons_box")
|
||||
self._use_http_switch = builder.get_object("use_http_switch")
|
||||
self.init_properties()
|
||||
|
||||
if profile is Profile.NEUTRINO_MP:
|
||||
self._webtv_radio_button.set_visible(True)
|
||||
builder.get_object("http_radio_button").set_visible(False)
|
||||
builder.get_object("use_http_box").set_visible(False)
|
||||
self._use_http_switch.set_active(False)
|
||||
|
||||
def show(self):
|
||||
self._dialog_window.show()
|
||||
|
||||
def init_properties(self):
|
||||
self._host_entry.set_text(self._profile_properties["host"])
|
||||
self._data_path_entry.set_text(self._profile_properties["data_dir_path"])
|
||||
|
||||
@run_idle
|
||||
def on_receive(self, item):
|
||||
if self._profile_properties.get("backup_before_downloading", True):
|
||||
data_path = self._profile_properties.get("data_dir_path", self._data_path_entry.get_text())
|
||||
backup_path = self._profile_properties.get("backup_dir_path", data_path + "backup/")
|
||||
backup_data(data_path, backup_path)
|
||||
|
||||
self.download(True, self.get_download_type())
|
||||
|
||||
@run_idle
|
||||
def on_send(self, item):
|
||||
if show_dialog(DialogType.QUESTION, self._dialog) != Gtk.ResponseType.CANCEL:
|
||||
if show_dialog(DialogType.QUESTION, self._dialog_window) != Gtk.ResponseType.CANCEL:
|
||||
self.download(False, self.get_download_type())
|
||||
|
||||
def get_download_type(self):
|
||||
@@ -56,37 +86,69 @@ class DownloadDialog:
|
||||
elif self._satellites_radio_button.get_active():
|
||||
download_type = DownloadType.SATELLITES
|
||||
elif self._webtv_radio_button.get_active():
|
||||
download_type = DownloadType.WEBTV
|
||||
download_type = DownloadType.WEB_TV
|
||||
return download_type
|
||||
|
||||
def run(self):
|
||||
return self._dialog.run()
|
||||
|
||||
def destroy(self):
|
||||
self._dialog.destroy()
|
||||
self._dialog_window.destroy()
|
||||
|
||||
def on_settings_button(self, button):
|
||||
if button.get_active():
|
||||
label = button.get_label()
|
||||
if label == "Telnet":
|
||||
self._login_entry.set_text(self._profile_properties.get("telnet_user", ""))
|
||||
self._password_entry.set_text(self._profile_properties.get("telnet_password", ""))
|
||||
self._port_entry.set_text(self._profile_properties.get("telnet_port", ""))
|
||||
self._timeout_entry.set_text(str(self._profile_properties.get("telnet_timeout", 0)))
|
||||
elif label == "HTTP":
|
||||
self._login_entry.set_text(self._profile_properties.get("http_user", "root"))
|
||||
self._password_entry.set_text(self._profile_properties.get("http_password", ""))
|
||||
self._port_entry.set_text(self._profile_properties.get("http_port", ""))
|
||||
self._timeout_entry.set_text(str(self._profile_properties.get("http_timeout", 0)))
|
||||
elif label == "FTP":
|
||||
self._login_entry.set_text(self._profile_properties.get("user", ""))
|
||||
self._password_entry.set_text(self._profile_properties.get("password", ""))
|
||||
self._port_entry.set_text(self._profile_properties.get("port", ""))
|
||||
self._timeout_entry.set_text("")
|
||||
self._current_property = label
|
||||
|
||||
def on_preferences(self, item):
|
||||
show_settings_dialog(self._dialog_window, self._properties)
|
||||
self._profile_properties = get_config().get(self._profile.value)
|
||||
|
||||
for button in self._settings_buttons_box.get_children():
|
||||
if button.get_active():
|
||||
self.on_settings_button(button)
|
||||
self.init_properties()
|
||||
break
|
||||
|
||||
def on_info_bar_close(self, bar=None, resp=None):
|
||||
self._info_bar.set_visible(False)
|
||||
|
||||
@run_idle
|
||||
@run_task
|
||||
def download(self, download, d_type):
|
||||
""" Download/upload data from/to receiver """
|
||||
try:
|
||||
self._expander.set_expanded(True)
|
||||
self.clear_output()
|
||||
|
||||
if download:
|
||||
download_data(properties=self._properties, download_type=d_type)
|
||||
download_data(properties=self._profile_properties, download_type=d_type, callback=self.append_output)
|
||||
else:
|
||||
self.show_info_message(get_message("Please, wait..."), Gtk.MessageType.INFO)
|
||||
upload_data(properties=self._properties,
|
||||
upload_data(properties=self._profile_properties,
|
||||
download_type=d_type,
|
||||
remove_unused=self._remove_unused_check_button.get_active(),
|
||||
profile=self._profile,
|
||||
callback=lambda: self.show_info_message(get_message("Done!"), Gtk.MessageType.INFO))
|
||||
callback=self.append_output,
|
||||
done_callback=lambda: self.show_info_message(get_message("Done!"), Gtk.MessageType.INFO),
|
||||
use_http=self._use_http_switch.get_active())
|
||||
except Exception as e:
|
||||
message = str(getattr(e, "message", str(e)))
|
||||
self.show_info_message(message, Gtk.MessageType.ERROR)
|
||||
else:
|
||||
if download and d_type is not DownloadType.SATELLITES:
|
||||
self._open_data()
|
||||
GLib.idle_add(self._open_data_callback)
|
||||
|
||||
@run_idle
|
||||
def show_info_message(self, text, message_type):
|
||||
@@ -94,6 +156,14 @@ class DownloadDialog:
|
||||
self._info_bar.set_message_type(message_type)
|
||||
self._message_label.set_text(text)
|
||||
|
||||
@run_idle
|
||||
def append_output(self, text):
|
||||
append_text_to_tview(text, self._text_view)
|
||||
|
||||
@run_idle
|
||||
def clear_output(self):
|
||||
self._text_view.get_buffer().set_text("")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
|
||||
@@ -34,9 +34,10 @@ Author: Dmitriy Yefremov
|
||||
<!-- interface-copyright 2018 Dmitriy Yefremov -->
|
||||
<!-- interface-authors Dmitriy Yefremov -->
|
||||
<object class="GtkDialog" id="search_unavailable_streams_dialog">
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="width_request">320</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes"> </property>
|
||||
<property name="title" translatable="yes"> </property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="window_position">center</property>
|
||||
@@ -45,48 +46,33 @@ Author: Dmitriy Yefremov
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="skip_pager_hint">True</property>
|
||||
<property name="gravity">center</property>
|
||||
<signal name="delete-event" handler="on_search_unavailable_close" swapped="no"/>
|
||||
<signal name="response" handler="on_response" swapped="no"/>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="search_unavailable_cancel_button">
|
||||
<property name="label">gtk-cancel</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>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<object class="GtkBox" id="search_unavailable_dialog_box">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">1</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="button6">
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="clicked" handler="on_search_unavailable_close" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<object class="GtkFrame" id="search_unavailable_box_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
@@ -190,6 +176,9 @@ Author: Dmitriy Yefremov
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">search_unavailable_cancel_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkListStore" id="stream_type_liststore">
|
||||
<columns>
|
||||
@@ -206,105 +195,61 @@ Author: Dmitriy Yefremov
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkDialog" id="iptv_dialog">
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="width_request">480</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Stream data</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_taskbar_hint">True</property>
|
||||
<property name="skip_pager_hint">True</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="iptv_dialog_header">
|
||||
<signal name="response" handler="on_response" swapped="no"/>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="iptv_dialog_cancel_button">
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Stream data</property>
|
||||
<property name="spacing">2</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="iptv_dialog_cancel_button">
|
||||
<property name="label">gtk-cancel</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>
|
||||
<signal name="clicked" handler="on_cancel" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="iptv_dialog_add_button">
|
||||
<property name="label">gtk-add</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>
|
||||
<signal name="clicked" handler="on_save" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="iptv_dialog_save_button">
|
||||
<property name="label">gtk-save</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>
|
||||
<signal name="clicked" handler="on_save" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<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>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="iptv_dialog_add_button">
|
||||
<property name="label">gtk-add</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>
|
||||
<signal name="clicked" handler="on_save" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="iptv_dialog_save_button">
|
||||
<property name="label">gtk-save</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>
|
||||
<signal name="clicked" handler="on_save" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<object class="GtkBox" id="iptv_dialog_box">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</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="iptv_dialog_main_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">2</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
@@ -482,6 +427,7 @@ Author: Dmitriy Yefremov
|
||||
<object class="GtkFrame" id="iptv_dialog_ts_data_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="label_xalign">0.019999999552965164</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
@@ -655,11 +601,15 @@ Author: Dmitriy Yefremov
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">iptv_dialog_cancel_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
<object class="GtkDialog" id="iptv_list_configuration_dialog">
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="width_request">400</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title"> </property>
|
||||
<property name="title"> IPTV streams list configuration</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="window_position">center</property>
|
||||
@@ -668,73 +618,39 @@ Author: Dmitriy Yefremov
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="skip_pager_hint">True</property>
|
||||
<property name="gravity">center</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<signal name="response" handler="on_response" swapped="no"/>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="close_config_list_button">
|
||||
<property name="label">gtk-close</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">2</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="close_config_list_button">
|
||||
<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="margin_right">15</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="title">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">IPTV streams list configuration</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="list_configuration_apply_button">
|
||||
<property name="label">gtk-apply</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="margin_left">15</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_apply" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<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>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="list_configuration_apply_button">
|
||||
<property name="label">gtk-apply</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>
|
||||
<signal name="clicked" handler="on_apply" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox">
|
||||
<object class="GtkBox" id="iptv_list_configuration_dialog_box">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="iptv_list_data_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">2</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
@@ -835,6 +751,7 @@ Author: Dmitriy Yefremov
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="label_xalign">0.019999999552965164</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
@@ -1135,6 +1052,9 @@ Author: Dmitriy Yefremov
|
||||
<child>
|
||||
<object class="GtkInfoBar" id="list_configuration_info_bar">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">1</property>
|
||||
<property name="margin_right">1</property>
|
||||
<property name="margin_bottom">1</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<signal name="response" handler="on_info_bar_close" swapped="no"/>
|
||||
<child internal-child="action_area">
|
||||
@@ -1185,7 +1105,7 @@ Author: Dmitriy Yefremov
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-7">close_config_list_button</action-widget>
|
||||
<action-widget response="-6">close_config_list_button</action-widget>
|
||||
</action-widgets>
|
||||
</object>
|
||||
</interface>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import re
|
||||
import urllib
|
||||
from urllib.error import HTTPError
|
||||
|
||||
from urllib.parse import urlparse
|
||||
@@ -27,10 +28,10 @@ def is_data_correct(elems):
|
||||
class IptvDialog:
|
||||
|
||||
def __init__(self, transient, view, services, bouquet, profile=Profile.ENIGMA_2, action=Action.ADD):
|
||||
handlers = {"on_entry_changed": self.on_entry_changed,
|
||||
handlers = {"on_response": self.on_response,
|
||||
"on_entry_changed": self.on_entry_changed,
|
||||
"on_url_changed": self.on_url_changed,
|
||||
"on_save": self.on_save,
|
||||
"on_cancel": self.on_cancel,
|
||||
"on_stream_type_changed": self.on_stream_type_changed}
|
||||
|
||||
builder = Gtk.Builder()
|
||||
@@ -88,8 +89,9 @@ class IptvDialog:
|
||||
def show(self):
|
||||
self._dialog.run()
|
||||
|
||||
def on_cancel(self, item):
|
||||
self._dialog.destroy()
|
||||
def on_response(self, dialog, response):
|
||||
if response == Gtk.ResponseType.CANCEL:
|
||||
self._dialog.destroy()
|
||||
|
||||
def on_save(self, item):
|
||||
self.on_url_changed(self._url_entry)
|
||||
@@ -109,10 +111,10 @@ class IptvDialog:
|
||||
self.init_enigma2_data(fav_id) if self._profile is Profile.ENIGMA_2 else self.init_neutrino_data(fav_id)
|
||||
|
||||
def init_enigma2_data(self, fav_id):
|
||||
data, sep, desc = fav_id.partition("#DESCRIPTION:")
|
||||
data, sep, desc = fav_id.partition("#DESCRIPTION")
|
||||
self._description_entry.set_text(desc.strip())
|
||||
data = data.split(":")
|
||||
if len(data) < 12:
|
||||
if len(data) < 11:
|
||||
return
|
||||
self._stream_type_combobox.set_active(0 if StreamType(data[0].strip()) is StreamType.DVB_TS else 1)
|
||||
self._srv_type_entry.set_text(data[2])
|
||||
@@ -120,7 +122,7 @@ class IptvDialog:
|
||||
self._tr_id_entry.set_text(str(int(data[4], 16)))
|
||||
self._net_id_entry.set_text(str(int(data[5], 16)))
|
||||
self._namespace_entry.set_text(str(int(data[6], 16)))
|
||||
self._url_entry.set_text(data[10].replace("%3a", ":"))
|
||||
self._url_entry.set_text(urllib.request.unquote(data[10].strip()))
|
||||
self._update_reference_entry()
|
||||
|
||||
def init_neutrino_data(self, fav_id):
|
||||
@@ -162,7 +164,7 @@ class IptvDialog:
|
||||
int(self._tr_id_entry.get_text()),
|
||||
int(self._net_id_entry.get_text()),
|
||||
int(self._namespace_entry.get_text()),
|
||||
self._url_entry.get_text().replace(":", "%3a"),
|
||||
urllib.request.quote(self._url_entry.get_text()),
|
||||
name, name)
|
||||
self.update_bouquet_data(name, fav_id)
|
||||
|
||||
@@ -196,7 +198,7 @@ class IptvDialog:
|
||||
class SearchUnavailableDialog:
|
||||
|
||||
def __init__(self, transient, model, fav_bouquet, iptv_rows, profile):
|
||||
handlers = {"on_search_unavailable_close": self.on_close}
|
||||
handlers = {"on_response": self.on_response}
|
||||
|
||||
builder = Gtk.Builder()
|
||||
builder.set_translation_domain(TEXT_DOMAIN)
|
||||
@@ -262,12 +264,15 @@ class SearchUnavailableDialog:
|
||||
|
||||
def show(self):
|
||||
response = self._dialog.run()
|
||||
self._dialog.destroy()
|
||||
|
||||
return self._to_delete if response not in (Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT) else False
|
||||
|
||||
def on_response(self, dialog, response):
|
||||
if response == Gtk.ResponseType.CANCEL:
|
||||
self.on_close()
|
||||
|
||||
@run_idle
|
||||
def on_close(self, item=None, event=None):
|
||||
def on_close(self):
|
||||
if self._download_task and show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL:
|
||||
return
|
||||
self._download_task = False
|
||||
@@ -278,6 +283,7 @@ class IptvListConfigurationDialog:
|
||||
|
||||
def __init__(self, transient, services, iptv_rows, bouquet, profile):
|
||||
handlers = {"on_apply": self.on_apply,
|
||||
"on_response": self.on_response,
|
||||
"on_stream_type_default_togged": self.on_stream_type_default_togged,
|
||||
"on_stream_type_changed": self.on_stream_type_changed,
|
||||
"on_default_type_toggled": self.on_default_type_toggled,
|
||||
@@ -328,7 +334,10 @@ class IptvListConfigurationDialog:
|
||||
|
||||
def show(self):
|
||||
self._dialog.run()
|
||||
self._dialog.destroy()
|
||||
|
||||
def on_response(self, dialog, response):
|
||||
if response == Gtk.ResponseType.CANCEL:
|
||||
self._dialog.destroy()
|
||||
|
||||
def on_stream_type_changed(self, box):
|
||||
self.update_reference()
|
||||
|
||||
BIN
app/ui/lang/es/LC_MESSAGES/demon-editor.mo
Normal file
BIN
app/ui/lang/es/LC_MESSAGES/demon-editor.mo
Normal file
Binary file not shown.
BIN
app/ui/lang/nl/LC_MESSAGES/demon-editor.mo
Normal file
BIN
app/ui/lang/nl/LC_MESSAGES/demon-editor.mo
Normal file
Binary file not shown.
BIN
app/ui/lang/pt/LC_MESSAGES/demon-editor.mo
Normal file
BIN
app/ui/lang/pt/LC_MESSAGES/demon-editor.mo
Normal file
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,8 @@
|
||||
""" This is helper module for ui """
|
||||
import os
|
||||
import shutil
|
||||
import urllib.request
|
||||
|
||||
from gi.repository import GdkPixbuf, GLib
|
||||
|
||||
from app.commons import run_task
|
||||
@@ -8,7 +10,7 @@ from app.eparser import Service
|
||||
from app.eparser.ecommons import Flag, BouquetService, Bouquet, BqType
|
||||
from app.eparser.enigma.bouquets import BqServiceType, to_bouquet_id
|
||||
from app.properties import Profile
|
||||
from .uicommons import ViewTarget, BqGenType, Gtk, Gdk, HIDE_ICON, LOCKED_ICON
|
||||
from .uicommons import ViewTarget, BqGenType, Gtk, Gdk, HIDE_ICON, LOCKED_ICON, KeyboardKey, Column
|
||||
from .dialogs import show_dialog, DialogType, get_chooser_dialog, WaitDialog
|
||||
|
||||
|
||||
@@ -25,37 +27,18 @@ def insert_marker(view, bouquets, selected_bouquet, channels, parent_window):
|
||||
return
|
||||
|
||||
# Searching for max num value in all marker services (if empty default = 0)
|
||||
max_num = max(map(lambda num: int(num.data_id, 18),
|
||||
max_num = max(map(lambda num: int(num.data_id, 16),
|
||||
filter(lambda ch: ch.service_type == BqServiceType.MARKER.name, channels.values())), default=0)
|
||||
max_num = '{:x}'.format(max_num + 1)
|
||||
max_num = '{:X}'.format(max_num + 1)
|
||||
fav_id = "1:64:{}:0:0:0:0:0:0:0::{}\n#DESCRIPTION {}\n".format(max_num, response, response)
|
||||
s_type = BqServiceType.MARKER.name
|
||||
model, paths = view.get_selection().get_selected_rows()
|
||||
marker = (None, None, response, None, None, s_type, None, fav_id, None)
|
||||
marker = (None, None, response, None, None, s_type, None, fav_id, None, None, None)
|
||||
itr = model.insert_before(model.get_iter(paths[0]), marker) if paths else model.insert(0, marker)
|
||||
bouquets[selected_bouquet].insert(model.get_path(itr)[0], fav_id)
|
||||
channels[fav_id] = Service(None, None, None, response, None, None, None, s_type, *[None] * 9, max_num, fav_id, None)
|
||||
|
||||
|
||||
def edit_marker(view, bouquets, selected_bouquet, channels, parent_window):
|
||||
""" Edits marker text """
|
||||
model, paths = view.get_selection().get_selected_rows()
|
||||
itr = model.get_iter(paths[0])
|
||||
name, fav_id = model.get(itr, 2, 7)
|
||||
response = show_dialog(DialogType.INPUT, parent_window, text=name)
|
||||
if response == Gtk.ResponseType.CANCEL:
|
||||
return
|
||||
|
||||
bq_services = bouquets[selected_bouquet]
|
||||
index = bq_services.index(fav_id)
|
||||
old_ch = channels.pop(fav_id, None)
|
||||
new_fav_id = "{}::{}\n#DESCRIPTION {}\n".format(fav_id.split("::")[0], response, response)
|
||||
model.set(itr, {2: response, 7: new_fav_id})
|
||||
channels[new_fav_id] = old_ch._replace(service=response, fav_id=new_fav_id)
|
||||
bq_services.pop(index)
|
||||
bq_services.insert(index, new_fav_id)
|
||||
|
||||
|
||||
# ***************** Movement *******************#
|
||||
|
||||
def move_items(key, view: Gtk.TreeView):
|
||||
@@ -86,27 +69,29 @@ def move_items(key, view: Gtk.TreeView):
|
||||
parent_itr = model.iter_parent(model.get_iter(paths[0]))
|
||||
parent_index = model.get_path(parent_itr)
|
||||
children_num = model.iter_n_children(parent_itr)
|
||||
if key in (Gdk.KEY_Page_Down, Gdk.KEY_KP_Page_Down, Gdk.KEY_End):
|
||||
if key in (KeyboardKey.PAGE_DOWN, KeyboardKey.END, KeyboardKey.END_KP, KeyboardKey.PAGE_DOWN_KP):
|
||||
children_num -= 1
|
||||
min_path = Gtk.TreePath.new_from_string("{}:{}".format(parent_index, 0))
|
||||
max_path = Gtk.TreePath.new_from_string("{}:{}".format(parent_index, children_num))
|
||||
is_tree_store = True
|
||||
|
||||
if key == Gdk.KEY_Up:
|
||||
if key is KeyboardKey.UP:
|
||||
top_path = Gtk.TreePath(paths[0])
|
||||
set_cursor(top_path, paths, selection, view)
|
||||
top_path.prev()
|
||||
move_up(top_path, model, paths)
|
||||
elif key == Gdk.KEY_Down:
|
||||
elif key is KeyboardKey.DOWN:
|
||||
down_path = Gtk.TreePath(paths[-1])
|
||||
set_cursor(down_path, paths, selection, view)
|
||||
down_path.next()
|
||||
if down_path < max_path:
|
||||
move_down(down_path, model, paths)
|
||||
else:
|
||||
max_path.prev()
|
||||
move_down(max_path, model, paths)
|
||||
elif key in (Gdk.KEY_Page_Up, Gdk.KEY_KP_Page_Up, Gdk.KEY_Home):
|
||||
elif key in (KeyboardKey.PAGE_UP, KeyboardKey.HOME, KeyboardKey.PAGE_UP_KP, KeyboardKey.HOME_KP):
|
||||
move_up(min_path if is_tree_store else cursor_path, model, paths)
|
||||
elif key in (Gdk.KEY_Page_Down, Gdk.KEY_KP_Page_Down, Gdk.KEY_End):
|
||||
elif key in (KeyboardKey.PAGE_DOWN, KeyboardKey.END, KeyboardKey.END_KP, KeyboardKey.PAGE_DOWN_KP):
|
||||
move_down(max_path if is_tree_store else cursor_path, model, paths)
|
||||
|
||||
|
||||
@@ -137,50 +122,62 @@ def is_some_level(paths):
|
||||
return True
|
||||
|
||||
|
||||
def set_cursor(dest_path, paths, selection, view):
|
||||
view.set_cursor(dest_path, view.get_column(0), False)
|
||||
for p in paths:
|
||||
selection.select_path(p)
|
||||
|
||||
|
||||
# ***************** Rename *******************#
|
||||
|
||||
def rename(view, parent_window, target, fav_view=None, service_view=None, channels=None):
|
||||
def rename(view, parent_window, target, fav_view=None, service_view=None, services=None):
|
||||
selection = get_selection(view, parent_window)
|
||||
if not selection:
|
||||
return
|
||||
|
||||
model, paths = selection
|
||||
itr = model.get_iter(paths)
|
||||
f_id = None
|
||||
channel_name = None
|
||||
f_id, srv_name, srv_type = None, None, None
|
||||
|
||||
if target is ViewTarget.SERVICES:
|
||||
name, fav_id = model.get(itr, 3, 18)
|
||||
name, fav_id = model.get(itr, Column.SRV_SERVICE, Column.SRV_FAV_ID)
|
||||
f_id = fav_id
|
||||
response = show_dialog(DialogType.INPUT, parent_window, name)
|
||||
if response == Gtk.ResponseType.CANCEL:
|
||||
return
|
||||
channel_name = response
|
||||
model.set_value(itr, 3, response)
|
||||
srv_name = response
|
||||
model.set_value(itr, Column.SRV_SERVICE, response)
|
||||
if fav_view is not None:
|
||||
for row in fav_view.get_model():
|
||||
if row[7] == fav_id:
|
||||
row[2] = response
|
||||
if row[Column.FAV_ID] == fav_id:
|
||||
row[Column.FAV_SERVICE] = response
|
||||
break
|
||||
elif target is ViewTarget.FAV:
|
||||
name, fav_id = model.get(itr, 2, 7)
|
||||
name, srv_type, fav_id = model.get(itr, Column.FAV_SERVICE, Column.FAV_TYPE, Column.FAV_ID)
|
||||
f_id = fav_id
|
||||
response = show_dialog(DialogType.INPUT, parent_window, name)
|
||||
if response == Gtk.ResponseType.CANCEL:
|
||||
return
|
||||
|
||||
channel_name = response
|
||||
model.set_value(itr, 2, response)
|
||||
srv_name = response
|
||||
model.set_value(itr, Column.FAV_SERVICE, response)
|
||||
|
||||
if service_view is not None:
|
||||
for row in get_base_model(service_view.get_model()):
|
||||
if row[18] == fav_id:
|
||||
row[3] = response
|
||||
if row[Column.SRV_FAV_ID] == fav_id:
|
||||
row[Column.SRV_SERVICE] = response
|
||||
break
|
||||
|
||||
old_ch = channels.get(f_id, None)
|
||||
if old_ch:
|
||||
channels[f_id] = old_ch._replace(service=channel_name)
|
||||
old_srv = services.get(f_id, None)
|
||||
if old_srv:
|
||||
if srv_type == BqServiceType.IPTV.name or srv_type == BqServiceType.MARKER.name:
|
||||
l, sep, r = f_id.partition("#DESCRIPTION")
|
||||
old_name = old_srv.service.strip()
|
||||
new_name = srv_name.strip()
|
||||
new_fav_id = "".join((new_name.join(l.rsplit(old_name, 1)), sep, new_name.join(r.rsplit(old_name, 1))))
|
||||
services[f_id] = old_srv._replace(service=srv_name, fav_id=new_fav_id)
|
||||
else:
|
||||
services[f_id] = old_srv._replace(service=srv_name)
|
||||
|
||||
|
||||
def get_selection(view, parent):
|
||||
@@ -221,9 +218,9 @@ def set_flags(flag, services_view, fav_view, services, blacklist):
|
||||
if target is ViewTarget.SERVICES:
|
||||
set_hide(services, model, paths)
|
||||
else:
|
||||
fav_ids = [model.get_value(model.get_iter(path), 7) for path in paths]
|
||||
fav_ids = [model.get_value(model.get_iter(path), Column.FAV_ID) for path in paths]
|
||||
srv_model = get_base_model(services_view.get_model())
|
||||
srv_paths = [row.path for row in srv_model if row[18] in fav_ids]
|
||||
srv_paths = [row.path for row in srv_model if row[Column.SRV_FAV_ID] in fav_ids]
|
||||
set_hide(services, srv_model, srv_paths)
|
||||
elif flag is Flag.LOCK:
|
||||
set_lock(blacklist, services, model, paths, target, services_model=get_base_model(services_view.get_model()))
|
||||
@@ -233,20 +230,20 @@ def set_flags(flag, services_view, fav_view, services, blacklist):
|
||||
|
||||
def update_fav_model(fav_view, services):
|
||||
for row in get_base_model(fav_view.get_model()):
|
||||
srv = services.get(row[7], None)
|
||||
srv = services.get(row[Column.FAV_ID], None)
|
||||
if srv:
|
||||
row[3], row[4] = srv.locked, srv.hide
|
||||
row[Column.FAV_LOCKED], row[Column.FAV_HIDE] = srv.locked, srv.hide
|
||||
|
||||
|
||||
def set_lock(blacklist, services, model, paths, target, services_model):
|
||||
col_num = 4 if target is ViewTarget.SERVICES else 3
|
||||
col_num = Column.SRV_LOCKED if target is ViewTarget.SERVICES else Column.FAV_LOCKED
|
||||
locked = has_locked_hide(model, paths, col_num)
|
||||
|
||||
ids = []
|
||||
|
||||
for path in paths:
|
||||
itr = model.get_iter(path)
|
||||
fav_id = model.get_value(itr, 18 if target is ViewTarget.SERVICES else 7)
|
||||
fav_id = model.get_value(itr, Column.SRV_FAV_ID if target is ViewTarget.SERVICES else Column.FAV_ID)
|
||||
srv = services.get(fav_id, None)
|
||||
if srv:
|
||||
bq_id = to_bouquet_id(srv)
|
||||
@@ -264,13 +261,13 @@ def set_lock(blacklist, services, model, paths, target, services_model):
|
||||
|
||||
def update_services_model(ids, locked, services_model):
|
||||
for srv in services_model:
|
||||
if srv[18] in ids:
|
||||
srv[4] = None if locked else LOCKED_ICON
|
||||
if srv[Column.SRV_FAV_ID] in ids:
|
||||
srv[Column.SRV_LOCKED] = None if locked else LOCKED_ICON
|
||||
yield True
|
||||
|
||||
|
||||
def set_hide(services, model, paths):
|
||||
col_num = 5
|
||||
col_num = Column.SRV_HIDE
|
||||
hide = has_locked_hide(model, paths, col_num)
|
||||
|
||||
for path in paths:
|
||||
@@ -305,7 +302,7 @@ def set_hide(services, model, paths):
|
||||
flags.append(value)
|
||||
|
||||
model.set_value(itr, 0, (",".join(reversed(sorted(flags)))))
|
||||
fav_id = model.get_value(itr, 18)
|
||||
fav_id = model.get_value(itr, Column.SRV_FAV_ID)
|
||||
srv = services.get(fav_id, None)
|
||||
if srv:
|
||||
services[fav_id] = srv._replace(hide=None if hide else HIDE_ICON)
|
||||
@@ -330,9 +327,9 @@ def locate_in_services(fav_view, services_view, parent_window):
|
||||
show_dialog(DialogType.ERROR, parent_window, "Please, select only one item!")
|
||||
return
|
||||
|
||||
fav_id = model.get_value(model.get_iter(paths[0]), 7)
|
||||
fav_id = model.get_value(model.get_iter(paths[0]), Column.FAV_ID)
|
||||
for index, row in enumerate(services_view.get_model()):
|
||||
if row[18] == fav_id:
|
||||
if row[Column.SRV_FAV_ID] == fav_id:
|
||||
scroll_to(index, services_view)
|
||||
break
|
||||
|
||||
@@ -360,7 +357,7 @@ def update_picons_data(path, picons):
|
||||
def append_picons(picons, model):
|
||||
def append_picons_data(pcs, mod):
|
||||
for r in mod:
|
||||
mod.set_value(mod.get_iter(r.path), 8, pcs.get(r[9], None))
|
||||
mod.set_value(mod.get_iter(r.path), Column.SRV_PICON, pcs.get(r[Column.SRV_PICON_ID], None))
|
||||
yield True
|
||||
|
||||
app = append_picons_data(picons, model)
|
||||
@@ -381,11 +378,11 @@ def assign_picon(target, srv_view, fav_view, transient, picons, options, service
|
||||
show_dialog(DialogType.ERROR, transient, text="No png file is selected!")
|
||||
return
|
||||
|
||||
picon_pos = 8
|
||||
picon_pos = Column.SRV_PICON
|
||||
model = get_base_model(model)
|
||||
itr = model.get_iter(paths)
|
||||
fav_id = model.get_value(itr, 18 if target is ViewTarget.SERVICES else 7)
|
||||
picon_id = services.get(fav_id)[9]
|
||||
fav_id = model.get_value(itr, Column.SRV_FAV_ID if target is ViewTarget.SERVICES else Column.FAV_ID)
|
||||
picon_id = services.get(fav_id)[Column.SRV_PICON_ID]
|
||||
|
||||
if picon_id:
|
||||
picon_file = options.get("picons_dir_path") + picon_id
|
||||
@@ -395,9 +392,9 @@ def assign_picon(target, srv_view, fav_view, transient, picons, options, service
|
||||
picons[picon_id] = picon
|
||||
model.set_value(itr, picon_pos, picon)
|
||||
if target is ViewTarget.SERVICES:
|
||||
set_picon(fav_id, fav_view.get_model(), picon, 7, picon_pos)
|
||||
set_picon(fav_id, fav_view.get_model(), picon, Column.FAV_ID, picon_pos)
|
||||
else:
|
||||
set_picon(fav_id, get_base_model(srv_view.get_model()), picon, 18, picon_pos)
|
||||
set_picon(fav_id, get_base_model(srv_view.get_model()), picon, Column.SRV_FAV_ID, picon_pos)
|
||||
|
||||
|
||||
def set_picon(fav_id, model, picon, fav_id_pos, picon_pos):
|
||||
@@ -414,26 +411,26 @@ def remove_picon(target, srv_view, fav_view, picons, options):
|
||||
|
||||
fav_ids = []
|
||||
picon_ids = []
|
||||
picon_pos = 8 # picon position is equal for services and fav
|
||||
picon_pos = Column.SRV_PICON # picon position is equal for services and fav
|
||||
|
||||
for path in paths:
|
||||
itr = model.get_iter(path)
|
||||
model.set_value(itr, picon_pos, None)
|
||||
if target is ViewTarget.SERVICES:
|
||||
fav_ids.append(model.get_value(itr, 18))
|
||||
picon_ids.append(model.get_value(itr, 9))
|
||||
fav_ids.append(model.get_value(itr, Column.SRV_FAV_ID))
|
||||
picon_ids.append(model.get_value(itr, Column.SRV_PICON_ID))
|
||||
else:
|
||||
srv_type, fav_id = model.get(itr, 5, 7)
|
||||
srv_type, fav_id = model.get(itr, Column.FAV_TYPE, Column.FAV_ID)
|
||||
if srv_type == BqServiceType.IPTV.name:
|
||||
picon_ids.append("{}_{}_{}_{}_{}_{}_{}_{}_{}_{}.png".format(*fav_id.split(":")[0:10]).strip())
|
||||
else:
|
||||
fav_ids.append(fav_id)
|
||||
|
||||
def remove(md, path, it):
|
||||
if md.get_value(it, 7 if target is ViewTarget.SERVICES else 18) in fav_ids:
|
||||
if md.get_value(it, Column.FAV_ID if target is ViewTarget.SERVICES else Column.SRV_FAV_ID) in fav_ids:
|
||||
md.set_value(it, picon_pos, None)
|
||||
if target is ViewTarget.FAV:
|
||||
picon_ids.append(md.get_value(it, 9))
|
||||
picon_ids.append(md.get_value(it, Column.SRV_PICON_ID))
|
||||
|
||||
fav_view.get_model().foreach(remove) if target is ViewTarget.SERVICES else get_base_model(
|
||||
srv_view.get_model()).foreach(remove)
|
||||
@@ -456,13 +453,13 @@ def copy_picon_reference(target, view, services, clipboard, transient):
|
||||
return
|
||||
|
||||
if target is ViewTarget.SERVICES:
|
||||
picon_id = model.get_value(model.get_iter(paths), 9)
|
||||
picon_id = model.get_value(model.get_iter(paths), Column.SRV_PICON_ID)
|
||||
if picon_id:
|
||||
clipboard.set_text(picon_id.rstrip(".png"), -1)
|
||||
else:
|
||||
show_dialog(DialogType.ERROR, transient, "No reference is present!")
|
||||
elif target is ViewTarget.FAV:
|
||||
fav_id = model.get_value(model.get_iter(paths), 7)
|
||||
fav_id = model.get_value(model.get_iter(paths), Column.FAV_ID)
|
||||
srv = services.get(fav_id, None)
|
||||
if srv and srv.picon_id:
|
||||
clipboard.set_text(srv.picon_id.rstrip(".png"), -1)
|
||||
@@ -490,16 +487,19 @@ def get_picon_pixbuf(path):
|
||||
|
||||
def gen_bouquets(view, bq_view, transient, gen_type, tv_types, profile, callback):
|
||||
""" Auto-generate and append list of bouquets """
|
||||
fav_id_index = 18
|
||||
index = 6 if gen_type in (BqGenType.PACKAGE, BqGenType.EACH_PACKAGE) else 16 if gen_type in (
|
||||
BqGenType.SAT, BqGenType.EACH_SAT) else 7
|
||||
fav_id_index = Column.SRV_FAV_ID
|
||||
index = Column.SRV_TYPE
|
||||
if gen_type in (BqGenType.PACKAGE, BqGenType.EACH_PACKAGE):
|
||||
index = Column.SRV_PACKAGE
|
||||
elif gen_type in (BqGenType.SAT, BqGenType.EACH_SAT):
|
||||
index = Column.SRV_POS
|
||||
|
||||
model, paths = view.get_selection().get_selected_rows()
|
||||
model = get_base_model(model)
|
||||
bq_type = BqType.BOUQUET.value if profile is Profile.NEUTRINO_MP else BqType.TV.value
|
||||
if gen_type in (BqGenType.SAT, BqGenType.PACKAGE, BqGenType.TYPE):
|
||||
if not is_only_one_item_selected(paths, transient):
|
||||
return
|
||||
service = Service(*model[paths][:])
|
||||
service = Service(*model[paths][:Column.SRV_TOOLTIP])
|
||||
if service.service_type not in tv_types:
|
||||
bq_type = BqType.RADIO.value
|
||||
append_bouquets(bq_type, bq_view, callback, fav_id_index, index, model,
|
||||
@@ -561,6 +561,13 @@ def get_base_model(model):
|
||||
return model
|
||||
|
||||
|
||||
def get_model_data(view):
|
||||
""" Returns model name and base model from the given view """
|
||||
model = get_base_model(view.get_model())
|
||||
model_name = model.get_name()
|
||||
return model_name, model
|
||||
|
||||
|
||||
def append_text_to_tview(char, view):
|
||||
""" Appending text and scrolling to a given line in the text view. """
|
||||
buf = view.get_buffer()
|
||||
@@ -571,12 +578,18 @@ def append_text_to_tview(char, view):
|
||||
|
||||
def get_iptv_url(row, profile):
|
||||
""" Returns url from iptv type row """
|
||||
data = row[7].split(":" if profile is Profile.ENIGMA_2 else "::")
|
||||
data = row[Column.FAV_ID].split(":" if profile is Profile.ENIGMA_2 else "::")
|
||||
if profile is Profile.ENIGMA_2:
|
||||
data = list(filter(lambda x: "http" in x, data))
|
||||
if data:
|
||||
url = data[0]
|
||||
return url.replace("%3a", ":") if profile is Profile.ENIGMA_2 else url
|
||||
return urllib.request.unquote(url) if profile is Profile.ENIGMA_2 else url
|
||||
|
||||
|
||||
def on_popup_menu(menu, event):
|
||||
""" Shows popup menu for the view """
|
||||
if event.get_event_type() == Gdk.EventType.BUTTON_PRESS and event.button == Gdk.BUTTON_SECONDARY:
|
||||
menu.popup(None, None, None, None, event.button, event.time)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -65,17 +65,61 @@ Author: Dmitriy Yefremov
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name on_id -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name ssid -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name single -->
|
||||
<column type="gboolean"/>
|
||||
<!-- column-name selected -->
|
||||
<column type="gboolean"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkImage" id="remove_selection_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="icon_name">edit-undo</property>
|
||||
</object>
|
||||
<object class="GtkMenu" id="providers_popup_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="select_all_popup_item">
|
||||
<property name="label">gtk-select-all</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_select_all" object="providers_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="unselect_all_popup_item">
|
||||
<property name="label" translatable="yes">Remove selection</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">remove_selection_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_unselect_all" object="providers_tree_view" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkListStore" id="satellites_list_store">
|
||||
<columns>
|
||||
<!-- column-name satellite -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name url -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name pos -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkDialog" id="picons_dialog">
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="icon_name">emblem-photos</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<signal name="close" handler="on_close" swapped="no"/>
|
||||
<signal name="destroy" handler="on_close" swapped="no"/>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="visible">True</property>
|
||||
@@ -94,7 +138,7 @@ Author: Dmitriy Yefremov
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="label" translatable="yes">Picons download tool</property>
|
||||
<property name="xalign">0.55000001192092896</property>
|
||||
<property name="xalign">0.52999997138977051</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
@@ -136,7 +180,7 @@ Author: Dmitriy Yefremov
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
@@ -222,7 +266,7 @@ Author: Dmitriy Yefremov
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
@@ -240,7 +284,7 @@ Author: Dmitriy Yefremov
|
||||
</child>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="picons_dialog_vbox">
|
||||
<property name="width_request">570</property>
|
||||
<property name="width_request">640</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="margin_right">2</property>
|
||||
@@ -287,72 +331,56 @@ Author: Dmitriy Yefremov
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkFrame" id="downloader_frame">
|
||||
<object class="GtkBox" id="providers_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="label_xalign">0.039999999105930328</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<property name="spacing">5</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkFrame" id="satellites_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="margin_bottom">2</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<property name="label_xalign">0.10000000149011612</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="url_entry">
|
||||
<object class="GtkScrolledWindow" id="satellites_scrolled_window">
|
||||
<property name="width_request">200</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_bottom">2</property>
|
||||
<property name="primary_icon_name">network-workgroup-symbolic</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="placeholder_text" translatable="yes">https://www.lyngsat.com/*satellite*.html</property>
|
||||
<property name="input_purpose">url</property>
|
||||
<signal name="changed" handler="on_url_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="providers_scrolled_window">
|
||||
<property name="height_request">150</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_bottom">2</property>
|
||||
<property name="shadow_type">out</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="providers_tree_view">
|
||||
<object class="GtkTreeView" id="satellites_tree_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_focus">True</property>
|
||||
<property name="model">providers_list_store</property>
|
||||
<property name="model">satellites_list_store</property>
|
||||
<property name="headers_visible">False</property>
|
||||
<property name="search_column">0</property>
|
||||
<property name="activate_on_single_click">True</property>
|
||||
<signal name="realize" handler="on_satellites_view_realize" swapped="no"/>
|
||||
<signal name="row-activated" handler="on_satellite_selection" swapped="no"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="treeview_selection"/>
|
||||
<object class="GtkTreeSelection" id="satellites_tree_selection"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="provider_column">
|
||||
<property name="spacing">15</property>
|
||||
<property name="title" translatable="yes">Providers</property>
|
||||
<object class="GtkTreeViewColumn" id="sat_name_column">
|
||||
<property name="title" translatable="yes">Satellite</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="logo_cellrendererpixbuf"/>
|
||||
<object class="GtkCellRendererText" id="satellites_cell_renderer"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">0</attribute>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="sat_url_column">
|
||||
<property name="visible">False</property>
|
||||
<property name="title" translatable="yes">Url</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="name_cellrenderertext"/>
|
||||
<object class="GtkCellRendererText" id="url_cell_renderer"/>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
@@ -360,173 +388,307 @@ Author: Dmitriy Yefremov
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="pos_column">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Position</property>
|
||||
<object class="GtkTreeViewColumn" id="sat_pos_columnt">
|
||||
<property name="visible">False</property>
|
||||
<property name="title" translatable="yes">Pos</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>
|
||||
<object class="GtkCellRendererText" id="pos_cell_renderer"/>
|
||||
<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="url_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="on_id_column">
|
||||
<property name="visible">False</property>
|
||||
<property name="title" translatable="yes">ONID</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="onid_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">4</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="selected_column">
|
||||
<property name="title" translatable="yes">Selected</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererToggle" id="cellrenderer_toggle">
|
||||
<signal name="toggled" handler="on_selected_toggled" swapped="no"/>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="active">5</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">2</property>
|
||||
<property name="margin_bottom">2</property>
|
||||
<property name="column_spacing">2</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="ip_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="primary_icon_name">network-transmit-receive-symbolic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="picons_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="ip_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Receiver IP:</property>
|
||||
<property name="xalign">0.05000000074505806</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="res_picons_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Receiver picons path:</property>
|
||||
<property name="xalign">0.05000000074505806</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<property name="label" translatable="yes">Satellite</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="picons_dir_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Current picons path:</property>
|
||||
<property name="xalign">0.019999999552965164</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="picons_dir_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="secondary_icon_name">folder-open-symbolic</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<signal name="icon-press" handler="on_picons_dir_open" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel" id="downloader_frame_label">
|
||||
<child>
|
||||
<object class="GtkFrame" id="providers_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Satellite url (www.lyngsat.com):</property>
|
||||
<property name="label_xalign">0.05000000074505806</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="proveders_pox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="url_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_bottom">2</property>
|
||||
<property name="primary_icon_name">network-workgroup-symbolic</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<property name="placeholder_text" translatable="yes">https://www.lyngsat.com/*satellite*.html</property>
|
||||
<property name="input_purpose">url</property>
|
||||
<signal name="changed" handler="on_url_changed" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="providers_scrolled_window">
|
||||
<property name="height_request">150</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_bottom">2</property>
|
||||
<property name="shadow_type">out</property>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="providers_tree_view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_focus">True</property>
|
||||
<property name="model">providers_list_store</property>
|
||||
<signal name="button-press-event" handler="on_popup_menu" object="providers_popup_menu" swapped="no"/>
|
||||
<signal name="select-all" handler="on_select_all" swapped="no"/>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="treeview_selection"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="provider_column">
|
||||
<property name="spacing">15</property>
|
||||
<property name="title" translatable="yes">Providers</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererPixbuf" id="logo_cellrendererpixbuf"/>
|
||||
<attributes>
|
||||
<attribute name="pixbuf">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="name_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="pos_column">
|
||||
<property name="sizing">autosize</property>
|
||||
<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="url_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="on_id_column">
|
||||
<property name="visible">False</property>
|
||||
<property name="title" translatable="yes">ONID</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="onid_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">4</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="ssid_column">
|
||||
<property name="visible">False</property>
|
||||
<property name="title" translatable="yes">SSID</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="ssid_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">5</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="single_column">
|
||||
<property name="visible">False</property>
|
||||
<property name="title" translatable="yes">Single</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="single_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">6</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="selected_column">
|
||||
<property name="title" translatable="yes">Selected</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererToggle" id="cellrenderer_toggle">
|
||||
<signal name="toggled" handler="on_selected_toggled" swapped="no"/>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="active">7</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGrid" id="grid">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">2</property>
|
||||
<property name="margin_bottom">2</property>
|
||||
<property name="column_spacing">2</property>
|
||||
<property name="column_homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkEntry" id="ip_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="primary_icon_name">network-transmit-receive-symbolic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="picons_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="ip_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Receiver IP:</property>
|
||||
<property name="xalign">0.05000000074505806</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="res_picons_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Receiver picons path:</property>
|
||||
<property name="xalign">0.05000000074505806</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="picons_dir_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Current picons path:</property>
|
||||
<property name="xalign">0.019999999552965164</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkEntry" id="picons_dir_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="secondary_icon_name">folder-open-symbolic</property>
|
||||
<property name="primary_icon_activatable">False</property>
|
||||
<signal name="icon-press" handler="on_picons_dir_open" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label">
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Satellite url:</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
@@ -923,10 +1085,4 @@ Author: Dmitriy Yefremov
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkListStore" id="sat_position_list_store">
|
||||
<columns>
|
||||
<!-- column-name pos -->
|
||||
<column type="gchararray"/>
|
||||
</columns>
|
||||
</object>
|
||||
</interface>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
@@ -6,20 +8,23 @@ import time
|
||||
from gi.repository import GLib, GdkPixbuf
|
||||
|
||||
from app.commons import run_idle, run_task
|
||||
from app.ftp import upload_data, DownloadType
|
||||
from app.connections import upload_data, DownloadType
|
||||
from app.tools.picons import PiconsParser, parse_providers, Provider, convert_to
|
||||
from app.properties import Profile
|
||||
from app.tools.satellites import SatellitesParser, SatelliteSource
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN, TV_ICON
|
||||
from .dialogs import show_dialog, DialogType, get_message
|
||||
from .main_helper import update_entry_data, append_text_to_tview
|
||||
from .main_helper import update_entry_data, append_text_to_tview, scroll_to, on_popup_menu
|
||||
|
||||
|
||||
class PiconsDialog:
|
||||
def __init__(self, transient, options, picon_ids, profile=Profile.ENIGMA_2):
|
||||
def __init__(self, transient, options, picon_ids, sat_positions, profile=Profile.ENIGMA_2):
|
||||
self._picon_ids = picon_ids
|
||||
self._sat_positions = sat_positions
|
||||
self._TMP_DIR = tempfile.gettempdir() + "/"
|
||||
self._BASE_URL = "www.lyngsat.com/packages/"
|
||||
self._PATTERN = re.compile("^https://www\.lyngsat\.com/[\w-]+\.html$")
|
||||
self._POS_PATTERN = re.compile("^\d+\.\d+[EW]?$")
|
||||
self._current_process = None
|
||||
self._terminate = False
|
||||
|
||||
@@ -34,7 +39,12 @@ class PiconsDialog:
|
||||
"on_url_changed": self.on_url_changed,
|
||||
"on_position_edited": self.on_position_edited,
|
||||
"on_notebook_switch_page": self.on_notebook_switch_page,
|
||||
"on_convert": self.on_convert}
|
||||
"on_convert": self.on_convert,
|
||||
"on_satellites_view_realize": self.on_satellites_view_realize,
|
||||
"on_satellite_selection": self.on_satellite_selection,
|
||||
"on_select_all": self.on_select_all,
|
||||
"on_unselect_all": self.on_unselect_all,
|
||||
"on_popup_menu": on_popup_menu}
|
||||
|
||||
builder = Gtk.Builder()
|
||||
builder.set_translation_domain(TEXT_DOMAIN)
|
||||
@@ -44,6 +54,7 @@ class PiconsDialog:
|
||||
self._dialog = builder.get_object("picons_dialog")
|
||||
self._dialog.set_transient_for(transient)
|
||||
self._providers_tree_view = builder.get_object("providers_tree_view")
|
||||
self._satellites_tree_view = builder.get_object("satellites_tree_view")
|
||||
self._expander = builder.get_object("expander")
|
||||
self._text_view = builder.get_object("text_view")
|
||||
self._info_bar = builder.get_object("info_bar")
|
||||
@@ -88,6 +99,29 @@ class PiconsDialog:
|
||||
self._dialog.run()
|
||||
self._dialog.destroy()
|
||||
|
||||
def on_satellites_view_realize(self, view):
|
||||
self.get_satellites(view)
|
||||
|
||||
@run_task
|
||||
def get_satellites(self, view):
|
||||
sats = SatellitesParser().get_satellites_list(SatelliteSource.LYNGSAT)
|
||||
gen = self.append_satellites(view.get_model(), sats)
|
||||
GLib.idle_add(lambda: next(gen, False), priority=GLib.PRIORITY_LOW)
|
||||
|
||||
def append_satellites(self, model, sats):
|
||||
for sat in sats:
|
||||
pos = sat[1]
|
||||
name = "{} ({})".format(sat[0], pos)
|
||||
pos = "{}{}".format("-" if pos[-1] == "W" else "", pos[:-1])
|
||||
if not self._terminate and model:
|
||||
if pos in self._sat_positions:
|
||||
model.append((name, sat[3], pos))
|
||||
yield True
|
||||
|
||||
def on_satellite_selection(self, view, path, column):
|
||||
model = view.get_model()
|
||||
self._url_entry.set_text(model.get(model.get_iter(path), 1)[0])
|
||||
|
||||
@run_idle
|
||||
def on_load_providers(self, item):
|
||||
self._expander.set_expanded(True)
|
||||
@@ -108,7 +142,7 @@ class PiconsDialog:
|
||||
providers = parse_providers(self._TMP_DIR + url[url.find("w"):])
|
||||
if providers:
|
||||
for p in providers:
|
||||
model.append((self.get_pixbuf(p[0]) if p[0] else TV_ICON, p.name, p.pos, p.url, p.on_id, p.selected))
|
||||
model.append((self.get_pixbuf(p[0]) if p[0] else TV_ICON, *p[1:]))
|
||||
self.update_receive_button_state()
|
||||
|
||||
def get_pixbuf(self, img_url):
|
||||
@@ -130,15 +164,19 @@ class PiconsDialog:
|
||||
|
||||
providers = self.get_selected_providers()
|
||||
for prv in providers:
|
||||
if not prv[2] and prv[2][:-2].isdigit():
|
||||
if not self._POS_PATTERN.match(prv[2]):
|
||||
self.show_info_message(
|
||||
get_message("Specify the correct position value for the provider!"), Gtk.MessageType.ERROR)
|
||||
scroll_to(prv.path, self._providers_tree_view)
|
||||
return
|
||||
|
||||
for prv in providers:
|
||||
if self._terminate:
|
||||
break
|
||||
self.process_provider(Provider(*prv))
|
||||
self.resize(self._picons_path)
|
||||
if not self._terminate:
|
||||
self.show_info_message(get_message("Done!"), Gtk.MessageType.INFO)
|
||||
|
||||
def process_provider(self, prv):
|
||||
url = prv.url
|
||||
@@ -149,13 +187,8 @@ class PiconsDialog:
|
||||
universal_newlines=True)
|
||||
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:]
|
||||
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._picon_ids, self.get_picons_format())
|
||||
self.resize(self._picons_path)
|
||||
if not self._terminate:
|
||||
self.show_info_message(get_message("Done!"), Gtk.MessageType.INFO)
|
||||
path = self._TMP_DIR + (url[url.find("//") + 2:] if prv.single else self._BASE_URL + url[url.rfind("/") + 1:])
|
||||
PiconsParser.parse(path, self._picons_path, self._TMP_DIR, prv, self._picon_ids, self.get_picons_format())
|
||||
|
||||
def write_to_buffer(self, fd, condition):
|
||||
if condition == GLib.IO_IN:
|
||||
@@ -193,7 +226,9 @@ class PiconsDialog:
|
||||
@run_idle
|
||||
def on_close(self, item):
|
||||
self.on_cancel(item)
|
||||
self._dialog.destroy()
|
||||
path = self._TMP_DIR + "www.lyngsat.com"
|
||||
if os.path.exists(path):
|
||||
shutil.rmtree(path)
|
||||
|
||||
def on_send(self, item):
|
||||
if show_dialog(DialogType.QUESTION, self._dialog) == Gtk.ResponseType.CANCEL:
|
||||
@@ -231,9 +266,18 @@ 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), 5, not toggle.get_active())
|
||||
model.set_value(model.get_iter(path), 7, not toggle.get_active())
|
||||
self.update_receive_button_state()
|
||||
|
||||
def on_select_all(self, view):
|
||||
self.update_selection(view, True)
|
||||
|
||||
def on_unselect_all(self, view):
|
||||
self.update_selection(view, False)
|
||||
|
||||
def update_selection(self, view, select):
|
||||
view.get_model().foreach(lambda mod, path, itr: mod.set_value(itr, 7, select))
|
||||
|
||||
def on_url_changed(self, entry):
|
||||
suit = self._PATTERN.search(entry.get_text())
|
||||
entry.set_name("GtkEntry" if suit else "digit-entry")
|
||||
@@ -277,7 +321,7 @@ class PiconsDialog:
|
||||
|
||||
def get_selected_providers(self):
|
||||
""" returns selected providers """
|
||||
return [r for r in self._providers_tree_view.get_model() if r[5]]
|
||||
return [r for r in self._providers_tree_view.get_model() if r[7]]
|
||||
|
||||
@run_idle
|
||||
def show_dialog(self, message, dialog_type):
|
||||
|
||||
@@ -1,10 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<!-- Generated with glade 3.22.1
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018-2019 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
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
Author: Dmitriy Yefremov
|
||||
|
||||
-->
|
||||
<!--
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Dmitriy Yefremov
|
||||
Copyright (c) 2018-2019 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,69 +57,8 @@ Author: Dmitriy Yefremov
|
||||
<requires lib="gtk+" version="3.16"/>
|
||||
<!-- interface-license-type mit -->
|
||||
<!-- interface-name DemonEditor -->
|
||||
<!-- interface-copyright 2018 Dmitriy Yefremov -->
|
||||
<!-- interface-copyright 2018-2019 Dmitriy Yefremov -->
|
||||
<!-- interface-authors Dmitriy Yefremov -->
|
||||
<object class="GtkPopoverMenu" id="add_header_popover_menu">
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkFrame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkBox" id="add_header_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<property name="homogeneous">True</property>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="text" translatable="yes">Satellite</property>
|
||||
<property name="centered">True</property>
|
||||
<signal name="clicked" handler="on_satellite_add" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="text" translatable="yes">Transponder</property>
|
||||
<property name="centered">True</property>
|
||||
<signal name="clicked" handler="on_transponder_add" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="label_item">
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="submenu">main</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkListStore" id="fec_store">
|
||||
<columns>
|
||||
<!-- column-name fec -->
|
||||
@@ -137,137 +102,109 @@ Author: Dmitriy Yefremov
|
||||
</object>
|
||||
<object class="GtkPopoverMenu" id="left_header_menu">
|
||||
<property name="can_focus">False</property>
|
||||
<signal name="button-release-event" handler="on_popover_release" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkFrame" id="left_popover_munu_frame">
|
||||
<object class="GtkBox" id="left_popover_munu_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="margin_left">10</property>
|
||||
<property name="margin_right">10</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<object class="GtkModelButton" id="open_popover_munu_button">
|
||||
<property name="width_request">85</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="text" translatable="yes">Open</property>
|
||||
<signal name="clicked" handler="on_open" object="satellites_tree_store" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton" id="save_popover_munu_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="text" translatable="yes">Save</property>
|
||||
<signal name="clicked" handler="on_save" object="satellites_editor_tree_view" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton" id="save_as_popover_munu_button">
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="text" translatable="yes">Save as...</property>
|
||||
<signal name="clicked" handler="on_save_as" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="open_left_popover_munu_button">
|
||||
<property name="label">gtk-open</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_open" object="satellites_tree_store" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="save_left_popover_munu_button">
|
||||
<property name="label">gtk-save</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_save" object="satellites_editor_tree_view" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="save_as_left_popover_munu_button">
|
||||
<property name="label">gtk-save-as</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_save_as" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<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="GtkButton" id="update_left_popover_munu_button">
|
||||
<property name="label">gtk-refresh</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_update" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<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="padding">2</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="exit_left_popover_munu_button">
|
||||
<property name="label">gtk-quit</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="relief">none</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_quit" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="label_item">
|
||||
<placeholder/>
|
||||
<child>
|
||||
<object class="GtkModelButton" id="update_popover_munu_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="text" translatable="yes">Update</property>
|
||||
<signal name="clicked" handler="on_update" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<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="padding">2</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton" id="exit_popover_menu_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="text" translatable="yes">Exit</property>
|
||||
<signal name="clicked" handler="on_quit" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">6</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
@@ -336,41 +273,46 @@ Author: Dmitriy Yefremov
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkImage" id="popup_menu_add_image">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-add</property>
|
||||
</object>
|
||||
<object class="GtkImage" id="popup_menu_add_image_2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-add</property>
|
||||
</object>
|
||||
<object class="GtkMenu" id="popup_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="reserve_toggle_size">False</property>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="add_popoup_menu_item">
|
||||
<property name="label">gtk-add</property>
|
||||
<object class="GtkImageMenuItem" id="add_sat_popup_menu_item">
|
||||
<property name="label" translatable="yes">Satellite</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">popup_menu_add_image</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_satellite_add" swapped="no"/>
|
||||
<accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImageMenuItem" id="add_tr_popup_menu_item">
|
||||
<property name="label" translatable="yes">Transponder</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="image">popup_menu_add_image_2</property>
|
||||
<property name="use_stock">False</property>
|
||||
<signal name="activate" handler="on_transponder_add" swapped="no"/>
|
||||
<accelerator key="t" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="popup_menu_separator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<child type="submenu">
|
||||
<object class="GtkMenu" id="add_menu">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="add_sat_popup_menu_item">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Satellite</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="on_satellite_add" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="add_tr_popup_menu_item">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Transponder</property>
|
||||
<property name="use_underline">True</property>
|
||||
<signal name="activate" handler="on_transponder_add" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -381,6 +323,13 @@ Author: Dmitriy Yefremov
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_edit" object="satellites_editor_tree_view" swapped="no"/>
|
||||
<accelerator key="e" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparatorMenuItem" id="popup_menu_separator_2">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -391,6 +340,7 @@ Author: Dmitriy Yefremov
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_stock">True</property>
|
||||
<signal name="activate" handler="on_remove" object="satellites_editor_tree_view" swapped="no"/>
|
||||
<accelerator key="Delete" signal="activate"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
@@ -538,6 +488,7 @@ Author: Dmitriy Yefremov
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Update</property>
|
||||
<signal name="clicked" handler="on_update" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="update_header_button_img">
|
||||
@@ -562,79 +513,6 @@ Author: Dmitriy Yefremov
|
||||
<property name="label" translatable="yes">Satellites edit tool</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="right_header_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkMenuButton" id="add_header_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Add</property>
|
||||
<property name="popover">add_header_popover_menu</property>
|
||||
<child>
|
||||
<object class="GtkImage" id="add_header_button_img">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-add</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="edit_header_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Edit</property>
|
||||
<signal name="clicked" handler="on_edit" object="satellites_editor_tree_view" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="edit_header_button_img">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-edit</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="remove_header_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Remove</property>
|
||||
<signal name="clicked" handler="on_remove" object="satellites_editor_tree_view" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkImage" id="remove_header_button_img">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="stock">gtk-remove</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="pack_type">end</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
@@ -845,12 +723,15 @@ Author: Dmitriy Yefremov
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkDialog" id="satellite_dialog">
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="skip_pager_hint">True</property>
|
||||
<property name="gravity">center</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="satellites_dialog_header">
|
||||
<property name="visible">True</property>
|
||||
@@ -904,10 +785,10 @@ Author: Dmitriy Yefremov
|
||||
<object class="GtkFrame" id="satellite_dialog_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">2</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="label_xalign">0.019999999552965164</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
@@ -960,6 +841,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="secondary_icon_activatable">False</property>
|
||||
<property name="secondary_icon_sensitive">False</property>
|
||||
<property name="input_purpose">number</property>
|
||||
@@ -1032,15 +914,18 @@ Author: Dmitriy Yefremov
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkDialog" id="transponder_dialog">
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="width_request">320</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="default_width">320</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="skip_pager_hint">True</property>
|
||||
<property name="gravity">center</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="transponder_dialog_header">
|
||||
<property name="visible">True</property>
|
||||
@@ -1094,9 +979,10 @@ Author: Dmitriy Yefremov
|
||||
<object class="GtkFrame" id="transponder_dialog_frame">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="label_xalign">0.019999999552965164</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
@@ -1464,9 +1350,11 @@ Author: Dmitriy Yefremov
|
||||
<object class="GtkWindow" id="satellites_update_window">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="skip_pager_hint">True</property>
|
||||
<property name="gravity">center</property>
|
||||
<signal name="delete-event" handler="on_quit" swapped="no"/>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
|
||||
@@ -7,9 +7,9 @@ from app.commons import run_idle, run_task
|
||||
from app.eparser import get_satellites, write_satellites, Satellite, Transponder
|
||||
from app.tools.satellites import SatellitesParser, SatelliteSource
|
||||
from .search import SearchProvider
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN, MOVE_KEYS
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, TEXT_DOMAIN, MOVE_KEYS, KeyboardKey
|
||||
from .dialogs import show_dialog, DialogType, WaitDialog
|
||||
from .main_helper import move_items, scroll_to, append_text_to_tview, get_base_model
|
||||
from .main_helper import move_items, scroll_to, append_text_to_tview, get_base_model, on_popup_menu
|
||||
|
||||
|
||||
def show_satellites_dialog(transient, options):
|
||||
@@ -30,12 +30,11 @@ class SatellitesDialog:
|
||||
"on_update": self.on_update,
|
||||
"on_up": self.on_up,
|
||||
"on_down": self.on_down,
|
||||
"on_popup_menu": self.on_popup_menu,
|
||||
"on_popup_menu": on_popup_menu,
|
||||
"on_satellite_add": self.on_satellite_add,
|
||||
"on_transponder_add": self.on_transponder_add,
|
||||
"on_edit": self.on_edit,
|
||||
"on_key_release": self.on_key_release,
|
||||
"on_popover_release": self.on_popover_release,
|
||||
"on_row_activated": self.on_row_activated,
|
||||
"on_resize": self.on_resize,
|
||||
"on_quit": self.on_quit}
|
||||
@@ -44,12 +43,11 @@ class SatellitesDialog:
|
||||
builder.set_translation_domain(TEXT_DOMAIN)
|
||||
builder.add_objects_from_file(UI_RESOURCES_PATH + "satellites_dialog.glade",
|
||||
("satellites_editor_window", "satellites_tree_store", "popup_menu",
|
||||
"left_header_menu", "add_header_popover_menu"))
|
||||
"left_header_menu", "popup_menu_add_image", "popup_menu_add_image_2"))
|
||||
builder.connect_signals(handlers)
|
||||
|
||||
self._window = builder.get_object("satellites_editor_window")
|
||||
self._window.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._wait_dialog = WaitDialog(self._window)
|
||||
# Setting the last size of the dialog window if it was saved
|
||||
@@ -106,36 +104,34 @@ class SatellitesDialog:
|
||||
view.expand_row(path, column)
|
||||
|
||||
def on_up(self, item):
|
||||
move_items(Gdk.KEY_Up, self._sat_view)
|
||||
move_items(KeyboardKey.UP, self._sat_view)
|
||||
|
||||
def on_down(self, item):
|
||||
move_items(Gdk.KEY_Down, self._sat_view)
|
||||
move_items(KeyboardKey.DOWN, self._sat_view)
|
||||
|
||||
def on_key_release(self, view, event):
|
||||
""" Handling keystrokes """
|
||||
key = event.keyval
|
||||
key_code = event.hardware_keycode
|
||||
if not KeyboardKey.value_exist(key_code):
|
||||
return
|
||||
key = KeyboardKey(key_code)
|
||||
ctrl = event.state & Gdk.ModifierType.CONTROL_MASK
|
||||
|
||||
if key == Gdk.KEY_Delete:
|
||||
if key is KeyboardKey.DELETE:
|
||||
self.on_remove(view)
|
||||
elif key == Gdk.KEY_Insert:
|
||||
elif key is KeyboardKey.INSERT:
|
||||
pass
|
||||
elif ctrl and key == Gdk.KEY_E or key == Gdk.KEY_e:
|
||||
elif ctrl and key is KeyboardKey.E:
|
||||
self.on_edit(view)
|
||||
elif ctrl and key == Gdk.KEY_s or key == Gdk.KEY_S:
|
||||
elif ctrl and key is KeyboardKey.S:
|
||||
self.on_satellite()
|
||||
elif ctrl and key == Gdk.KEY_t or key == Gdk.KEY_T:
|
||||
elif ctrl and key is KeyboardKey.T:
|
||||
self.on_transponder()
|
||||
elif key == Gdk.KEY_space:
|
||||
pass
|
||||
elif ctrl and key in MOVE_KEYS:
|
||||
move_items(key, self._sat_view)
|
||||
elif key == Gdk.KEY_Left or key == Gdk.KEY_Right:
|
||||
elif key is KeyboardKey.LEFT or key is KeyboardKey.RIGHT:
|
||||
view.do_unselect_all(view)
|
||||
|
||||
def on_popover_release(self, menu, event):
|
||||
menu.hide()
|
||||
|
||||
@run_idle
|
||||
def on_satellites_list_load(self, model):
|
||||
""" Load satellites data into model """
|
||||
@@ -307,11 +303,6 @@ class SatellitesDialog:
|
||||
satellite = Satellite(sat[0], sat[-2], sat[-1], transponders)
|
||||
sats.append(satellite)
|
||||
|
||||
@staticmethod
|
||||
def on_popup_menu(menu, event):
|
||||
if event.get_event_type() == Gdk.EventType.BUTTON_PRESS and event.button == Gdk.BUTTON_SECONDARY:
|
||||
menu.popup(None, None, None, None, event.button, event.time)
|
||||
|
||||
|
||||
# ***************** Transponder dialog *******************#
|
||||
|
||||
@@ -456,7 +447,7 @@ class SatellitesUpdateDialog:
|
||||
"on_info_bar_close": self.on_info_bar_close,
|
||||
"on_filter_toggled": self.on_filter_toggled,
|
||||
"on_find_toggled": self.on_find_toggled,
|
||||
"on_popup_menu": self.on_popup_menu,
|
||||
"on_popup_menu": on_popup_menu,
|
||||
"on_select_all": self.on_select_all,
|
||||
"on_unselect_all": self.on_unselect_all,
|
||||
"on_filter": self.on_filter,
|
||||
@@ -683,11 +674,6 @@ class SatellitesUpdateDialog:
|
||||
itr = self._filter_model.convert_iter_to_child_iter(model.convert_iter_to_child_iter(model.get_iter(path)))
|
||||
self._filter_model.get_model().set_value(itr, 4, select)
|
||||
|
||||
def on_popup_menu(self, menu, event):
|
||||
""" Shows popup menu for the view """
|
||||
if event.get_event_type() == Gdk.EventType.BUTTON_PRESS and event.button == Gdk.BUTTON_SECONDARY:
|
||||
menu.popup(None, None, None, None, event.button, event.time)
|
||||
|
||||
def on_quit(self, window, event):
|
||||
self._download_task = False
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@
|
||||
<row>
|
||||
<col id="0" translatable="yes">4/5</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">6/7</col>
|
||||
</row>
|
||||
<row>
|
||||
<col id="0" translatable="yes">9/10</col>
|
||||
</row>
|
||||
@@ -214,86 +217,79 @@
|
||||
</row>
|
||||
</data>
|
||||
</object>
|
||||
<object class="GtkDialog" id="service_details_dialog">
|
||||
<object class="GtkComboBox" id="rate_lp_combo_box">
|
||||
<property name="visible">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="model">fec_list_store</property>
|
||||
<property name="id_column">0</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="rate_lp_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkDialog" id="service_details_dialog">
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Service data</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
<property name="icon_name">document-properties-symbolic</property>
|
||||
<property name="type_hint">dialog</property>
|
||||
<property name="skip_taskbar_hint">True</property>
|
||||
<property name="skip_pager_hint">True</property>
|
||||
<property name="gravity">center</property>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar">
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="cancel_button">
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Service data</property>
|
||||
<property name="spacing">2</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="apply_button">
|
||||
<property name="label">gtk-save</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Save current service</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_save" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="create_button">
|
||||
<property name="label">gtk-new</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Create and save as new service</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_create_new" swapped="no"/>
|
||||
</object>
|
||||
</child>
|
||||
<action-widgets>
|
||||
<action-widget response="-6">cancel_button</action-widget>
|
||||
</action-widgets>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="dialog_vbox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">2</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox" id="dialog-action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="cancel_button">
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Cancel</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>
|
||||
<child>
|
||||
<object class="GtkButton" id="apply_button">
|
||||
<property name="label">gtk-save</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Save current service</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_save" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="create_button">
|
||||
<property name="label">gtk-new</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Create and save as new service</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="always_show_image">True</property>
|
||||
<signal name="clicked" handler="on_create_new" swapped="no"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
@@ -307,6 +303,7 @@
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="label_xalign">0.019999999552965164</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
@@ -924,6 +921,7 @@
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">2</property>
|
||||
<property name="margin_right">2</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="label_xalign">0.019999999552965164</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
@@ -941,7 +939,7 @@
|
||||
<property name="can_focus">False</property>
|
||||
<property name="column_spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label1">
|
||||
<object class="GtkLabel" id="position_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Position</property>
|
||||
@@ -952,7 +950,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label16">
|
||||
<object class="GtkLabel" id="freq_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Freq</property>
|
||||
@@ -978,7 +976,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label17">
|
||||
<object class="GtkLabel" id="rate_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Rate</property>
|
||||
@@ -1004,9 +1002,11 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label18">
|
||||
<object class="GtkLabel" id="pol_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="label" translatable="yes">Pol</property>
|
||||
</object>
|
||||
<packing>
|
||||
@@ -1034,9 +1034,11 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label19">
|
||||
<object class="GtkLabel" id="fec_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">5</property>
|
||||
<property name="margin_right">5</property>
|
||||
<property name="label" translatable="yes">FEC</property>
|
||||
</object>
|
||||
<packing>
|
||||
@@ -1080,7 +1082,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label30">
|
||||
<object class="GtkLabel" id="namespace_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Namespace</property>
|
||||
@@ -1106,7 +1108,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label4">
|
||||
<object class="GtkLabel" id="tid_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">TID</property>
|
||||
@@ -1133,7 +1135,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label8">
|
||||
<object class="GtkLabel" id="nid_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">NID</property>
|
||||
@@ -1177,7 +1179,7 @@
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="column_spacing">2</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label25">
|
||||
<object class="GtkLabel" id="inversion_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Inversion</property>
|
||||
@@ -1188,7 +1190,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label23">
|
||||
<object class="GtkLabel" id="rolloff_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Rolloff</property>
|
||||
@@ -1200,7 +1202,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label24">
|
||||
<object class="GtkLabel" id="pilot_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Pilot</property>
|
||||
@@ -1268,7 +1270,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label10">
|
||||
<object class="GtkLabel" id="pls_mode_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">PLS mode</property>
|
||||
@@ -1298,7 +1300,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label29">
|
||||
<object class="GtkLabel" id="tr_flag_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Flag</property>
|
||||
@@ -1324,7 +1326,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label9">
|
||||
<object class="GtkLabel" id="pls_code_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">PLS code</property>
|
||||
@@ -1350,7 +1352,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label28">
|
||||
<object class="GtkLabel" id="stream_id_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Stream ID</property>
|
||||
@@ -1376,7 +1378,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label21">
|
||||
<object class="GtkLabel" id="system_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">System</property>
|
||||
@@ -1408,7 +1410,7 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="label22">
|
||||
<object class="GtkLabel" id="mod_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Mod</property>
|
||||
@@ -1545,9 +1547,11 @@
|
||||
</columns>
|
||||
</object>
|
||||
<object class="GtkDialog" id="tr_services_dialog">
|
||||
<property name="use-header-bar">1</property>
|
||||
<property name="width_request">480</property>
|
||||
<property name="height_request">300</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="title" translatable="yes">Transponder details</property>
|
||||
<property name="resizable">False</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="window_position">center-on-parent</property>
|
||||
<property name="destroy_with_parent">True</property>
|
||||
@@ -1558,45 +1562,34 @@
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="tr_services_no_button">
|
||||
<property name="label">gtk-cancel</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>
|
||||
</child>
|
||||
<child type="action">
|
||||
<object class="GtkButton" id="tr_services_ok_button">
|
||||
<property name="label">gtk-ok</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>
|
||||
</child>
|
||||
<child internal-child="vbox">
|
||||
<object class="GtkBox" id="tr_services_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="tr_services_dialog_action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkButton" id="tr_services_no_button">
|
||||
<property name="label">gtk-cancel</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>
|
||||
<child>
|
||||
<object class="GtkButton" id="tr_services_ok_button">
|
||||
<property name="label">gtk-ok</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">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
@@ -1605,172 +1598,172 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox" id="infor_box">
|
||||
<object class="GtkInfoBar" id="srv_list_dialog_info_bar">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="srv_list_dialog_hdr_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="message_type">warning</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<child internal-child="action_area">
|
||||
<object class="GtkButtonBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="label" translatable="yes">Changes will be applied to all services of this transponder!
|
||||
<property name="spacing">6</property>
|
||||
<property name="layout_style">end</property>
|
||||
<child>
|
||||
<object class="GtkLabel" id="srv_list_dialog_hdr_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="margin_left">20</property>
|
||||
<property name="margin_right">20</property>
|
||||
<property name="margin_top">5</property>
|
||||
<property name="margin_bottom">5</property>
|
||||
<property name="label" translatable="yes">Changes will be applied to all services of this transponder!
|
||||
Continue?</property>
|
||||
<property name="use_markup">True</property>
|
||||
<property name="justify">center</property>
|
||||
<property name="lines">2</property>
|
||||
<style>
|
||||
<class name="primary-toolbar"/>
|
||||
</style>
|
||||
<property name="justify">center</property>
|
||||
<property name="lines">2</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="separator1">
|
||||
<property name="visible">True</property>
|
||||
<child internal-child="content_area">
|
||||
<object class="GtkBox">
|
||||
<property name="can_focus">False</property>
|
||||
<property name="spacing">16</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">2</property>
|
||||
<property name="position">1</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">0</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="GtkScrolledWindow" id="tr_srv_scrolled_window">
|
||||
<property name="height_request">120</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow" id="tr_srv_scrolled_window">
|
||||
<property name="height_request">120</property>
|
||||
<object class="GtkTreeView" id="tr_services_list_treeview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">in</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="model">transponder_services_liststore</property>
|
||||
<property name="enable_search">False</property>
|
||||
<property name="enable_grid_lines">vertical</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="treeview-selection1"/>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeView" id="tr_services_list_treeview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="model">transponder_services_liststore</property>
|
||||
<property name="enable_search">False</property>
|
||||
<property name="enable_grid_lines">vertical</property>
|
||||
<child internal-child="selection">
|
||||
<object class="GtkTreeSelection" id="treeview-selection1"/>
|
||||
</child>
|
||||
<object class="GtkTreeViewColumn" id="tr_srv_treeviewcolumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Service</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="tr_srv_treeviewcolumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Service</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="srv_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkCellRendererText" id="srv_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">0</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="package_treeview_column">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Package</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="package_treeview_column">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Package</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="package_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GtkCellRendererText" id="package_cellrenderertext"/>
|
||||
<attributes>
|
||||
<attribute name="text">1</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="type_treeviewcolumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Type</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="type_treeviewcolumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Type</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="type_cellrenderertext">
|
||||
<property name="xalign">0.50999999046325684</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<object class="GtkCellRendererText" id="type_cellrenderertext">
|
||||
<property name="xalign">0.50999999046325684</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">2</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="ssid_treeviewcolumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Ssid</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="ssid_treeviewcolumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Ssid</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="ssid_cellrenderertext">
|
||||
<property name="xalign">0.50999999046325684</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<object class="GtkCellRendererText" id="ssid_cellrenderertext">
|
||||
<property name="xalign">0.50999999046325684</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">3</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="freq_treeviewcolumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Freq.</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="freq_treeviewcolumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Freq.</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="freq_cellrenderertext">
|
||||
<property name="xalign">0.50999999046325684</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">4</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<object class="GtkCellRendererText" id="freq_cellrenderertext">
|
||||
<property name="xalign">0.50999999046325684</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">4</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="pos_treeviewcolumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Pos.</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkTreeViewColumn" id="pos_treeviewcolumn">
|
||||
<property name="sizing">autosize</property>
|
||||
<property name="title" translatable="yes">Pos.</property>
|
||||
<property name="alignment">0.5</property>
|
||||
<child>
|
||||
<object class="GtkCellRendererText" id="pos_cellrenderertext">
|
||||
<property name="xalign">0.50999999046325684</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">5</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
<object class="GtkCellRendererText" id="pos_cellrenderertext">
|
||||
<property name="xalign">0.50999999046325684</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">5</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator" id="tr_srv_dialog_separator">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="padding">2</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="position">1</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
|
||||
@@ -4,9 +4,10 @@ import os
|
||||
from app.commons import run_idle
|
||||
from app.eparser import Service
|
||||
from app.eparser.ecommons import MODULATION, Inversion, ROLL_OFF, Pilot, Flag, Pids, POLARIZATION, \
|
||||
get_key_by_value, get_value_by_name, FEC_DEFAULT, PLS_MODE, SERVICE_TYPE
|
||||
get_key_by_value, get_value_by_name, FEC_DEFAULT, PLS_MODE, SERVICE_TYPE, T_MODULATION, C_MODULATION, TrType, \
|
||||
SystemCable, T_SYSTEM, BANDWIDTH, TRANSMISSION_MODE, GUARD_INTERVAL, HIERARCHY, T_FEC
|
||||
from app.properties import Profile
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, HIDE_ICON, TEXT_DOMAIN, CODED_ICON
|
||||
from .uicommons import Gtk, Gdk, UI_RESOURCES_PATH, HIDE_ICON, TEXT_DOMAIN, CODED_ICON, Column
|
||||
from .dialogs import show_dialog, DialogType, Action
|
||||
from .main_helper import get_base_model
|
||||
|
||||
@@ -31,7 +32,7 @@ class ServiceDetailsDialog:
|
||||
|
||||
_DIGIT_ENTRY_NAME = "digit-entry"
|
||||
|
||||
def __init__(self, transient, options, srv_view, fav_view, services, bouquets, action=Action.EDIT):
|
||||
def __init__(self, transient, options, srv_view, fav_view, services, bouquets, new_color, action=Action.EDIT):
|
||||
handlers = {"on_system_changed": self.on_system_changed,
|
||||
"on_save": self.on_save,
|
||||
"on_create_new": self.on_create_new,
|
||||
@@ -50,6 +51,7 @@ class ServiceDetailsDialog:
|
||||
self._dialog = builder.get_object("service_details_dialog")
|
||||
self._dialog.set_transient_for(transient)
|
||||
self._profile = Profile(options["profile"])
|
||||
self._tr_type = None
|
||||
self._satellites_xml_path = options.get(self._profile.value)["data_dir_path"] + "satellites.xml"
|
||||
self._picons_dir_path = options.get(self._profile.value)["picons_dir_path"]
|
||||
self._services_view = srv_view
|
||||
@@ -58,6 +60,7 @@ class ServiceDetailsDialog:
|
||||
self._old_service = None
|
||||
self._services = services
|
||||
self._bouquets = bouquets
|
||||
self._new_color = new_color
|
||||
self._transponder_services_iters = None
|
||||
self._current_model = None
|
||||
self._current_itr = None
|
||||
@@ -116,6 +119,7 @@ class ServiceDetailsDialog:
|
||||
self._sat_pos_button = builder.get_object("sat_pos_button")
|
||||
self._pol_combo_box = builder.get_object("pol_combo_box")
|
||||
self._fec_combo_box = builder.get_object("fec_combo_box")
|
||||
self._rate_lp_combo_box = builder.get_object("rate_lp_combo_box")
|
||||
self._sys_combo_box = builder.get_object("sys_combo_box")
|
||||
self._mod_combo_box = builder.get_object("mod_combo_box")
|
||||
self._invertion_combo_box = builder.get_object("invertion_combo_box")
|
||||
@@ -130,7 +134,7 @@ class ServiceDetailsDialog:
|
||||
self._TRANSPONDER_ELEMENTS = (self._sat_pos_button, self._pol_combo_box, self._invertion_combo_box,
|
||||
self._sys_combo_box, self._freq_entry, self._transponder_id_entry,
|
||||
self._network_id_entry, self._namespace_entry, self._fec_combo_box,
|
||||
self._rate_entry)
|
||||
self._rate_entry, self._rate_lp_combo_box)
|
||||
|
||||
if self._action is Action.EDIT:
|
||||
self.update_data_elements()
|
||||
@@ -183,7 +187,7 @@ class ServiceDetailsDialog:
|
||||
if not itr:
|
||||
return
|
||||
|
||||
srv = Service(*self._current_model[itr][:])
|
||||
srv = Service(*self._current_model[itr][: Column.SRV_TOOLTIP])
|
||||
self._old_service = srv
|
||||
self._current_itr = itr
|
||||
# Service
|
||||
@@ -191,12 +195,19 @@ class ServiceDetailsDialog:
|
||||
self._package_entry.set_text(srv.package)
|
||||
self._sid_entry.set_text(str(int(srv.ssid, 16)))
|
||||
# Transponder
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
self._tr_type = TrType(srv.transponder_type)
|
||||
self._freq_entry.set_text(srv.freq)
|
||||
self._rate_entry.set_text(srv.rate)
|
||||
self.select_active_text(self._pol_combo_box, srv.pol)
|
||||
self.select_active_text(self._fec_combo_box, srv.fec)
|
||||
self.select_active_text(self._sys_combo_box, srv.system)
|
||||
self.set_sat_positions(srv.pos)
|
||||
if self._tr_type is TrType.Terrestrial:
|
||||
self.update_ui_for_terrestrial()
|
||||
elif self._tr_type is TrType.Cable:
|
||||
self.update_ui_for_cable()
|
||||
else:
|
||||
self.set_sat_positions(srv.pos)
|
||||
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
self.init_enigma2_service_data(srv)
|
||||
@@ -260,21 +271,42 @@ class ServiceDetailsDialog:
|
||||
""" Transponder data initialisation """
|
||||
data = srv.data_id.split(":")
|
||||
tr_data = srv.transponder.split(":")
|
||||
|
||||
if srv.system == "DVB-S2":
|
||||
self.select_active_text(self._mod_combo_box, MODULATION.get(tr_data[8]))
|
||||
self.select_active_text(self._rolloff_combo_box, ROLL_OFF.get(tr_data[9]))
|
||||
self.select_active_text(self._pilot_combo_box, Pilot(tr_data[10]).name)
|
||||
self._tr_flag_entry.set_text(tr_data[7])
|
||||
if len(tr_data) > 12:
|
||||
self._stream_id_entry.set_text(tr_data[11])
|
||||
self._pls_code_entry.set_text(tr_data[12])
|
||||
self.select_active_text(self._pls_mode_combo_box, PLS_MODE.get(tr_data[13]))
|
||||
tr_type = TrType(srv.transponder_type)
|
||||
|
||||
self._namespace_entry.set_text(str(int(data[1], 16)))
|
||||
self._transponder_id_entry.set_text(str(int(data[2], 16)))
|
||||
self._network_id_entry.set_text(str(int(data[3], 16)))
|
||||
self.select_active_text(self._invertion_combo_box, Inversion(tr_data[5]).name)
|
||||
|
||||
if tr_type is TrType.Satellite:
|
||||
self.select_active_text(self._invertion_combo_box, Inversion(tr_data[5]).name)
|
||||
if srv.system == "DVB-S2":
|
||||
self.select_active_text(self._mod_combo_box, MODULATION.get(tr_data[8]))
|
||||
self.select_active_text(self._rolloff_combo_box, ROLL_OFF.get(tr_data[9]))
|
||||
self.select_active_text(self._pilot_combo_box, Pilot(tr_data[10]).name)
|
||||
self._tr_flag_entry.set_text(tr_data[7])
|
||||
if len(tr_data) > 12:
|
||||
self._stream_id_entry.set_text(tr_data[11])
|
||||
self._pls_code_entry.set_text(tr_data[12])
|
||||
self.select_active_text(self._pls_mode_combo_box, PLS_MODE.get(tr_data[13]))
|
||||
elif tr_type is TrType.Cable:
|
||||
self.select_active_text(self._invertion_combo_box, Inversion(tr_data[2]).name)
|
||||
self.select_active_text(self._mod_combo_box, C_MODULATION.get(tr_data[3]))
|
||||
self.select_active_text(self._fec_combo_box, FEC_DEFAULT.get(tr_data[4]))
|
||||
self.select_active_text(self._sys_combo_box, SystemCable(tr_data[5]).name)
|
||||
elif tr_type is TrType.Terrestrial:
|
||||
self.select_active_text(self._fec_combo_box, T_FEC.get(tr_data[2]))
|
||||
self.select_active_text(self._rate_lp_combo_box, T_FEC.get(tr_data[3]))
|
||||
# Pol -> Bandwidth
|
||||
self.select_active_text(self._pol_combo_box, BANDWIDTH.get(tr_data[1]))
|
||||
self.select_active_text(self._mod_combo_box, T_MODULATION.get(tr_data[4]))
|
||||
# Transmission Mode -> Roll off
|
||||
self.select_active_text(self._rolloff_combo_box, TRANSMISSION_MODE.get(tr_data[5]))
|
||||
# GuardInterval -> Pilot
|
||||
self.select_active_text(self._pilot_combo_box, GUARD_INTERVAL.get(tr_data[6]))
|
||||
# Hierarchy -> Pls Mode
|
||||
self.select_active_text(self._pls_mode_combo_box, HIERARCHY.get(tr_data[7]))
|
||||
self.select_active_text(self._invertion_combo_box, Inversion(tr_data[8]).name)
|
||||
self.select_active_text(self._sys_combo_box, T_SYSTEM.get(tr_data[9]))
|
||||
# Should be called last to properly initialize the reference
|
||||
self._srv_type_entry.set_text(data[4])
|
||||
|
||||
@@ -291,7 +323,9 @@ class ServiceDetailsDialog:
|
||||
def init_neutrino_ui_elements(self):
|
||||
self._builder.get_object("flags_box").set_visible(False)
|
||||
self._builder.get_object("pids_grid").set_visible(False)
|
||||
self._builder.get_object("tr_grid").remove_column(7)
|
||||
tr_grid = self._builder.get_object("tr_grid")
|
||||
tr_grid.remove_column(7)
|
||||
tr_grid.set_margin_bottom(5)
|
||||
self._builder.get_object("tr_extra_expander").set_visible(False)
|
||||
self._builder.get_object("srv_separator").set_visible(False)
|
||||
|
||||
@@ -342,21 +376,48 @@ class ServiceDetailsDialog:
|
||||
self.on_edit() if self._action is Action.EDIT else self.on_new()
|
||||
self._dialog.destroy()
|
||||
|
||||
def on_new(self):
|
||||
""" Create new service. """
|
||||
service = self.get_service(*self.get_srv_data(), self.get_satellite_transponder_data())
|
||||
show_dialog(DialogType.ERROR, transient=self._dialog, text="Not implemented yet!")
|
||||
|
||||
def on_edit(self):
|
||||
""" Edit current service. """
|
||||
fav_id, data_id = self.get_srv_data()
|
||||
# transponder
|
||||
transponder = self._old_service.transponder
|
||||
if self._tr_edit_switch.get_active():
|
||||
transponder = self.get_transponder_data()
|
||||
if self._transponder_services_iters:
|
||||
self.update_transponder_services(transponder)
|
||||
try:
|
||||
if self._tr_type is TrType.Satellite:
|
||||
transponder = self.get_satellite_transponder_data()
|
||||
elif self._tr_type is TrType.Terrestrial:
|
||||
transponder = self.get_terrestrial_transponder_data()
|
||||
elif self._tr_type is TrType.Cable:
|
||||
transponder = self.get_cable_transponder_data()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
show_dialog(DialogType.ERROR, transient=self._dialog, text="Error getting transponder parameters!")
|
||||
else:
|
||||
if self._transponder_services_iters:
|
||||
self.update_transponder_services(transponder)
|
||||
# service
|
||||
service = self.get_service(fav_id, data_id, transponder)
|
||||
old_fav_id = self._old_service.fav_id
|
||||
if old_fav_id != fav_id:
|
||||
self.update_bouquets(fav_id, old_fav_id)
|
||||
self._services[fav_id] = service
|
||||
|
||||
if self._old_service.picon_id != service.picon_id:
|
||||
self.update_picon_name(self._old_service.picon_id, service.picon_id)
|
||||
|
||||
flags = service.flags_cas
|
||||
extra_data = {Column.SRV_TOOLTIP: None, Column.SRV_BACKGROUND: None}
|
||||
if flags:
|
||||
f_flags = list(filter(lambda x: x.startswith("f:"), flags.split(",")))
|
||||
if f_flags and Flag.is_new(int(f_flags[0][2:])):
|
||||
extra_data[Column.SRV_BACKGROUND] = self._new_color
|
||||
|
||||
self._current_model.set(self._current_itr, extra_data)
|
||||
self._current_model.set(self._current_itr, {i: v for i, v in enumerate(service)})
|
||||
self.update_fav_view(self._old_service, service)
|
||||
self._old_service = service
|
||||
@@ -395,15 +456,12 @@ class ServiceDetailsDialog:
|
||||
os.rename(old_file, new_file)
|
||||
break
|
||||
|
||||
def on_new(self):
|
||||
service = self.get_service(*self.get_srv_data(), self.get_transponder_data())
|
||||
print(service)
|
||||
show_dialog(DialogType.ERROR, transient=self._dialog, text="Not implemented yet!")
|
||||
# ***************** Service ********************* #
|
||||
|
||||
def get_service(self, fav_id, data_id, transponder):
|
||||
freq, rate, pol, fec, system, pos = self.get_transponder_values()
|
||||
return Service(flags_cas=self.get_flags(),
|
||||
transponder_type="s",
|
||||
transponder_type=self._old_service.transponder_type,
|
||||
coded=CODED_ICON if self._cas_entry.get_text() else None,
|
||||
service=self._name_entry.get_text(),
|
||||
locked=self._old_service.locked,
|
||||
@@ -481,16 +539,27 @@ class ServiceDetailsDialog:
|
||||
fav_id = self._NEUTRINO_FAV_ID.format(tr_id, net_id, ssid)
|
||||
return fav_id, self._old_service.data_id
|
||||
|
||||
# ***************** Transponder ********************* #
|
||||
|
||||
def get_transponder_values(self):
|
||||
freq = self._freq_entry.get_text()
|
||||
rate = self._rate_entry.get_text()
|
||||
pol = self._pol_combo_box.get_active_id()
|
||||
fec = self._fec_combo_box.get_active_id()
|
||||
system = self._sys_combo_box.get_active_id()
|
||||
pos = str(round(self._sat_pos_button.get_value(), 1))
|
||||
return freq, rate, pol, fec, system, pos
|
||||
|
||||
def get_transponder_data(self):
|
||||
if self._tr_type is TrType.Satellite or self._profile is Profile.NEUTRINO_MP:
|
||||
freq = self._freq_entry.get_text()
|
||||
rate = self._rate_entry.get_text()
|
||||
pol = self._pol_combo_box.get_active_id()
|
||||
pos = str(round(self._sat_pos_button.get_value(), 1))
|
||||
return freq, rate, pol, fec, system, pos
|
||||
elif self._tr_type is TrType.Terrestrial:
|
||||
o_srv = self._old_service
|
||||
return freq, o_srv.rate, o_srv.pol, fec, system, o_srv.pos
|
||||
elif self._tr_type is TrType.Cable:
|
||||
o_srv = self._old_service
|
||||
return freq, self._rate_entry.get_text(), o_srv.pol, fec, o_srv.system, o_srv.pos
|
||||
|
||||
def get_satellite_transponder_data(self):
|
||||
sys = self._sys_combo_box.get_active_id()
|
||||
freq = self._freq_entry.get_text()
|
||||
rate = self._rate_entry.get_text()
|
||||
@@ -520,18 +589,47 @@ class ServiceDetailsDialog:
|
||||
srv_sys = None
|
||||
return self._NEUTRINO_TRANSPONDER_DATA.format(tr_id, on_id, freq, inv, rate, fec, pol, mod, srv_sys)
|
||||
|
||||
def get_terrestrial_transponder_data(self):
|
||||
tr_data = re.split("\s|:", self._old_service.transponder)
|
||||
# frequency, bandwidth, code rate HP, code rate LP, modulation, transmission mode, guard interval, hierarchy,
|
||||
# inversion, system, plp_id
|
||||
# Bandwidth -> Pol, Rate HP -> FEC, TransmissionMode -> Roll off, GuardInterval -> Pilot, Hierarchy -> Pls Mode
|
||||
tr_data[1] = self._freq_entry.get_text()
|
||||
tr_data[2] = self.get_value_from_combobox_id(self._pol_combo_box, BANDWIDTH)
|
||||
tr_data[3] = self.get_value_from_combobox_id(self._fec_combo_box, T_FEC)
|
||||
tr_data[4] = self.get_value_from_combobox_id(self._rate_lp_combo_box, T_FEC)
|
||||
tr_data[5] = self.get_value_from_combobox_id(self._mod_combo_box, T_MODULATION)
|
||||
tr_data[6] = self.get_value_from_combobox_id(self._rolloff_combo_box, TRANSMISSION_MODE)
|
||||
tr_data[7] = self.get_value_from_combobox_id(self._pilot_combo_box, GUARD_INTERVAL)
|
||||
tr_data[8] = self.get_value_from_combobox_id(self._pls_mode_combo_box, HIERARCHY)
|
||||
tr_data[9] = get_value_by_name(Inversion, self._invertion_combo_box.get_active_id())
|
||||
tr_data[10] = self.get_value_from_combobox_id(self._sys_combo_box, T_SYSTEM)
|
||||
return "{} {}".format(tr_data[0], ":".join(tr_data[1:]))
|
||||
|
||||
def get_cable_transponder_data(self):
|
||||
tr_data = re.split("\s|:", self._old_service.transponder)
|
||||
# frequency, symbol_rate, modulation, inversion, fec_inner, system;
|
||||
tr_data[1] = self._freq_entry.get_text()
|
||||
tr_data[2] = self._rate_entry.get_text()
|
||||
tr_data[3] = get_value_by_name(Inversion, self._invertion_combo_box.get_active_id())
|
||||
tr_data[4] = self.get_value_from_combobox_id(self._mod_combo_box, C_MODULATION)
|
||||
tr_data[5] = self.get_value_from_combobox_id(self._fec_combo_box, FEC_DEFAULT)
|
||||
tr_data[6] = get_value_by_name(SystemCable, self._sys_combo_box.get_active_id())
|
||||
return "{} {}".format(tr_data[0], ":".join(tr_data[1:]))
|
||||
|
||||
def update_transponder_services(self, transponder):
|
||||
for itr in self._transponder_services_iters:
|
||||
srv = self._current_model[itr][:]
|
||||
srv[-9], srv[-8], srv[-7], srv[-6], srv[-5], srv[-4] = self.get_transponder_values()
|
||||
srv[-1] = transponder
|
||||
srv = self._current_model[itr][:Column.SRV_TOOLTIP]
|
||||
srv[Column.SRV_FREQ], srv[Column.SRV_RATE], srv[Column.SRV_POL], srv[Column.SRV_FEC], srv[
|
||||
Column.SRV_SYSTEM], srv[Column.SRV_POS] = self.get_transponder_values()
|
||||
srv[Column.SRV_TRANSPONDER] = transponder
|
||||
srv = Service(*srv)
|
||||
self._services[srv.fav_id] = self._services.pop(srv.fav_id)._replace(transponder=transponder)
|
||||
self._current_model.set(itr, {i: v for i, v in enumerate(srv)})
|
||||
|
||||
# ***************** Others *********************#
|
||||
|
||||
def select_active_text(self, box: Gtk.ComboBox, text):
|
||||
def select_active_text(self, box, text):
|
||||
model = box.get_model()
|
||||
for index, row in enumerate(model):
|
||||
if row[0] == text:
|
||||
@@ -552,8 +650,7 @@ class ServiceDetailsDialog:
|
||||
return get_key_by_value(dc, cb_id)
|
||||
|
||||
@run_idle
|
||||
def on_tr_edit_toggled(self, switch: Gtk.Switch, active):
|
||||
|
||||
def on_tr_edit_toggled(self, switch, active):
|
||||
if active and self._action is Action.EDIT:
|
||||
self._transponder_services_iters = []
|
||||
response = TransponderServicesDialog(self._dialog,
|
||||
@@ -565,7 +662,8 @@ class ServiceDetailsDialog:
|
||||
self._transponder_services_iters = None
|
||||
return
|
||||
|
||||
self.update_dvb_s2_elements(active and self._sys_combo_box.get_active_id() == "DVB-S2")
|
||||
self.update_dvb_s2_elements(active and (self._sys_combo_box.get_active_id() == "DVB-S2"
|
||||
or self._old_service.transponder_type in "tc"))
|
||||
|
||||
for elem in self._TRANSPONDER_ELEMENTS:
|
||||
elem.set_sensitive(active)
|
||||
@@ -587,17 +685,130 @@ class ServiceDetailsDialog:
|
||||
self.update_reference_entry()
|
||||
|
||||
def update_reference_entry(self):
|
||||
srv_type = 0 if self._srv_type_entry.get_text() == "2" else 1
|
||||
srv_type = int(self._srv_type_entry.get_text())
|
||||
ssid = int(self._sid_entry.get_text())
|
||||
tid = int(self._transponder_id_entry.get_text())
|
||||
nid = int(self._network_id_entry.get_text())
|
||||
if self._profile is Profile.ENIGMA_2:
|
||||
on_id = int(self._namespace_entry.get_text())
|
||||
ref = "1:0:{}:{:X}:{:X}:{:X}:{:X}:0:0:0".format(srv_type, ssid, tid, nid, on_id)
|
||||
ref = "1:0:{:X}:{:X}:{:X}:{:X}:{:X}:0:0:0".format(srv_type, ssid, tid, nid, on_id)
|
||||
self._reference_entry.set_text(ref)
|
||||
else:
|
||||
self._reference_entry.set_text("{:x}{:04x}{:04x}".format(tid, nid, ssid))
|
||||
|
||||
def update_ui_for_terrestrial(self):
|
||||
tr_grid = self.get_transponder_grid_for_non_satellite()
|
||||
tr_grid.remove_column(1)
|
||||
tr_grid.insert_column(1)
|
||||
extra_tr_grid = self._builder.get_object("extra_transponder_grid")
|
||||
for i in range(4):
|
||||
extra_tr_grid.remove_column(6)
|
||||
# Bandwidth -> Pol
|
||||
pol_label = self._builder.get_object("pol_label")
|
||||
pol_label.set_text("Bandwidth")
|
||||
tr_grid.attach(pol_label, 1, 0, 1, 1)
|
||||
tr_grid.attach(self._pol_combo_box, 1, 1, 1, 1)
|
||||
# Rate HP -> FEC
|
||||
self._builder.get_object("fec_label").set_text("Rate HP")
|
||||
# Rate LP
|
||||
tr_grid.insert_column(3)
|
||||
rate_lp_label = self._builder.get_object("pls_code_label")
|
||||
rate_lp_label.set_text("Rate LP")
|
||||
tr_grid.attach(rate_lp_label, 3, 0, 1, 1)
|
||||
tr_grid.attach(self._rate_lp_combo_box, 3, 1, 1, 1)
|
||||
# Modulation
|
||||
tr_grid.insert_column(4)
|
||||
extra_tr_grid.remove_column(1)
|
||||
tr_grid.attach(self._builder.get_object("mod_label"), 4, 0, 1, 1)
|
||||
tr_grid.attach(self._mod_combo_box, 4, 1, 1, 1)
|
||||
# TransmissionMode -> Roll off
|
||||
rolloff_label = self._builder.get_object("rolloff_label")
|
||||
rolloff_label.set_text("T mode")
|
||||
# GuardInterval -> Pilot
|
||||
pilot_label = self._builder.get_object("pilot_label")
|
||||
pilot_label.set_text("Guard Interval")
|
||||
# Hierarchy -> Pls Mode
|
||||
pls_mode_label = self._builder.get_object("pls_mode_label")
|
||||
pls_mode_label.set_text("Hierarchy")
|
||||
# Models
|
||||
fec_model, modulation_model, sys_model = self.get_models_for_non_satellite()
|
||||
pol_model = self._pol_combo_box.get_model()
|
||||
roll_off_model = self._rolloff_combo_box.get_model()
|
||||
pilot_model = self._pilot_combo_box.get_model()
|
||||
pls_model = self._pls_mode_combo_box.get_model()
|
||||
# Models clearing
|
||||
for m in pol_model, roll_off_model, pilot_model, pls_model:
|
||||
m.clear()
|
||||
|
||||
self.init_terrestrial_models((pol_model, modulation_model, roll_off_model, pilot_model, pls_model, sys_model),
|
||||
(BANDWIDTH, T_MODULATION, TRANSMISSION_MODE, GUARD_INTERVAL, HIERARCHY, T_SYSTEM))
|
||||
|
||||
# Removing the latest FEC elements from the model
|
||||
for itr in [fec_model.get_iter(Gtk.TreePath.new_from_string(str(i))) for i in range(7, 11)]:
|
||||
fec_model.remove(itr)
|
||||
# Extra
|
||||
self._namespace_entry.set_max_width_chars(15)
|
||||
self._sys_combo_box.set_hexpand(False)
|
||||
|
||||
def init_terrestrial_models(self, models, properties):
|
||||
for index, model in enumerate(models):
|
||||
for v in properties[index].values():
|
||||
model.append((v,))
|
||||
|
||||
def update_ui_for_cable(self):
|
||||
tr_grid = self.get_transponder_grid_for_non_satellite()
|
||||
tr_box = self._builder.get_object("tr_box")
|
||||
# Models
|
||||
fec_model, modulation_model, system_model = self.get_models_for_non_satellite()
|
||||
|
||||
extra_tr_grid = self._builder.get_object("extra_transponder_grid")
|
||||
for child in extra_tr_grid.get_children():
|
||||
extra_tr_grid.remove(child)
|
||||
tr_grid.remove(extra_tr_grid)
|
||||
|
||||
tr_grid.insert_column(3)
|
||||
tr_grid.insert_column(4)
|
||||
tr_grid.insert_column(5)
|
||||
# Modulation
|
||||
tr_grid.attach(self._builder.get_object("mod_label"), 3, 0, 1, 1)
|
||||
tr_grid.attach(self._mod_combo_box, 3, 1, 1, 1)
|
||||
for v in C_MODULATION.values():
|
||||
modulation_model.append((v,))
|
||||
# Inversion
|
||||
tr_grid.attach(self._builder.get_object("inversion_label"), 4, 0, 1, 1)
|
||||
tr_grid.attach(self._invertion_combo_box, 4, 1, 1, 1)
|
||||
# System
|
||||
tr_grid.attach(self._builder.get_object("system_label"), 5, 0, 1, 1)
|
||||
tr_grid.attach(self._sys_combo_box, 5, 1, 1, 1)
|
||||
system_model.append((SystemCable.ANNEX_A.name,))
|
||||
system_model.append((SystemCable.ANNEX_C.name,))
|
||||
# FEC
|
||||
fec_model.append(("None",))
|
||||
# Extra
|
||||
tr_box.remove(self._tr_extra_expander)
|
||||
tr_grid.set_margin_bottom(5)
|
||||
self._freq_entry.set_width_chars(10)
|
||||
self._freq_entry.set_max_width_chars(10)
|
||||
self._rate_entry.set_width_chars(10)
|
||||
self._rate_entry.set_max_width_chars(10)
|
||||
self._transponder_id_entry.set_max_width_chars(8)
|
||||
self._network_id_entry.set_max_width_chars(8)
|
||||
|
||||
def get_transponder_grid_for_non_satellite(self):
|
||||
self._pids_grid.set_visible(False)
|
||||
tr_grid = self._builder.get_object("tr_grid")
|
||||
tr_grid.remove_column(0)
|
||||
tr_grid.remove_column(2)
|
||||
return tr_grid
|
||||
|
||||
def get_models_for_non_satellite(self):
|
||||
fec_model = self._fec_combo_box.get_model()
|
||||
modulation_model = self._mod_combo_box.get_model()
|
||||
modulation_model.clear()
|
||||
system_model = self._sys_combo_box.get_model()
|
||||
system_model.clear()
|
||||
return fec_model, modulation_model, system_model
|
||||
|
||||
|
||||
class TransponderServicesDialog:
|
||||
def __init__(self, transient, model, transponder, tr_iters):
|
||||
@@ -609,11 +820,13 @@ class TransponderServicesDialog:
|
||||
self._dialog.set_transient_for(transient)
|
||||
self._srv_model = builder.get_object("transponder_services_liststore")
|
||||
self.append_services(model, transponder, tr_iters)
|
||||
builder.get_object("srv_list_dialog_info_bar").connect("response", lambda bar, resp: bar.hide())
|
||||
|
||||
def append_services(self, model, transponder, tr_iters):
|
||||
for row in model:
|
||||
if row[-1] == transponder:
|
||||
self._srv_model.append((row[3], row[6], row[7], row[10], row[11], row[16]))
|
||||
if row[Column.SRV_TRANSPONDER] == transponder:
|
||||
self._srv_model.append((row[Column.SRV_SERVICE], row[Column.SRV_PACKAGE], row[Column.SRV_TYPE],
|
||||
row[Column.SRV_SSID], row[Column.SRV_FREQ], row[Column.SRV_POS]))
|
||||
tr_iters.append(model.get_iter(row.path))
|
||||
|
||||
def show(self):
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,12 @@
|
||||
from enum import Enum
|
||||
|
||||
from gi.repository import Gdk
|
||||
|
||||
from app.commons import run_task, run_idle
|
||||
from app.connections import test_telnet, test_ftp, TestException, test_http
|
||||
from app.properties import write_config, Profile, get_default_settings
|
||||
from .uicommons import Gtk, UI_RESOURCES_PATH, TEXT_DOMAIN
|
||||
from app.ui.dialogs import get_message
|
||||
from .uicommons import Gtk, UI_RESOURCES_PATH, TEXT_DOMAIN, NEW_COLOR, EXTRA_COLOR
|
||||
from .main_helper import update_entry_data
|
||||
|
||||
|
||||
@@ -7,14 +14,22 @@ def show_settings_dialog(transient, options):
|
||||
return SettingsDialog(transient, options).show()
|
||||
|
||||
|
||||
class Property(Enum):
|
||||
FTP = "ftp"
|
||||
HTTP = "http"
|
||||
TELNET = "telnet"
|
||||
|
||||
|
||||
class SettingsDialog:
|
||||
|
||||
def __init__(self, transient, options):
|
||||
handlers = {"on_data_dir_field_icon_press": self.on_data_dir_field_icon_press,
|
||||
"on_picons_dir_field_icon_press": self.on_picons_dir_field_icon_press,
|
||||
handlers = {"on_field_icon_press": self.on_field_icon_press,
|
||||
"on_profile_changed": self.on_profile_changed,
|
||||
"on_reset": self.on_reset,
|
||||
"apply_settings": self.apply_settings}
|
||||
"apply_settings": self.apply_settings,
|
||||
"on_connection_test": self.on_connection_test,
|
||||
"on_info_bar_close": self.on_info_bar_close,
|
||||
"on_set_color_switch_state": self.on_set_color_switch_state}
|
||||
|
||||
builder = Gtk.Builder()
|
||||
builder.set_translation_domain(TEXT_DOMAIN)
|
||||
@@ -23,50 +38,78 @@ class SettingsDialog:
|
||||
|
||||
self._dialog = builder.get_object("settings_dialog")
|
||||
self._dialog.set_transient_for(transient)
|
||||
self._header_bar = builder.get_object("header_bar")
|
||||
# Network
|
||||
self._host_field = builder.get_object("host_field")
|
||||
self._port_field = builder.get_object("port_field")
|
||||
self._login_field = builder.get_object("login_field")
|
||||
self._password_field = builder.get_object("password_field")
|
||||
self._http_login_field = builder.get_object("http_login_field")
|
||||
self._http_password_field = builder.get_object("http_password_field")
|
||||
self._http_port_field = builder.get_object("http_port_field")
|
||||
self._telnet_login_field = builder.get_object("telnet_login_field")
|
||||
self._telnet_password_field = builder.get_object("telnet_password_field")
|
||||
self._telnet_port_field = builder.get_object("telnet_port_field")
|
||||
self._telnet_timeout_spin_button = builder.get_object("telnet_timeout_spin_button")
|
||||
self._settings_stack = builder.get_object("settings_stack")
|
||||
# Paths
|
||||
self._services_field = builder.get_object("services_field")
|
||||
self._user_bouquet_field = builder.get_object("user_bouquet_field")
|
||||
self._satellites_xml_field = builder.get_object("satellites_xml_field")
|
||||
self._data_dir_field = builder.get_object("data_dir_field")
|
||||
self._picons_field = builder.get_object("picons_field")
|
||||
self._picons_dir_field = builder.get_object("picons_dir_field")
|
||||
self._backup_dir_field = builder.get_object("backup_dir_field")
|
||||
# Info bar
|
||||
self._info_bar = builder.get_object("info_bar")
|
||||
self._message_label = builder.get_object("info_bar_message_label")
|
||||
self._test_spinner = builder.get_object("test_spinner")
|
||||
# Profile
|
||||
self._enigma_radio_button = builder.get_object("enigma_radio_button")
|
||||
self._neutrino_radio_button = builder.get_object("neutrino_radio_button")
|
||||
self._support_ver5_check_button = builder.get_object("support_ver5_check_button")
|
||||
|
||||
self._support_http_api_check_button = builder.get_object("support_http_api_check_button")
|
||||
# Program
|
||||
self._before_save_switch = builder.get_object("before_save_switch")
|
||||
self._before_downloading_switch = builder.get_object("before_downloading_switch")
|
||||
self._program_box = builder.get_object("program_box")
|
||||
self._colors_grid = builder.get_object("colors_grid")
|
||||
self._set_color_switch = builder.get_object("set_color_switch")
|
||||
self._new_color_button = builder.get_object("new_color_button")
|
||||
self._extra_color_button = builder.get_object("extra_color_button")
|
||||
# Options
|
||||
self._options = options
|
||||
self._active_profile = options.get("profile")
|
||||
self.set_settings()
|
||||
profile = Profile(self._active_profile)
|
||||
self.init_ui_elements(Profile(self._active_profile))
|
||||
|
||||
def init_ui_elements(self, profile):
|
||||
is_enigma_profile = profile is Profile.ENIGMA_2
|
||||
self._neutrino_radio_button.set_active(profile is Profile.NEUTRINO_MP)
|
||||
self._support_ver5_check_button.set_sensitive(profile is not Profile.NEUTRINO_MP)
|
||||
self._settings_stack.get_child_by_name(Property.HTTP.value).set_visible(is_enigma_profile)
|
||||
self._program_box.set_sensitive(is_enigma_profile)
|
||||
self.update_subtitle(profile)
|
||||
|
||||
def show(self):
|
||||
response = self._dialog.run()
|
||||
if response == Gtk.ResponseType.OK:
|
||||
self.apply_settings()
|
||||
write_config(self._options)
|
||||
self._dialog.destroy()
|
||||
|
||||
return response
|
||||
|
||||
def on_data_dir_field_icon_press(self, entry, icon, event_button):
|
||||
update_entry_data(entry, self._dialog, self._options.get(self._options.get("profile")))
|
||||
|
||||
def on_picons_dir_field_icon_press(self, entry, icon, event_button):
|
||||
def on_field_icon_press(self, entry, icon, event_button):
|
||||
update_entry_data(entry, self._dialog, self._options.get(self._options.get("profile")))
|
||||
|
||||
def on_profile_changed(self, item):
|
||||
profile = Profile.ENIGMA_2 if self._enigma_radio_button.get_active() else Profile.NEUTRINO_MP
|
||||
self.set_profile(profile)
|
||||
self._support_ver5_check_button.set_sensitive(profile is Profile.ENIGMA_2)
|
||||
self._active_profile = profile.value
|
||||
self.set_settings()
|
||||
self.init_ui_elements(profile)
|
||||
|
||||
def update_subtitle(self, profile):
|
||||
sub = "{} Enigma2" if profile is Profile.ENIGMA_2 else "{} Neutrino-MP"
|
||||
self._header_bar.set_subtitle(sub.format(get_message("Profile:")))
|
||||
|
||||
def set_profile(self, profile):
|
||||
self._active_profile = profile.value
|
||||
@@ -84,23 +127,40 @@ class SettingsDialog:
|
||||
self.set_settings()
|
||||
|
||||
def set_settings(self):
|
||||
def_settings = get_default_settings().get(self._active_profile)
|
||||
options = self._options.get(self._active_profile)
|
||||
self._host_field.set_text(options.get("host", ""))
|
||||
self._port_field.set_text(options.get("port", ""))
|
||||
self._login_field.set_text(options.get("user", ""))
|
||||
self._password_field.set_text(options.get("password", ""))
|
||||
self._telnet_login_field.set_text(options.get("telnet_user", ""))
|
||||
self._telnet_password_field.set_text(options.get("telnet_password", ""))
|
||||
self._telnet_port_field.set_text(options.get("telnet_port", ""))
|
||||
self._telnet_timeout_spin_button.set_value(options.get("telnet_timeout", 5))
|
||||
self._services_field.set_text(options.get("services_path", ""))
|
||||
self._user_bouquet_field.set_text(options.get("user_bouquet_path", ""))
|
||||
self._satellites_xml_field.set_text(options.get("satellites_xml_path", ""))
|
||||
self._picons_field.set_text(options.get("picons_path", ""))
|
||||
self._data_dir_field.set_text(options.get("data_dir_path", ""))
|
||||
self._picons_dir_field.set_text(options.get("picons_dir_path", ""))
|
||||
self._host_field.set_text(options.get("host", def_settings["host"]))
|
||||
self._port_field.set_text(options.get("port", def_settings["port"]))
|
||||
self._login_field.set_text(options.get("user", def_settings["user"]))
|
||||
self._password_field.set_text(options.get("password", def_settings["password"]))
|
||||
self._http_login_field.set_text(options.get("http_user", def_settings["http_user"]))
|
||||
self._http_password_field.set_text(options.get("http_password", def_settings["http_password"]))
|
||||
self._http_port_field.set_text(options.get("http_port", def_settings["http_port"]))
|
||||
self._telnet_login_field.set_text(options.get("telnet_user", def_settings["telnet_user"]))
|
||||
self._telnet_password_field.set_text(options.get("telnet_password", def_settings["telnet_password"]))
|
||||
self._telnet_port_field.set_text(options.get("telnet_port", def_settings["telnet_port"]))
|
||||
self._telnet_timeout_spin_button.set_value(options.get("telnet_timeout", def_settings["telnet_timeout"]))
|
||||
self._services_field.set_text(options.get("services_path", def_settings["services_path"]))
|
||||
self._user_bouquet_field.set_text(options.get("user_bouquet_path", def_settings["user_bouquet_path"]))
|
||||
self._satellites_xml_field.set_text(options.get("satellites_xml_path", def_settings["satellites_xml_path"]))
|
||||
self._picons_field.set_text(options.get("picons_path", def_settings["picons_path"]))
|
||||
self._data_dir_field.set_text(options.get("data_dir_path", def_settings["data_dir_path"]))
|
||||
self._picons_dir_field.set_text(options.get("picons_dir_path", def_settings["picons_dir_path"]))
|
||||
self._backup_dir_field.set_text(options.get("backup_dir_path", def_settings["backup_dir_path"]))
|
||||
self._before_save_switch.set_active(options.get("backup_before_save", def_settings["backup_before_save"]))
|
||||
self._before_downloading_switch.set_active(options.get("backup_before_downloading",
|
||||
def_settings["backup_before_downloading"]))
|
||||
|
||||
if Profile(self._active_profile) is Profile.ENIGMA_2:
|
||||
self._support_ver5_check_button.set_active(options.get("v5_support", False))
|
||||
self._support_http_api_check_button.set_active(options.get("http_api_support", False))
|
||||
self._set_color_switch.set_active(options.get("use_colors", False))
|
||||
new_rgb = Gdk.RGBA()
|
||||
new_rgb.parse(options.get("new_color", NEW_COLOR))
|
||||
extra_rgb = Gdk.RGBA()
|
||||
extra_rgb.parse(options.get("extra_color", EXTRA_COLOR))
|
||||
self._new_color_button.set_rgba(new_rgb)
|
||||
self._extra_color_button.set_rgba(extra_rgb)
|
||||
|
||||
def apply_settings(self, item=None):
|
||||
profile = Profile.ENIGMA_2 if self._enigma_radio_button.get_active() else Profile.NEUTRINO_MP
|
||||
@@ -111,6 +171,9 @@ class SettingsDialog:
|
||||
options["port"] = self._port_field.get_text()
|
||||
options["user"] = self._login_field.get_text()
|
||||
options["password"] = self._password_field.get_text()
|
||||
options["http_user"] = self._http_login_field.get_text()
|
||||
options["http_password"] = self._http_password_field.get_text()
|
||||
options["http_port"] = self._http_port_field.get_text()
|
||||
options["telnet_user"] = self._telnet_login_field.get_text()
|
||||
options["telnet_password"] = self._telnet_password_field.get_text()
|
||||
options["telnet_port"] = self._telnet_port_field.get_text()
|
||||
@@ -121,8 +184,79 @@ class SettingsDialog:
|
||||
options["picons_path"] = self._picons_field.get_text()
|
||||
options["data_dir_path"] = self._data_dir_field.get_text()
|
||||
options["picons_dir_path"] = self._picons_dir_field.get_text()
|
||||
options["backup_dir_path"] = self._backup_dir_field.get_text()
|
||||
options["backup_before_save"] = self._before_save_switch.get_active()
|
||||
options["backup_before_downloading"] = self._before_downloading_switch.get_active()
|
||||
|
||||
if profile is Profile.ENIGMA_2:
|
||||
options["v5_support"] = self._support_ver5_check_button.get_active()
|
||||
options["http_api_support"] = self._support_http_api_check_button.get_active()
|
||||
options["use_colors"] = self._set_color_switch.get_active()
|
||||
options["new_color"] = self._new_color_button.get_rgba().to_string()
|
||||
options["extra_color"] = self._extra_color_button.get_rgba().to_string()
|
||||
|
||||
write_config(self._options)
|
||||
|
||||
@run_task
|
||||
def on_connection_test(self, item):
|
||||
if self._test_spinner.get_state() is Gtk.StateType.ACTIVE:
|
||||
return
|
||||
self.show_spinner(True)
|
||||
current_property = Property(self._settings_stack.get_visible_child_name())
|
||||
if current_property is Property.HTTP:
|
||||
self.test_http()
|
||||
elif current_property is Property.TELNET:
|
||||
self.test_telnet()
|
||||
elif current_property is Property.FTP:
|
||||
self.test_ftp()
|
||||
|
||||
def test_http(self):
|
||||
user, password = self._http_login_field.get_text(), self._http_password_field.get_text()
|
||||
host, port = self._host_field.get_text(), self._http_port_field.get_text()
|
||||
try:
|
||||
self.show_info_message(test_http(host, port, user, password), Gtk.MessageType.INFO)
|
||||
except TestException as e:
|
||||
self.show_info_message(str(e), Gtk.MessageType.ERROR)
|
||||
finally:
|
||||
self.show_spinner(False)
|
||||
|
||||
def test_telnet(self):
|
||||
timeout = int(self._telnet_timeout_spin_button.get_value())
|
||||
host, port = self._host_field.get_text(), self._telnet_port_field.get_text()
|
||||
user, password = self._telnet_login_field.get_text(), self._telnet_password_field.get_text()
|
||||
try:
|
||||
self.show_info_message(test_telnet(host, port, user, password, timeout), Gtk.MessageType.INFO)
|
||||
self.show_spinner(False)
|
||||
except TestException as e:
|
||||
self.show_info_message(str(e), Gtk.MessageType.ERROR)
|
||||
self.show_spinner(False)
|
||||
|
||||
def test_ftp(self):
|
||||
host, port = self._host_field.get_text(), self._port_field.get_text()
|
||||
user, password = self._login_field.get_text(), self._password_field.get_text()
|
||||
try:
|
||||
self.show_info_message("OK. {}".format(test_ftp(host, port, user, password)), Gtk.MessageType.INFO)
|
||||
except TestException as e:
|
||||
self.show_info_message(str(e), Gtk.MessageType.ERROR)
|
||||
finally:
|
||||
self.show_spinner(False)
|
||||
|
||||
@run_idle
|
||||
def show_info_message(self, text, message_type):
|
||||
self._info_bar.set_visible(True)
|
||||
self._info_bar.set_message_type(message_type)
|
||||
self._message_label.set_text(text)
|
||||
|
||||
@run_idle
|
||||
def show_spinner(self, show):
|
||||
self._test_spinner.start() if show else self._test_spinner.stop()
|
||||
self._test_spinner.set_state(Gtk.StateType.ACTIVE if show else Gtk.StateType.NORMAL)
|
||||
|
||||
def on_info_bar_close(self, bar=None, resp=None):
|
||||
self._info_bar.set_visible(False)
|
||||
|
||||
def on_set_color_switch_state(self, switch, state):
|
||||
self._colors_grid.set_sensitive(state)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -2,7 +2,7 @@ import locale
|
||||
import os
|
||||
|
||||
import gi
|
||||
from enum import Enum
|
||||
from enum import Enum, IntEnum
|
||||
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gtk, Gdk
|
||||
@@ -26,9 +26,53 @@ HIDE_ICON = theme.load_icon("go-jump", 16, 0) if theme.lookup_icon("go-jump", 16
|
||||
TV_ICON = theme.load_icon("tv-symbolic", 16, 0) if theme.lookup_icon("tv-symbolic", 16, 0) else _IMAGE_MISSING
|
||||
IPTV_ICON = theme.load_icon("emblem-shared", 16, 0) if theme.load_icon("emblem-shared", 16, 0) else None
|
||||
|
||||
# keys for move in lists
|
||||
MOVE_KEYS = (Gdk.KEY_Up, Gdk.KEY_Page_Up, Gdk.KEY_Down, Gdk.KEY_Page_Down, Gdk.KEY_Home, Gdk.KEY_End,
|
||||
Gdk.KEY_KP_Page_Up, Gdk.KEY_KP_Page_Down) # KEY_KP_Page_Up(Down) for laptop!
|
||||
# Colors
|
||||
NEW_COLOR = "rgb(255,230,204)" # Color for new services in the main list
|
||||
EXTRA_COLOR = "rgb(179,230,204)" # Color for services with a extra name for the bouquet
|
||||
|
||||
|
||||
class KeyboardKey(Enum):
|
||||
""" The raw(hardware) codes of the keyboard keys """
|
||||
E = 26
|
||||
R = 27
|
||||
T = 28
|
||||
P = 33
|
||||
S = 39
|
||||
H = 43
|
||||
L = 46
|
||||
X = 53
|
||||
C = 54
|
||||
V = 55
|
||||
W = 25
|
||||
Z = 52
|
||||
INSERT = 118
|
||||
HOME = 110
|
||||
END = 115
|
||||
UP = 111
|
||||
DOWN = 116
|
||||
PAGE_UP = 112
|
||||
PAGE_DOWN = 117
|
||||
LEFT = 113
|
||||
RIGHT = 114
|
||||
F2 = 68
|
||||
DELETE = 119
|
||||
BACK_SPACE = 22
|
||||
CTRL_L = 37
|
||||
CTRL_R = 105
|
||||
# Laptop codes
|
||||
HOME_KP = 79
|
||||
END_KP = 87
|
||||
PAGE_UP_KP = 81
|
||||
PAGE_DOWN_KP = 89
|
||||
|
||||
@classmethod
|
||||
def value_exist(cls, value):
|
||||
return value in (val.value for val in cls.__members__.values())
|
||||
|
||||
|
||||
# Keys for move in lists. KEY_KP_(NAME) for laptop!!!
|
||||
MOVE_KEYS = (KeyboardKey.UP, KeyboardKey.PAGE_UP, KeyboardKey.DOWN, KeyboardKey.PAGE_DOWN, KeyboardKey.HOME,
|
||||
KeyboardKey.END, KeyboardKey.HOME_KP, KeyboardKey.END_KP, KeyboardKey.PAGE_UP_KP, KeyboardKey.PAGE_DOWN_KP)
|
||||
|
||||
|
||||
class ViewTarget(Enum):
|
||||
@@ -48,5 +92,48 @@ class BqGenType(Enum):
|
||||
EACH_TYPE = 5
|
||||
|
||||
|
||||
class Column(IntEnum):
|
||||
""" Column nums in the views """
|
||||
# main view
|
||||
SRV_CAS_FLAGS = 0
|
||||
SRV_STANDARD = 1
|
||||
SRV_CODED = 2
|
||||
SRV_SERVICE = 3
|
||||
SRV_LOCKED = 4
|
||||
SRV_HIDE = 5
|
||||
SRV_PACKAGE = 6
|
||||
SRV_TYPE = 7
|
||||
SRV_PICON = 8
|
||||
SRV_PICON_ID = 9
|
||||
SRV_SSID = 10
|
||||
SRV_FREQ = 11
|
||||
SRV_RATE = 12
|
||||
SRV_POL = 13
|
||||
SRV_FEC = 14
|
||||
SRV_SYSTEM = 15
|
||||
SRV_POS = 16
|
||||
SRV_DATA_ID = 17
|
||||
SRV_FAV_ID = 18
|
||||
SRV_TRANSPONDER = 19
|
||||
SRV_TOOLTIP = 20
|
||||
SRV_BACKGROUND = 21
|
||||
# fav view
|
||||
FAV_NUM = 0
|
||||
FAV_CODED = 1
|
||||
FAV_SERVICE = 2
|
||||
FAV_LOCKED = 3
|
||||
FAV_HIDE = 4
|
||||
FAV_TYPE = 5
|
||||
FAV_POS = 6
|
||||
FAV_ID = 7
|
||||
FAV_PICON = 8
|
||||
FAV_TOOLTIP = 9
|
||||
FAV_BACKGROUND = 10
|
||||
|
||||
def __index__(self):
|
||||
""" Overridden to get the index in slices directly """
|
||||
return self.value
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
VER="0.4.0_Pre-alpha"
|
||||
VER="0.4.3_Pre-alpha"
|
||||
B_PATH="dist/DemonEditor"
|
||||
DEB_PATH="$B_PATH/usr/share/demoneditor"
|
||||
|
||||
|
||||
45
deb/DEBIAN/README.source
Normal file
45
deb/DEBIAN/README.source
Normal file
@@ -0,0 +1,45 @@
|
||||
demon-editor for Debian
|
||||
----------------------
|
||||
|
||||
DemonEditor
|
||||
Enigma2 channel and satellites list editor for GNU/Linux.
|
||||
|
||||
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 + Insert - copies the selected channels from the main list to the the bouquet beginning
|
||||
or inserts (creates) a new bouquet.
|
||||
Ctrl + BackSpace - copies the selected channels from the main list to the bouquet end.
|
||||
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.
|
||||
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.
|
||||
Space - select/deselect.
|
||||
Left/Right - remove selection.
|
||||
Ctrl + Up, Down, PageUp, PageDown, Home, End - move selected items in the list.
|
||||
|
||||
Extra:
|
||||
|
||||
Multiple selections in lists only with Space key (as in file managers).
|
||||
Ability to import IPTV into bouquet (Neutrino WEBTV) from m3u files.
|
||||
Ability to download picons and update satellites (transponders) from web.
|
||||
Preview (playing) IPTV or other streams directly from the bouquet list(should be installed VLC).
|
||||
|
||||
Minimum requirements:
|
||||
|
||||
Python >= 3.5.2 and GTK+ >= 3.16 with PyGObject bindings.
|
||||
Launching
|
||||
|
||||
Terrestrial(DVB-T/T2) and cable channels are supported(Enigma2 only) with limitation!
|
||||
|
||||
Main supported lamedb format is version 4. Versions 3 and 5 has only experimental support!
|
||||
For version 3 is only read mode available. When saving, version 4 format is used instead!
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
Package: DemonEditor
|
||||
Version: 0.4.0-Pre-alpha
|
||||
Version: 0.4.3-Pre-alpha
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Architecture: all
|
||||
|
||||
1
deb/DEBIAN/demon-editor-docs.docs
Normal file
1
deb/DEBIAN/demon-editor-docs.docs
Normal file
@@ -0,0 +1 @@
|
||||
README.source
|
||||
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 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
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,36 +0,0 @@
|
||||
# DemonEditor
|
||||
|
||||
## Enigma2 channel and satellites list editor for GNU/Linux.
|
||||
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, Enter, P.**
|
||||
* **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.
|
||||
* **P** - enable/disable preview mode for IPTV in the bouquet list.
|
||||
* **Enter** - start play IPTV or other stream in the bouquet list.
|
||||
* **Space** - select/deselect.
|
||||
* **Left/Right** - remove selection.
|
||||
* **Ctrl + Up, Down, PageUp, PageDown, Home, End** - move selected items in the list.
|
||||
### Extra:
|
||||
* Multiple selections in lists only with Space key (as in file managers).
|
||||
* Ability to import IPTV into bouquet (Neutrino WEBTV) from m3u files.
|
||||
* Ability to download picons and update satellites (transponders) from web.
|
||||
* Preview (playing) IPTV or other streams directly from the bouquet list(should be installed VLC).
|
||||
### Minimum requirements:
|
||||
Python >= 3.5.2 and GTK+ 3 with PyGObject bindings.
|
||||
#### Note.
|
||||
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!**
|
||||
|
||||
|
||||
BIN
deb/usr/share/locale/es/LC_MESSAGES/demon-editor.mo
Normal file
BIN
deb/usr/share/locale/es/LC_MESSAGES/demon-editor.mo
Normal file
Binary file not shown.
BIN
deb/usr/share/locale/nl/LC_MESSAGES/demon-editor.mo
Normal file
BIN
deb/usr/share/locale/nl/LC_MESSAGES/demon-editor.mo
Normal file
Binary file not shown.
BIN
deb/usr/share/locale/pt/LC_MESSAGES/demon-editor.mo
Normal file
BIN
deb/usr/share/locale/pt/LC_MESSAGES/demon-editor.mo
Normal file
Binary file not shown.
Binary file not shown.
621
po/es/demon-editor.po
Normal file
621
po/es/demon-editor.po
Normal file
@@ -0,0 +1,621 @@
|
||||
# Copyright (C) 2018 Frank Neirynck
|
||||
# This file is distributed under the MIT license.
|
||||
#
|
||||
#Frank Neirynck <frank@insink.be>, 2018.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Last-Translator: Frank Neirynck\n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "translator-credits"
|
||||
msgstr "Frank Neirynck <frank@insink.be>"
|
||||
|
||||
# Main
|
||||
msgid "Service"
|
||||
msgstr "Servicio"
|
||||
|
||||
msgid "Package"
|
||||
msgstr "Paquete"
|
||||
|
||||
msgid "Type"
|
||||
msgstr "Tipo"
|
||||
|
||||
msgid "Picon"
|
||||
msgstr "Picon"
|
||||
|
||||
msgid "Freq"
|
||||
msgstr "Frec."
|
||||
|
||||
msgid "Rate"
|
||||
msgstr "Ratio"
|
||||
|
||||
msgid "Pol"
|
||||
msgstr "Pol."
|
||||
|
||||
msgid "System"
|
||||
msgstr "Sistema"
|
||||
|
||||
msgid "Pos"
|
||||
msgstr "Pos."
|
||||
|
||||
msgid "Num"
|
||||
msgstr "Núm"
|
||||
|
||||
msgid "Current IP:"
|
||||
msgstr "IP actual:"
|
||||
|
||||
msgid "Assign"
|
||||
msgstr "Assignar"
|
||||
|
||||
msgid "Bouquet details"
|
||||
msgstr "Detalles Ramo"
|
||||
|
||||
msgid "Bouquets"
|
||||
msgstr "Ramos"
|
||||
|
||||
msgid "Copy"
|
||||
msgstr "Copiar"
|
||||
|
||||
msgid "Copy reference"
|
||||
msgstr "Copia de Referencia"
|
||||
|
||||
msgid "Download"
|
||||
msgstr "Descargar"
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Editar"
|
||||
|
||||
msgid "Edit "
|
||||
msgstr "Editar "
|
||||
|
||||
msgid "Edit mаrker text"
|
||||
msgstr "Editar texto del mаrcador"
|
||||
|
||||
msgid "FTP-transfer"
|
||||
msgstr "Transferencia-FTP"
|
||||
|
||||
msgid "Global search"
|
||||
msgstr "Búsqueda Global"
|
||||
|
||||
msgid "Hide"
|
||||
msgstr "Esconder"
|
||||
|
||||
msgid "Hide/Skip On/Off Ctrl + H"
|
||||
msgstr "Esconder/Saltar Encender/Apagar Ctrl + H"
|
||||
|
||||
msgid "Add IPTV or stream service"
|
||||
msgstr "Añadir servicio IPTV"
|
||||
|
||||
msgid "Import m3u"
|
||||
msgstr "Importar m3u"
|
||||
|
||||
msgid "Import m3u file"
|
||||
msgstr "Importar fichero m3u"
|
||||
|
||||
msgid "List configuration"
|
||||
msgstr "Lista configuración"
|
||||
|
||||
msgid "Rename for this bouquet"
|
||||
msgstr "Renombrar para este ramo"
|
||||
|
||||
msgid "Set default name"
|
||||
msgstr "Establecer nombre predeterminado"
|
||||
|
||||
msgid "Insert marker"
|
||||
msgstr "Insertar marcador"
|
||||
|
||||
msgid "Locate in services"
|
||||
msgstr "Buscar en servicios"
|
||||
|
||||
msgid "Locked"
|
||||
msgstr "Cerrado"
|
||||
|
||||
msgid "Move"
|
||||
msgstr "Mover"
|
||||
|
||||
msgid "New"
|
||||
msgstr "Nuevo"
|
||||
|
||||
msgid "New bouquet"
|
||||
msgstr "Ramo nuevo"
|
||||
|
||||
msgid "Create bouquet"
|
||||
msgstr "Crear ramo"
|
||||
|
||||
msgid "For current satellite"
|
||||
msgstr "Para el Satélite actual"
|
||||
|
||||
msgid "For current package"
|
||||
msgstr "Para el paquete actual"
|
||||
|
||||
msgid "For current type"
|
||||
msgstr "Para el tipo actual"
|
||||
|
||||
msgid "For each satellite"
|
||||
msgstr "Para cada Satélite"
|
||||
|
||||
msgid "For each package"
|
||||
msgstr "Para cada paquete"
|
||||
|
||||
msgid "For each type"
|
||||
msgstr "Para cada tipo"
|
||||
|
||||
msgid "Open"
|
||||
msgstr "Abrir"
|
||||
|
||||
msgid "Parent lock On/Off Ctrl + L"
|
||||
msgstr "Bloqueo parentesco Encender/Apagar Ctrl + L"
|
||||
|
||||
msgid "Picons"
|
||||
msgstr "Picons"
|
||||
|
||||
msgid "Picons downloader"
|
||||
msgstr "Picons descargar"
|
||||
|
||||
msgid "Satellites downloader"
|
||||
msgstr "Satélites descargar"
|
||||
|
||||
msgid "Remove"
|
||||
msgstr "Remover"
|
||||
|
||||
msgid "Remove all unavailable"
|
||||
msgstr "Remover todo lo indisponible"
|
||||
|
||||
msgid "Satellites editor"
|
||||
msgstr "Editor Satélites"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Guardar"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Buscar"
|
||||
|
||||
msgid "Services"
|
||||
msgstr "Servicios"
|
||||
|
||||
msgid "Services filter"
|
||||
msgstr "Filtro servicios"
|
||||
|
||||
msgid "Settings"
|
||||
msgstr "Configuraciones"
|
||||
|
||||
msgid "Up"
|
||||
msgstr "Arriba"
|
||||
|
||||
msgid "Down"
|
||||
msgstr "Abajo"
|
||||
|
||||
msgid "Active profile:"
|
||||
msgstr "Perfil activo:"
|
||||
|
||||
msgid "All"
|
||||
msgstr "Todo"
|
||||
|
||||
msgid "Are you sure?"
|
||||
msgstr "Estás seguro?"
|
||||
|
||||
msgid "Current data path:"
|
||||
msgstr "Ruta de datos actual:"
|
||||
|
||||
msgid "Data:"
|
||||
msgstr "Datos:"
|
||||
|
||||
msgid "Enigma2 channel and satellites list editor for GNU/Linux"
|
||||
msgstr "Editor de Canales y Satélites Enigma2 para GNU/Linux"
|
||||
|
||||
msgid "Host:"
|
||||
msgstr "Anfitrión:"
|
||||
|
||||
msgid "Loading data..."
|
||||
msgstr "Cargar datos..."
|
||||
|
||||
msgid "Receive"
|
||||
msgstr "Recibir"
|
||||
|
||||
msgid "Receive files from receiver"
|
||||
msgstr "Recibir ficheros de su receptor"
|
||||
|
||||
msgid "Receiver IP:"
|
||||
msgstr "Receptor IP:"
|
||||
|
||||
msgid "Remove unused bouquets"
|
||||
msgstr "Remover ramos sin usar"
|
||||
|
||||
msgid "Reset profile"
|
||||
msgstr "Restablecer perfil"
|
||||
|
||||
msgid "Satellites"
|
||||
msgstr "Satélites"
|
||||
|
||||
msgid "Satellites.xml file:"
|
||||
msgstr "Fichero Satellites.xml:"
|
||||
|
||||
msgid "Selected"
|
||||
msgstr "Seleccionado"
|
||||
|
||||
msgid "Send"
|
||||
msgstr "Enviar"
|
||||
|
||||
msgid "Send files to receiver"
|
||||
msgstr "Enviar ficheros al receptor"
|
||||
|
||||
msgid "Services and Bouquets files:"
|
||||
msgstr "Ficheros de Servicios y ramos:"
|
||||
|
||||
msgid "User bouquet files:"
|
||||
msgstr "Importar ficheros de ramos:"
|
||||
|
||||
msgid "Extra:"
|
||||
msgstr "Extra:"
|
||||
|
||||
# Filter bar
|
||||
msgid "Only free"
|
||||
msgstr "Solamente gratis"
|
||||
|
||||
msgid "All positions"
|
||||
msgstr "Todas las posiciones"
|
||||
|
||||
msgid "All types"
|
||||
msgstr "Todos los tipos"
|
||||
|
||||
# Streams player
|
||||
msgid "Play"
|
||||
msgstr "Play"
|
||||
|
||||
msgid "Stop playback"
|
||||
msgstr "Detener la reproducción"
|
||||
|
||||
msgid "Previous stream in the list"
|
||||
msgstr "Secuencia anterior en la lista"
|
||||
|
||||
msgid "Next stream in the list"
|
||||
msgstr "Secuencia siguiente en la lista"
|
||||
|
||||
msgid "Toggle in fullscreen"
|
||||
msgstr "Cambiar a pantalla completa"
|
||||
|
||||
msgid "Close"
|
||||
msgstr "Cerrar"
|
||||
|
||||
# Picons dialog
|
||||
msgid "Load providers"
|
||||
msgstr "Cargar Proveedores"
|
||||
|
||||
msgid "Providers"
|
||||
msgstr "Proveedores"
|
||||
|
||||
msgid "Receive picons"
|
||||
msgstr "Recibir picons"
|
||||
|
||||
msgid "Picons name format:"
|
||||
msgstr "Picons formato nombres:"
|
||||
|
||||
msgid "Resize:"
|
||||
msgstr "Redimensionar:"
|
||||
|
||||
msgid "Current picons path:"
|
||||
msgstr "Ruta actual Picons:"
|
||||
|
||||
msgid "Receiver picons path:"
|
||||
msgstr "Ruta picons receptor:"
|
||||
|
||||
msgid "Picons download tool"
|
||||
msgstr "Picons herramiento de descarga"
|
||||
|
||||
msgid "Transfer to receiver"
|
||||
msgstr "Transferir al receptor"
|
||||
|
||||
msgid "Downloader"
|
||||
msgstr "Descargador"
|
||||
|
||||
msgid "Converter"
|
||||
msgstr "Convertidor"
|
||||
|
||||
msgid "Convert"
|
||||
msgstr "Convertir"
|
||||
|
||||
msgid "Path to save:"
|
||||
msgstr "Ruta para guardar:"
|
||||
|
||||
msgid "Path to Enigma2 picons:"
|
||||
msgstr "Ruta a picons Enigma2:"
|
||||
|
||||
msgid "Specify the correct position value for the provider!"
|
||||
msgstr "Especifique la posición correcta para el proveedor!"
|
||||
|
||||
msgid "Converter between name formats"
|
||||
msgstr "Conversor entre formatos de nombre"
|
||||
|
||||
msgid "Receive picons for providers"
|
||||
msgstr "Recibir picons para proovedor"
|
||||
|
||||
msgid "Load satellite providers."
|
||||
msgstr "Cargar proovedores Satélite."
|
||||
|
||||
msgid "To automatically set the identifiers for picons,\nfirst load the required services list into the main application window."
|
||||
msgstr "Para configurar automáticamente los identificadores para picons, \nprimero cargue la lista de serviços requeridos en la ventana principal."
|
||||
|
||||
# Satellites editor
|
||||
msgid "Satellites edit tool"
|
||||
msgstr "Editor de Satélites"
|
||||
|
||||
msgid "Add"
|
||||
msgstr "Añadir"
|
||||
|
||||
msgid "Satellite"
|
||||
msgstr "Satélite"
|
||||
|
||||
msgid "Transponder"
|
||||
msgstr "Transpondedor"
|
||||
|
||||
msgid "Satellite properties:"
|
||||
msgstr "Propiedades del Satélite:"
|
||||
|
||||
msgid "Transponder properties:"
|
||||
msgstr "Propiedades del Transpondedor:"
|
||||
|
||||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
msgid "Position"
|
||||
msgstr "Posición"
|
||||
|
||||
# Satellites update dialog
|
||||
msgid "Satellites update"
|
||||
msgstr "Actualisar Satélite"
|
||||
|
||||
msgid "Remove selection"
|
||||
msgstr "Remover selección"
|
||||
|
||||
# Service details dialog
|
||||
msgid "Service data:"
|
||||
msgstr "Datos servicio:"
|
||||
|
||||
msgid "Transponder data:"
|
||||
msgstr "Datos Transpondedor:"
|
||||
|
||||
msgid "Service data"
|
||||
msgstr "Datos servicio"
|
||||
|
||||
msgid "Transponder details"
|
||||
msgstr "Detalles Transpondedor"
|
||||
|
||||
msgid "Changes will be applied to all services of this transponder!\nContinue?"
|
||||
msgstr "Los cambios se aplicarán a todos los servicios de este transpondedor!\nContinuar?"
|
||||
|
||||
msgid "Reference"
|
||||
msgstr "Referencia"
|
||||
|
||||
msgid "Namespace"
|
||||
msgstr "Namespace"
|
||||
|
||||
msgid "Flags:"
|
||||
msgstr "Flags:"
|
||||
|
||||
msgid "Delays (ms):"
|
||||
msgstr "Retraso (mc)"
|
||||
|
||||
msgid "Bitstream"
|
||||
msgstr "Secuencia de Bits"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Descripción"
|
||||
|
||||
msgid "Source:"
|
||||
msgstr "Fuente:"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "Annular"
|
||||
|
||||
msgid "Update"
|
||||
msgstr "Actualisar"
|
||||
|
||||
msgid "Filter"
|
||||
msgstr "Filtrar"
|
||||
|
||||
msgid "Find"
|
||||
msgstr "Buscar"
|
||||
|
||||
# IPTV dialog
|
||||
msgid "Stream data"
|
||||
msgstr "Datos de la Secuencia"
|
||||
|
||||
# IPTV list configuration dialog
|
||||
msgid "Starting values"
|
||||
msgstr "Valores iniciales"
|
||||
|
||||
msgid "Reset to default"
|
||||
msgstr "Restablecer a predeterminado"
|
||||
|
||||
msgid "IPTV streams list configuration"
|
||||
msgstr "Configurar lista de Secuencias IPTV"
|
||||
|
||||
#Settings dialog
|
||||
msgid "Preferences"
|
||||
msgstr "Preferencias"
|
||||
|
||||
msgid "Profile:"
|
||||
msgstr "Perfil:"
|
||||
|
||||
msgid "Timeout between commands in seconds"
|
||||
msgstr "Tiempo de espera entre comandos en segundos"
|
||||
|
||||
msgid "Timeout:"
|
||||
msgstr "Time-out:"
|
||||
|
||||
msgid "Login:"
|
||||
msgstr "Usuario:"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "Opciones"
|
||||
|
||||
msgid "Password:"
|
||||
msgstr "Contraseña:"
|
||||
|
||||
msgid "Picons:"
|
||||
msgstr "Picons:"
|
||||
|
||||
msgid "Port:"
|
||||
msgstr "Puerta:"
|
||||
|
||||
msgid "Data path:"
|
||||
msgstr "Ruta de datos:"
|
||||
|
||||
msgid "Picons path:"
|
||||
msgstr "Ruta de Picons:"
|
||||
|
||||
msgid "Network settings:"
|
||||
msgstr "Configuración de red:"
|
||||
|
||||
msgid "STB file paths:"
|
||||
msgstr "Ruta de ficherors STB:"
|
||||
|
||||
msgid "Local file paths:"
|
||||
msgstr "Ruta de ficheros local:"
|
||||
|
||||
# Dialogs messages
|
||||
msgid "Error. No bouquet is selected!"
|
||||
msgstr "Error. Ningún ramo está seleccionado!"
|
||||
|
||||
msgid "This item is not allowed to be removed!"
|
||||
msgstr "Este artículo no puede ser eliminado!"
|
||||
|
||||
msgid "This item is not allowed to edit!"
|
||||
msgstr "Este artículo no puede ser editado!"
|
||||
|
||||
msgid "Not allowed in this context!"
|
||||
msgstr "No permitido en este contexto!"
|
||||
|
||||
msgid "Please, download files from receiver or setup your path for read data!"
|
||||
msgstr "Por favor, descargue archivos desde el receptor o configure su ruta para leer los datos!"
|
||||
|
||||
msgid "Reading data error!"
|
||||
msgstr "Error de lectura de datos!"
|
||||
|
||||
msgid "No m3u file is selected!"
|
||||
msgstr "Ningún archivo m3u ha sido seleccionado!"
|
||||
|
||||
msgid "Not implemented yet!"
|
||||
msgstr "Aun no implementado!"
|
||||
|
||||
msgid "The text of marker is empty, please try again!"
|
||||
msgstr "El texto del marcador está vacío, inténtalo de nuevo!"
|
||||
|
||||
msgid "Please, select only one item!"
|
||||
msgstr "Por favor, seleccione solo un elemento!"
|
||||
|
||||
msgid "No png file is selected!"
|
||||
msgstr "Ningún fichero png seleccionado!"
|
||||
|
||||
msgid "No reference is present!"
|
||||
msgstr "Ninguna referencia presente!"
|
||||
|
||||
msgid "No selected item!"
|
||||
msgstr "Ningún elemento seleccionado!"
|
||||
|
||||
msgid "The task is already running!"
|
||||
msgstr "La tarea ya se está ejecutando!"
|
||||
|
||||
msgid "Done!"
|
||||
msgstr "Hecho!"
|
||||
|
||||
msgid "Please, wait..."
|
||||
msgstr "Por favor, espere..."
|
||||
|
||||
msgid "Resizing..."
|
||||
msgstr "Redimensionando..."
|
||||
|
||||
msgid "Select paths!"
|
||||
msgstr "Seleccione rutas!"
|
||||
|
||||
msgid "No satellite is selected!"
|
||||
msgstr "Ningún Satélite seleccionado!"
|
||||
|
||||
msgid "Please, select only one satellite!"
|
||||
msgstr "Seleccione solo un Satélite!"
|
||||
|
||||
msgid "Please check your parameters and try again."
|
||||
msgstr "Por favor revise sus parámetros y vuelva a intentar!"
|
||||
|
||||
msgid "No satellites.xml file is selected!"
|
||||
msgstr "Ningún satellites.xml seleccionado!"
|
||||
|
||||
msgid "Error. Verify the data!"
|
||||
msgstr "Error. Revise sus datos!"
|
||||
|
||||
msgid "Operation not allowed in this context!"
|
||||
msgstr "Operación no permitida en este contexto!"
|
||||
|
||||
msgid "No VLC is found. Check that it is installed!"
|
||||
msgstr "VLC no encontrado. Verifica si está instalado!"
|
||||
|
||||
# Search unavailable streams dialog
|
||||
msgid "Please wait, streams testing in progress..."
|
||||
msgstr "Por favor espera una prueba de las secuencias..."
|
||||
|
||||
msgid "Found"
|
||||
msgstr "Encontrado"
|
||||
|
||||
msgid "unavailable streams."
|
||||
msgstr "Secuencias no presentes"
|
||||
|
||||
msgid "No changes required!"
|
||||
msgstr "ningún cambio requerido!"
|
||||
|
||||
msgid "This list does not contains IPTV streams!"
|
||||
msgstr "La lista no contiene secuencias IPTV!"
|
||||
|
||||
msgid "New empty configuration"
|
||||
msgstr "Nueva configuración vacía"
|
||||
|
||||
msgid "No data to save!"
|
||||
msgstr "No hay datos para guardar!"
|
||||
|
||||
msgid "Network"
|
||||
msgstr "Red"
|
||||
|
||||
msgid "Paths"
|
||||
msgstr "Rutas"
|
||||
|
||||
msgid "Program"
|
||||
msgstr "Programa"
|
||||
|
||||
msgid "Backup:"
|
||||
msgstr "Backup:"
|
||||
|
||||
msgid "Backup"
|
||||
msgstr "Backup"
|
||||
|
||||
msgid "Backups"
|
||||
msgstr "Backups"
|
||||
|
||||
msgid "Restore bouquets"
|
||||
msgstr "Restaurar ramos"
|
||||
|
||||
msgid "Restore all"
|
||||
msgstr "Restaurar todo"
|
||||
|
||||
msgid "Before saving"
|
||||
msgstr "Antes de guardar"
|
||||
|
||||
msgid "Before downloading from the receiver"
|
||||
msgstr "Antes de recibir del receptor"
|
||||
|
||||
msgid "Set background color for the services"
|
||||
msgstr "Determinar color de fondo para servicios"
|
||||
|
||||
msgid "Marked as new:"
|
||||
msgstr "Marcado como nuevo:"
|
||||
|
||||
msgid "With an extra name in the bouquet:"
|
||||
msgstr "Con nombre adicional en ramo:"
|
||||
|
||||
msgid "About"
|
||||
msgstr "Sobre"
|
||||
|
||||
msgid "Exit"
|
||||
msgstr "Salir"
|
||||
621
po/nl/demon-editor.po
Normal file
621
po/nl/demon-editor.po
Normal file
@@ -0,0 +1,621 @@
|
||||
# Copyright (C) 2018 Frank Neirynck
|
||||
# This file is distributed under the MIT license.
|
||||
#
|
||||
#Frank Neirynck <frank@insink.be>, 2018.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Last-Translator: Frank Neirynck\n"
|
||||
"Language: nl\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "translator-credits"
|
||||
msgstr "Frank Neirynck <frank@insink.be>"
|
||||
|
||||
# Main
|
||||
msgid "Service"
|
||||
msgstr "Dienst"
|
||||
|
||||
msgid "Package"
|
||||
msgstr "Pakket"
|
||||
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
msgid "Picon"
|
||||
msgstr "Picon"
|
||||
|
||||
msgid "Freq"
|
||||
msgstr "Freq."
|
||||
|
||||
msgid "Rate"
|
||||
msgstr "Rate"
|
||||
|
||||
msgid "Pol"
|
||||
msgstr "Pol."
|
||||
|
||||
msgid "System"
|
||||
msgstr "Systeem"
|
||||
|
||||
msgid "Pos"
|
||||
msgstr "Pos."
|
||||
|
||||
msgid "Num"
|
||||
msgstr "Nr"
|
||||
|
||||
msgid "Current IP:"
|
||||
msgstr "Huidig IP:"
|
||||
|
||||
msgid "Assign"
|
||||
msgstr "Toekennen"
|
||||
|
||||
msgid "Bouquet details"
|
||||
msgstr "Details Boeket"
|
||||
|
||||
msgid "Bouquets"
|
||||
msgstr "Boeketten"
|
||||
|
||||
msgid "Copy"
|
||||
msgstr "Kopieer"
|
||||
|
||||
msgid "Copy reference"
|
||||
msgstr "Referentiekopie"
|
||||
|
||||
msgid "Download"
|
||||
msgstr "Download"
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Wijzig"
|
||||
|
||||
msgid "Edit "
|
||||
msgstr "Wijzig "
|
||||
|
||||
msgid "Edit mаrker text"
|
||||
msgstr "Wijzig mаrker tekst"
|
||||
|
||||
msgid "FTP-transfer"
|
||||
msgstr "FTP-overdracht"
|
||||
|
||||
msgid "Global search"
|
||||
msgstr "Globale zoekopdracht"
|
||||
|
||||
msgid "Hide"
|
||||
msgstr "Verberg"
|
||||
|
||||
msgid "Hide/Skip On/Off Ctrl + H"
|
||||
msgstr "Verberg/Overslaan Aan/Uit Ctrl + H"
|
||||
|
||||
msgid "Add IPTV or stream service"
|
||||
msgstr "Voeg IPTV of stream dienst toe"
|
||||
|
||||
msgid "Import m3u"
|
||||
msgstr "Importeer m3u"
|
||||
|
||||
msgid "Import m3u file"
|
||||
msgstr "Importeer m3u file"
|
||||
|
||||
msgid "List configuration"
|
||||
msgstr "Lijst configuratie"
|
||||
|
||||
msgid "Rename for this bouquet"
|
||||
msgstr "Hernoem voor dit boeket"
|
||||
|
||||
msgid "Set default name"
|
||||
msgstr "Stel standaard naam in"
|
||||
|
||||
msgid "Insert marker"
|
||||
msgstr "Inserteer marker"
|
||||
|
||||
msgid "Locate in services"
|
||||
msgstr "Zoek in diensten"
|
||||
|
||||
msgid "Locked"
|
||||
msgstr "Gesloten"
|
||||
|
||||
msgid "Move"
|
||||
msgstr "Verplaats"
|
||||
|
||||
msgid "New"
|
||||
msgstr "Nieuw"
|
||||
|
||||
msgid "New bouquet"
|
||||
msgstr "Nieuw boeket"
|
||||
|
||||
msgid "Create bouquet"
|
||||
msgstr "Creeer boeket"
|
||||
|
||||
msgid "For current satellite"
|
||||
msgstr "Voor huidige satelliet"
|
||||
|
||||
msgid "For current package"
|
||||
msgstr "Voor huidig pakket"
|
||||
|
||||
msgid "For current type"
|
||||
msgstr "Voor huidig type"
|
||||
|
||||
msgid "For each satellite"
|
||||
msgstr "Voor elke satelliet"
|
||||
|
||||
msgid "For each package"
|
||||
msgstr "Voor elk pakket"
|
||||
|
||||
msgid "For each type"
|
||||
msgstr "Voor elk type"
|
||||
|
||||
msgid "Open"
|
||||
msgstr "Open"
|
||||
|
||||
msgid "Parent lock On/Off Ctrl + L"
|
||||
msgstr "Ouderlijk slot aan/uit Ctrl + L"
|
||||
|
||||
msgid "Picons"
|
||||
msgstr "Picons"
|
||||
|
||||
msgid "Picons downloader"
|
||||
msgstr "Picons downloader"
|
||||
|
||||
msgid "Satellites downloader"
|
||||
msgstr "Satellieten downloader"
|
||||
|
||||
msgid "Remove"
|
||||
msgstr "Verwijder"
|
||||
|
||||
msgid "Remove all unavailable"
|
||||
msgstr "Verwijder alle onbeschikbare"
|
||||
|
||||
msgid "Satellites editor"
|
||||
msgstr "Satelliet editor"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Opslaan"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Zoek"
|
||||
|
||||
msgid "Services"
|
||||
msgstr "Diensten"
|
||||
|
||||
msgid "Services filter"
|
||||
msgstr "Diensten filter"
|
||||
|
||||
msgid "Settings"
|
||||
msgstr "Instellingen"
|
||||
|
||||
msgid "Up"
|
||||
msgstr "Boven"
|
||||
|
||||
msgid "Down"
|
||||
msgstr "Onder"
|
||||
|
||||
msgid "Active profile:"
|
||||
msgstr "Actief profiel:"
|
||||
|
||||
msgid "All"
|
||||
msgstr "Alle"
|
||||
|
||||
msgid "Are you sure?"
|
||||
msgstr "Ben je zeker?"
|
||||
|
||||
msgid "Current data path:"
|
||||
msgstr "Huidig datapad:"
|
||||
|
||||
msgid "Data:"
|
||||
msgstr "Data:"
|
||||
|
||||
msgid "Enigma2 channel and satellites list editor for GNU/Linux"
|
||||
msgstr "Enigma2 kanaal and satelliet lijst editor voor GNU/Linux"
|
||||
|
||||
msgid "Host:"
|
||||
msgstr "Host:"
|
||||
|
||||
msgid "Loading data..."
|
||||
msgstr "Laden data..."
|
||||
|
||||
msgid "Receive"
|
||||
msgstr "Ontvangen"
|
||||
|
||||
msgid "Receive files from receiver"
|
||||
msgstr "Ophalen files van uw ontvanger"
|
||||
|
||||
msgid "Receiver IP:"
|
||||
msgstr "Ontvanger IP:"
|
||||
|
||||
msgid "Remove unused bouquets"
|
||||
msgstr "Verwijder ongebruikte boeketten"
|
||||
|
||||
msgid "Reset profile"
|
||||
msgstr "Profiel terugzetten"
|
||||
|
||||
msgid "Satellites"
|
||||
msgstr "Satellieten"
|
||||
|
||||
msgid "Satellites.xml file:"
|
||||
msgstr "Satellites.xml bestand:"
|
||||
|
||||
msgid "Selected"
|
||||
msgstr "Geselecteerd"
|
||||
|
||||
msgid "Send"
|
||||
msgstr "Verzend"
|
||||
|
||||
msgid "Send files to receiver"
|
||||
msgstr "Verzend bestanden naar ontvanger"
|
||||
|
||||
msgid "Services and Bouquets files:"
|
||||
msgstr "Diensten en Boeketten bestanden:"
|
||||
|
||||
msgid "User bouquet files:"
|
||||
msgstr "Importeer boeket bestanden:"
|
||||
|
||||
msgid "Extra:"
|
||||
msgstr "Extra:"
|
||||
|
||||
# Filter bar
|
||||
msgid "Only free"
|
||||
msgstr "Enkel gratis"
|
||||
|
||||
msgid "All positions"
|
||||
msgstr "Alle posities"
|
||||
|
||||
msgid "All types"
|
||||
msgstr "Alle types"
|
||||
|
||||
# Streams player
|
||||
msgid "Play"
|
||||
msgstr "Play"
|
||||
|
||||
msgid "Stop playback"
|
||||
msgstr "Stop afspelen"
|
||||
|
||||
msgid "Previous stream in the list"
|
||||
msgstr "Vorige stream in de lijst"
|
||||
|
||||
msgid "Next stream in the list"
|
||||
msgstr "Volgende stream in de lijst"
|
||||
|
||||
msgid "Toggle in fullscreen"
|
||||
msgstr "Wissel naar volledig scherm"
|
||||
|
||||
msgid "Close"
|
||||
msgstr "Afsluiten"
|
||||
|
||||
# Picons dialog
|
||||
msgid "Load providers"
|
||||
msgstr "Laad leveranciers"
|
||||
|
||||
msgid "Providers"
|
||||
msgstr "Leveranciers"
|
||||
|
||||
msgid "Receive picons"
|
||||
msgstr "Ontvang picons"
|
||||
|
||||
msgid "Picons name format:"
|
||||
msgstr "Picons naam formaat:"
|
||||
|
||||
msgid "Resize:"
|
||||
msgstr "Verklein/vergroot:"
|
||||
|
||||
msgid "Current picons path:"
|
||||
msgstr "Huidig pad picons:"
|
||||
|
||||
msgid "Receiver picons path:"
|
||||
msgstr "Ontvanger picons pad:"
|
||||
|
||||
msgid "Picons download tool"
|
||||
msgstr "Picons download gereedschap"
|
||||
|
||||
msgid "Transfer to receiver"
|
||||
msgstr "Transfereren naar ontvanger"
|
||||
|
||||
msgid "Downloader"
|
||||
msgstr "Downloader"
|
||||
|
||||
msgid "Converter"
|
||||
msgstr "Omvormer"
|
||||
|
||||
msgid "Convert"
|
||||
msgstr "Converteer"
|
||||
|
||||
msgid "Path to save:"
|
||||
msgstr "Pad om op te slaan:"
|
||||
|
||||
msgid "Path to Enigma2 picons:"
|
||||
msgstr "Pad naar Enigma2 picons:"
|
||||
|
||||
msgid "Specify the correct position value for the provider!"
|
||||
msgstr "Geeft de juiste positie waarde voor de provider!"
|
||||
|
||||
msgid "Converter between name formats"
|
||||
msgstr "Omvormer tussen naam formaten"
|
||||
|
||||
msgid "Receive picons for providers"
|
||||
msgstr "Ontvang picons voor leveranciers"
|
||||
|
||||
msgid "Load satellite providers."
|
||||
msgstr "Laad satelliet leveranciers."
|
||||
|
||||
msgid "To automatically set the identifiers for picons,\nfirst load the required services list into the main application window."
|
||||
msgstr "Om automatisch de ID in te stellen voor picons,\nlaad eerst de vereiste serviceslijst in via het hoofdvenster van het programma."
|
||||
|
||||
# Satellites editor
|
||||
msgid "Satellites edit tool"
|
||||
msgstr "Satelliet wijzingingsgereedschap"
|
||||
|
||||
msgid "Add"
|
||||
msgstr "Voeg toe"
|
||||
|
||||
msgid "Satellite"
|
||||
msgstr "Satelliet"
|
||||
|
||||
msgid "Transponder"
|
||||
msgstr "Transponder"
|
||||
|
||||
msgid "Satellite properties:"
|
||||
msgstr "Satelliet eigenschappen:"
|
||||
|
||||
msgid "Transponder properties:"
|
||||
msgstr "Transponder eigenschappen:"
|
||||
|
||||
msgid "Name"
|
||||
msgstr "Naam"
|
||||
|
||||
msgid "Position"
|
||||
msgstr "Positie"
|
||||
|
||||
# Satellites update dialog
|
||||
msgid "Satellites update"
|
||||
msgstr "Actualiseren Satelliet"
|
||||
|
||||
msgid "Remove selection"
|
||||
msgstr "Verwijder selectie"
|
||||
|
||||
# Service details dialog
|
||||
msgid "Service data:"
|
||||
msgstr "Gegevens Dienst:"
|
||||
|
||||
msgid "Transponder data:"
|
||||
msgstr "Gegevens Transponder:"
|
||||
|
||||
msgid "Service data"
|
||||
msgstr "Gegevens Dienst"
|
||||
|
||||
msgid "Transponder details"
|
||||
msgstr "Details Transponder"
|
||||
|
||||
msgid "Changes will be applied to all services of this transponder!\nContinue?"
|
||||
msgstr "Wijzigingen zullen worden doorgevoerd op alle diensten van deze transponder!\nDoorgaan?"
|
||||
|
||||
msgid "Reference"
|
||||
msgstr "Referentie"
|
||||
|
||||
msgid "Namespace"
|
||||
msgstr "Namespace"
|
||||
|
||||
msgid "Flags:"
|
||||
msgstr "Flags:"
|
||||
|
||||
msgid "Delays (ms):"
|
||||
msgstr "Vertraging (mc)"
|
||||
|
||||
msgid "Bitstream"
|
||||
msgstr "Bitstream"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Omschrijving"
|
||||
|
||||
msgid "Source:"
|
||||
msgstr "Bron:"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "Annuleren"
|
||||
|
||||
msgid "Update"
|
||||
msgstr "Bijwerken"
|
||||
|
||||
msgid "Filter"
|
||||
msgstr "Filteren"
|
||||
|
||||
msgid "Find"
|
||||
msgstr "Zoeken"
|
||||
|
||||
# IPTV dialog
|
||||
msgid "Stream data"
|
||||
msgstr "Gegevens stream"
|
||||
|
||||
# IPTV list configuration dialog
|
||||
msgid "Starting values"
|
||||
msgstr "Start waardes"
|
||||
|
||||
msgid "Reset to default"
|
||||
msgstr "Reset naar standaard"
|
||||
|
||||
msgid "IPTV streams list configuration"
|
||||
msgstr "Configureren IPTV Streamlijst"
|
||||
|
||||
#Settings dialog
|
||||
msgid "Preferences"
|
||||
msgstr "Voorkeuren"
|
||||
|
||||
msgid "Profile:"
|
||||
msgstr "Profiel:"
|
||||
|
||||
msgid "Timeout between commands in seconds"
|
||||
msgstr "Time-out tussen opdrachten in seconden"
|
||||
|
||||
msgid "Timeout:"
|
||||
msgstr "Time-out:"
|
||||
|
||||
msgid "Login:"
|
||||
msgstr "Log in:"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "Opties"
|
||||
|
||||
msgid "Password:"
|
||||
msgstr "Paswoord:"
|
||||
|
||||
msgid "Picons:"
|
||||
msgstr "Picons:"
|
||||
|
||||
msgid "Port:"
|
||||
msgstr "Poort:"
|
||||
|
||||
msgid "Data path:"
|
||||
msgstr "Gegevenspad:"
|
||||
|
||||
msgid "Picons path:"
|
||||
msgstr "Picons pad:"
|
||||
|
||||
msgid "Network settings:"
|
||||
msgstr "Netwerk instellingen:"
|
||||
|
||||
msgid "STB file paths:"
|
||||
msgstr "STB bestandspad:"
|
||||
|
||||
msgid "Local file paths:"
|
||||
msgstr "Lokaal bestandspad:"
|
||||
|
||||
# Dialogs messages
|
||||
msgid "Error. No bouquet is selected!"
|
||||
msgstr "Fout. Er is geen boeket geselecteerd!"
|
||||
|
||||
msgid "This item is not allowed to be removed!"
|
||||
msgstr "Dit item kan niet verwijderd worden!"
|
||||
|
||||
msgid "This item is not allowed to edit!"
|
||||
msgstr "Dit item kan niet gewijzigd worden!"
|
||||
|
||||
msgid "Not allowed in this context!"
|
||||
msgstr "Niet toegelaten in deze contekst!"
|
||||
|
||||
msgid "Please, download files from receiver or setup your path for read data!"
|
||||
msgstr "Download alstublieft bestanden van de ontvanger of stel het pad in voor het lezen van gegevens!"
|
||||
|
||||
msgid "Reading data error!"
|
||||
msgstr "Fout tijdens het legezen van gegevens!"
|
||||
|
||||
msgid "No m3u file is selected!"
|
||||
msgstr "Geen m3u bestand geslecteerd!"
|
||||
|
||||
msgid "Not implemented yet!"
|
||||
msgstr "Nog niet geïmplementeerd!"
|
||||
|
||||
msgid "The text of marker is empty, please try again!"
|
||||
msgstr "De tekst van de marker is leeg. Probeer opnieuw!"
|
||||
|
||||
msgid "Please, select only one item!"
|
||||
msgstr "Kies maar 1 item graag!"
|
||||
|
||||
msgid "No png file is selected!"
|
||||
msgstr "Geen png bestand geselecteerd!"
|
||||
|
||||
msgid "No reference is present!"
|
||||
msgstr "Geen referentie aanwezig!"
|
||||
|
||||
msgid "No selected item!"
|
||||
msgstr "Geen item geseleceerd!"
|
||||
|
||||
msgid "The task is already running!"
|
||||
msgstr "Deze taak is al bezig!"
|
||||
|
||||
msgid "Done!"
|
||||
msgstr "Gedaan!"
|
||||
|
||||
msgid "Please, wait..."
|
||||
msgstr "Even geduld, aub..."
|
||||
|
||||
msgid "Resizing..."
|
||||
msgstr "Verkleinen/Vergroten..."
|
||||
|
||||
msgid "Select paths!"
|
||||
msgstr "Selecteer paden!"
|
||||
|
||||
msgid "No satellite is selected!"
|
||||
msgstr "Geen satelliet geselecteerd!"
|
||||
|
||||
msgid "Please, select only one satellite!"
|
||||
msgstr "Selecteer alstublieft slechts één satelliet!"
|
||||
|
||||
msgid "Please check your parameters and try again."
|
||||
msgstr "Controleer aub uw parameters en probeer opnieuw!"
|
||||
|
||||
msgid "No satellites.xml file is selected!"
|
||||
msgstr "Geen satellites.xml geselecteerd!"
|
||||
|
||||
msgid "Error. Verify the data!"
|
||||
msgstr "Fout. Controleer de gegevens!"
|
||||
|
||||
msgid "Operation not allowed in this context!"
|
||||
msgstr "Opdracht niet toegestaan in deze context!"
|
||||
|
||||
msgid "No VLC is found. Check that it is installed!"
|
||||
msgstr "Geen VLC gevonden. Controleer of VLC gïnstalleerd is!"
|
||||
|
||||
# Search unavailable streams dialog
|
||||
msgid "Please wait, streams testing in progress..."
|
||||
msgstr "Even geduld, test van streams bezig ..."
|
||||
|
||||
msgid "Found"
|
||||
msgstr "Gevonden"
|
||||
|
||||
msgid "unavailable streams."
|
||||
msgstr "Steams niet aanwezig."
|
||||
|
||||
msgid "No changes required!"
|
||||
msgstr "Geen wijzigingen vereist!"
|
||||
|
||||
msgid "This list does not contains IPTV streams!"
|
||||
msgstr "Deze lijst bevat geen IPTV streams!"
|
||||
|
||||
msgid "New empty configuration"
|
||||
msgstr "Nieuwe lege configuratie"
|
||||
|
||||
msgid "No data to save!"
|
||||
msgstr "Geen gegevens om op te slaan!"
|
||||
|
||||
msgid "Network"
|
||||
msgstr "Netwerk"
|
||||
|
||||
msgid "Paths"
|
||||
msgstr "Paden"
|
||||
|
||||
msgid "Program"
|
||||
msgstr "Programma"
|
||||
|
||||
msgid "Backup:"
|
||||
msgstr "Backup:"
|
||||
|
||||
msgid "Backup"
|
||||
msgstr "Backup"
|
||||
|
||||
msgid "Backups"
|
||||
msgstr "Backups"
|
||||
|
||||
msgid "Restore bouquets"
|
||||
msgstr "Herstek boeketten"
|
||||
|
||||
msgid "Restore all"
|
||||
msgstr "Herstel alles"
|
||||
|
||||
msgid "Before saving"
|
||||
msgstr "Voor opslaan"
|
||||
|
||||
msgid "Before downloading from the receiver"
|
||||
msgstr "Voor download uit de ontvanger"
|
||||
|
||||
msgid "Set background color for the services"
|
||||
msgstr "Stel achtergrond kleur in voor diensten"
|
||||
|
||||
msgid "Marked as new:"
|
||||
msgstr "Gemarkeerd als nieuw:"
|
||||
|
||||
msgid "With an extra name in the bouquet:"
|
||||
msgstr "Met een extra naam in het boeket:"
|
||||
|
||||
msgid "About"
|
||||
msgstr "Over"
|
||||
|
||||
msgid "Exit"
|
||||
msgstr "Exit"
|
||||
621
po/pt/demon-editor.po
Normal file
621
po/pt/demon-editor.po
Normal file
@@ -0,0 +1,621 @@
|
||||
# Copyright (C) 2018 Frank Neirynck
|
||||
# This file is distributed under the MIT license.
|
||||
#
|
||||
#Frank Neirynck <frank@insink.be>, 2018.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Last-Translator: Frank Neirynck\n"
|
||||
"Language: pt\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "translator-credits"
|
||||
msgstr "Frank Neirynck <frank@insink.be>"
|
||||
|
||||
# Main
|
||||
msgid "Service"
|
||||
msgstr "Serviço"
|
||||
|
||||
msgid "Package"
|
||||
msgstr "Pacote"
|
||||
|
||||
msgid "Type"
|
||||
msgstr "Tipo"
|
||||
|
||||
msgid "Picon"
|
||||
msgstr "Picon"
|
||||
|
||||
msgid "Freq"
|
||||
msgstr "Freq."
|
||||
|
||||
msgid "Rate"
|
||||
msgstr "Ratio"
|
||||
|
||||
msgid "Pol"
|
||||
msgstr "Pol."
|
||||
|
||||
msgid "System"
|
||||
msgstr "Sistema"
|
||||
|
||||
msgid "Pos"
|
||||
msgstr "Pos."
|
||||
|
||||
msgid "Num"
|
||||
msgstr "Núm"
|
||||
|
||||
msgid "Current IP:"
|
||||
msgstr "IP atual:"
|
||||
|
||||
msgid "Assign"
|
||||
msgstr "Atribuir"
|
||||
|
||||
msgid "Bouquet details"
|
||||
msgstr "Detalhes do Ramo"
|
||||
|
||||
msgid "Bouquets"
|
||||
msgstr "Ramos"
|
||||
|
||||
msgid "Copy"
|
||||
msgstr "Copiar"
|
||||
|
||||
msgid "Copy reference"
|
||||
msgstr "Copia de Referência"
|
||||
|
||||
msgid "Download"
|
||||
msgstr "Descarregar"
|
||||
|
||||
msgid "Edit"
|
||||
msgstr "Editar"
|
||||
|
||||
msgid "Edit "
|
||||
msgstr "Editar "
|
||||
|
||||
msgid "Edit mаrker text"
|
||||
msgstr "Editar texto do mаrcador"
|
||||
|
||||
msgid "FTP-transfer"
|
||||
msgstr "Transferência-FTP"
|
||||
|
||||
msgid "Global search"
|
||||
msgstr "Pesquisa Global"
|
||||
|
||||
msgid "Hide"
|
||||
msgstr "Esconder"
|
||||
|
||||
msgid "Hide/Skip On/Off Ctrl + H"
|
||||
msgstr "Esconder/Pular Acender/Desligar Ctrl + H"
|
||||
|
||||
msgid "Add IPTV or stream service"
|
||||
msgstr "Acrescentar serviço IPTV"
|
||||
|
||||
msgid "Import m3u"
|
||||
msgstr "Importar m3u"
|
||||
|
||||
msgid "Import m3u file"
|
||||
msgstr "Importar ficheiro m3u"
|
||||
|
||||
msgid "List configuration"
|
||||
msgstr "Lista configuração"
|
||||
|
||||
msgid "Rename for this bouquet"
|
||||
msgstr "Renomear para este ramo"
|
||||
|
||||
msgid "Set default name"
|
||||
msgstr "Estabelecer nome predeterminado"
|
||||
|
||||
msgid "Insert marker"
|
||||
msgstr "Inserir marcador"
|
||||
|
||||
msgid "Locate in services"
|
||||
msgstr "Procurar em serviços"
|
||||
|
||||
msgid "Locked"
|
||||
msgstr "Fechado"
|
||||
|
||||
msgid "Move"
|
||||
msgstr "Mover"
|
||||
|
||||
msgid "New"
|
||||
msgstr "Novo"
|
||||
|
||||
msgid "New bouquet"
|
||||
msgstr "Ramo novo"
|
||||
|
||||
msgid "Create bouquet"
|
||||
msgstr "Criar ramo"
|
||||
|
||||
msgid "For current satellite"
|
||||
msgstr "Para o satélite atual"
|
||||
|
||||
msgid "For current package"
|
||||
msgstr "Para o pacote atual"
|
||||
|
||||
msgid "For current type"
|
||||
msgstr "Para o tipo atual"
|
||||
|
||||
msgid "For each satellite"
|
||||
msgstr "Para cada Satélite"
|
||||
|
||||
msgid "For each package"
|
||||
msgstr "Para cada pacote"
|
||||
|
||||
msgid "For each type"
|
||||
msgstr "Para cada tipo"
|
||||
|
||||
msgid "Open"
|
||||
msgstr "Abrir"
|
||||
|
||||
msgid "Parent lock On/Off Ctrl + L"
|
||||
msgstr "Bloqueio parentesco Acender/Desligar Ctrl + L"
|
||||
|
||||
msgid "Picons"
|
||||
msgstr "Picons"
|
||||
|
||||
msgid "Picons downloader"
|
||||
msgstr "Picons descargar"
|
||||
|
||||
msgid "Satellites downloader"
|
||||
msgstr "Satélites descarregar"
|
||||
|
||||
msgid "Remove"
|
||||
msgstr "Remover"
|
||||
|
||||
msgid "Remove all unavailable"
|
||||
msgstr "Remover tudo lo indisponível"
|
||||
|
||||
msgid "Satellites editor"
|
||||
msgstr "Editor Satélites"
|
||||
|
||||
msgid "Save"
|
||||
msgstr "Guardar"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Procurar"
|
||||
|
||||
msgid "Services"
|
||||
msgstr "Serviços"
|
||||
|
||||
msgid "Services filter"
|
||||
msgstr "Filtro serviços"
|
||||
|
||||
msgid "Settings"
|
||||
msgstr "Configurações"
|
||||
|
||||
msgid "Up"
|
||||
msgstr "Arriba"
|
||||
|
||||
msgid "Down"
|
||||
msgstr "Abaixo"
|
||||
|
||||
msgid "Active profile:"
|
||||
msgstr "Perfil ativo:"
|
||||
|
||||
msgid "All"
|
||||
msgstr "Tudo"
|
||||
|
||||
msgid "Are you sure?"
|
||||
msgstr "Tem certeza?"
|
||||
|
||||
msgid "Current data path:"
|
||||
msgstr "Rota de dados atual:"
|
||||
|
||||
msgid "Data:"
|
||||
msgstr "Dados:"
|
||||
|
||||
msgid "Enigma2 channel and satellites list editor for GNU/Linux"
|
||||
msgstr "Editor de Canais e Satélites Enigma2 para GNU/Linux"
|
||||
|
||||
msgid "Host:"
|
||||
msgstr "Anfitrião:"
|
||||
|
||||
msgid "Loading data..."
|
||||
msgstr "Carregar dados..."
|
||||
|
||||
msgid "Receive"
|
||||
msgstr "Receber"
|
||||
|
||||
msgid "Receive files from receiver"
|
||||
msgstr "Receber ficheiros do seu receptor"
|
||||
|
||||
msgid "Receiver IP:"
|
||||
msgstr "Receptor IP:"
|
||||
|
||||
msgid "Remove unused bouquets"
|
||||
msgstr "Remover ramos sem usar"
|
||||
|
||||
msgid "Reset profile"
|
||||
msgstr "Restabelecer perfil"
|
||||
|
||||
msgid "Satellites"
|
||||
msgstr "Satélites"
|
||||
|
||||
msgid "Satellites.xml file:"
|
||||
msgstr "Ficheiro Satellites.xml:"
|
||||
|
||||
msgid "Selected"
|
||||
msgstr "Selecionado"
|
||||
|
||||
msgid "Send"
|
||||
msgstr "Enviar"
|
||||
|
||||
msgid "Send files to receiver"
|
||||
msgstr "Enviar ficheiros ao recetor"
|
||||
|
||||
msgid "Services and Bouquets files:"
|
||||
msgstr "Ficheiros de Serviços e ramos:"
|
||||
|
||||
msgid "User bouquet files:"
|
||||
msgstr "Importar ficheiros de ramos:"
|
||||
|
||||
msgid "Extra:"
|
||||
msgstr "Extra:"
|
||||
|
||||
# Filter bar
|
||||
msgid "Only free"
|
||||
msgstr "Somente de graça"
|
||||
|
||||
msgid "All positions"
|
||||
msgstr "Todas as posições"
|
||||
|
||||
msgid "All types"
|
||||
msgstr "Todos os tipos"
|
||||
|
||||
# Streams player
|
||||
msgid "Play"
|
||||
msgstr "Play"
|
||||
|
||||
msgid "Stop playback"
|
||||
msgstr "Deter a reprodução"
|
||||
|
||||
msgid "Previous stream in the list"
|
||||
msgstr "Sequência anterior na lista"
|
||||
|
||||
msgid "Next stream in the list"
|
||||
msgstr "Sequência siguinte na lista"
|
||||
|
||||
msgid "Toggle in fullscreen"
|
||||
msgstr "Trocar na ecrã completa"
|
||||
|
||||
msgid "Close"
|
||||
msgstr "Fexar"
|
||||
|
||||
# Picons dialog
|
||||
msgid "Load providers"
|
||||
msgstr "Carregar provedores"
|
||||
|
||||
msgid "Providers"
|
||||
msgstr "Fornecedores"
|
||||
|
||||
msgid "Receive picons"
|
||||
msgstr "Recever picons"
|
||||
|
||||
msgid "Picons name format:"
|
||||
msgstr "Picons formato nomes:"
|
||||
|
||||
msgid "Resize:"
|
||||
msgstr "Redimensionar:"
|
||||
|
||||
msgid "Current picons path:"
|
||||
msgstr "Rota atual Picons:"
|
||||
|
||||
msgid "Receiver picons path:"
|
||||
msgstr "Rota picons recetor:"
|
||||
|
||||
msgid "Picons download tool"
|
||||
msgstr "Picons ferramenta de descarga"
|
||||
|
||||
msgid "Transfer to receiver"
|
||||
msgstr "Transferir ao recetor"
|
||||
|
||||
msgid "Downloader"
|
||||
msgstr "Descarregador"
|
||||
|
||||
msgid "Converter"
|
||||
msgstr "Conversor"
|
||||
|
||||
msgid "Convert"
|
||||
msgstr "Converter"
|
||||
|
||||
msgid "Path to save:"
|
||||
msgstr "Rota para guardar:"
|
||||
|
||||
msgid "Path to Enigma2 picons:"
|
||||
msgstr "Rota a picons Enigma2:"
|
||||
|
||||
msgid "Specify the correct position value for the provider!"
|
||||
msgstr "Especifique a posição correta para o provedor!"
|
||||
|
||||
msgid "Converter between name formats"
|
||||
msgstr "Conversor entre formatos de nomes"
|
||||
|
||||
msgid "Receive picons for providers"
|
||||
msgstr "Recever picons para provedor"
|
||||
|
||||
msgid "Load satellite providers."
|
||||
msgstr "Carregar provedores Satélite."
|
||||
|
||||
msgid "To automatically set the identifiers for picons,\nfirst load the required services list into the main application window."
|
||||
msgstr "Para configurar automaticamente os identificadores para picons, \nprimeiro carregue a lista de serviços necessários na janela principal."
|
||||
|
||||
# Satellites editor
|
||||
msgid "Satellites edit tool"
|
||||
msgstr "Editor de Satélites"
|
||||
|
||||
msgid "Add"
|
||||
msgstr "Adicionar"
|
||||
|
||||
msgid "Satellite"
|
||||
msgstr "Satélite"
|
||||
|
||||
msgid "Transponder"
|
||||
msgstr "Transponder"
|
||||
|
||||
msgid "Satellite properties:"
|
||||
msgstr "Propriedades do Satélite:"
|
||||
|
||||
msgid "Transponder properties:"
|
||||
msgstr "Propriedades do Transponder:"
|
||||
|
||||
msgid "Name"
|
||||
msgstr "Nome"
|
||||
|
||||
msgid "Position"
|
||||
msgstr "Posição"
|
||||
|
||||
# Satellites update dialog
|
||||
msgid "Satellites update"
|
||||
msgstr "Atualisar Satélite"
|
||||
|
||||
msgid "Remove selection"
|
||||
msgstr "Remover seleçáo"
|
||||
|
||||
# Service details dialog
|
||||
msgid "Service data:"
|
||||
msgstr "Dados serviço:"
|
||||
|
||||
msgid "Transponder data:"
|
||||
msgstr "Dados Transponder:"
|
||||
|
||||
msgid "Service data"
|
||||
msgstr "Dados serviço"
|
||||
|
||||
msgid "Transponder details"
|
||||
msgstr "Detalhes Transponder"
|
||||
|
||||
msgid "Changes will be applied to all services of this transponder!\nContinue?"
|
||||
msgstr "Os mudanças serão aplicadas a todos os serviços deste transponder!\nContinuar?"
|
||||
|
||||
msgid "Reference"
|
||||
msgstr "Referência"
|
||||
|
||||
msgid "Namespace"
|
||||
msgstr "Namespace"
|
||||
|
||||
msgid "Flags:"
|
||||
msgstr "Flags:"
|
||||
|
||||
msgid "Delays (ms):"
|
||||
msgstr "Atraso (mc)"
|
||||
|
||||
msgid "Bitstream"
|
||||
msgstr "Sequência de Bits"
|
||||
|
||||
msgid "Description"
|
||||
msgstr "Descrição"
|
||||
|
||||
msgid "Source:"
|
||||
msgstr "Fonte:"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "Annular"
|
||||
|
||||
msgid "Update"
|
||||
msgstr "Atualizar"
|
||||
|
||||
msgid "Filter"
|
||||
msgstr "Filtrar"
|
||||
|
||||
msgid "Find"
|
||||
msgstr "Procurar"
|
||||
|
||||
# IPTV dialog
|
||||
msgid "Stream data"
|
||||
msgstr "Dados da sequência"
|
||||
|
||||
# IPTV list configuration dialog
|
||||
msgid "Starting values"
|
||||
msgstr "Valores iniciais"
|
||||
|
||||
msgid "Reset to default"
|
||||
msgstr "Restabelecer a predeterminado"
|
||||
|
||||
msgid "IPTV streams list configuration"
|
||||
msgstr "Configurar lista de sequências IPTV"
|
||||
|
||||
#Settings dialog
|
||||
msgid "Preferences"
|
||||
msgstr "Preferências"
|
||||
|
||||
msgid "Profile:"
|
||||
msgstr "Perfil:"
|
||||
|
||||
msgid "Timeout between commands in seconds"
|
||||
msgstr "Tempo de espera entre comandos em segundos"
|
||||
|
||||
msgid "Timeout:"
|
||||
msgstr "Time-out:"
|
||||
|
||||
msgid "Login:"
|
||||
msgstr "Usuário:"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "Opções"
|
||||
|
||||
msgid "Password:"
|
||||
msgstr "Palavra-passe:"
|
||||
|
||||
msgid "Picons:"
|
||||
msgstr "Picons:"
|
||||
|
||||
msgid "Port:"
|
||||
msgstr "Porta:"
|
||||
|
||||
msgid "Data path:"
|
||||
msgstr "Rota de dados:"
|
||||
|
||||
msgid "Picons path:"
|
||||
msgstr "Rota de Picons:"
|
||||
|
||||
msgid "Network settings:"
|
||||
msgstr "Configuração de rede:"
|
||||
|
||||
msgid "STB file paths:"
|
||||
msgstr "Rota de ficheirors STB:"
|
||||
|
||||
msgid "Local file paths:"
|
||||
msgstr "Rota de ficheiros local:"
|
||||
|
||||
# Dialogs messages
|
||||
msgid "Error. No bouquet is selected!"
|
||||
msgstr "Erro. Nenhum ramo está selecionado!"
|
||||
|
||||
msgid "This item is not allowed to be removed!"
|
||||
msgstr "Este artigo não pode ser eliminado!"
|
||||
|
||||
msgid "This item is not allowed to edit!"
|
||||
msgstr "Este artigo não pode ser editado!"
|
||||
|
||||
msgid "Not allowed in this context!"
|
||||
msgstr "Náo permitido neste contexto!"
|
||||
|
||||
msgid "Please, download files from receiver or setup your path for read data!"
|
||||
msgstr "Por favor, descarregue arquivos desde o recetor ou configure a sua rota para ler os dados!"
|
||||
|
||||
msgid "Reading data error!"
|
||||
msgstr "Erro de leitura de dados!"
|
||||
|
||||
msgid "No m3u file is selected!"
|
||||
msgstr "Nenhum ficheiro m3u foi selecionado!"
|
||||
|
||||
msgid "Not implemented yet!"
|
||||
msgstr "Ainda não implementado!"
|
||||
|
||||
msgid "The text of marker is empty, please try again!"
|
||||
msgstr "O texto do marcador está vazio, tente de novo!"
|
||||
|
||||
msgid "Please, select only one item!"
|
||||
msgstr "Por favor, selecione só um elemento!"
|
||||
|
||||
msgid "No png file is selected!"
|
||||
msgstr "Nenhum ficheiro png foi selecionado!"
|
||||
|
||||
msgid "No reference is present!"
|
||||
msgstr "Nenhuma referência presente!"
|
||||
|
||||
msgid "No selected item!"
|
||||
msgstr "Nenhum elemento selecionado!"
|
||||
|
||||
msgid "The task is already running!"
|
||||
msgstr "A tarefa ya está en execuçáo!"
|
||||
|
||||
msgid "Done!"
|
||||
msgstr "Feito!"
|
||||
|
||||
msgid "Please, wait..."
|
||||
msgstr "Por favor, espere..."
|
||||
|
||||
msgid "Resizing..."
|
||||
msgstr "A redimensionar..."
|
||||
|
||||
msgid "Select paths!"
|
||||
msgstr "Selecione as rotas!"
|
||||
|
||||
msgid "No satellite is selected!"
|
||||
msgstr "Nemhun Satélite selecionado!"
|
||||
|
||||
msgid "Please, select only one satellite!"
|
||||
msgstr "Selecione só um Satélite!"
|
||||
|
||||
msgid "Please check your parameters and try again."
|
||||
msgstr "Por favor rever seus parâmetros e volte a tentar!"
|
||||
|
||||
msgid "No satellites.xml file is selected!"
|
||||
msgstr "Nemhun satellites.xml selecionado!"
|
||||
|
||||
msgid "Error. Verify the data!"
|
||||
msgstr "Erro. Rever os dados!"
|
||||
|
||||
msgid "Operation not allowed in this context!"
|
||||
msgstr "Operação não permitida neste contexto!"
|
||||
|
||||
msgid "No VLC is found. Check that it is installed!"
|
||||
msgstr "VLC não achado. Verifique se está instalado!"
|
||||
|
||||
# Search unavailable streams dialog
|
||||
msgid "Please wait, streams testing in progress..."
|
||||
msgstr "Por favor aguarde uma prova das sequências..."
|
||||
|
||||
msgid "Found"
|
||||
msgstr "Achado"
|
||||
|
||||
msgid "unavailable streams."
|
||||
msgstr "Sequências não presentes"
|
||||
|
||||
msgid "No changes required!"
|
||||
msgstr "Nemhuma mudança requerida!"
|
||||
|
||||
msgid "This list does not contains IPTV streams!"
|
||||
msgstr "A lista não tem sequências IPTV!"
|
||||
|
||||
msgid "New empty configuration"
|
||||
msgstr "Nova configuração vazia"
|
||||
|
||||
msgid "No data to save!"
|
||||
msgstr "Não há dados para guardar!"
|
||||
|
||||
msgid "Network"
|
||||
msgstr "Rede"
|
||||
|
||||
msgid "Paths"
|
||||
msgstr "Rotas"
|
||||
|
||||
msgid "Program"
|
||||
msgstr "Programa"
|
||||
|
||||
msgid "Backup:"
|
||||
msgstr "Backup:"
|
||||
|
||||
msgid "Backup"
|
||||
msgstr "Backup"
|
||||
|
||||
msgid "Backups"
|
||||
msgstr "Backups"
|
||||
|
||||
msgid "Restore bouquets"
|
||||
msgstr "Restaurar ramos"
|
||||
|
||||
msgid "Restore all"
|
||||
msgstr "Restaurar tudo"
|
||||
|
||||
msgid "Before saving"
|
||||
msgstr "Antes de guardar"
|
||||
|
||||
msgid "Before downloading from the receiver"
|
||||
msgstr "Antes de recever do recetor"
|
||||
|
||||
msgid "Set background color for the services"
|
||||
msgstr "Determinar a cor de fundo para serviços"
|
||||
|
||||
msgid "Marked as new:"
|
||||
msgstr "Marcado como novo:"
|
||||
|
||||
msgid "With an extra name in the bouquet:"
|
||||
msgstr "Com nome adicional em ramo:"
|
||||
|
||||
msgid "About"
|
||||
msgstr "Acerca"
|
||||
|
||||
msgid "Exit"
|
||||
msgstr "Sair"
|
||||
Binary file not shown.
@@ -1,13 +1,17 @@
|
||||
# Copyright (C) 2018 Dmitriy Yefremov
|
||||
# This file is distributed under the MIT license.
|
||||
# Dmitriy Yefremov , 2018.
|
||||
#
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Last-Translator: Dmitry Yefremov\n"
|
||||
"Language: ru\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "translator-credits"
|
||||
msgstr ""
|
||||
|
||||
# Main
|
||||
msgid "Service"
|
||||
@@ -482,6 +486,9 @@ msgstr "Этот элемент не разрешен к удалению!"
|
||||
msgid "This item is not allowed to edit!"
|
||||
msgstr "Элемент не предназначен для редактирования!"
|
||||
|
||||
msgid "Not allowed in this context!"
|
||||
msgstr "Запрещено в данном контексте!"
|
||||
|
||||
msgid "Please, download files from receiver or setup your path for read data!"
|
||||
msgstr "Пожалуйста, загрузите файлы из приемника или настройте путь для чтения данных!"
|
||||
|
||||
@@ -561,6 +568,66 @@ msgstr "Изменений не требуется!"
|
||||
msgid "This list does not contains IPTV streams!"
|
||||
msgstr "Текущий список не содержит потоков IPTV!"
|
||||
|
||||
msgid "New empty configuration"
|
||||
msgstr "Новая конфигурация"
|
||||
|
||||
msgid "No data to save!"
|
||||
msgstr "Нет данных для сохранения!"
|
||||
|
||||
msgid "Network"
|
||||
msgstr "Сеть"
|
||||
|
||||
msgid "Paths"
|
||||
msgstr "Пути"
|
||||
|
||||
msgid "Program"
|
||||
msgstr "Программа"
|
||||
|
||||
msgid "Backup:"
|
||||
msgstr "Резервное копирование:"
|
||||
|
||||
msgid "Backup"
|
||||
msgstr "Резервное копирование"
|
||||
|
||||
msgid "Backups"
|
||||
msgstr "Резервные копии"
|
||||
|
||||
msgid "Backup path:"
|
||||
msgstr "Путь к резервным копиям:"
|
||||
|
||||
msgid "Restore bouquets"
|
||||
msgstr "Восстановить букеты"
|
||||
|
||||
msgid "Restore all"
|
||||
msgstr "Восстановить все"
|
||||
|
||||
msgid "Before saving"
|
||||
msgstr "Перед сохранением"
|
||||
|
||||
msgid "Before downloading from the receiver"
|
||||
msgstr "Перед загрузкой с ресивера"
|
||||
|
||||
msgid "Set background color for the services"
|
||||
msgstr "Установить цвет фона для сервисов"
|
||||
|
||||
msgid "Marked as new:"
|
||||
msgstr "Помеченные как новые:"
|
||||
|
||||
msgid "With an extra name in the bouquet:"
|
||||
msgstr "С пользовательским именем в букете:"
|
||||
|
||||
msgid "Select"
|
||||
msgstr "Выбрать"
|
||||
|
||||
msgid "About"
|
||||
msgstr "О программе"
|
||||
|
||||
msgid "Exit"
|
||||
msgstr "Выход"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
demon-editor (0.4.0-1~ppa1) bionic; urgency=low
|
||||
|
||||
* Initial release
|
||||
|
||||
-- Dmitriy Yefremov <dmitry.v.yefremov@gmail.com> Tue, 02 Oct 2018 12:41:40 +0300
|
||||
@@ -1 +0,0 @@
|
||||
10
|
||||
@@ -1,12 +0,0 @@
|
||||
Source: demon-editor
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: Dmitriy Yefremov <dmitry.v.yefremov@gmail.com>
|
||||
Build-Depends: python3 (>= 3.5), debhelper (>= 10)
|
||||
Standards-Version: 4.1.2
|
||||
|
||||
Package: demon-editor
|
||||
Architecture: all
|
||||
Depends: python3 (>= 3.5)
|
||||
Description: Enigma2 channel and satellites list editor
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Contact: Dmitriy Yefremov <dmitry.v.yefremov@gmail.com>
|
||||
Source: https://github.com/DYefremov/DemonEditor
|
||||
|
||||
Files: *
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 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
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,2 +0,0 @@
|
||||
usr/share /usr
|
||||
usr/bin /usr
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/usr/bin/make -f
|
||||
export PYBUILD_NAME=demon-editor
|
||||
|
||||
%:
|
||||
dh $@
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
3.0 (native)
|
||||
@@ -1 +0,0 @@
|
||||
extend-diff-ignore = "^[^/]*[.]egg-info/"
|
||||
Reference in New Issue
Block a user