Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
/cache
*.pyo
*.log
xmltv.xml
xmltv*.xml
*.json
3 changes: 2 additions & 1 deletion addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="script.module.zap2epg" name="zap2epg" version="1.3.3" provider-name="edit4ever">
<addon id="script.module.zap2epg" name="zap2epg" version="1.3.4" provider-name="edit4ever">
<requires>
<import addon="xbmc.python" version="2.7.13"/>
<import addon="script.module.dateutil" version="2.4.2"/>
Expand Down Expand Up @@ -29,6 +29,7 @@ Setup:
<email></email>
<source></source>
<news>
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
Expand Down
40 changes: 40 additions & 0 deletions settings_example.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<settings version="2">
<setting id="chmatch">true</setting>
<setting id="days">14</setting>
<setting id="desc01">10</setting>
<setting id="desc02">18</setting>
<setting id="desc03">6</setting>
<setting id="desc04">13</setting>
<setting id="desc05">6</setting>
<setting id="desc06">15</setting>
<setting id="desc07">2</setting>
<setting id="desc08">9</setting>
<setting id="desc09">2</setting>
<setting id="desc10">14</setting>
<setting id="desc11">6</setting>
<setting id="desc12">11</setting>
<setting id="desc13">6</setting>
<setting id="desc14">12</setting>
<setting id="desc15">6</setting>
<setting id="desc16">20</setting>
<setting id="desc17">6</setting>
<setting id="desc18">19</setting>
<setting id="desc19" default="true">0</setting>
<setting id="desc20" default="true">0</setting>
<setting id="device" default="true">-</setting>
<setting id="epgenre">2</setting>
<setting id="epicon">0</setting>
<setting id="lineup">Local Over the Air Broadcast</setting>
<setting id="lineupcode">lineupId</setting>
<setting id="passw" default="true"></setting>
<setting id="redays">0</setting>
<setting id="slist">45867,53502,72755,65995,73014,63040,74875,58688,87652,44368,54298,58927,72895</setting>
<setting id="tvhmatch">false</setting>
<setting id="tvhoff">false</setting>
<setting id="tvhport">9981</setting>
<setting id="tvhurl" default="true">127.0.0.1</setting>
<setting id="usern" default="true"></setting>
<setting id="xdesc">false</setting>
<setting id="xdetails" default="true">false</setting>
<setting id="zipcode">J3B2X8</setting>
</settings>
100 changes: 64 additions & 36 deletions zap2epg.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
################################################################################

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
Expand Down Expand Up @@ -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
Expand All @@ -104,23 +111,24 @@ 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']:
channelName = ch['name']
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):
Expand All @@ -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))

Expand All @@ -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))

Expand Down Expand Up @@ -211,7 +219,7 @@ def printHeader(fh, enc):
fh.write("<?xml version=\"1.0\" encoding=\"" + enc + "\"?>\n")
fh.write("<?xml-stylesheet href=\"xmltv.xsl\" type=\"text/xsl\"?>\n")
fh.write("<!DOCTYPE tv SYSTEM \"xmltv.dtd\">\n\n")
fh.write("<tv source-info-url=\"http://tvschedule.zap2it.com/\" source-info-name=\"zap2it.com\">\n")
fh.write("<tv source-info-url=\"http://tvschedule.gracenote.com/\" source-info-name=\"gracenote.com\">\n")

def printFooter(fh):
fh.write("</tv>\n")
Expand All @@ -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<channel id=\"' + station + '.zap2epg\">\n')
if 'chtvh' in scheduleSort[station] and scheduleSort[station]['chtvh'] is not None:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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=&timespan=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=&timespan=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:
Expand All @@ -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
Expand All @@ -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__':
Expand Down