From 0ad364676647c589e6cae2bfd2d11e5b85b07e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Jakub=20=C5=A0puro?= Date: Thu, 10 Jan 2019 21:36:31 +0100 Subject: [PATCH] Merged code with multi account version --- account.py | 17 +++++++ addon.xml | 2 +- exports.py | 2 +- main.py | 28 ++++++++---- resources/language/Czech/strings.po | 32 ++++++------- resources/language/English/strings.po | 30 ++++++------ resources/language/Slovak/strings.po | 30 ++++++------ resources/settings.xml | 10 ++-- service.py | 66 +++++++++++++++++++++------ skylink.py | 19 ++++---- 10 files changed, 154 insertions(+), 82 deletions(-) create mode 100644 account.py diff --git a/account.py b/account.py new file mode 100644 index 0000000..ea486af --- /dev/null +++ b/account.py @@ -0,0 +1,17 @@ +class Account: + id = '' + username = '' + password = '' + provider = '' + + def __init__(self, id, username, password, provider): + self.id = id + self.username = username + self.password = password + self.provider = provider + + def is_valid(self): + if self.username and self.password and self.provider: + return True + else: + return False diff --git a/addon.xml b/addon.xml index b139440..51ab306 100644 --- a/addon.xml +++ b/addon.xml @@ -1,5 +1,5 @@ - + diff --git a/exports.py b/exports.py index c4fee30..ca8ebf5 100644 --- a/exports.py +++ b/exports.py @@ -27,7 +27,7 @@ def create_m3u(channels, path): for c in channels: file.write(u'#EXTINF:-1 tvg-id="%s" tvg-logo="%s.png",%s\n' % ( c['stationid'], logo_id(c['title']), c['title'])) - file.write(u'plugin://plugin.video.sl/?action=play&id=%s\n' % c['id']) + file.write(u'plugin://plugin.video.sl/?action=play&account=%s&channel=%s\n' % (c['account'], c['id'])) def create_epg(channels, epg, path, addon=None): diff --git a/main.py b/main.py index 82944e8..6816e49 100644 --- a/main.py +++ b/main.py @@ -3,6 +3,7 @@ import logger import requests import skylink +import account import xbmc import xbmcaddon import xbmcgui @@ -12,9 +13,6 @@ _id = int(sys.argv[1]) _addon = xbmcaddon.Addon() _profile = xbmc.translatePath(_addon.getAddonInfo('profile')).decode("utf-8") -_user_name = xbmcplugin.getSetting(_id, 'username') -_password = xbmcplugin.getSetting(_id, 'password') -_provider = 'skylink.sk' if int(xbmcplugin.getSetting(_id, 'provider')) == 0 else 'skylink.cz' _handle = int(sys.argv[1]) @@ -25,10 +23,23 @@ def select_device(devices): items.append(device['name'].replace("+", " ")) return dialog.select(_addon.getLocalizedString(30403), items) +def get_account(id): + if id == 'sk': + return account.Account('sk', xbmcplugin.getSetting(_id, 'username_sk'), xbmcplugin.getSetting(_id, 'password_sk'), 'skylink.sk') -def play(channel_id): - logger.log.info('play: ' + channel_id) - sl = skylink.Skylink(_user_name, _password, _profile, _provider) + if id == 'cz': + return account.Account('cz', xbmcplugin.getSetting(_id, 'username_cz'), xbmcplugin.getSetting(_id, 'password_cz'), 'skylink.cz') + + return account.Account('unknown', '', '', '') + +def play(account_id, channel_id): + account = get_account(account_id) + + if not account.is_valid(): + exit(1) + + logger.log.info('Play channel %s from %s' % (channel_id, account.provider)) + sl = skylink.Skylink(account, _profile) info = {} try: @@ -53,8 +64,7 @@ def play(channel_id): playitem.setProperty('inputstream.adaptive.license_key', info['key']) xbmcplugin.setResolvedUrl(_handle, True, playitem) - if __name__ == '__main__': args = urlparse.parse_qs(sys.argv[2][1:]) - if 'id' in args: - play(str(args['id'][0])) + if 'account' in args and 'channel' in args: + play(str(args['account'][0]), str(args['channel'][0])) \ No newline at end of file diff --git a/resources/language/Czech/strings.po b/resources/language/Czech/strings.po index aedd128..07117b0 100644 --- a/resources/language/Czech/strings.po +++ b/resources/language/Czech/strings.po @@ -8,25 +8,29 @@ msgid "Account" msgstr "Účet" msgctxt "#30101" -msgid "Provider" -msgstr "Poskytovatel" +msgid "Skylink SK" +msgstr "Skylink SK" msgctxt "#30102" msgid "Email / Card number" -msgstr "Číslo karty/Emailová adresa" +msgstr "Email / číslo karty" msgctxt "#30103" msgid "Password" msgstr "Heslo" -msgctxt "#30111" -msgid "Skylink SK" -msgstr "Skylink SK" - -msgctxt "#30112" +msgctxt "#30104" msgid "Skylink CZ" msgstr "Skylink CZ" +msgctxt "#30105" +msgid "Email / Card number" +msgstr "Email / číslo karty" + +msgctxt "#30106" +msgid "Password" +msgstr "Heslo" + msgctxt "#30200" msgid "Playlist" msgstr "Playlist" @@ -43,6 +47,10 @@ msgctxt "#30203" msgid "Filename" msgstr "Název souboru" +msgctxt "#30204" +msgid "Eliminate duplicate channels" +msgstr "Odstrániť duplikátne stanice" + msgctxt "#30300" msgid "EPG" msgstr "EPG" @@ -91,14 +99,6 @@ msgctxt "#30504" msgid "EPG file can't be created" msgstr "EPG soubor nemůže být vytvořen" -msgctxt "#30505" -msgid "Too many Skylink LiveTV connections" -msgstr "Přihlášených příliš mnoho zařízení" - -msgctxt "#30506" -msgid "Internet connection error" -msgstr "Internetové spojení není dostupné" - msgctxt "#30900" msgid "Music" msgstr "Hudba" diff --git a/resources/language/English/strings.po b/resources/language/English/strings.po index 857192d..f98811f 100644 --- a/resources/language/English/strings.po +++ b/resources/language/English/strings.po @@ -8,8 +8,8 @@ msgid "Account" msgstr "Account" msgctxt "#30101" -msgid "Provider" -msgstr "Provider" +msgid "Skylink SK" +msgstr "Skylink SK" msgctxt "#30102" msgid "Email / Card number" @@ -19,14 +19,18 @@ msgctxt "#30103" msgid "Password" msgstr "Password" -msgctxt "#30111" -msgid "Skylink SK" -msgstr "Skylink SK" - -msgctxt "#30112" +msgctxt "#30104" msgid "Skylink CZ" msgstr "Skylink CZ" +msgctxt "#30105" +msgid "Email / Card number" +msgstr "Email / Card number" + +msgctxt "#30106" +msgid "Password" +msgstr "Password" + msgctxt "#30200" msgid "Playlist" msgstr "Playlist" @@ -43,6 +47,10 @@ msgctxt "#30203" msgid "Filename" msgstr "Filename" +msgctxt "#30204" +msgid "Eliminate duplicate channels" +msgstr "Eliminate duplicate channels" + msgctxt "#30300" msgid "EPG" msgstr "EPG" @@ -91,14 +99,6 @@ msgctxt "#30504" msgid "EPG file can't be created" msgstr "EPG file can't be created" -msgctxt "#30505" -msgid "Too many Skylink LiveTV connections" -msgstr "Too many active devices" - -msgctxt "#30506" -msgid "Internet connection error" -msgstr "Internet connection error" - msgctxt "#30900" msgid "Music" msgstr "Music" diff --git a/resources/language/Slovak/strings.po b/resources/language/Slovak/strings.po index fcaacf2..f72dd15 100644 --- a/resources/language/Slovak/strings.po +++ b/resources/language/Slovak/strings.po @@ -8,8 +8,8 @@ msgid "Account" msgstr "Účet" msgctxt "#30101" -msgid "Provider" -msgstr "Provider" +msgid "Skylink SK" +msgstr "Skylink SK" msgctxt "#30102" msgid "Email / Card number" @@ -19,14 +19,18 @@ msgctxt "#30103" msgid "Password" msgstr "Heslo" -msgctxt "#30111" -msgid "Skylink SK" -msgstr "Skylink SK" - -msgctxt "#30112" +msgctxt "#30104" msgid "Skylink CZ" msgstr "Skylink CZ" +msgctxt "#30105" +msgid "Email / Card number" +msgstr "Email / číslo karty" + +msgctxt "#30106" +msgid "Password" +msgstr "Heslo" + msgctxt "#30200" msgid "Playlist" msgstr "Playlist" @@ -43,6 +47,10 @@ msgctxt "#30203" msgid "Filename" msgstr "Súbor" +msgctxt "#30204" +msgid "Eliminate duplicate channels" +msgstr "Odstrániť duplikátne stanice" + msgctxt "#30300" msgid "EPG" msgstr "EPG" @@ -91,14 +99,6 @@ msgctxt "#30504" msgid "EPG file can't be created" msgstr "EPG súbor sa nepodarilo vytvoriť" -msgctxt "#30505" -msgid "Too many Skylink LiveTV connections" -msgstr "Prihlásených príliš veľa zariadení" - -msgctxt "#30506" -msgid "Internet connection error" -msgstr "Internetové spojenie nie je dostupné" - msgctxt "#30900" msgid "Music" msgstr "Hudba" diff --git a/resources/settings.xml b/resources/settings.xml index 64ae01b..6001f47 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -1,14 +1,18 @@ - - - + + + + + + + diff --git a/service.py b/service.py index 9c73e22..47e775f 100644 --- a/service.py +++ b/service.py @@ -5,19 +5,46 @@ import exports import logger import skylink +import account import xbmc import xbmcaddon import xbmcgui +import sys +reload(sys) +sys.setdefaultencoding('utf8') class SkylinkMonitor(xbmc.Monitor): _addon = xbmcaddon.Addon() _next_update = 0 + _accounts = [] def __init__(self): xbmc.Monitor.__init__(self) ts = self._addon.getSetting('next_update') self._next_update = datetime.datetime.now() if ts == '' else datetime.datetime.fromtimestamp(float(ts)) + self.update_accounts() + + def update_accounts(self): + logger.log.info('Updating accounts...') + + account_sk = account.Account('sk', self._addon.getSetting('username_sk'), self._addon.getSetting('password_sk'), 'skylink.sk') + account_cz = account.Account('cz', self._addon.getSetting('username_cz'), self._addon.getSetting('password_cz'), 'skylink.cz') + + self._accounts.append(account_sk) + self._accounts.append(account_cz) + + def make_unique_list(self, channels): + logger.log.info('Filtering channels to create unique list...') + + names_list = [] + channels_list = [] + for channel in channels: + if not channel['stationid'] in names_list: + names_list.append(channel['stationid']) + channels_list.append(channel) + + return channels_list def notify(self, text, error=False): icon = u'DefaultIconError.png' if error else '' @@ -31,6 +58,8 @@ def select_device(self, d): return dialog.select(self._addon.getLocalizedString(30403), items) def onSettingsChanged(self): + self.update_accounts() + if not self.abortRequested(): try: res = self.update(True) @@ -44,23 +73,32 @@ def shedule_next(self, seconds): self._next_update = dt def update(self, try_reconnect=False): - sl = skylink.Skylink(self._addon.getSetting('username'), self._addon.getSetting('password'), - xbmc.translatePath(self._addon.getAddonInfo('profile')), - 'skylink.sk' if int(self._addon.getSetting('provider')) == 0 else 'skylink.cz') + channels = [] - try: - channels = sl.channels() - except skylink.TooManyDevicesException as e: - if try_reconnect: - d = self.select_device(e.devices) - if d > -1: - logger.log.info('reconnecting as: ' + e.devices[d]['id']) - sl.reconnect(e.devices[d]['id']) - channels = sl.channels() + for account in self._accounts: + if not account.is_valid(): + continue + + sl = skylink.Skylink(account, xbmc.translatePath(self._addon.getAddonInfo('profile')).decode("utf-8")) + + logger.log.info('Getting channels for account: %s' % (account.username)) + + try: + channels = channels + sl.channels() + except skylink.TooManyDevicesException as e: + if try_reconnect: + d = self.select_device(e.devices) + if d > -1: + logger.log.info('reconnecting as: ' + e.devices[d]['id']) + sl.reconnect(e.devices[d]['id']) + channels = channels + sl.channels() + else: + raise else: raise - else: - raise + + if bool(self._addon.getSetting('playlist_unique')): + channels = self.make_unique_list(channels) logger.log.info('Updating playlist [%d channels]' % len(channels)) try: diff --git a/skylink.py b/skylink.py index 52f011a..c2414b2 100644 --- a/skylink.py +++ b/skylink.py @@ -35,6 +35,7 @@ def __init__(self, data): class Skylink: + _id = '' _username = '' _password = '' _data_root = '' @@ -45,13 +46,14 @@ class Skylink: _url = '' _login_url = '' - def __init__(self, username, password, data_root, provider='skylink.sk'): - self._usermane = username - self._password = password + def __init__(self, account, data_root): + self._id = account.id + self._username = account.username + self._password = account.password self._data_root = data_root - self._cookies_path = os.path.join(self._data_root, '%s.cookie' % username.lower()) - self._url = 'https://livetv.' + provider - self._login_url = 'https://login.' + provider + self._cookies_path = os.path.join(self._data_root, '%s@%s.cookie' % (self._username.lower(), account.provider)) + self._url = 'https://livetv.' + account.provider + self._login_url = 'https://login.' + account.provider def _store_cookies(self): if not os.path.exists(self._data_root): @@ -75,13 +77,13 @@ def _clear_cookies(self): def _auth(self, ubp=''): - if (self._usermane == '') or (self._password == ''): + if (self._username == '') or (self._password == ''): raise UserNotDefinedException self._session.cookies.clear() self._session.get(self._url + '/sso.aspx', headers={'User-Agent': UA}) - resp = self._session.post(self._login_url, data={'Username': self._usermane, 'Password': self._password}, + resp = self._session.post(self._login_url, data={'Username': self._username, 'Password': self._password}, headers={'User-Agent': UA, 'Referer': self._url}) r, self._u, self._q, error = self._parse_cookies() @@ -168,6 +170,7 @@ def channels(self): is_live = (len(data[3][0]) > (idx >> 5)) and (data[3][0][idx >> 5] & (1 << (idx & 31)) > 0) if is_stream and is_live: + c['account'] = self._id result.append(c) idx += 1