diff --git a/.gitignore b/.gitignore index 3a58806..8b7a832 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,5 @@ /cache *.pyo *.log -xmltv.xml +xmltv*.xml *.json diff --git a/addon.xml b/addon.xml index 205e592..cc7b987 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + @@ -29,6 +29,7 @@ Setup: + v1.3.4 - update source to gracenote.com v1.3.3 - fix category naming, episode is sorted in in xmltv.xml v1.3.2 - added movies year to subtitles, fix channel sorting v1.3.1 - fix category parsing diff --git a/settings_example.xml b/settings_example.xml new file mode 100644 index 0000000..8c50af6 --- /dev/null +++ b/settings_example.xml @@ -0,0 +1,40 @@ + + true + 14 + 10 + 18 + 6 + 13 + 6 + 15 + 2 + 9 + 2 + 14 + 6 + 11 + 6 + 12 + 6 + 20 + 6 + 19 + 0 + 0 + - + 2 + 0 + Local Over the Air Broadcast + lineupId + + 0 + 45867,53502,72755,65995,73014,63040,74875,58688,87652,44368,54298,58927,72895 + false + false + 9981 + 127.0.0.1 + + false + false + J3B2X8 + diff --git a/zap2epg.py b/zap2epg.py index 6943b55..9f7265f 100644 --- a/zap2epg.py +++ b/zap2epg.py @@ -14,7 +14,14 @@ # along with this program. If not, see . ################################################################################ -import urllib2 +try: + # Python 3 + from urllib.request import urlopen, Request + from urllib.error import HTTPError, URLError +except ImportError: + # Python 2 + from urllib2 import urlopen, Request, HTTPError, URLError + import base64 import codecs import time @@ -93,7 +100,7 @@ def mainRun(userdata): country = 'USA' else: country = 'CAN' - logging.info('Running zap2epg-0.7.4 for zipcode: %s and lineup: %s', zipcode, lineup) + logging.info('Running zap2epg-1.3.4 for zipcode: %s and lineup: %s', zipcode, lineup) pythonStartTime = time.time() cacheDir = os.path.join(userdata, 'cache') dayHours = int(days) * 8 # set back to 8 when done testing @@ -104,14 +111,15 @@ def mainRun(userdata): def tvhMatchGet(): tvhUrlBase = 'http://' + tvhurl + ":" + tvhport channels_url = tvhUrlBase + '/api/channel/grid?all=1&limit=999999999&sort=name&filter=[{"type":"boolean","value":true,"field":"enabled"}]' - if usern is not None and passw is not None: - logging.info('Adding Tvheadend username and password to request url...') - request = urllib2.Request(channels_url) - request.add_header('Authorization', b'Basic ' + base64.b64encode(usern + b':' + passw)) - response = urllib2.urlopen(request) - else: - response = urllib2.urlopen(channels_url) try: + if usern is not None and passw is not None: + logging.info('Adding Tvheadend username and password to request url...') + request = Request(channels_url) + request.add_header('Authorization', b'Basic ' + base64.b64encode(usern + b':' + passw)) + response = urlopen(request) + else: + response = urlopen(channels_url) + logging.info('Accessing Tvheadend channel list from: %s', tvhUrlBase) channels = json.load(response) for ch in channels['entries']: @@ -119,8 +127,8 @@ def tvhMatchGet(): channelNum = ch['number'] tvhMatchDict[channelNum] = channelName logging.info('%s Tvheadend channels found...', str(len(tvhMatchDict))) - except urllib2.HTTPError as e: - logging.exception('Exception: tvhMatch - %s', e.strerror) + except (HTTPError, URLError) as e: + logging.exception('Exception: tvhMatch - %s', str(e)) pass def deleteOldCache(gridtimeStart): @@ -136,8 +144,8 @@ def deleteOldCache(gridtimeStart): fn = os.path.join(cacheDir, entry) os.remove(fn) logging.info('Deleting old cache: %s', entry) - except OSError, e: - logging.warn('Error Deleting: %s - %s.' % (e.filename, e.strerror)) + except OSError as e: + logging.warn('Error Deleting: %s - %s.' % (e.filename, str(e))) except Exception as e: logging.exception('Exception: deleteOldCache - %s', repr(e)) @@ -154,8 +162,8 @@ def deleteOldShowCache(showList): try: os.remove(fn) logging.info('Deleting old show cache: %s', entry) - except OSError, e: - logging.warn('Error Deleting: %s - %s.' % (e.filename, e.strerror)) + except OSError as e: + logging.warn('Error Deleting: %s - %s.' % (e.filename, str(e))) except Exception as e: logging.exception('Exception: deleteOldshowCache - %s', repr(e)) @@ -211,7 +219,7 @@ def printHeader(fh, enc): fh.write("\n") fh.write("\n") fh.write("\n\n") - fh.write("\n") + fh.write("\n") def printFooter(fh): fh.write("\n") @@ -222,9 +230,16 @@ def printStations(fh): try: logging.info('Writing Stations to xmltv.xml file...') try: - scheduleSort = OrderedDict(sorted(schedule.iteritems(), key=lambda x: float(x[1]['chnum']))) + # Python 3 + iter_method = schedule.items + except AttributeError: + # Python 2 + iter_method = schedule.iteritems + + try: + scheduleSort = OrderedDict(sorted(iter_method(), key=lambda x: float(x[1]['chnum']))) except: - scheduleSort = OrderedDict(sorted(schedule.iteritems(), key=lambda x: x[1]['chfcc'])) + scheduleSort = OrderedDict(sorted(iter_method(), key=lambda x: x[1]['chfcc'])) for station in scheduleSort: fh.write('\t\n') if 'chtvh' in scheduleSort[station] and scheduleSort[station]['chtvh'] is not None: @@ -256,15 +271,26 @@ def printEpisodes(fh): logging.info('Writing Episodes to xmltv.xml file...') if xdesc is True: logging.info('Appending Xdetails to description for xmltv.xml file...') - try: - scheduleSort = OrderedDict(sorted(schedule.iteritems(), key=lambda x: float(x[1]['chnum']))) + # Python 3 + iter_method = schedule.items + except AttributeError: + # Python 2 + iter_method = schedule.iteritems + try: + scheduleSort = OrderedDict(sorted(iter_method(), key=lambda x: float(x[1]['chnum']))) except: - scheduleSort = OrderedDict(sorted(schedule.iteritems(), key=lambda x: x[1]['chfcc'])) + scheduleSort = OrderedDict(sorted(iter_method(), key=lambda x: x[1]['chfcc'])) for station in scheduleSort: lang = 'en' - sdict = OrderedDict(sorted(schedule[station].iteritems())) + try: + # Python 3 + iter_method = schedule[station].items + except AttributeError: + # Python 2 + iter_method = schedule[station].iteritems + sdict = OrderedDict(sorted(iter_method())) for episode in sdict: if not episode.startswith("ch"): try: @@ -335,7 +361,7 @@ def printEpisodes(fh): #os.remove(fn) #logging.info('Deleting episode %s:', episode) except Exception as e: - logging.exception('Exception: printEpisodes') + logging.exception('Exception: printEpisodes: %s', str(e)) def xmltv(): try: @@ -463,11 +489,11 @@ def parseXdetails(): retry = 3 while retry > 0: logging.info('Downloading details data for: %s', EPseries) - url = 'https://tvlistings.zap2it.com/api/program/overviewDetails' + url = 'https://tvlistings.gracenote.com/api/program/overviewDetails' data = 'programSeriesID=' + EPseries try: - URLcontent = urllib2.Request(url, data=data) - JSONcontent = urllib2.urlopen(URLcontent).read() + URLcontent = Request(url, data=data) + JSONcontent = urlopen(URLcontent).read() if JSONcontent: with open(fileDir, "wb+") as f: f.write(JSONcontent) @@ -477,7 +503,7 @@ def parseXdetails(): time.sleep(1) retry -= 1 logging.warn('Retry downloading missing details data for: %s', EPseries) - except urllib2.URLError, e: + except URLError as e: time.sleep(1) retry -= 1 logging.warn('Retry downloading details data for: %s - %s', EPseries, e) @@ -516,8 +542,8 @@ def parseXdetails(): os.remove(fileDir) logging.info('Deleting %s due to TBA listings', filename) showList.remove(edict['epseries']) - except OSError, e: - logging.warn('Error Deleting: %s - %s.' % (e.filename, e.strerror)) + except OSError as e: + logging.warn('Error Deleting: %s - %s.' % (e.filename, str(e))) except Exception as e: logging.exception('Could not parse TBAcheck for: %s - %s', episode, e) else: @@ -690,12 +716,13 @@ def makeDescsortList(optList): if not os.path.exists(fileDir): try: logging.info('Downloading guide data for: %s', str(gridtime)) - url = 'http://tvlistings.zap2it.com/api/grid?lineupId=×pan=3&headendId=' + lineupcode + '&country=' + country + '&device=' + device + '&postalCode=' + zipcode + '&time=' + str(gridtime) + '&pref=-&userId=-' - saveContent = urllib2.urlopen(url).read() + url = 'https://tvlistings.gracenote.com/api/grid?lineupId=×pan=3&headendId=' + lineupcode + '&country=' + country + '&device=' + device + '&postalCode=' + zipcode + '&time=' + str(gridtime) + '&pref=-&userId=-' + saveContent = urlopen(url).read() savepage(fileDir, saveContent) - except: + except Exception as e: logging.warn('Could not download guide data for: %s', str(gridtime)) logging.warn('URL: %s', url) + logging.warn('Exception: %s', str(e)) if os.path.exists(fileDir): try: with gzip.open(fileDir, 'rb') as f: @@ -709,10 +736,11 @@ def makeDescsortList(optList): try: os.remove(fileDir) logging.info('Deleting %s due to TBA listings', filename) - except OSError, e: - logging.warn('Error Deleting: %s - %s.' % (e.filename, e.strerror)) - except: + except OSError as e: + logging.warn('Error Deleting: %s - %s.' % (e.filename, str(e))) + except Exception as e: logging.warn('JSON file error for: %s - deleting file', filename) + logging.warn('Exception: %s', str(e)) os.remove(fileDir) count += 1 gridtime = gridtime + 10800 @@ -727,7 +755,7 @@ def makeDescsortList(optList): logging.info('%s Stations and %s Episodes written to xmltv.xml file.', str(stationCount), str(episodeCount)) return timeRun, stationCount, episodeCount except Exception as e: - logging.exception('Exception: main') + logging.exception('Exception: main ' + str(e)) if __name__ == '__main__':