Skip to content

Commit ff32c97

Browse files
authored
Merge pull request #60 from wbeard52/master
Improved addon experience. Updated TVH authentication to work with TVH version 4.3+ (digest)
2 parents 406113b + 3ec1d87 commit ff32c97

File tree

8 files changed

+661
-428
lines changed

8 files changed

+661
-428
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,8 @@
22
*.pyo
33
*.log
44
xmltv.xml
5+
settings.xml
6+
zap2epg.log
57
*.json
8+
.venv
9+
__pycache__

addon.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<addon id="script.module.zap2epg" name="zap2epg" version="2.1.0" provider-name="edit4ever">
2+
<addon id="script.module.zap2epg" name="zap2epg" version="2.1.1" provider-name="edit4ever">
33
<requires>
44
<import addon="xbmc.python" version="3.0.0"/>
55
<import addon="script.module.dateutil" version="2.8.2"/>

default.py

Lines changed: 85 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,23 @@
1313
# You should have received a copy of the GNU General Public License
1414
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1515
################################################################################
16-
import xbmc,xbmcaddon,xbmcvfs,xbmcgui,xbmcplugin
17-
import subprocess
18-
from subprocess import Popen
19-
from xbmcswift2 import Plugin
20-
import io
16+
import xbmc, xbmcaddon, xbmcvfs, xbmcgui
17+
from tvh import tvh_connect, tvh_getData, tvh_logsetup
18+
19+
from xbmcswift2 import Plugin
2120
import os
2221
import re
23-
import sys
2422
import logging
2523
import zap2epg
2624
import urllib.request, urllib.error, urllib.parse
2725
import json
2826
from collections import OrderedDict
2927
import time
3028
import datetime
31-
import _strptime
32-
import requests
3329
#import web_pdb; web_pdb.set_trace()
3430

3531
userdata = xbmcvfs.translatePath(xbmcaddon.Addon().getAddonInfo('profile'))
36-
tvhoff = xbmcaddon.Addon().getSetting('tvhoff')
32+
tvhoff = True if xbmcaddon.Addon().getSetting('tvhoff') == 'true' else False
3733
if not os.path.exists(userdata):
3834
os.mkdir(userdata)
3935
log = os.path.join(userdata, 'zap2epg.log')
@@ -43,64 +39,69 @@
4339
plugin = Plugin()
4440
dialog = xbmcgui.Dialog()
4541
gridtime = (int(time.mktime(time.strptime(str(datetime.datetime.now().replace(microsecond=0,second=0,minute=0)), '%Y-%m-%d %H:%M:%S'))))
42+
connection = None
4643

47-
if tvhoff == 'true':
48-
try:
49-
tvh_url_get = xbmcaddon.Addon('pvr.hts').getSetting("host")
50-
if tvh_url_get:
51-
tvh_url_set = xbmcaddon.Addon().setSetting(id='tvhurl', value=tvh_url_get)
52-
else:
53-
try:
54-
tvh_url = xbmcaddon.Addon().getSetting('tvhurl')
55-
except:
56-
tvh_url_set = xbmcaddon.Addon().setSetting(id='tvhurl', value="127.0.0.1")
57-
tvh_port_get = xbmcaddon.Addon('pvr.hts').getSetting("http_port")
58-
if tvh_port_get:
59-
tvh_port_set = xbmcaddon.Addon().setSetting(id='tvhport', value=tvh_port_get)
44+
def connectTVH(updateSetting = False):
45+
global tvhoff
46+
if tvhoff is True:
47+
tvh_url = xbmcaddon.Addon().getSetting('tvhurl')
48+
tvh_port = xbmcaddon.Addon().getSetting('tvhport')
49+
tvh_usern = xbmcaddon.Addon().getSetting('usern')
50+
tvh_passw = xbmcaddon.Addon().getSetting('passw')
51+
52+
pvr = {}
53+
try:
54+
pvr['ipaddress'] = xbmcaddon.Addon('pvr.hts').getSetting("host")
55+
pvr['port'] = xbmcaddon.Addon('pvr.hts').getSetting("http_port")
56+
pvr['user'] = tvh_usern
57+
pvr['password'] = tvh_passw
58+
except:
59+
pvr.clear()
60+
global connection
61+
connection = tvh_connect(tvh_url, tvh_port, tvh_usern, tvh_passw, pvr)
62+
tvhoff = True if connection is not None else False
63+
if tvhoff is True:
64+
if tvh_url != connection['ipaddress']:
65+
response = dialog.yesno('Update TVH Settings?', f'{tvh_url} TVH server was not found.\n\nWould you like to use the IP address found in the TVH PVR?\n{connection["ipaddress"]}')
66+
if response is True:
67+
xbmcaddon.Addon().setSetting(id='tvhurl', value=connection['ipaddress'])
68+
xbmcaddon.Addon().setSetting(id='tvhport', value=connection['port'])
69+
else:
70+
if updateSetting:
71+
connection = None
72+
tvhoff = False
73+
xbmcaddon.Addon().setSetting(id='tvhoff', value='false')
6074
else:
61-
try:
62-
tvh_port = xbmcaddon.Addon().getSetting('tvhport')
63-
except:
64-
tvh_port_set = xbmcaddon.Addon().setSetting(id='tvhport', value="9981")
65-
except:
66-
pass
75+
dialog.ok("TVHeadend Server", f'The TVH server {tvh_url} was not found or username / password was incorrect. Please check TVH settings')
76+
if updateSetting:
77+
connection = None
78+
tvhoff = False
79+
xbmcaddon.Addon().setSetting(id='tvhoff', value='false')
6780

68-
tvh_port = xbmcaddon.Addon().getSetting('tvhport')
69-
tvh_usern = xbmcaddon.Addon().getSetting('usern')
70-
tvh_passw = xbmcaddon.Addon().getSetting('passw')
71-
if tvh_usern == None and tvh_passw == None:
72-
tvh_url = xbmcaddon.Addon().getSetting('tvhurl')
73-
elif tvh_usern == "" and tvh_passw == "":
74-
tvh_url = xbmcaddon.Addon().getSetting('tvhurl')
75-
else:
76-
tvh_url = tvh_usern + ":" + tvh_passw + "@" + xbmcaddon.Addon().getSetting('tvhurl')
77-
try:
78-
check_url = 'http://' + tvh_url + ':' + tvh_port + '/api/status/connections'
79-
check_load = requests.get(check_url)
80-
check_status = check_load.raise_for_status()
81-
except requests.exceptions.HTTPError as err:
82-
dialog.ok("Tvheadend Access Error!",f"{err}\n\nPlease check your username/password in settings.")
83-
except requests.exceptions.RequestException as e:
84-
dialog.ok("Tvheadend Access Error!", "Could not connect to Tvheadend server.\nPlease check your Tvheadend server is running or check the IP and port configuration in the settings.")
81+
def getTVHChannels():
82+
global tvhoff, connection
83+
if connection is None:
84+
connectTVH()
85+
if connection is not None:
86+
response = tvh_getData('/api/channel/grid?all=1&limit=999999999&sort=name')
87+
try:
88+
logging.info('Accessing Tvheadend channel list from: %s', connection['ipaddress'])
89+
channels = response.json()
90+
with open(tvhList,"w") as f:
91+
json.dump(channels,f)
92+
except urllib.error.HTTPError as e:
93+
logging.exception('Exception: tvhClist - %s', e.strerror)
94+
tvhoff = False
8595

8696
def get_icon_path(icon_name):
8797
addon_path = xbmcaddon.Addon().getAddonInfo("path")
8898
return os.path.join(addon_path, 'resources', 'img', icon_name+".png")
8999

90100
def create_cList():
91101
tvhClist = []
92-
if tvhoff == 'true':
93-
if not os.path.isfile(tvhList):
94-
channels_url = 'http://' + tvh_url + ':' + tvh_port + '/api/channel/grid?all=1&limit=999999999&sort=name'
95-
response = requests.get(channels_url)
96-
try:
97-
logging.info('Accessing Tvheadend channel list from: %s', channels_url)
98-
channels = response.json()
99-
with open(tvhList,"w") as f:
100-
json.dump(channels,f)
101-
except urllib.error.HTTPError as e:
102-
logging.exception('Exception: tvhClist - %s', e.strerror)
103-
pass
102+
if tvhoff is True and not os.path.isfile(tvhList):
103+
getTVHChannels()
104+
if tvhoff is True:
104105
with open(tvhList) as tvhData:
105106
tvhDict = json.load(tvhData)
106107
for ch in tvhDict['entries']:
@@ -123,6 +124,15 @@ def create_cList():
123124
else:
124125
stationDict[skey]['include'] = 'False'
125126
stationDictSort = OrderedDict(sorted(iter(stationDict.items()), key=lambda i: (float(i[1]['num']))))
127+
128+
#Search the stations for duplicate channel numbers. Get rid of the non 'DT' channel(s) if so.
129+
for station in stationDictSort:
130+
myStations = {k: v for k, v in stationDictSort.items() if v['num'] == stationDictSort[station]['num']}
131+
if len(myStations) > 1:
132+
for st in myStations:
133+
if myStations[st]['name'].find('DT') < 0:
134+
stationDictSort[st]['include'] = 'False'
135+
126136
with open(Clist,"w") as f:
127137
json.dump(stationDictSort,f)
128138

@@ -149,7 +159,7 @@ def channels():
149159
stationCode.append(station)
150160
stationListName.append(stationDict[station]['name'])
151161
stationListNum.append(stationDict[station]['num'])
152-
stationListInclude.append(stationDict[station]['include'])
162+
stationListInclude.append(stationDict[station]['include'])
153163
stationPre = [i for i, x in enumerate(stationListInclude) if x == 'True']
154164
stationListFull = list(zip(stationListNum, stationListName))
155165
stationList = ["%s %s" % x for x in stationListFull]
@@ -175,7 +185,6 @@ def location():
175185
zipcodeNew = dialog.input('Enter your zipcode', defaultt=zipcode, type=xbmcgui.INPUT_NUMERIC)
176186
if countryNew == 1:
177187
zipcodeNew = dialog.input('Enter your zipcode', defaultt=zipcode, type=xbmcgui.INPUT_ALPHANUM)
178-
#import web_pdb; web_pdb.set_trace()
179188
if not 'zipcodeNew' in vars() or 'zipcodeNew' in globals():
180189
return
181190
zipcodeNew = re.sub(' ', '', zipcodeNew)
@@ -239,15 +248,29 @@ def location():
239248
@plugin.route('/run')
240249
def run():
241250
logging.basicConfig(filename=log, filemode='w', format='%(asctime)s %(message)s', datefmt='%Y/%m/%d %H:%M:%S', level=logging.DEBUG)
251+
tvh_logsetup(filename=log, filemode='w', format='%(asctime)s %(message)s', datefmt='%Y/%m/%d %H:%M:%S', level=logging.DEBUG)
242252
status = zap2epg.mainRun(userdata)
243253
dialog.ok('zap2epg Finished!', 'zap2epg completed in ' + str(status[0]) + ' seconds.\n' + str(status[1]) + ' Stations and ' + str(status[2]) + ' Episodes written to xmltv.xml file.')
244254

245255

246256

247257
@plugin.route('/open_settings')
248258
def open_settings():
249-
plugin.open_settings()
250-
259+
plugin.open_settings()
260+
global tvhoff, connection
261+
# Test the connection to TVH if tvhoff is true
262+
tvhoff = True if xbmcaddon.Addon().getSetting('tvhoff') == 'true' else False
263+
if tvhoff is True:
264+
connectTVH(True)
265+
try:
266+
os.remove(tvhList)
267+
except:
268+
pass
269+
if connection is not None:
270+
getTVHChannels()
271+
else:
272+
tvhoff = False
273+
xbmcaddon.Addon().setSetting(id='tvhoff', value='false')
251274

252275
@plugin.route('/')
253276
def index():
@@ -295,4 +318,4 @@ def index():
295318
xbmc.executebuiltin('Container.Refresh')
296319
except:
297320
dialog.ok('No Lineup Configured!', '', 'Please configure your zipcode and lineup under Change Current Location.')
298-
plugin.run()
321+
plugin.run()

0 commit comments

Comments
 (0)