def call_url(self): try: if self.payload is not None: debug('POST DATA: {}'.format(self.payload)) self.response = Sc.post(self.url, data=self.payload) else: self.response = Sc.get(self.url) except: debug('CALL URL ERR: {}'.format(traceback.format_exc())) self.response = {}
def search(self): input = self.args.get('name', [''])[0] cont = get_info_label('Container.PluginName') debug('autocomplet input: {} / {}'.format(cont, input)) if input == '': xbmcplugin.endOfDirectory(args.handle) return filter = self.args.get('f', [])[0] data = Sc.post('/FSug', data={'q': input, 'f': filter}) debug('data: {}'.format(data)) items = [] for (count, result) in enumerate(data): debug('{} / {}'.format(count, result)) listitem = xbmcgui.ListItem(result) param = { SC.ITEM_ACTION: 'autocomplet', SC.ITEM_ID: 'type', SC.ITEM_TITLE: result } url = create_plugin_url(param) listitem.setPath(url) listitem.setProperty('path', url) listitem.setProperty("index", str(count)) listitem.setProperty("isPlayable", "false") items.append(listitem) xbmcplugin.addDirectoryItems(handle=args.handle, items=[(i.getProperty("path"), i, False) for i in items], totalItems=len(items)) xbmcplugin.endOfDirectory(args.handle)
def speedtest(self, isp, ident='15VFNFJrCKHn'): kr = Kraska() url = kr.resolve(ident) smin = 999999999 smax = 0 durmin = 999999999 hosts = ['b01', 's01', 'v01'] for h in hosts: u = re.sub(r':\/\/([^.]+)', '://{}'.format(h), url) debug('speedtest URL {}'.format(u)) s, dur = self.calculate_speed(u) debug('speedtest host {} speed: {}'.format(h, convert_bitrate(s))) smin = min(s, smin) smax = max(s, smax) durmin = min(dur, durmin) isp.update({h: s}) debug('min/max {}/{}'.format(convert_bitrate(smin), convert_bitrate(smax))) debug('res: {}'.format(isp)) try: st = Sc.post('/Stats/speedtest', json=isp) debug('Speed stats: {}'.format(st)) except: pass speed = smin settings.set_setting('stream.adv.speedtest', speed) settings.set_setting('stream.adv.speedtest.asn', isp.get('a', 'N/A')) settings.set_setting('stream.adv.speedtest.last', int(time.time())) return (smin, smax, durmin)
def isp_call(url, ref): from resources.lib.api.sc import Sc ip = Sc.get('/IP') from resources.lib.system import Http url = url.format(ip) r = Http.get(url, headers={'referer': ref}) return r.json()
def run(self): path = get_setting('androidtv.path') cur = int(time()) if path and self.last_run + 3600 < cur: self.last_run = time() items = self.list.get() for i in items: path_name = make_legal_filename('{}/{}/'.format( path, i.get(SC.ITEM_ID))) debug('android: {} {}'.format(i, path_name)) mkdir(path_name) files = xbmcvfs.listdir(path_name) debug('files {}'.format(files)) for f in files: if len(f): debug('file: {}'.format(f)) xbmcvfs.delete(f[0]) res = Sc.get(i.get('url')) menu = res.get('menu', {}) if len(menu): debug('Mame menu polozky') for pos, s in enumerate(menu): if pos < 30: url = create_plugin_url({ SC.ITEM_ID: '{}'.format(s.get('id', 0)), SC.ITEM_URL: s.get('url', '') }) base_name = '{}{:04d}'.format(path_name, pos) fn = make_legal_filename( '{}.strm'.format(base_name)) # debug('{} -> {} {} {}'.format(pos, fn, url, s.get(SC.ITEM_UIDS))) fs = xbmcvfs.File(fn, 'w') fs.write('{}'.format(url)) fs.close() nfo = SCNFO(s) # debug('NFO: {}'.format(encode(nfo.xml()))) fs = xbmcvfs.File( make_legal_filename( '{}.nfo'.format(base_name)), 'w') fs.write('{}'.format(encode(nfo.xml()))) fs.close() playlist_base = make_legal_filename( 'special://profile/playlists/video/') xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>' \ '<smartplaylist type="movies">' \ ' <name>{}</name>' \ ' <match>all</match>' \ ' <rule field="path" operator="contains"><value>{}</value></rule>' \ '</smartplaylist>' xbmcvfs.mkdirs(playlist_base) filename = make_legal_filename('{}{}.xsp'.format( playlist_base, i.get(SC.ITEM_ID))) fs = xbmcvfs.File(filename, 'w') fs.write(xml.format(i.get(SC.ITEM_ID), path_name)) fs.close() self.cleanup_library_path(path) exec_build_in('UpdateLibrary(video,{})'.format(path))
def trakt2sc(self, items, typ): debug('items {}'.format(len(items))) res = Sc.post('/Ftrakt2sc', data={ 'trakt': dumps(list(items.keys())), 't': typ }) debug('res: {}'.format(len(res))) return res, items
def set_item(self, item=None): self.up_next = False # self.item = item if not self.win.getProperty('SC.play_item'): return item_data = loads(self.win.getProperty('SC.play_item')) self.win.clearProperty('SC.play_item') self.item = item_data.get('info') debug('ITEM: {}'.format(self.item.get('info', {}).get('unique_ids'))) linfo = item_data.get('strms').get('linfo') ids = self.win.getProperty('{}.ids'.format(ADDON_ID)) self.win.clearProperty('{}.ids'.format(ADDON_ID)) self.ids = loads(ids) if ids else {} self.my_id = self.ids.get('sc') if self.ids.get('sc') else None debug('my ids: {}'.format(self.ids)) if self.my_id is not None: self.win.setProperty('{}.play'.format(ADDON_ID), '1') debug('je to moj plugin') self.is_my_plugin = True series = self.item['info'].get('season') episode = self.item['info'].get('episode') self.movie = SCKODIItem(self.my_id, series=series, episode=episode, trakt=self.ids.get('trakt')) self.movie.scrobble(self.percent_played(), SCKODIItem.SCROBBLE_START) audio = self.getAvailableAudioStreams() if len(audio) == 1: debug('Nemame na vyber, mame len jednu audio stopu') return if linfo: audio = linfo debug('AvailableAudioStreams {}'.format(len(audio))) lang1 = settings.get_setting('stream.lang1').lower() lang2 = settings.get_setting('stream.lang2').lower() if Sc.parental_control_is_active(): lang1 = settings.get_setting('parental.control.lang1').lower() lang2 = settings.get_setting('parental.control.lang2').lower() plf = Storage(SC.ITEM_PREFERRED_LANG) plf.load(True) debug('PREF LANGS: {} / {}'.format(self.my_id, plf.data)) force_lang = plf.get(self.my_id) force = False if force_lang is not None: lang = force_lang.lower() debug('mame force lang {}'.format(force_lang)) force = self.try_audio(lang, audio) if force is False and self.try_audio(lang1, audio) is False: self.try_audio(lang2, audio)
def system_after(self): data = self.response.get(SC.ITEM_SYSTEM, {}) if 'setContent' in data: # and settings.get_setting_bool('gui.views.enabled'): xbmcplugin.setContent(params.handle, data['setContent']) # view_mode = data["setContent"].lower() # view_code = settings.get_setting_int('gui.views.{0}'.format(view_mode)) # if view_code > 0: # xbmc.executebuiltin("Container.SetViewMode(%d)" % view_code) if 'SetSortMethod' in data: #method = SORT_METHODS[int(data.get('SetSortMethod'))] #xbmc.executebuiltin('Container.SetSortMethod(%d)' % method) pass if SC.ITEM_FOCUS in data: try: control = cur_win.getControl(cur_win.getFocusId()) control.selectItem(int(data[SC.ITEM_FOCUS])) except: pass check_last_key = '{}.last_series'.format(ADDON_ID) if 'checkLast' in data and get_setting_as_bool( 'stream.autoplay.episode'): check_last = data['checkLast'] stop = home_win.getProperty('{}.stop'.format(ADDON_ID)) debug('Mame check last data: {} / {}'.format(stop, check_last)) item_id = int(check_last.get('id', 0)) ki = SCKODIItem(int(item_id)) last_ep = ki.get_last_ep() if item_id > 0 and last_ep: win_last_series = home_win.getProperty(check_last_key) home_win.setProperty(check_last_key, str(item_id)) debug('last {} cur {}'.format(win_last_series, item_id)) if win_last_series == '' or win_last_series != str(item_id): debug('last ep: {}'.format(last_ep)) try: data = Sc.up_next(item_id, last_ep[0], last_ep[1]) d = SCUpNext(data) debug('NEXT EP: {}'.format(d.get().get('play_info'))) cmd = 'PlayMedia({})'.format( create_plugin_url(d.get().get('play_info'))) if stop is None or stop == '': debug('play: {}'.format(cmd)) exec_build_in(cmd) except: debug('chyba: {}'.format(traceback.format_exc())) pass else: home_win.clearProperty(check_last_key) # upraceme po sebe home_win.clearProperty('{}.stop'.format(ADDON_ID))
def send_up_next(self): try: series = self.item['info'].get('season') episode = self.item['info'].get('episode') url = '/upNext/{}/{}/{}'.format(self.my_id, series, episode) debug('upnext call {}'.format(url)) data = Sc.get(url) if 'info' in data: debug('Mame next item: {}'.format(data)) d = SCUpNext(data) # sleep(3 * 1000) upnext_signal(ADDON_ID, d.get()) except: debug('send_up_next ERR {}'.format(traceback.format_exc()))
def update_items(self): query = 'select item_key, item_value from storage where item_key like ? and item_value like ?' search = '{}-%'.format(SCKODIItem.ITEM_NAME) # debug('search: {}'.format(search)) res = self.list._db.execute(query, search, '%"last_ep"%').fetchall() total = len(res) skip_list = self.get() debug('NEXTEP: {} z {} ({})'.format(len(skip_list), total, total - len(skip_list))) dialog = dprogressgb() dialog.create('Next Ep in progress') pos = 0 for i in res: if monitor.abortRequested() or player.isPlayback(): dialog.close() return False pos += 1 _, item_id = i[0].split('-') if item_id in skip_list: debug('ITEM {} uz ma nextep, nepotrebujeme update'.format(item_id)) continue item = SCKODIItem(item_id) last_ep = item.get_last_ep() debug('Next Ep in progress: {}%'.format(int(pos / total * 100))) dialog.update(int(pos / total * 100), message='{} - {}x{}'.format(item_id, last_ep[0], last_ep[1])) try: debug('last {}x{}'.format(last_ep[0], last_ep[1])) info = Sc.up_next(item_id, last_ep[0], last_ep[1]) if 'error' in info or ('info' in info and info.get('info') is None): debug('nemame data k next EP') continue new = { 's': last_ep[0], 'e': last_ep[1], 't': int(time()), } cur = self.list.get(item_id) if cur is None or (cur and str(cur.get('e')) != str(new.get('e'))): debug('nextep update {} -> {}'.format(item_id, last_ep)) self.list[item_id] = new else: debug('nezmenene {} -> {}'.format(item_id, last_ep)) except: debug('mazem serial zo zoznamu {}'.format(item_id)) del(self.list[item_id]) pass dialog.close() debug('LIST NEXT EP: {}'.format(self.list._data)) return True
def sync_playback_movies(self, last=0): last_at = TraktAPI.utc2timestamp(last) playback = self.get_playback_movies({}) debug('paused at {}'.format(len(playback))) sync = {} tr = [] for m in playback: paused_at = TraktAPI.utc2timestamp(m['paused_at']) if paused_at is None or last_at is None or paused_at >= last_at: sync.update({m['movie']['ids']['trakt']: m}) tr.append(m['movie']['ids']['trakt']) if len(sync): res = Sc.post('/Ftrakt2sc', data={'trakt': dumps(tr), 't': 1}) debug('sync {} / {} {}'.format(len(sync), len(res), res)) max = len(res) dialog = dprogressgb() dialog.create('sync_playback_movies Trakt.Movies') for pos, scid in enumerate(res): if self.monitor.abortRequested(): return debug('trakt {}%'.format(int(pos / max * 100))) dialog.update(int(pos / max * 100)) itm = res.get(scid) item = SCKODIItem(scid, trakt=itm['trakt']) tr = sync.get(int(itm['trakt'])) progress = float(sync.get(int(itm['trakt']))['progress']) try: watched = int( float(itm['duration']) * float(progress / 100)) except: watched = 0 debug('itm {} {} {} {} {} {}'.format(scid, itm, itm['duration'], watched, progress, tr)) item.set_watched(watched) d = datetime.fromtimestamp( self.utc2timestamp(tr.get('paused_at'))) item.set_last_played(d.strftime('%Y-%m-%d %H:%M:%S')) dialog.close() pass
def set_last_ep(self, s, e, last_time=None): self[self.LAST_EP_KEY] = '{}x{}'.format(s, e) ne = Storage('nextep') try: info = Sc.up_next(self.name, s, e) if 'error' in info or ('info' in info and info.get('info') is None): debug('nemame data k next EP') del (ne[self.name]) return new = { 's': s, 'e': e, 't': int(time()) if last_time is None else last_time, } ne[self.name] = new except: import traceback debug('ERR: {}'.format(traceback.format_exc())) del (ne[self.name]) debug('nastavujem LAST_EP na: {} pre {}'.format( self[self.LAST_EP_KEY], self.name))
def action(self): action = self.args.get(SC.ITEM_ACTION) if action == SC.ACTION_PLAY_URL: self.play_url(self.args.get(SC.ITEM_URL)) self.succeeded = True elif action == SC.ACTION_CMD: self.action_cmd() elif action == 'intro': intro(2, True) elif action == SC.ACTION_PIN: self.action_pin() elif action == SC.ACTION_CSEARCH: self.action_csearch() elif action == SC.ACTION_LAST: self.action_last() elif action == 'nextep': self.action_next_ep() elif action == 'update_nextep': self.action_update_next_ep() return True elif action == 'search_next_episodes': self.action_search_next_episodes() elif action == SC.ACTION_DEBUG: from resources.lib.kodiutils import check_set_debug check_set_debug(True) elif action == SC.ACTION_DOWNLOAD: self.url = self.args.get(SC.ITEM_DOWNLOAD) self.call_url_and_response() elif action == SC.ACTION_BUFFER: set_kodi_cache_size() elif action == SC.ACTION_ANDROID: self.action_android() elif action == SC.ACTION_ADD2HP: self.action_add2hp() elif action == SC.ACTION_DEL2HP: self.action_add2hp(True) elif action == SC.ACTION_ADD_CUSTOM_FILTER: self.action_add_custom_filter() elif action == SC.ACTION_DEL_CUSTOM_FILTER: self.action_add_custom_filter(True) elif action == SC.ACTION_REMOVE_FROM_LIST: self.action_remove_from_list() elif action == SC.ACTION_UPDATE_ADDON: update_addon() elif 'trakt.' in action: from resources.lib.trakt.Trakt import trakt trakt.action(action, self) return True elif action in ['add_to_library', 'add_to_library_sub']: lib = List(SC.ITEM_LIBRARY) lib.add(self.args.get(SC.ITEM_ID)) if action == 'add_to_library_sub': sub = List(SC.ITEM_LIBRARY_SUB) sub.add(self.args.get(SC.ITEM_ID)) container_refresh() elif action == 'remove_from_sub': lib = List(SC.ITEM_LIBRARY) lib.add(self.args.get(SC.ITEM_ID), True) if action == 'remove_from_sub': sub = List(SC.ITEM_LIBRARY_SUB) sub.add(self.args.get(SC.ITEM_ID), True) container_refresh() elif action == 'autocomplet': from resources.lib.services.autocomplete import Autocomplete Autocomplete(self.args) return True elif action == SC.ACTION_DEL_PREFERRED_LANGUAGE: del preferred_lang_list[self.args.get(SC.ITEM_ID)] container_refresh() return elif action == SC.ACTION_SET_PREFERRED_LANGUAGE: lang_list = Sc.get('/Lang/{}'.format(self.args.get(SC.ITEM_ID))) debug('parametre: {} / langs: {}'.format(self.args, lang_list)) ret = dselect(lang_list, Strings.txt(Strings.CONTEXT_ADD_PREF_LANG)) if ret > -1: st = preferred_lang_list st[self.args.get(SC.ITEM_ID)] = lang_list[ret] debug('znovelene: {} / {}'.format( ret, st[self.args.get(SC.ITEM_ID)])) container_refresh() return else: info('Neznama akcia: {}'.format(action)) return False
def resolve(self): data = self.data del (data[SC.ITEM_URL]) self.streams = self.input.get(SC.ITEM_STRMS) self.filter() items = [] matrix = [] for s in self.streams: debug('ideme vytvorit listItems zo streamov') s.update(data) itm = SCStreamSelect(s) x = itm.get() title_items = [ '[B]{}[/B] - '.format(s.get(SC.ITEM_LANG)), '[B]{}[/B] '.format(s.get(SC.ITEM_QUALITY)), '{} '.format(s.get(SC.ITEM_SIZE)), '{}{}'.format(s.get(SC.ITEM_VIDEO_INFO), s.get(SC.ITEM_AUDIO_INFO)), ] matrix.append(title_items) items.append(x[1]) # matrix = make_table(matrix) # info('matrix: {}'.format(matrix)) for i, itm in enumerate(items): itm.setProperty('old_title', itm.getLabel()) itm.setLabel(' '.join(matrix[i])) if len( items ) > 1 or SC.ACTION_SELECT_STREAM in self.params or SC.ACTION_DOWNLOAD in self.params: pos = dselect(items, heading=items[0].getProperty('old_title'), use_details=True) # info('post: {} | {}'.format(pos, json.dumps(self.data))) if pos is False or pos == -1: raise BaseException res = items[pos] self.selected = self.streams[pos] elif len(items) == 1: res = items[0] self.selected = self.streams[ 0] if self.selected is None else self.selected else: raise BaseException url = res.getPath() # info('vybrany stream: {} / {}'.format(res.getPath(), self.selected)) if res.getProperty(SC.ITEM_PROVIDER) == SC.PROVIDER: resp = Sc.get(res.getPath()) kr = Kraska() try: ident = resp.get(SC.ITEM_IDENT) debug('ideme resolvovat ident {} na kra.sk'.format(ident)) url = kr.resolve(ident) except ResolveException as e: dok(Strings.txt(Strings.RESOLVE_ERROR_H1), Strings.txt(Strings.RESOLVE_ERROR_L1)) raise BaseException except: raise BaseException if res.getProperty(SC.ITEM_SUBS): debug('subor ma titulky, tak ich natahujem') part = res.getProperty(SC.ITEM_SUBS).split('/file/') self.item.setSubtitles([kr.resolve(part[1])]) else: info('nemame titulky') info('resolve: {}'.format(url)) if 'lid' in data: lid = 'p-{}'.format( data.get('lid')) if parental_history() else data.get('lid') st = List(lid, max_items=20) st.add(res.getProperty(SC.ITEM_ID)) self.item.setPath(url) self.item.setLabel(res.getProperty('original_title')) # home_win.setProperty('SC-lite-item', '{}'.format(res.getProperty(SC.ITEM_ID))) if 'unique_ids' in self.input.get(SC.ITEM_INFO): unique_ids = self.input.get(SC.ITEM_INFO).get('unique_ids') home_win.setProperty('script.trakt.ids', '{}'.format(dumps(unique_ids))) home_win.setProperty('{}.ids'.format(ADDON_ID), '{}'.format(dumps(unique_ids)))
def filter(self): speedtest_last = get_setting_as_int('stream.adv.speedtest.last') now = time.time() force = True if speedtest_last is None or ( speedtest_last + (24 * 3600 * 2)) < now else False isp = self.isp() asn = settings.get_setting('stream.adv.speedtest.asn') asn_changed = str(isp.get('a')) != str(asn) wrong_speed = settings.get_setting_as_int('stream.adv.speedtest') < 1 debug('Force: {} ASN: {} / {} [{}] / SPEED: {} [{}]'.format( force, asn, isp.get('a'), asn_changed, settings.get_setting_as_int('stream.adv.speedtest'), wrong_speed)) if force is True or (get_setting_as_int('stream.max.bitrate') == 100 and (asn_changed or wrong_speed)): smin, smax, dur = self.speedtest(isp) debug('smin {} / smax {} / dur {}'.format(smin, smax, dur)) # @todo autoselect / filtrovanie nechcenych streamov if not get_setting_as_bool('stream.autoselect') \ or SC.ACTION_SELECT_STREAM in self.params or SC.ACTION_DOWNLOAD in self.params: debug( 'nieje autoselect, alebo je vynuteny vyber streamu alebo download' ) return if get_setting_as_bool('stream.autoselect'): lang1 = get_setting('stream.lang1').lower() lang2 = get_setting('stream.lang2').lower() if Sc.parental_control_is_active(): lang1 = get_setting('parental.control.lang1').lower() lang2 = get_setting('parental.control.lang2').lower() score = {pos: 0 for pos, s in enumerate(self.streams)} for pos, s in enumerate(self.streams): debug( '-----------------------------------------------------------------------------------------------' ) debug('stream: bitrate: {} quality: {} lang: {}'.format( s.get('bitrate', 0), s.get('quality', 'N/A'), s.get('linfo', 'N/A'))) self.video_score(score, pos, s) stream_info = s.get('stream_info', {}) linfo = s.get('linfo', []) if lang1 in linfo: score = self.audio_score(lang1, pos, score, stream_info, 3) elif lang2 in linfo: score = self.audio_score(lang2, pos, score, stream_info, 1) else: debug('Nemame primarny, ani sekundarny jazyk') debug( '-----------------------------------------------------------------------------------------------' ) debug('final score: {}'.format(score[pos])) score = { k: v for k, v in sorted( score.items(), key=lambda item: item[1], reverse=True) } sel = list(score.keys())[0] debug('score: {} / {}'.format(score, sel)) self.selected = self.streams[sel] self.streams = [self.selected] return debug('autoselect nic nevybral, tak nechame usera vybrat')