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
2120import os
2221import re
23- import sys
2422import logging
2523import zap2epg
2624import urllib .request , urllib .error , urllib .parse
2725import json
2826from collections import OrderedDict
2927import time
3028import datetime
31- import _strptime
32- import requests
3329#import web_pdb; web_pdb.set_trace()
3430
3531userdata = xbmcvfs .translatePath (xbmcaddon .Addon ().getAddonInfo ('profile' ))
36- tvhoff = xbmcaddon .Addon ().getSetting ('tvhoff' )
32+ tvhoff = True if xbmcaddon .Addon ().getSetting ('tvhoff' ) == 'true' else False
3733if not os .path .exists (userdata ):
3834 os .mkdir (userdata )
3935log = os .path .join (userdata , 'zap2epg.log' )
4339plugin = Plugin ()
4440dialog = xbmcgui .Dialog ()
4541gridtime = (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 \n Would 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 \n Please 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.\n Please 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
8696def 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
90100def 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' )
240249def 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' )
248258def 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 ('/' )
253276def 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