# coding=utf-8 import xbmcgui import xbmc import time try: import simplejson as json except: import json from datetime import datetime, date, timedelta from define import * from framework import gui from etvnet.details import MediaDetails, ContainerDetails from etvnet.api import eTV from etvnet.settings import SettingsWindow from dt import ru_strftime # NEXT TODO: make back button and breadcrumb work LETTERS = (u'А', u'Б', u'В', u'Г', u'Д', u'Е', u'Ж', u'З', u'И', u'К', u'Л', u'М', u'Н', u'О', u'П', u'Р', u'С', u'Т', u'У', u'Ф', u'Х', u'Ц', u'Ч', u'Ш', u'Щ', u'Э', u'Ю', u'Я',) ETVNET_API_URI = 'https://secure.etvnet.com/api/v3.0/' DEFAULT_CHARSET = 'utf-8' ALL_GENRES = u'Все рубрики'.encode(DEFAULT_CHARSET) ALL_CHANNELS = u'Все каналы'.encode(DEFAULT_CHARSET) CACHE_EXPIRES_SEC = 3 * 60 # cache request for 3 minytes TIMEZONES = ( (0, u'Москва', u'Москва'), (-8, u'Нью-Йорк', u'Нью-Йорк'), (-9, u'Чикаго', u'Чикаго'), (-10, u'Денвер', u'Денвер'), (-11, u'Лос-Анджелес', u'Лос-Андж.'), ) class Breadcrumbs(list): def __init__(self, *a, **k): self.window = None super(Breadcrumbs, self).__init__(*a, **k) self.level_incrised = None def __str__(self): string = 'Все' for item in self: string += ' > ' string += item['label'] return string def ui_refresh(self): self.window.getControl(9090).setLabel(str(self)) def clear(self): del self[:] def replace_or_append(self, index, item): try: self[index] = item self.level_icrised = False except IndexError: self.append(item) self.level_icrised = True def append(self, el, *a, **k): try: el['id'] except KeyError: el['id'] = None try: el['channel'] except KeyError: el['channel'] = None try: el['genre'] except KeyError: el['genre'] = None super(Breadcrumbs, self).append(el, *a, **k) @property def length(self): return self.__len__() from framework.gui import Settings config = Settings() class eTVxbmc(gui.XMLWindow): quality = None xml = "main.xml" CHANNELS, GENRES, FOLDERS, LIVE_CHANNELS, MAIN_ITEMS = range(5) NULL, MENU_MAIN, MENU_CHANNELS, MENU_ARRIVALS, MENU_ARCHIVE, MENU_BOOKMARKS, MENU_SEARCH, MENU_HISTORY, MENU_LIVE_CHANNELS = range(9) PER_PAGE = 24 MAIN_PAGE_ITEMS = [ {'id':'etvslider/main', 'title':u'Выбор редакции'}, {'id':'newmedias', 'title':u'Стоит посмотреть'}, {'id':'best', 'title':u'Лучшее 100'}, {'id':'top', 'title':u'Лучшее за 7 дней'}, {'id':'newest', 'title':u'Последние поступления'}, {'id':'now_watched', 'title':u'Сейчас смотрят'}, {'id':'recommend', 'title':u'Персональные рекомендации'}, ] etvnet = eTV(access_token=config.GetValue('access_token')) def onInit(self): self.shut_up_player() self.manager.hide(9093, 9092) if not getattr(self, 'loaded', None): self.loaded = True self.alter_etvnet_request() self.getMainPageForBoxee() self.getMainPageItemForBoxee() self.setup_letters() self.breadcrumbs = Breadcrumbs() self.breadcrumbs.window = self self.onMainPageClick() self.breadcrumbs.ui_refresh() self._current_channel = None elif self.main_menu == self.MENU_LIVE_CHANNELS: self.manager.show(9093, 9092) self.show_curent_live_page() self.manager.goto(6662) self.set_default_shifting_status() self.set_default_filter_status() def alter_etvnet_request(self): orig_request = self.etvnet.request # modified request for xbmc pagination def xbmc_request(slf, *args, **kwargs): resp = orig_request(slf, *args, **kwargs) if getattr(resp, 'data', None) is not None: self.setup_pagination(resp) return resp self.etvnet.request = xbmc_request def setup_pagination(self, resp): pagin = None if not isinstance(resp.data, list): pagin = resp.data.get('pagination') if pagin: if pagin['has_next']: self.manager.show(NEXT_PAGE_CONTEN) else: self.manager.hide(NEXT_PAGE_CONTEN) if pagin['has_previous']: self.manager.show(BACK_PAGE_CONTEN) else: self.manager.hide(BACK_PAGE_CONTEN) if pagin['page'] and pagin['pages']: page_pages = '%d / %d' % (pagin['page'], pagin['pages']) self.getControl(9057).setLabel(page_pages) @gui.onclick(9098) @gui.in_thread @gui.with_progress def on_nex_page(self): resp = self.etvnet.getNextPage() if self.main_menu == self.MENU_BOOKMARKS: list_key = 'bookmarks' else: list_key = 'media' if resp: self.responseToXBMCItems(resp, list_key=list_key) @gui.onclick(9097) @gui.in_thread @gui.with_progress def on_prev_page(self): resp = self.etvnet.getPreviousPage() if self.main_menu == self.MENU_BOOKMARKS: list_key = 'bookmarks' else: list_key = 'media' if resp: self.responseToXBMCItems(resp, list_key=list_key) # refersh breadcrubms after menu state changed, all states except live channels @gui.onclick(9001, 9002, 9003, 9004, 9005, 9006, 9007) def flash_after_menu_reload(self): self.getControl(1987).setImage('clean/background_main.png') self.manager.hide(LIVE_CHANNEL_LIST, 9092, 9093) self.manager.show(MEDIA_LIST_MENU, MIDDLE_MENU, 9064, 9065, 9098, 9097, 9057) self.gl = 0 self.breadcrumbs.ui_refresh() @gui.onclick(MENU_MAIN + 9000) def onMainPageClick(self): self.breadcrumbs.clear() self.gl = 1 self.breadcrumbs.replace_or_append(self.gl, {'channel': False, 'id': None, 'genre': False, 'label': "Главная"}) self.breadcrumbs.ui_refresh() self.main_menu = self.MENU_MAIN @gui.onclick(MENU_HISTORY + 9000) def onHistoryClick(self): self.breadcrumbs.clear() self.gl = 0 self.breadcrumbs.replace_or_append(self.gl, {'channel': False, 'id': None, 'genre': False, 'label': "История Просмотров"}) self.main_menu = self.MENU_HISTORY @gui.onclick(MENU_CHANNELS + 9000) def onChannelsClick(self): self.breadcrumbs.clear() self.gl = 0 self.breadcrumbs.replace_or_append(self.gl, {'channel': False, 'id': None, 'genre': False, 'label': "Каналы"}) self.breadcrumbs.ui_refresh() self.main_menu = self.MENU_CHANNELS @gui.onclick(MENU_ARCHIVE + 9000) def onArchiveClick(self): self.gl = 0 self.breadcrumbs.clear() self.breadcrumbs.replace_or_append(self.gl, {'channel': False, 'id': None, 'genre': False, 'label': "Архив"}) self.main_menu = self.MENU_ARCHIVE @gui.onclick(MENU_ARRIVALS + 9000) def onArrivalsClick(self): self.gl = 0 self.breadcrumbs.clear() self.breadcrumbs.replace_or_append(self.gl, {'channel': False, 'id': None, 'genre': False, 'label': "Новое"}) self.main_menu = self.MENU_ARRIVALS @gui.onclick(MENU_BOOKMARKS + 9000) def onBookmarksClick(self): self.breadcrumbs.clear() self.gl = 2 self.breadcrumbs.replace_or_append(self.gl, {'channel': False, 'id': None, 'genre': False, 'label': "Избранное"}) self.main_menu = self.MENU_BOOKMARKS @gui.onclick(MENU_LIVE_CHANNELS + 9000) def onLiveChanClick(self): self.manager.hide(MIDDLE_MENU, MEDIA_LIST_MENU, 9064, 9098, 9097, 9057) self.manager.show(LIVE_CHANNEL_LIST, 9092, 9093) self.breadcrumbs.clear() self.breadcrumbs.replace_or_append(self.gl, {'channel': False, 'id': None, 'genre': False, 'label': "Live"}) self.main_menu = self.MENU_LIVE_CHANNELS self.getControl(1987).setImage('live/background_vprogram.jpg') self.gl = 0 self.breadcrumbs.ui_refresh() DONT_EXIT_CONTROLS = [9066, 2100, 6662, 9118, 9119, 9198, 9500, 9501, 9156, 9099, 9095, 9094, 9051, 9053, 9054, 9095] def onExit(self, _self, controlID): if controlID in self.DONT_EXIT_CONTROLS: self.manager.goto(9157) raise Exception('Exeption To prevent closing') for i in [1,2,3,4,5,6,7,8]: xbmc.executebuiltin("Skin.Reset(900%s)" % i) def shut_up_player(self): player = xbmc.Player(xbmc.PLAYER_CORE_DVDPLAYER) if player.isPlaying(): player.stop() def responseToXBMCItems(self, resp, list_key="media"): self.manager.show(MEDIA_LIST_MENU) content_list_control = self.getControl(MEDIA_LIST_MENU) menu_items = [] for item in resp.data[list_key]: list_item = xbmcgui.ListItem() list_item.setProperty('id', str(item['id'])) list_item.setProperty('type', item['type'].encode('utf-8')) list_item.setLabel(item['name'].encode('utf-8')) list_item.setProperty('duration', str(item['duration'] * 60)) list_item.setProperty('thumbnail', item['thumb'].encode('utf-8')) list_item.setProperty('data', json.dumps(item)) list_item.setProperty('stars', 'stars/' + str(item['mark']['total']) + '.png') dt = datetime(*time.strptime(item['on_air'], '%Y-%m-%d %H:%M:%S')[:6]) list_item.setProperty('on_air', "%d/%d/%d %d:%d" % (dt.day, dt.month, dt.year, dt.hour, dt.minute)) list_item.setProperty('tag', item['tag'].encode('utf-8')) list_item.setProperty('rating', "Рейтинг: " + str(item['rating'])) list_item.setProperty('duration', str(item['duration']) + ' мин.') list_item.setProperty('year', str(item['year']) + ' г.') list_item.setProperty('channel', item['channel']['name'].encode('utf-8')) menu_items.append(list_item) content_list_control.reset() content_list_control.addItems(menu_items) @gui.onclick(9002, 9004) @gui.in_thread @gui.with_progress def getArchive(self, genre=None, channel=None): resp = self.etvnet.getArchive(genre=genre, channel=channel, per_page=self.PER_PAGE) self.responseToXBMCItems(resp) @gui.onclick(9003) @gui.in_thread @gui.with_progress def getNewArrivals(self, genre=None, channel=None): resp = self.etvnet.getNewArrivals(genre=genre, channel=channel, per_page=self.PER_PAGE) self.responseToXBMCItems(resp) @gui.onclick(MIDDLE_MENU) def middle_menu_clicked(self): self.breadcrumbs.ui_refresh() @gui.onclick(9005) @gui.in_thread @gui.with_progress def getBookmarks(self, folder=None): resp = self.etvnet.getBookmarks(folder=folder) self.responseToXBMCItems(resp, list_key='bookmarks') @gui.onclick(9005) @gui.in_thread def getFolders(self): middle_menu = self.getControl(MIDDLE_MENU) folders = self.etvnet.getFolders() menu_items = [] for item in folders.data['folders']: list_item = xbmcgui.ListItem() list_item.setProperty('id', str(item['id'])) list_item.setLabel(item['title'].encode('utf-8')) list_item.setProperty('count', str(item['items_count']).encode('utf-8')) menu_items.append(list_item) middle_menu.reset() middle_menu.addItems(menu_items) self.middle_panel_state = self.FOLDERS @gui.onclick(9007) @gui.in_thread @gui.with_progress def getHistory(self): resp = self.etvnet.getHistory() self.responseToXBMCItems(resp) @gui.onclick(9006) def search(self): keyboard = xbmc.Keyboard("", heading="Please type your login") keyboard.doModal() if (keyboard.isConfirmed()): inputText = keyboard.getText() if inputText: try: self.progress.show() response = self.etvnet.search(inputText) self.responseToXBMCItems(response) self.breadcrumbs.clear() self.breadcrumbs.append({'channel': False, 'id': None, 'genre': False, 'label': "Поиск"}) self.breadcrumbs.append({'channel': False, 'id': None, 'genre': False, 'label': inputText}) self.breadcrumbs.ui_refresh() finally: self.progress.hide() self.manager.hide(9064, 9065) del keyboard def form_time_start_and_string(self, start, end): return '%s - %s' % (str(start[-8:-3]), str(end[-8:-3])) @gui.onclick(9008) @gui.with_progress def liveChannels(self, use_cache=False): middle_menu = self.getControl(LIVE_CHANNEL_LIST) offset = self.getOffset() category = int(self.config.GetValue('live_filter_id')) chan = self.etvnet.getLiveChannels(use_cache=False, offset=offset, category=int(category)) chan = self.order_live_chanels(chan) if chan.data[0]['current_show']: current_start_time = chan.data[0]['current_show']['start_time'] current_finish_time = chan.data[0]['current_show']['finish_time'] current_title = chan.data[0]['current_show']['title'].encode('utf-8') else: current_start_time = '' current_finish_time = '' current_title = '' if chan.data[0]['files']: bitrate_list = ','.join([str(i['bitrate']) for i in chan.data[0]['files']]) else: bitrate_list = '' time_range = self.form_time_start_and_string(current_start_time, current_finish_time) self.loadLiveChannelPage(chan.data[0]['id'], chan.data[0]['name'].encode('utf-8'), chan.data[0]['live_format'].encode('utf-8'), current_title, show_time=time_range, bitrates=bitrate_list) menu_items = [] for item in chan.data: format = self.format_for_live_channale(item) if item['icon'] is not None: icon = item['icon'].encode('utf-8') else: icon = '' if item['current_show'] is not None: current_show = item['current_show']['title'].encode('utf-8') time_range = self.form_time_start_and_string(item['current_show']['start_time'], item['current_show']['finish_time']) else: current_show = 'Программа телеканала отсутствует' time_range = '-' if item['favorite']: favorite = '1' else: favorite = '0' if item['files']: bitrate_list = ','.join([str(i['bitrate']) for i in item['files']]) else: bitrate_list = '' list_item = xbmcgui.ListItem() list_item.setProperty('thumbnail', icon) list_item.setProperty('id', str(item['id'])) list_item.setLabel(item['name'].encode('utf-8')) list_item.setProperty('format', format.encode('utf-8')) list_item.setProperty('tvshow', current_show) list_item.setProperty('time', time_range) list_item.setProperty('favorite', favorite) list_item.setProperty('bitrates', bitrate_list) menu_items.append(list_item) middle_menu.reset() middle_menu.addItems(menu_items) self.middle_panel_state = self.LIVE_CHANNELS def order_live_chanels(self, channels): favorites = [] for item in channels.data: if item['favorite'] is True: channels.data.remove(item) favorites.append(item) channels.data = favorites + channels.data return channels def format_for_live_channale(self, channel): if channel['live_format'] == 'zixi': return 'zixi' if channel['files'].__len__() == 1: format = channel['files'][0]['format'] else: format = 'mp4' return format ZIXI_QUALITY_TO_BITRATE = {'1': '500', '2': '800', '3': '1200'} @gui.in_thread @gui.with_progress def loadLiveChannelPage(self, id, label, format, tvshow, show_time=None, bitrates=','.join(ZIXI_QUALITY_TO_BITRATE.values())): self.genres_level = 1 self.breadcrumbs.replace_or_append(self.genres_level, { 'channel': False, 'id': id, 'genre': False, 'label': label, 'live_format': format, 'tvshow': tvshow, 'time': show_time, 'bitrates': bitrates }) self.breadcrumbs.ui_refresh() l = ['e', 'p', 'y', 't', 'e', 'm', 'i', 'm'] l.reverse() MMTP, _TYPE = "".join(l), "".join(['v', 'i', 'd', 'e', 'o', '/', 'x', '-', 'f', 'l', 'v']), def getQuality(self): q = self.config.GetValue('quality') if not q: self.quality = 2 q = str(self.quality) else: self.quality = int(q) return int(q) def getLiveBitrate(self): bitrates = self.breadcrumbs[-1]['bitrates'].split(',') q = self.getQuality() index = q - 1 if len(bitrates) == 2: if q in [2, 3]: return bitrates[1] if len(bitrates) == 3: return bitrates[index] if len(bitrates) > 3: if q == 2: return bitrates[-2] if q == 3: return bitrates[-1] return bitrates[0] def getOffset(self): val = self.config.GetValue('shifting') return int(val) @gui.onclick(LIVE_CHANNEL_LIST, 6662, 9198) @gui.with_progress def runLiveChannelSHift(self): offset = self.getOffset() live_id = self.breadcrumbs[-1]['id'] format = self.breadcrumbs[-1]['live_format'] title = self.breadcrumbs[-1]['label'] bitrate = self.getLiveBitrate() url = self.etvnet.get_xbmc_url(live=True, format=format, bitrate=bitrate, channel_id=live_id, offset=offset).encode('utf-8') #url = url + ' live=true' self.play(url, title=title) @gui.onclick(MEDIA_LIST_MENU) def showMediaDetails(self): control = self.getControl(MEDIA_LIST_MENU) selected = control.getSelectedItem() data = json.loads(selected.getProperty('data')) no_container = data['parent'] == '' and data['type'] == 'MediaObject' if no_container: Window = MediaDetails else: Window = ContainerDetails wn = Window("DefaultSkin", params={'main_window': self, 'data': data, 'breadcrumbs': str(self.breadcrumbs)}) wn.doModal() del wn def play(self, url, title="Live"): item = xbmcgui.ListItem(title) print url xbmc.Player(xbmc.PLAYER_CORE_DVDPLAYER).play(url, item) def setup_letters(self): letters = self.getControl(6619) list_items = [] for char in LETTERS: item = xbmcgui.ListItem() item.setLabel(char) list_items.append(item) letters.addItems(list_items) @gui.onclick(6619) @gui.in_thread @gui.with_progress def order_by_letter_boxee(self, letter=None): if not letter: list = self.getControl(6619) item = list.getSelectedItem() letter = item.getLabel() if self.etvnet._last_url_requested.params.get('dir') == 'desc': self.etvnet._last_url_requested.params['dir'] = 'asc' else: self.etvnet._last_url_requested.params['dir'] = 'desc' resp = self.etvnet.getByLetter(letter) if resp: self.responseToXBMCItems(resp) @gui.onclick(6620) def A_Z_order_by(self): self.order_by_letter_boxee(letter='EN') @gui.onclick(6621) def NUM_order_by(self): self.order_by_letter_boxee(letter='NUM') @gui.onclick(6611) def sortByName(self): self.order_by_boxee('simple_name') @gui.onclick(6612) def sortByOnAir(self): self.order_by_boxee('on_air') @gui.onclick(6613) def sortByRating(self): self.order_by_boxee('precalc_rating') @gui.onclick(6614) def sortByStarse(self): self.order_by_boxee('sort_by_star') @gui.with_progress def order_by_boxee(self, field): if self.etvnet._last_url_requested.params.get('dir') == 'desc': self.etvnet._last_url_requested.params['dir'] = 'asc' else: self.etvnet._last_url_requested.params['dir'] = 'desc' resp = self.etvnet.getSortedBy(field) if resp: self.responseToXBMCItems(resp) @gui.onclick(6622) def clear_sorting(self): self.etvnet._last_url_requested.params['first_letter'] = None self.etvnet._last_url_requested.params['dir'] = None resp = self.etvnet.getPageAgain() if resp: self.responseToXBMCItems(resp) @gui.onclick(MIDDLE_MENU) def getGenrOrChannelOrFolder(self): list = self.getControl(MIDDLE_MENU) item = list.getSelectedItem() if self.main_menu == self.MENU_MAIN: r_id = item.getProperty('id') else: r_id = int(item.getProperty('id')) label = item.getLabel() need_up = False if label: need_up = True if r_id == 0: self.previousMiddleMenu() return # load middle area today = self.main_menu == self.MENU_ARRIVALS if self.middle_panel_state == self.GENRES: # depende on genre level replaces or appends item to breadcrumbs if self.breadcrumbs.length > 2 and self.breadcrumbs[-2]['id'] == r_id: self.getGenres(parent=r_id, channel=self._current_channel, inc_genres_level=self.NO, today=today) del self.breadcrumbs[-1] # elif self.breadcrumbs[-1]['id'] == r_id: # pass else: self.getGenres(parent=r_id, channel=self._current_channel, today=today, need_up=need_up) self.breadcrumbs.replace_or_append(self.gl, { 'channel': False, 'id': r_id, 'genre': True, 'label': label }) elif self.middle_panel_state == self.CHANNELS: self._current_channel = r_id self.getGenres(parent=None, channel=r_id, today=today, need_up=need_up) self.gl += 1 self.breadcrumbs.replace_or_append(self.gl, { 'channel': True, 'id': r_id, 'genre': False, 'label': label }) else: self.breadcrumbs.replace_or_append(self.gl, { 'channel': True, 'id': r_id, 'genre': False, 'label': label }) # load content area if self.main_menu == self.MENU_CHANNELS and self.middle_panel_state == self.GENRES: genre = (r_id, None)[self.breadcrumbs.length <= 2] self.getArchive(channel=self._current_channel, genre=genre) elif self.main_menu == self.MENU_CHANNELS: self.getArchive(channel=r_id) elif self.main_menu == self.MENU_ARRIVALS: self.getNewArrivals(genre=r_id) elif self.main_menu == self.MENU_ARCHIVE: self.getArchive(genre=r_id) elif self.main_menu == self.MENU_BOOKMARKS: self.getBookmarks(folder=r_id) elif self.middle_panel_state == self.LIVE_CHANNELS: self.loadLiveChannelPage(r_id, label, item.getProperty('live_format'), bitrates=item.getProperty('bitrates')) elif self.main_menu == self.MENU_MAIN: self.getMainPageItemForBoxee(id=r_id) @gui.onclick(9002) @gui.in_thread def getChannels(self, genre=None): chan = self.etvnet.getChannels() itemL = [] for item in chan.data: list_item = xbmcgui.ListItem() list_item.setProperty('id', str(item['id'])) list_item.setLabel(item['name'].encode('utf-8')) itemL.append(list_item) lst_ctrl = self.getControl(MIDDLE_MENU) lst_ctrl.reset() lst_ctrl.addItems(itemL) self.middle_panel_state = self.CHANNELS if genre is None: self._current_channel = None NO, DEC, INC = range(3) @gui.onclick(9004) @gui.in_thread def getGenres(self, parent=None, parent_label=None, channel=None, inc_genres_level=2, today=False, need_up=False): genres = self.etvnet.getGenres(parent_id=parent, channel_id=channel, today=today) itemL = [] # set forst item for genres if need_up: list_item = xbmcgui.ListItem() list_item.setProperty('id', '0') list_item.setProperty('back', 'back') itemL.append(list_item) for item in genres.data: list_item = xbmcgui.ListItem() list_item.setProperty('id', str(item['id'])) list_item.setProperty('count', str(item['count'])) list_item.setLabel(item['name'].encode('utf-8')) itemL.append(list_item) if len(genres.data) and inc_genres_level == self.INC: self.gl += 1 lst_ctrl = self.getControl(MIDDLE_MENU) lst_ctrl.reset() lst_ctrl.addItems(itemL) elif len(genres.data) and inc_genres_level == self.DEC: self.gl -= 1 lst_ctrl = self.getControl(MIDDLE_MENU) lst_ctrl.reset() lst_ctrl.addItems(itemL) self.middle_panel_state = self.GENRES @gui.onclick(9003) def getNewArrivalsGenres(self): self.getGenres(today=True) def previousMiddleMenu(self): if len(self.breadcrumbs) == 2: need_up = False else: need_up = True if len(self.breadcrumbs) > 1: shrinked = self.breadcrumbs.pop(-1) genre_id = self.breadcrumbs[-1].get('id') if self.main_menu in [self.MENU_ARRIVALS]: today = True else: today = False if shrinked.get('channel'): self._current_channel = None self.gl = 0 self.getChannels() elif shrinked.get('genre'): channel = None if self.gl == 3: channel = genre_id genre_id = None self.getGenres(parent=genre_id, today=today, inc_genres_level=self.DEC, need_up=need_up, channel=channel) self.breadcrumbs.ui_refresh() # main page logic @gui.onclick(9001) @gui.in_thread @gui.with_progress def getMainPageItemForBoxee(self, id='etvslider/main'): resp = self.etvnet.getMainPageMediaItems(id=id) self.responseToXBMCItems(resp) @gui.onclick(9001) def getMainPageForBoxee(self): middle_menu = self.getControl(MIDDLE_MENU) menu_items = [] for item in self.MAIN_PAGE_ITEMS: list_item = xbmcgui.ListItem() list_item.setProperty('id', str(item['id'])) list_item.setLabel(item['title'].encode('utf-8')) menu_items.append(list_item) middle_menu.reset() middle_menu.addItems(menu_items) self.middle_panel_state = self.MAIN_ITEMS @gui.onclick(9091) def showSettings(self): wn = SettingsWindow(params={'main_window': self}) wn.doModal() del wn @gui.onright(9008, 9001, 9002, 9003, 9004, 9008, 9005, 9006, 9007) def onright_live(self): if self.main_menu == self.MENU_LIVE_CHANNELS: self.manager.goto(9157) @gui.onright(LIVE_CHANNEL_LIST) def show_curent_live_page(self): item = self.get_menu_item(LIVE_CHANNEL_LIST) channel_id = int(item.getProperty('id')) self.loadLiveChannelPage(channel_id, item.getLabel(), item.getProperty('format'), item.getProperty('tvshow'), show_time=item.getProperty('time'), bitrates=item.getProperty('bitrates')) icon = item.getProperty('thumbnail') self.getControl(2101).setImage(icon) favorite = item.getProperty('favorite') if favorite is '1': self.manager.show(9119) self.manager.hide(9118) else: self.manager.show(9118) self.manager.hide(9119) self.getLiveScheduleForXBMC(channel_id) def get_menu_item(self, list_id): control = self.getControl(list_id) return control.getSelectedItem() @gui.in_thread def getLiveScheduleForXBMC(self, channel_id, date=date.today()): self.current_channel_id = channel_id self.current_schedule_day = date resp = self.etvnet.getLiveSchedule(channel_id, date=date) show_list = self.getControl(9156) itemL = [] for item in resp.data: list_item = xbmcgui.ListItem() list_item.setLabel(item['name'].encode('utf-8')) formed_time = self.form_time_start_and_string(item['start_time'], item['finish_time']) if formed_time == self.breadcrumbs[-1]['time']: list_item.setProperty('current', 'current') list_item.setProperty('time', formed_time) itemL.append(list_item) show_list.reset() show_list.addItems(itemL) # HERE dt = ru_strftime(format=u"%d %B %Y", date=date, inflected=True) self.getControl(9503).setLabel(dt) self.middle_panel_state = self.LIVE_CHANNELS @gui.onclick(9501) @gui.with_progress def schedule_next(self): next_date = self.current_schedule_day + timedelta(days=1) self.getLiveScheduleForXBMC(self.current_channel_id, date=next_date) @gui.onclick(9500) @gui.with_progress def schedule_previous(self): previous_date = self.current_schedule_day - timedelta(days=1) self.getLiveScheduleForXBMC(self.current_channel_id, date=previous_date) def set_status(self, status_text): self.getControl(9199).setLabel(status_text) @gui.onclick(9119) def removeLiveChannelFromFavorites(self): ch_id = self.breadcrumbs[-1]['id'] self.etvnet.removeLiveChannelFromFavorites(ch_id) self.manager.hide(9119) self.manager.show(9118) self.manager.goto(9118) self.liveChannels() @gui.onclick(9118) def addLiveChannelToFavorites(self): ch_id = self.breadcrumbs[-1]['id'] self.etvnet.addLiveChannelToFavorites(ch_id) self.manager.hide(9118) self.manager.show(9119) self.manager.goto(9119) self.liveChannels() @gui.ondown(9157) @gui.onup(9157) def liveChannelOnUpDown(self): control = self.getControl(LIVE_CHANNEL_LIST) item = control.getSelectedItem() self.loadLiveChannelPage(item.getProperty('id'), item.getLabel(), item.getProperty('format'), item.getProperty('tvshow'), show_time=item.getProperty('time'), bitrates=item.getProperty('bitrates')) @gui.onclick(9092) def goToShiftings(self): self.manager.goto(9053) self.showZonesLiveTV() @gui.onclick(9093) def goToFilters(self): self.manager.goto(9095) self.getLiveCategories() def showZonesLiveTV(self): itemL = [] show_list = self.getControl(9051) for zone in TIMEZONES: list_item = xbmcgui.ListItem() list_item.setProperty('offset', str(zone[0])) list_item.setProperty('area', zone[2].encode('utf-8')) list_item.setLabel(zone[1].encode('utf-8')) itemL.append(list_item) show_list.reset() show_list.addItems(itemL) @gui.onclick(9051) def set_setting_shifting(self): item = self.get_menu_item(9051) offset = item.getProperty('offset') label_area = item.getProperty('area') self.getControl(9092).setLabel(label_area) self.config.SetValue('shifting', offset) self.manager.goto(9157) self.liveChannels() def set_default_shifting_status(self): offset = self.config.GetValue('shifting') if not offset: offset = 0 self.config.SetValue('shifting', '0') for zone in TIMEZONES: if zone[0] == int(offset): self.getControl(9092).setLabel(zone[2].encode('utf-8')) def set_default_filter_status(self): label = self.config.GetValue('live_filter_name') if not label: label = 'Все каналы' label = self.config.SetValue('live_filter_id', '0') label = self.config.SetValue('live_filter_name', label) self.getControl(9093).setLabel(label) def getLiveCategories(self): categories = self.etvnet.getLiveCategory() list_item = xbmcgui.ListItem() list_item.setProperty('id', '0') list_item.setLabel('Все каналы') itemL = [list_item] show_list = self.getControl(9054) for item in categories.data: list_item = xbmcgui.ListItem() list_item.setProperty('id', str(item['id'])) list_item.setLabel(item['name'].encode('utf-8')) itemL.append(list_item) show_list.reset() show_list.addItems(itemL) @gui.onclick(9054) def setCategoryFilter(self): item = self.get_menu_item(9054) category_id = item.getProperty('id') name = item.getLabel() self.getControl(9093).setLabel(name) self.config.SetValue('live_filter_id', category_id) self.config.SetValue('live_filter_name', name) self.manager.goto(9157) self.liveChannels() def trunk(self, text, letters=75): if len(text) > letters: return text[:letters] + '...' else: return text @gui.onfocus(6662) def onPlayFocus(self): if self.breadcrumbs[-1]['tvshow'] == 'Программа телеканала отсутствует': text = self.breadcrumbs[-1]['tvshow'] else: show_time = self.breadcrumbs[-1]['time'] to_insert = self.trunk(self.breadcrumbs[-1]['tvshow'], letters=80) text = 'В эфире: %s (%s)' % (to_insert, show_time) self.set_status(text) @gui.onfocus(9118) def onFavoriteAddFocus(self): self.set_status('Добавить в "Любимые каналы"') @gui.onfocus(9119) def onFavoriteRemoveFocus(self): self.set_status('Удалить из "Любимых каналов"') @gui.onfocus(9198) def onPlayOtherFocus(self): self.set_status('Смотреть с другого сервера')