Skip to content

Commit fb26eb5

Browse files
authored
Merge pull request #2 from edit4ever/picons
Picons
2 parents 85bace7 + 012c5ea commit fb26eb5

File tree

6 files changed

+459
-34
lines changed

6 files changed

+459
-34
lines changed

addon.xml

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
22
<addon id="script.module.tvh2kodi"
33
name="Tvheadend Setup for Kodi"
4-
version="1.9"
4+
version="1.9.6"
55
provider-name="edit4ever">
66
<requires>
77
<import addon="xbmc.python" version="2.6.0"/>
@@ -17,9 +17,7 @@
1717
<description>Tvh2Kodi gives access to the basic Tvheadend settings directly from the Kodi interface. This can be used in place of the Tvheadend web interface to get your Tvheadend backend server configured and running. It is also provides an easy way to scan for new services and channels and to configure your channel EPG sources.
1818

1919
* minimum version of Tvheadend is 4.2
20-
v1.9
21-
- add timeshift options under DVR configuration
22-
- fix epg grabber progress bar
20+
2321
</description>
2422
<disclaimer>Copyright (C) 2017 edit4ever - edit4ever@gmail.com</disclaimer>
2523
<platform>all</platform>
@@ -32,16 +30,9 @@ v1.9
3230
<screenshot>resources/screenshot-03.jpg</screenshot>
3331
</assets>
3432
<news>
35-
v1.8.1 - fix username-password display
36-
v1.8 - add support for IPTV Networks - fix error in muxes when 0 muxes available
37-
v1.7 - add support for Tvh username-password
38-
v1.6 - add backup and import of tvh userdata - add channel icon reset option
39-
v1.5 - add progress bar for internal epg grab - add base tvh config parameters (set dvb scan files and channel icon paths)
40-
v1.4 - fix adapter network issue - add multiple network support to adapter - allow custom Tvh server ip to be recalled
41-
v1.3 - add support for DVB-S mux editing
42-
v1.2 - fix error in network parameters load - fix wrong epg parameter selection
43-
v1.1 - add triggers for OTA and internal grabbers
44-
v1.0 - Initial Release
45-
</news>
33+
1.9.6 - add epg grabber cron wizard
34+
1.9.5 - add picons downloader (test)
35+
1.9 - add timeshift options under DVR configuration - fix epg grabber progress bar
36+
</news>
4637
</extension>
4738
</addon>

changelog.txt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
v1.9.6 (2017-11-29)
2+
- add epg grabber cron wizard
3+
4+
v1.9.5 (2017-08-08)
5+
- add picons downloader (test)
6+
7+
v1.9 (2017-08-03)
8+
- add timeshift options under DVR configuration - fix epg grabber progress bar
9+
10+
v1.8.1 (2017-07-28)
11+
- fix username-password display
12+
13+
v1.6/1.7/1.8 (2017-07-26)
14+
- add backup and import of tvh userdata - add channel icon reset option
15+
- add support for Tvh username-password
16+
- add support for IPTV Networks - fix error in muxes when 0 muxes available
17+
18+
v1.5 (2017-07-14)
19+
- add progress bar for internal epg grab - add base tvh config parameters (set dvb scan files and channel icon paths)
20+
21+
v1.4 (2017-07-10)
22+
- fix adapter network issue - add multiple network support to adapter - allow custom Tvh server ip to be recalled
23+
24+
v1.3 (2017-07-08)
25+
- add support for DVB-S mux editing
26+
27+
v1.2 (2017-07-08)
28+
- fix error in network parameters load - fix wrong epg parameter selection
29+
30+
v1.1 (2017-07-07)
31+
- add triggers for OTA and internal grabbers
32+
33+
v1.0 (2017-07-06)
34+
- Initial Release

default.py

Lines changed: 123 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
#!/usr/bin/env python
2+
################################################################################
3+
# This file is part of LibreELEC - https://libreelec.tv
4+
# Copyright (C) 2016-2017 Team LibreELEC
5+
# Copyright (C) 2017 Tnds82 (tndsrepo@gmail.com)
6+
#
7+
# LibreELEC is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU General Public License as published by
9+
# the Free Software Foundation, either version 2 of the License, or
10+
# (at your option) any later version.
11+
#
12+
# LibreELEC is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU General Public License
18+
# along with LibreELEC. If not, see <http://www.gnu.org/licenses/>.
19+
################################################################################
20+
121
import xbmc,xbmcaddon,xbmcvfs,xbmcgui,xbmcplugin
222
import subprocess
323
from subprocess import Popen
@@ -13,8 +33,8 @@
1333
import ast
1434
import zipfile
1535
import datetime
16-
#from requests.exceptions import HTTPError
17-
#from requests.exceptions import ConnectionError
36+
import urllib
37+
import picons
1838

1939
plugin = Plugin()
2040
dialog = xbmcgui.Dialog()
@@ -183,6 +203,45 @@ def _ArchiveDirectory(parentDirectory):
183203
_ArchiveDirectory(inputDir)
184204
zipOut.close()
185205

206+
def picons_param_load():
207+
url_latest = 'http://cvh.libreelec.tv/picons/latest2.json'
208+
ljson = requests.get(url_latest).json()
209+
picons_source_list = ['Custom URL']
210+
picons_source_files = ['Custom URL']
211+
for p in ljson['Picons']['latest']:
212+
picons_source_list.append(p['desc'])
213+
for n in ljson['Picons']['latest']:
214+
picons_source_files.append(n['name'])
215+
picons_source_value = xbmcaddon.Addon().getSetting('psource')
216+
picons_source = picons_source_list[int(picons_source_value)]
217+
picons_file = picons_source_files[int(picons_source_value)]
218+
picons_dest = xbmcaddon.Addon().getSetting('pdest')
219+
picons_url = xbmcaddon.Addon().getSetting('purl')
220+
picons_list = ["Picons Source: " + str(picons_source), "Picons Destination: " + str(picons_dest), "DOWNLOAD PICONS"]
221+
sel_param = dialog.select('Picons Download - Select parameter', list=picons_list)
222+
if sel_param < 0:
223+
return
224+
if sel_param >= 0:
225+
if sel_param == 0:
226+
sel_psource = dialog.select('Select Picons Source', list=picons_source_list)
227+
if sel_psource < 0:
228+
picons_param_load()
229+
else:
230+
picons_source_set = xbmcaddon.Addon().setSetting(id='psource', value=str(sel_psource))
231+
picons_param_load()
232+
if sel_param == 1:
233+
picons_dest_update = dialog.browse(3, "Select Picons Destination", "files", defaultt=picons_dest)
234+
picons_dest_set = xbmcaddon.Addon().setSetting(id='pdest', value=picons_dest_update)
235+
picons_param_load()
236+
if sel_param == 2:
237+
if picons_source_value == "0":
238+
sel_purl = dialog.input('Enter the Picons URL to Download', defaultt=picons_url,type=xbmcgui.INPUT_ALPHANUM)
239+
if sel_purl != "":
240+
picons_url_set = xbmcaddon.Addon().setSetting(id='purl', value=str(sel_purl))
241+
picons.url_external(sel_purl)
242+
if picons_source_value > "0":
243+
picons.compare_release(url_latest, picons_file, picons_source_value)
244+
186245
def dvr_param_load(dvr_uuid_sel):
187246
dvr_url = 'http://' + tvh_url + ':' + tvh_port + '/api/idnode/load?uuid=' + dvr_uuid_sel
188247
dvr_load = requests.get(dvr_url).json()
@@ -1077,7 +1136,7 @@ def ch_param_edit(ch_uuid_sel, ch_info_list, ch_enabled, ch_autoname, ch_name, c
10771136
param_update = '"autoname":' + ch_autoname
10781137
if sel_param == 4:
10791138
sel_ch_icon = dialog.input('Edit the channel icon URL', defaultt=ch_icon,type=xbmcgui.INPUT_ALPHANUM)
1080-
if sel_ch_name == "":
1139+
if sel_ch_icon == "":
10811140
ch_param_load(ch_uuid_sel)
10821141
else:
10831142
param_update = '"icon":"' + sel_ch_icon + '"'
@@ -1108,6 +1167,45 @@ def ch_param_edit(ch_uuid_sel, ch_info_list, ch_enabled, ch_autoname, ch_name, c
11081167
ch_param_load(ch_uuid_sel)
11091168

11101169

1170+
def cron_edit(epg_intcron):
1171+
cron_def_weekday_list = ['Everyday', 'Every Other Day', 'on Sundays', 'on Mondays', 'on Tuesdays', 'on Wednesdays', 'on Thursdays', 'on Fridays', 'on Saturdays']
1172+
cron_def_weekday = {'*':'Everyday', '2-30/2': 'Every Other Day', '0':'on Sundays', '1':'on Mondays', '2':'on Tuesdays', '3':'on Wednesdays', '4':'on Thursdays', '5':'on Fridays', '6':'on Saturdays'}
1173+
cron_def_split_hour_list = ['Specific Hour', '2x a Day', '3x a Day', '4x a Day', '6x a Day', '8x a Day', '12x a Day', 'every Hour']
1174+
cron_def_split_hour = {'*':'every Hour', '*/2':'12x a Day', '*/3':'8x a Day', '*/4':'6x a Day','*/6':'4x a Day', '*/8':'3x a Day', '*/12':'2x a Day'}
1175+
cron_def_hours = ['12:00AM - Midnight', '1:00AM', '2:00AM', '3:00AM', '4:00AM', '5:00AM', '6:00AM', '7:00AM', '8:00AM', '9:00AM', '10:00AM', '11:00AM', '12:00PM - Noon', '1:00PM', '2:00PM', '3:00PM', '4:00PM', '5:00PM', '6:00PM', '7:00PM', '8:00PM', '9:00PM', '10:00PM', '11:00PM']
1176+
epg_intcron_clean = re.sub('#.*\n', '', epg_intcron)
1177+
cron_current = epg_intcron_clean.split(' ')
1178+
cron_current_min = str(int(cron_current[0])).zfill(2)
1179+
if '*' in cron_current[1]:
1180+
cron_current_str = cron_current_min + ' Minutes past the hour, ' + cron_def_split_hour[cron_current[1]] + ', ' + cron_def_weekday[cron_current[2]]
1181+
else:
1182+
cron_ampm = 'AM'
1183+
if cron_current[1] == '00' or cron_current[1] == '0':
1184+
cron_current_hour = '12'
1185+
elif int(cron_current[1]) > 12:
1186+
cron_current_hour = str(24 - int(cron_current[1]))
1187+
cron_ampm = 'PM'
1188+
else:
1189+
cron_current_hour = cron_current[1]
1190+
cron_current_str = cron_current_hour + ':' + cron_current_min + cron_ampm + ' - ' + cron_def_weekday[cron_current[2]]
1191+
cron_edit_sel = dialog.yesno('Cron edit', 'The grabber is set to run at:', cron_current_str, 'Do you wish to edit this cron setting?')
1192+
if cron_edit_sel:
1193+
cron_sel_weekday = dialog.select('Select which day(s) to run the grabber', list=cron_def_weekday_list)
1194+
if cron_sel_weekday >= 0:
1195+
cron_new_weekday = cron_def_weekday.keys()[cron_def_weekday.values().index(cron_def_weekday_list[cron_sel_weekday])]
1196+
cron_sel_hour = dialog.select('Select which hour(s) to run the grabber', list=cron_def_split_hour_list)
1197+
if cron_sel_hour == 0:
1198+
cron_sel_hour_spec = dialog.select('Select which hour(s) to run the grabber', list=cron_def_hours)
1199+
cron_new_hour = cron_sel_hour_spec
1200+
if cron_sel_hour > 0:
1201+
cron_new_hour = cron_def_split_hour.keys()[cron_def_split_hour.values().index(cron_def_split_hour_list[cron_sel_hour])]
1202+
cron_new_min = dialog.input('Enter the minutes after the hour to run the grabber', defaultt='0', type=xbmcgui.INPUT_NUMERIC)
1203+
cron_update = str(cron_new_min) + ' ' + str(cron_new_hour) + ' ' + cron_new_weekday + ' * *'
1204+
return cron_update
1205+
else:
1206+
return epg_intcron
1207+
1208+
11111209
def epg_param(sel_epg, epg_rename, epg_renumber, epg_reicon, epg_dbsave, epg_intcron, epg_otainit, epg_otacron, epg_otatime):
11121210
param_update = ""
11131211
if sel_epg == 3:
@@ -1131,20 +1229,32 @@ def epg_param(sel_epg, epg_rename, epg_renumber, epg_reicon, epg_dbsave, epg_int
11311229
sel_epg_dbsave = epg_dbsave
11321230
param_update = '"epgdb_periodicsave":' + str(sel_epg_dbsave)
11331231
if sel_epg == 7:
1134-
sel_epg_intcron = dialog.input('Edit the cron multiline for internal grabbers', defaultt=epg_intcron,type=xbmcgui.INPUT_ALPHANUM)
1135-
if sel_epg_intcron == "":
1136-
sel_epg_intcron = epg_intcron
1232+
sel_epg_intcron_type = dialog.yesno('Edit the cron for internal grabbers', 'If you are familiar with cron settings you can manually enter the cron.', '', 'Otherwise use the wizard to select the grabber run times.', 'Wizard', 'Manual')
1233+
if sel_epg_intcron_type:
1234+
sel_epg_intcron = dialog.input('Edit the cron multiline for internal grabbers', defaultt=epg_intcron,type=xbmcgui.INPUT_ALPHANUM)
1235+
if sel_epg_intcron == "":
1236+
sel_epg_intcron = epg_intcron
1237+
else:
1238+
sel_epg_intcron = cron_edit(epg_intcron)
1239+
if sel_epg_intcron == "":
1240+
sel_epg_intcron = epg_intcron
11371241
param_update = '"cron":"' + sel_epg_intcron + '"'
11381242
if sel_epg == 8:
11391243
sel_epg_otainit = dialog.select('Enable or disable initial EPG grab at startup', list=enabledisable)
11401244
if sel_epg_otainit >= 0:
11411245
epg_otainit = truefalse[sel_epg_otainit]
11421246
param_update = '"ota_initial":' + epg_otainit
11431247
if sel_epg == 9:
1144-
sel_epg_otacron = dialog.input('Edit the cron multiline for over-the-air grabbers', defaultt=epg_otacron,type=xbmcgui.INPUT_ALPHANUM)
1145-
if sel_epg_otacron == "":
1146-
sel_epg_otacron = epg_otacron
1147-
param_update = '"cron":"' + sel_epg_otacron + '"'
1248+
sel_epg_otacron_type = dialog.yesno('Edit the cron for OTA grabbers', 'If you are familiar with cron settings you can manually enter the cron.', '', 'Otherwise use the wizard to select the grabber run times.', 'Wizard', 'Manual')
1249+
if sel_epg_otacron_type:
1250+
sel_epg_otacron = dialog.input('Edit the cron multiline for over-the-air grabbers', defaultt=epg_otacron,type=xbmcgui.INPUT_ALPHANUM)
1251+
if sel_epg_otacron == "":
1252+
sel_epg_otacron = epg_otacron
1253+
else:
1254+
sel_epg_otacron = cron_edit(epg_otacron)
1255+
if sel_epg_otacron == "":
1256+
sel_epg_otacron = epg_otacron
1257+
param_update = '"ota_cron":"' + sel_epg_otacron + '"'
11481258
if sel_epg == 10:
11491259
sel_epg_otatime = dialog.input('OTA EPG scan timeout in seconds (30-7200)', defaultt=str(epg_otatime),type=xbmcgui.INPUT_NUMERIC)
11501260
if sel_epg_otatime == "":
@@ -1692,8 +1802,6 @@ def wizard_start():
16921802
for adapter_t in adapter_get:
16931803
adapter_list.append(adapter_t['text'])
16941804
sel_adapter = dialog.select('Select which adapter you would like to setup first', list=adapter_list)
1695-
if sel_adapter < 0:
1696-
return
16971805
if sel_adapter >= 0:
16981806
adapter_uuid_sel = adapter_uuid[sel_adapter]
16991807
adapter_text_sel = adapter_list[sel_adapter]
@@ -1843,8 +1951,6 @@ def adapters():
18431951
adapters_full = zip(adapter_text, adapter_enabled)
18441952
adapters_list = ["%s %s" % x for x in adapters_full]
18451953
sel_adapter = dialog.select('Select which adapter you would like to configure', list=adapters_list)
1846-
if sel_adapter < 0:
1847-
return
18481954
if sel_adapter >= 0:
18491955
adapter_uuid_sel = adapter_uuid[sel_adapter]
18501956
adapt_param_load(adapter_uuid_sel)
@@ -1860,8 +1966,6 @@ def networks():
18601966
for net_u in networks['entries']:
18611967
net_uuid.append(net_u['uuid'])
18621968
sel_network = dialog.select('Select a network to configure', list=net_name)
1863-
if sel_network < 0:
1864-
return
18651969
if sel_network == 0:
18661970
net_uuid_sel = network_new()
18671971
if net_uuid_sel == "":
@@ -1883,8 +1987,6 @@ def muxes():
18831987
for net_u in networks['entries']:
18841988
net_uuid.append(net_u['uuid'])
18851989
sel_network = dialog.select('Select a network to see list of muxes', list=net_name)
1886-
if sel_network < 0:
1887-
return
18881990
if sel_network >= 0:
18891991
net_uuid_sel = net_uuid[sel_network]
18901992
muxes_load(net_uuid_sel)
@@ -2061,7 +2163,7 @@ def tvh():
20612163
ch_icon_scheme, ch_icon_scheme_key, ch_icon_scheme_val = find_param_dict(tvh_config_load, 'chiconscheme', 'enum')
20622164
picon_path = find_param(tvh_config_load, 'piconpath')
20632165
picon_scheme, picon_scheme_key, picon_scheme_val = find_param_dict(tvh_config_load, 'piconscheme', 'enum')
2064-
tvh_config_info_list = ["DVB scan path: " + str(dvb_scan_path), "Prefer picon: " + str(prefer_picon), "Channel icon path: " + str(ch_icon_path), "Channel icon scheme: " + str(ch_icon_scheme), "Picon path: " + str(picon_path), "Picon scheme: " + str(picon_scheme), "RESET ALL CHANNEL ICONS", "BACKUP TVHEADEND USERDATA", "IMPORT TVHEADEND USERDATA"]
2166+
tvh_config_info_list = ["DVB scan path: " + str(dvb_scan_path), "Prefer picon: " + str(prefer_picon), "Channel icon path: " + str(ch_icon_path), "Channel icon scheme: " + str(ch_icon_scheme), "Picon path: " + str(picon_path), "Picon scheme: " + str(picon_scheme), "RESET ALL CHANNEL ICONS", "BACKUP TVHEADEND USERDATA", "IMPORT TVHEADEND USERDATA", "DOWNLOAD PICONS"]
20652167
param_update = ""
20662168
sel_tvh = dialog.select('Select a Tvh configuration parameter to edit', list=tvh_config_info_list)
20672169
if sel_tvh < 0:
@@ -2173,6 +2275,8 @@ def tvh():
21732275
dialog.ok("Unable to Restart Tvheadend Service!", "Unable to restart the Tvheadend service.", "Please enable the service in Kodi addons.")
21742276
else:
21752277
dialog.ok("Tvheadend Service Still Running!", "Unable to stop the Tvheadend service.", "Unable to complete backup.")
2278+
if sel_tvh == 9:
2279+
picons_param_load()
21762280
if param_update != "":
21772281
param_url = 'http://' + tvh_url + ':' + tvh_port + '/api/config/save?node={' + param_update + '}'
21782282
param_save = requests.get(param_url)

0 commit comments

Comments
 (0)