def __validateFields(self): error = False all_values = ''.join([control.getText().strip() for control in self.query_controls]) if all_values == '': error_string = i18n('one_criteria') error = True else: # validate fields with allowed values valid_fields = ['genre', 'month', 'year', 'decade'] field_names = [param[0] for param in self.params] for field in valid_fields: field_value = self.query_controls[field_names.index(field)].getText() if field_value != '': if field_value not in allowed_values[field]: error_string = '%s %s %s' % (field.capitalize(), i18n('must_be_one_of'), str(allowed_values[field][1:]).replace("'", "")) # override error string on year if field == 'year': error_string = i18n('year_range_error') % (allowed_values[field][1], allowed_values[field][-1]) error = True break if error: _1CH.show_ok_dialog([error_string], title='PrimeWire') return not error
def get_adv_search_query(section): if section == 'tv': header_text = i18n('adv_tv_search') else: header_text = i18n('adv_movie_search') SEARCH_BUTTON = 200 CANCEL_BUTTON = 201 HEADER_LABEL = 100 ACTION_PREVIOUS_MENU = 10 ACTION_BACK = 92 CENTER_Y = 6 CENTER_X = 2 now = datetime.datetime.now() # allowed values have to be list of strings allowed_values = {} allowed_values['month'] = [''] + [str(month) for month in xrange(1, 13)] allowed_values['year'] = [''] + [str(year) for year in xrange(1900, now.year + 1)] allowed_values['decade'] = [''] + [str(decade) for decade in xrange(1900, now.year + 1, 10)] allowed_values['genre'] = [''] + pw_scraper.get_genres() class AdvSearchDialog(xbmcgui.WindowXMLDialog): ypos = 80 gap = 55 params = [ ('title', 10, ypos, 40, 490), ('tag', 10, ypos + gap, 40, 490), ('actor', 10, ypos + gap * 2, 40, 490), ('director', 10, ypos + gap * 3, 40, 490), ('country', 10, ypos + gap * 4, 40, 490), ('genre', 10, ypos + gap * 5, 40, 490), ('month', 30, ypos + gap * 6, 40, 140), ('year', 185, ypos + gap * 6, 40, 140), ('decade', 340, ypos + gap * 6, 40, 140)] def onInit(self): self.query_controls = [] # add edits for title, tag, actor and director for i in xrange(9): self.query_controls.append(self.__add_editcontrol(self.params[i][1], self.params[i][2], self.params[i][3], self.params[i][4])) if i > 0: self.query_controls[i].controlUp(self.query_controls[i - 1]) self.query_controls[i].controlLeft(self.query_controls[i - 1]) if i < 9: self.query_controls[i - 1].controlDown(self.query_controls[i]) self.query_controls[i - 1].controlRight(self.query_controls[i]) search = self.getControl(SEARCH_BUTTON) cancel = self.getControl(CANCEL_BUTTON) self.query_controls[0].controlUp(cancel) self.query_controls[0].controlLeft(cancel) self.query_controls[-1].controlDown(search) self.query_controls[-1].controlRight(search) search.controlUp(self.query_controls[-1]) search.controlLeft(self.query_controls[-1]) cancel.controlDown(self.query_controls[0]) cancel.controlRight(self.query_controls[0]) header = self.getControl(HEADER_LABEL) header.setLabel(header_text) def onAction(self, action): # print 'Action: %s' %(action.getId()) if action == ACTION_PREVIOUS_MENU or action == ACTION_BACK: self.close() def onControl(self, control): # print 'onControl: %s' % (control) pass def onFocus(self, control): # print 'onFocus: %s' % (control) pass def onClick(self, control): # print 'onClick: %s' %(control) if control == SEARCH_BUTTON: if not self.__validateFields(): return self.search = True if control == CANCEL_BUTTON: self.search = False if control == SEARCH_BUTTON or control == CANCEL_BUTTON: self.close() def get_result(self): return self.search def get_query(self): texts = [] for control in self.query_controls: if isinstance(control, xbmcgui.ControlEdit): texts.append(control.getText()) elif isinstance(control, xbmcgui.ControlList): texts.append(control.getSelectedItem().getLabel()) params = [param[0] for param in self.params] query = dict(zip(params, texts)) return query # returns True if everything validates, false otherwise def __validateFields(self): error = False all_values = ''.join([control.getText().strip() for control in self.query_controls]) if all_values == '': error_string = i18n('one_criteria') error = True else: # validate fields with allowed values valid_fields = ['genre', 'month', 'year', 'decade'] field_names = [param[0] for param in self.params] for field in valid_fields: field_value = self.query_controls[field_names.index(field)].getText() if field_value != '': if field_value not in allowed_values[field]: error_string = '%s %s %s' % (field.capitalize(), i18n('must_be_one_of'), str(allowed_values[field][1:]).replace("'", "")) # override error string on year if field == 'year': error_string = i18n('year_range_error') % (allowed_values[field][1], allowed_values[field][-1]) error = True break if error: _1CH.show_ok_dialog([error_string], title='PrimeWire') return not error # have to add edit controls programatically because getControl() (hard) crashes XBMC on them def __add_editcontrol(self, x, y, height, width): temp = xbmcgui.ControlEdit(0, 0, 0, 0, '', font='font12', textColor='0xFFFFFFFF', focusTexture='buttons/button-fo.png', noFocusTexture='buttons/button-nofo.png', _alignment=CENTER_Y | CENTER_X) temp.setPosition(x, y) temp.setHeight(height) temp.setWidth(width) self.addControl(temp) return temp dialog = AdvSearchDialog('AdvSearchDialog.xml', _1CH.get_path()) dialog.doModal() if dialog.get_result(): query = dialog.get_query() del dialog utils.log('Returning query of: %s' % (query), xbmc.LOGDEBUG) return query else: del dialog raise
def onPlayBackEnded(self): is_playing = self.window.getProperty(key=self.player_keys['twitch_playing']) == 'True' log_utils.log('Player: |onPlayBackEnded| isTwitch |{0}|'.format(is_playing), log_utils.LOGDEBUG) need_reset = True if is_playing: reconnect = kodi.get_setting('live_reconnect') == 'true' if reconnect: live_channel = self.window.getProperty(self.reconnect_keys['stream']) if live_channel: self.close_chat() channel_id, name, display_name, quality = live_channel.split(',') retries = 0 max_retries = 5 while not monitor.abortRequested(): if monitor.waitForAbort(5): break break if monitor.abortRequested(): dialog = None else: dialog = kodi.ProgressDialog(kodi.get_name(), line1=utils.i18n('attempt_reconnect') % display_name, line2=utils.i18n('attempt_number') % (retries + 1), line3=utils.i18n('retry_seconds') % 60) if dialog: need_reset = False with dialog: while (not monitor.abortRequested()) and (retries < max_retries) and (not dialog.is_canceled()): wait_time = 0.0 abort = False while wait_time <= 120.0: if monitor.waitForAbort(0.5) or dialog.is_canceled(): abort = True break wait_time += 1.0 if (wait_time % 2) == 0: percent = int(((wait_time / 120) * 100)) dialog.update(percent=percent, line3=utils.i18n('retry_seconds') % ((120.0 - wait_time) / 2)) if abort: break retries += 1 try: try: cache.reset_cache() except: pass twitch = api.Twitch() videos = twitch.get_live(name) result = twitch.get_channel_stream(channel_id)[Keys.STREAM] item_dict = converter.stream_to_playitem(result) video = converter.get_video_for_quality(videos, ask=False, quality=quality) if video: log_utils.log('Attempting playback using quality |%s| @ |%s|' % (video['name'], video['url']), log_utils.LOGDEBUG) item_dict['path'] = video['url'] playback_item = kodi.create_item(item_dict, add=False) stream_name = result[Keys.CHANNEL][Keys.DISPLAY_NAME] \ if result[Keys.CHANNEL][Keys.DISPLAY_NAME] else result[Keys.CHANNEL][Keys.NAME] self.window.setProperty(self.reconnect_keys['stream'], '{0},{1},{2},{3}'.format(channel_id, name, stream_name, quality)) self.play(item_dict['path'], playback_item) if utils.irc_enabled() and twitch.access_token: username = twitch.get_username() if username: utils.exec_irc_script(username, name) break except: log_utils.log('Player: |Reconnection| Failed attempt |{0}|'.format(retries), log_utils.LOGERROR) dialog.update(0, line2=utils.i18n('attempt_number') % (retries + 1), line3=utils.i18n('retry_seconds') % 60) if dialog.is_canceled(): self.reset() if need_reset: self.reset()
def onPlayBackEnded(self): is_playing = self.window.getProperty(key=self.player_keys['twitch_playing']) == 'True' log_utils.log('Player: |onPlayBackEnded| isTwitch |{0}|'.format(is_playing), log_utils.LOGDEBUG) need_reset = True if is_playing: reconnect = kodi.get_setting('live_reconnect') == 'true' if reconnect: live_channel = self.window.getProperty(self.reconnect_keys['stream']) if live_channel: channel_id, name, display_name, quality = live_channel.split(',') retries = 0 max_retries = 5 while not monitor.abortRequested(): if monitor.waitForAbort(5): break break if monitor.abortRequested(): dialog = None else: dialog = kodi.ProgressDialog(kodi.get_name(), line1=utils.i18n('attempt_reconnect') % display_name, line2=utils.i18n('attempt_number') % (retries + 1), line3=utils.i18n('retry_seconds') % 60) if dialog: need_reset = False with dialog: while (not monitor.abortRequested()) and (retries < max_retries) and (not dialog.is_canceled()): wait_time = 0.0 abort = False while wait_time <= 120.0: if monitor.waitForAbort(0.5) or dialog.is_canceled(): abort = True break wait_time += 1.0 if (wait_time % 2) == 0: percent = int(((wait_time / 120) * 100)) dialog.update(percent=percent, line3=utils.i18n('retry_seconds') % ((120.0 - wait_time) / 2)) if abort: break retries += 1 try: try: cache.reset_cache() except: pass twitch = api.Twitch() videos = twitch.get_live(name) result = twitch.get_channel_stream(channel_id)[Keys.STREAM] item_dict = converter.stream_to_playitem(result) video = converter.get_video_for_quality(videos, ask=False, quality=quality) if video: log_utils.log('Attempting playback using quality |%s| @ |%s|' % (video['name'], video['url']), log_utils.LOGDEBUG) item_dict['path'] = video['url'] playback_item = kodi.create_item(item_dict, add=False) stream_name = result[Keys.CHANNEL][Keys.DISPLAY_NAME] \ if result[Keys.CHANNEL][Keys.DISPLAY_NAME] else result[Keys.CHANNEL][Keys.NAME] self.window.setProperty(self.reconnect_keys['stream'], '{0},{1},{2}'.format(channel_id, name, stream_name)) self.play(item_dict['path'], playback_item) if utils.irc_enabled() and twitch.access_token: username = twitch.get_username() if username: utils.exec_irc_script(username, name) break except: log_utils.log('Player: |Reconnection| Failed attempt |{0}|'.format(retries), log_utils.LOGERROR) dialog.update(0, line2=utils.i18n('attempt_number') % (retries + 1), line3=utils.i18n('retry_seconds') % 60) if dialog.is_canceled(): self.reset() if need_reset: self.reset()
def stream_to_listitem(self, stream): channel = stream[Keys.CHANNEL] video_banner = channel.get(Keys.PROFILE_BANNER) if not video_banner: video_banner = channel.get(Keys.VIDEO_BANNER) if channel.get( Keys.VIDEO_BANNER) else Images.FANART preview = stream.get(Keys.PREVIEW) if Keys.MEDIUM in preview: preview = preview.get(Keys.MEDIUM) logo = channel.get(Keys.LOGO) if channel.get( Keys.LOGO) else Images.VIDEOTHUMB image = preview if preview else logo title = self.get_title_for_stream(stream) if stream.get(Keys.STREAM_TYPE) != 'live': color = get_vodcast_color() title = u'[COLOR={color}]{title}[/COLOR]'.format(title=title, color=color) info = self.get_plot_for_stream(stream) info.update({'mediatype': 'video', 'playcount': 0}) context_menu = list() context_menu.extend(menu_items.refresh()) name = channel.get(Keys.DISPLAY_NAME) if channel.get( Keys.DISPLAY_NAME) else channel.get(Keys.NAME) if self.has_token: context_menu.extend(menu_items.edit_follow(channel[Keys._ID], name)) # context_menu.extend(menu_items.edit_block(channel[Keys._ID], name)) context_menu.extend( menu_items.channel_videos(channel[Keys._ID], channel[Keys.NAME], name)) if channel[Keys.GAME]: context_menu.extend(menu_items.go_to_game(channel[Keys.GAME])) context_menu.extend(menu_items.add_blacklist(channel[Keys._ID], name)) context_menu.extend( menu_items.add_blacklist(b64encode(channel[Keys.GAME].encode( 'utf-8', 'ignore')), channel[Keys.GAME], list_type='game')) context_menu.extend( menu_items.set_default_quality('stream', channel[Keys._ID], channel[Keys.NAME])) context_menu.extend( menu_items.run_plugin( i18n('play_choose_quality'), { 'mode': MODES.PLAY, 'channel_id': channel[Keys._ID], 'ask': True, 'use_player': True })) return { 'label': title, 'path': kodi.get_plugin_url({ 'mode': MODES.PLAY, 'channel_id': channel[Keys._ID] }), 'context_menu': context_menu, 'is_playable': True, 'info': info, 'content_type': 'video', 'art': the_art({ 'fanart': video_banner, 'poster': image, 'thumb': image, 'icon': image }) }
def video_list_to_listitem(self, video): duration = video.get(Keys.LENGTH) date = video.get(Keys.CREATED_AT)[:10] if video.get( Keys.CREATED_AT) else '' year = video.get(Keys.CREATED_AT)[:4] if video.get( Keys.CREATED_AT) else '' image = video.get(Keys.PREVIEW) if video.get( Keys.PREVIEW) else Images.VIDEOTHUMB if Keys.MEDIUM in image: image = image.get(Keys.MEDIUM) channel = video[Keys.CHANNEL] context_menu = list() context_menu.extend(menu_items.refresh()) name = channel.get(Keys.DISPLAY_NAME) if channel.get( Keys.DISPLAY_NAME) else channel.get(Keys.NAME) if self.has_token: context_menu.extend(menu_items.edit_follow(channel[Keys._ID], name)) # context_menu.extend(menu_items.edit_block(channel[Keys._ID], name)) context_menu.extend( menu_items.channel_videos(channel[Keys._ID], channel[Keys.NAME], name)) if video[Keys.GAME]: context_menu.extend(menu_items.go_to_game(video[Keys.GAME])) context_menu.extend(menu_items.add_blacklist(channel[Keys._ID], name)) context_menu.extend( menu_items.add_blacklist(b64encode(video[Keys.GAME].encode( 'utf-8', 'ignore')), video[Keys.GAME], list_type='game')) context_menu.extend( menu_items.set_default_quality('video', channel[Keys._ID], channel[Keys.NAME], video[Keys._ID])) context_menu.extend( menu_items.run_plugin( i18n('play_choose_quality'), { 'mode': MODES.PLAY, 'video_id': video[Keys._ID], 'ask': True, 'use_player': True })) info = self.get_plot_for_video(video) info.update({ 'duration': str(duration), 'year': year, 'date': date, 'premiered': date, 'mediatype': 'video' }) return { 'label': self.get_title_for_video(video), 'path': kodi.get_plugin_url({ 'mode': MODES.PLAY, 'video_id': video[Keys._ID] }), 'context_menu': context_menu, 'is_playable': True, 'info': info, 'content_type': 'video', 'art': the_art({ 'poster': image, 'thumb': image, 'icon': image }) }
def clip_to_listitem(self, clip): duration = clip.get(Keys.DURATION) plot = clip.get(Keys.DESCRIPTION) date = clip.get(Keys.CREATED_AT)[:10] if clip.get( Keys.CREATED_AT) else '' year = clip.get(Keys.CREATED_AT)[:4] if clip.get( Keys.CREATED_AT) else '' image = clip.get(Keys.THUMBNAILS) if clip.get( Keys.THUMBNAILS) else Images.VIDEOTHUMB if Keys.MEDIUM in image: image = image.get(Keys.MEDIUM) broadcaster = clip[Keys.BROADCASTER] context_menu = list() context_menu.extend(menu_items.refresh()) name = broadcaster.get(Keys.DISPLAY_NAME) if broadcaster.get( Keys.DISPLAY_NAME) else broadcaster.get(Keys.NAME) if self.has_token: context_menu.extend( menu_items.edit_follow(broadcaster[Keys.ID], name)) # context_menu.extend(menu_items.edit_block(broadcaster[Keys.ID], name)) context_menu.extend( menu_items.channel_videos(broadcaster[Keys.ID], broadcaster[Keys.NAME], name)) if clip[Keys.GAME]: context_menu.extend(menu_items.go_to_game(clip[Keys.GAME])) context_menu.extend( menu_items.add_blacklist(broadcaster[Keys.ID], name)) context_menu.extend( menu_items.add_blacklist(b64encode(clip[Keys.GAME].encode( 'utf-8', 'ignore')), clip[Keys.GAME], list_type='game')) context_menu.extend( menu_items.set_default_quality('clip', broadcaster[Keys.ID], broadcaster[Keys.NAME], clip_id=clip[Keys.SLUG])) context_menu.extend( menu_items.run_plugin( i18n('play_choose_quality'), { 'mode': MODES.PLAY, 'slug': clip[Keys.SLUG], 'ask': True, 'use_player': True })) info = self.get_plot_for_clip(clip) info.update({ 'duration': str(duration), 'year': year, 'date': date, 'premiered': date, 'mediatype': 'video' }) return { 'label': self.get_title_for_clip(clip), 'path': kodi.get_plugin_url({ 'mode': MODES.PLAY, 'slug': clip[Keys.SLUG] }), 'context_menu': context_menu, 'is_playable': True, 'info': info, 'content_type': 'video', 'art': the_art({ 'poster': image, 'thumb': image, 'icon': image }) }