Skip to content

Commit 5f167c2

Browse files
authored
Merge pull request #59 from wbeard52/Kodi-Matrix-20
Kodi matrix 20
2 parents a3f6387 + e1e3939 commit 5f167c2

File tree

8 files changed

+671
-270
lines changed

8 files changed

+671
-270
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,17 @@ Setup:
1212
5. Setup the zap2epg grabber in tvheadend
1313
6. Enjoy your new EPG!
1414

15+
Language identification is accomplished through a python module 'LandId'. This module does not have to be installed inside the Kodi interpreter but must be installed in on the device machine.
16+
For debian based machines
17+
1. sudo apt-get update
18+
2. sudo apt-get install pip (if not already installed)
19+
3. sudo apt-get install python3-numpy
20+
4. pip install langid
21+
22+
If you try to install langid befoure installying numpy, you may get an error as the langid tries to install it but cannot find the required files.
23+
24+
The setting "Use Hex values for genre type instead of textual name" will use the hex values from http://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.11.01_60/en_300468v011101p.pdf
25+
Both Kodi and TVH use those categories as their genre groups. Kodi understands and stores the genre information as a hex value. As of now, I can't figure out how to get TVH to recognize the genre hex values.
26+
27+
1528
* Note that zap2epg is a proof of concept and is for personal experimentation only. It is not meant to be used in a commercial product and its use is your own responsibiility.

addon.xml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<addon id="script.module.zap2epg" name="zap2epg" version="1.3.1" provider-name="edit4ever">
2+
<addon id="script.module.zap2epg" name="zap2epg" version="2.1.0" provider-name="edit4ever">
33
<requires>
4-
<import addon="xbmc.python" version="2.7.13"/>
4+
<import addon="xbmc.python" version="3.0.0"/>
55
<import addon="script.module.dateutil" version="2.4.2"/>
66
<import addon="script.module.xbmcswift2" version="2.4.0"/>
77
<import addon="script.module.requests" version="2.9.1" />
8+
<!--import addon="script.module.web-pdb"/-->
89
</requires>
910
<extension point="xbmc.python.pluginsource" library="default.py">
1011
<provides>executable</provides>
@@ -29,7 +30,11 @@ Setup:
2930
<email></email>
3031
<source></source>
3132
<news>
32-
v1.3.1 - remove doctype error for TVH on OSMC
33+
v2.0.4 - Update for Kodi 20+. Updated EPG Genre linking and language detection.
34+
v2.0.3 - fix channel configuration error (2021-05-23)
35+
v2.0.2 - fix Tvheadend username and password option (2021-03-29)
36+
v2.0.1 - Kodi 19 dialog fix (2021-02-25)
37+
v2.0.0 - Python 3 update (2020-10-27)
3338
v1.3.0 - fix server issues for lineups (2019-04-12)
3439
v1.2.0 - add option to refresh download cache days (2019-03-04)
3540
v1.1.0 - added ability to refresh TBA episodes (2018-11-20)

bin/tv_grab_zap2epg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ do case "$1" in
3838
;;
3939

4040
-v | --version )
41-
printf "1.3.x\n"
41+
printf "2.0.x\n"
4242
;;
4343

4444
-c | --capabilities )

default.py

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,25 @@
1717
import subprocess
1818
from subprocess import Popen
1919
from xbmcswift2 import Plugin
20-
import StringIO
20+
import io
2121
import os
2222
import re
2323
import sys
2424
import logging
2525
import zap2epg
26-
import urllib2
26+
import urllib.request, urllib.error, urllib.parse
2727
import json
2828
from collections import OrderedDict
2929
import time
3030
import datetime
3131
import _strptime
3232
import requests
33+
#import web_pdb; web_pdb.set_trace()
3334

34-
userdata = xbmc.translatePath(xbmcaddon.Addon().getAddonInfo('profile'))
35+
userdata = xbmcvfs.translatePath(xbmcaddon.Addon().getAddonInfo('profile'))
3536
tvhoff = xbmcaddon.Addon().getSetting('tvhoff')
3637
if not os.path.exists(userdata):
37-
os.mkdir(userdata)
38+
os.mkdir(userdata)
3839
log = os.path.join(userdata, 'zap2epg.log')
3940
Clist = os.path.join(userdata, 'channels.json')
4041
tvhList = os.path.join(userdata, 'TVHchannels.json')
@@ -78,9 +79,9 @@
7879
check_load = requests.get(check_url)
7980
check_status = check_load.raise_for_status()
8081
except requests.exceptions.HTTPError as err:
81-
dialog.ok("Tvheadend Access Error!", str(err), "", "Please check your username/password in settings.")
82+
dialog.ok("Tvheadend Access Error!",f"{err}\n\nPlease check your username/password in settings.")
8283
except requests.exceptions.RequestException as e:
83-
dialog.ok("Tvheadend Access Error!", "Could not connect to Tvheadend server.", "Please check your Tvheadend server is running or check the IP and port configuration in the settings.")
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.")
8485

8586
def get_icon_path(icon_name):
8687
addon_path = xbmcaddon.Addon().getAddonInfo("path")
@@ -90,16 +91,16 @@ def create_cList():
9091
tvhClist = []
9192
if tvhoff == 'true':
9293
if not os.path.isfile(tvhList):
93-
channels_url = 'http://' + tvh_url + ':' + tvh_port + '/api/channel/grid?all=1&limit=999999999&sort=name'
94-
response = requests.get(channels_url)
95-
try:
96-
logging.info('Accessing Tvheadend channel list from: %s', channels_url)
97-
channels = response.json()
98-
with open(tvhList,"w") as f:
99-
json.dump(channels,f)
100-
except urllib2.HTTPError as e:
101-
logging.exception('Exception: tvhClist - %s', e.strerror)
102-
pass
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
103104
with open(tvhList) as tvhData:
104105
tvhDict = json.load(tvhData)
105106
for ch in tvhDict['entries']:
@@ -108,7 +109,7 @@ def create_cList():
108109
tvhClist.append(ch['number'])
109110
lineupcode = xbmcaddon.Addon().getSetting('lineupcode')
110111
url = 'http://tvlistings.zap2it.com/api/grid?lineupId=&timespan=3&headendId=' + lineupcode + '&country=' + country + '&device=' + device + '&postalCode=' + zipcode + '&time=' + str(gridtime) + '&pref=-&userId=-'
111-
content = urllib2.urlopen(url).read()
112+
content = urllib.request.urlopen(url).read()
112113
contentDict = json.loads(content)
113114
stationDict = {}
114115
if 'channels' in contentDict:
@@ -121,25 +122,25 @@ def create_cList():
121122
stationDict[skey]['include'] = 'True'
122123
else:
123124
stationDict[skey]['include'] = 'False'
124-
stationDictSort = OrderedDict(sorted(stationDict.iteritems(), key=lambda i: (float(i[1]['num']))))
125+
stationDictSort = OrderedDict(sorted(iter(stationDict.items()), key=lambda i: (float(i[1]['num']))))
125126
with open(Clist,"w") as f:
126127
json.dump(stationDictSort,f)
127128

128129
@plugin.route('/channels')
129130
def channels():
130131
lineupcode = xbmcaddon.Addon().getSetting('lineupcode')
131132
if lineup is None or zipcode is None:
132-
dialog.ok('Location not configured!', '', 'Please setup your location before configuring channels.')
133+
dialog.ok('Location not configured!', 'Please setup your location before configuring channels.')
133134
if not os.path.isfile(Clist):
134135
create_cList()
135136
else:
136-
newList = dialog.yesno('Existing Channel List Found', 'Would you like to download a new channel list or review your current list?', '', 'Select Yes to download new list.')
137+
newList = dialog.yesno('Existing Channel List Found', 'Would you like to download a new channel list or review your current list?', 'Review', 'Download')
137138
if newList:
138139
os.remove(Clist)
139140
create_cList()
140141
with open(Clist) as data:
141142
stationDict = json.load(data)
142-
stationDict = OrderedDict(sorted(stationDict.iteritems(), key=lambda i: (float(i[1]['num']))))
143+
stationDict = OrderedDict(sorted(iter(stationDict.items()), key=lambda i: (float(i[1]['num']))))
143144
stationCode = []
144145
stationListName = []
145146
stationListNum = []
@@ -150,13 +151,13 @@ def channels():
150151
stationListNum.append(stationDict[station]['num'])
151152
stationListInclude.append(stationDict[station]['include'])
152153
stationPre = [i for i, x in enumerate(stationListInclude) if x == 'True']
153-
stationListFull = zip(stationListNum, stationListName)
154+
stationListFull = list(zip(stationListNum, stationListName))
154155
stationList = ["%s %s" % x for x in stationListFull]
155156
selCh = dialog.multiselect('Click to Select Channels to Include', stationList, preselect=stationPre)
156157
for station in stationDict:
157158
stationDict[station]['include'] = 'False'
158159
stationListCodes = []
159-
if selCh >= 0:
160+
if selCh:
160161
for channel in selCh:
161162
skey = stationCode[channel]
162163
stationDict[skey]['include'] = 'True'
@@ -174,7 +175,8 @@ def location():
174175
zipcodeNew = dialog.input('Enter your zipcode', defaultt=zipcode, type=xbmcgui.INPUT_NUMERIC)
175176
if countryNew == 1:
176177
zipcodeNew = dialog.input('Enter your zipcode', defaultt=zipcode, type=xbmcgui.INPUT_ALPHANUM)
177-
if not zipcodeNew:
178+
#import web_pdb; web_pdb.set_trace()
179+
if not 'zipcodeNew' in vars() or 'zipcodeNew' in globals():
178180
return
179181
zipcodeNew = re.sub(' ', '', zipcodeNew)
180182
zipcodeNew = zipcodeNew.upper()
@@ -191,7 +193,7 @@ def location():
191193
lineupsN = ['AVAILABLE LINEUPS', 'TIMEZONE - Eastern', 'TIMEZONE - Central', 'TIMEZONE - Mountain', 'TIMEZONE - Pacific']
192194
lineupsC = ['NONE', 'DFLTEC', 'DFLTCC', 'DFLTMC', 'DFLTPC']
193195
deviceX = ['-', '-', '-', '-', '-']
194-
content = urllib2.urlopen(url).read()
196+
content = urllib.request.urlopen(url).read()
195197
lineupDict = json.loads(content)
196198
if 'Providers' in lineupDict:
197199
for provider in lineupDict['Providers']:
@@ -238,7 +240,7 @@ def location():
238240
def run():
239241
logging.basicConfig(filename=log, filemode='w', format='%(asctime)s %(message)s', datefmt='%Y/%m/%d %H:%M:%S', level=logging.DEBUG)
240242
status = zap2epg.mainRun(userdata)
241-
dialog.ok('zap2epg Finished!', 'zap2epg completed in ' + str(status[0]) + ' seconds.', '', str(status[1]) + ' Stations and ' + str(status[2]) + ' Episodes written to xmltv.xml file.')
243+
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.')
242244

243245

244246

@@ -253,25 +255,25 @@ def index():
253255
items.append(
254256
{
255257
'label': 'Run zap2epg and Update Guide Data',
256-
'path': plugin.url_for(u'run'),
258+
'path': plugin.url_for('run'),
257259
'thumbnail':get_icon_path('run'),
258260
})
259261
items.append(
260262
{
261263
'label': 'Change Current Location | Zipcode: ' + zipcode + ' & Lineup: ' + lineup,
262-
'path': plugin.url_for(u'location'),
264+
'path': plugin.url_for('location'),
263265
'thumbnail':get_icon_path('antenna'),
264266
})
265267
items.append(
266268
{
267269
'label': 'Configure Channel List',
268-
'path': plugin.url_for(u'channels'),
270+
'path': plugin.url_for('channels'),
269271
'thumbnail':get_icon_path('channel'),
270272
})
271273
items.append(
272274
{
273275
'label': 'Configure Settings and Options',
274-
'path': plugin.url_for(u'open_settings'),
276+
'path': plugin.url_for('open_settings'),
275277
'thumbnail':get_icon_path('settings'),
276278
})
277279
return items
@@ -287,7 +289,7 @@ def index():
287289
lineup = xbmcaddon.Addon().getSetting('lineup')
288290
device = xbmcaddon.Addon().getSetting('device')
289291
if zipcode == '' or lineup == '':
290-
zipConfig = dialog.yesno('No Lineup Configured!', 'You need to configure your lineup location before running zap2epg.', '', 'Would you like to setup your lineup?')
292+
zipConfig = dialog.yesno('No Lineup Configured!', 'You need to configure your lineup location before running zap2epg.\n\nWould you like to setup your lineup?')
291293
if zipConfig:
292294
location()
293295
xbmc.executebuiltin('Container.Refresh')

resources/language/resource.language.en_gb/strings.po

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ msgctxt "#32006"
3030
msgid "Device"
3131
msgstr ""
3232

33-
# 32007-32010 blank
33+
# 32007-32009 blank
34+
35+
msgctxt "#32010"
36+
msgid "Data Handling"
37+
msgstr ""
3438

3539
msgctxt "#32011"
3640
msgid "Options"
@@ -52,7 +56,20 @@ msgctxt "#32015"
5256
msgid "Number of Days to Delete Cache (re-download)"
5357
msgstr ""
5458

55-
# 32016-32019 blank
59+
msgctxt "#32016"
60+
msgid "Remove unsafe Windows® characters from Show Titles"
61+
msgstr ""
62+
63+
msgctxt "#32017"
64+
msgid "Remove unsafe Windows® characters from Episode Titles"
65+
msgstr ""
66+
67+
msgctxt "#32018"
68+
msgid "Replace unsafe characters with: "
69+
msgstr ""
70+
71+
msgctxt "#32019"
72+
msgid "Default language:"
5673

5774
msgctxt "#32020"
5875
msgid "Include Episode Thumbnail"
@@ -70,7 +87,28 @@ msgctxt "#32023"
7087
msgid "Episode Image"
7188
msgstr ""
7289

73-
# 32024-32029 blank
90+
msgctxt "#32024"
91+
msgid "Use Language Identification (requires langid module)"
92+
msgstr ""
93+
94+
msgctxt "#32025"
95+
msgid "English"
96+
msgstr ""
97+
98+
msgctxt "#32026"
99+
msgid "Spanish"
100+
msgstr ""
101+
102+
msgctxt "#32027"
103+
msgid "French"
104+
msgstr ""
105+
106+
107+
# 32028 blank
108+
109+
msgctxt "#32029"
110+
msgid "Use hex values for genre type instead of textual name"
111+
msgstr ""
74112

75113
msgctxt "#32030"
76114
msgid "Include Episode Genres (colored EPG grid)"
@@ -222,7 +260,15 @@ msgctxt "#32229"
222260
msgid "20"
223261
msgstr ""
224262

225-
# 32230-32299 blank
263+
msgctxt "#32230"
264+
msgid "21"
265+
msgstr ""
266+
267+
msgctxt "#32231"
268+
msgid "22"
269+
msgstr ""
270+
271+
# 32232-32299 blank
226272

227273
msgctxt "#32300"
228274
msgid "None"
@@ -284,6 +330,14 @@ msgctxt "#32314"
284330
msgid "Movie Release Year"
285331
msgstr ""
286332

333+
msgctxt "#32315"
334+
msgid "Genres"
335+
msgstr ""
336+
337+
msgctxt "#32316"
338+
msgid "Determined Language"
339+
msgstr ""
340+
287341
msgctxt "#32320"
288342
msgid "LINE BREAK"
289343
msgstr ""

0 commit comments

Comments
 (0)