def fetch(self, url, params=None, data=None, **request_params): try: with Timer(logger=self.log, name='Fetching URL %s with params %r' % (url, params)): time.sleep(1) response = self.session.request('post' if data else 'get', url, params=params, data=data, **request_params) response.raise_for_status() self.save_cookies() return response except Timeout as e: raise ScraperError(32000, "Timeout while fetching URL: %s (%%s)" % url, lang(30000), cause=e) except NoValidProxiesFound as e: raise ScraperError(32005, "Can't find anonymous proxy", cause=e) except RequestException as e: raise ScraperError(32001, "Can't fetch URL: %s (%%s)" % url, lang(30000), cause=e) except ProxyListException as e: plugin.set_setting('use-proxy', 0) raise ScraperError(32004, "Can't load anonymous proxy list", cause=e)
def fetch(self, url, params=None, data=None, **request_params): try: with Timer(logger=self.log, name='Fetching URL %s with params %r' % (url, params)): response = self.session.request( 'post' if data else 'get', url, params=params, data=data, headers={ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/601.4.4 (KHTML, like Gecko) Version/9.0.3 Safari/601.4.4' }, **request_params) response.raise_for_status() self.save_cookies() return response except Timeout as e: raise ScraperError(32000, "Timeout while fetching URL: %s (%%s)" % url, lang(30000), cause=e) except NoValidProxiesFound as e: raise ScraperError(32005, "Can't find anonymous proxy", cause=e) except RequestException as e: raise ScraperError(32001, "Can't fetch URL: %s (%%s)" % url, lang(30000), cause=e) except ProxyListException as e: plugin.set_setting('use-proxy', 0) raise ScraperError(32004, "Can't load anonymous proxy list", cause=e)
def browse_trailers(): per_page = plugin.get_setting('per-page', int) skip = plugin.request.arg('skip') scraper = get_scraper() trailers = scraper.browse_trailers(skip) items = [] if len(trailers) < per_page: skip = (skip or 1) + 1 trailers.extend(scraper.browse_trailers(skip)) total = len(trailers) if skip > 2: skip_prev = max(skip - 1, 0) total += 1 items.append({ 'label': lang(34003), 'path': plugin.request.url_with_params(skip=skip_prev) }) plugin.add_items(with_fanart(items), total) for batch_res in batch(trailers, BATCH_EPISODES_COUNT): if abort_requested(): break items = itemify_trailers(batch_res) plugin.add_items(with_fanart(items), total) items = [] if scraper.has_more: skip_next = (skip or 1) + 1 items.append({ 'label': lang(34004), 'path': plugin.request.url_with_params(skip=skip_next) }) plugin.add_items(with_fanart(items), len(items)) plugin.finish(update_listing=skip > 2)
def update(self, percent): lines = [] if self.name is not None: lines.append(lang(33011) % {'name': self.name}) if self.state in [ TorrentStatus.DOWNLOADING, TorrentStatus.SEEDING, TorrentStatus.CHECKING, TorrentStatus.PREBUFFERING ]: size = self._human_size( self.size) if self.size >= 0 else lang(33015) lines.append( lang(33013) % { 'transferred': self._human_size(self._transferred_bytes), 'total': size, 'state': self.state.localized }) if self.state != TorrentStatus.CHECKING: lines.append( lang(33014) % { 'download_rate': self._human_rate(self.download_rate), 'upload_rate': self._human_rate(self.upload_rate), 'peers': self.peers, 'seeds': self.seeds }) else: lines.append(lang(33012) % {'state': self.state.localized}) return self.handler.update(percent, *lines)
def browse(): header = [ { 'label': lang(40401), 'path': plugin.url_for('browse_all_series') }, { 'label': lang(40421), 'path': plugin.url_for('browse_new') }, { 'label': lang(40411), 'path': plugin.url_for('browse_favorites') }, { 'label': lang(40418), 'path': plugin.url_for('browse_trailers') }, { 'label': lang(40422), 'path': plugin.url_for('search') }, ] plugin.add_items(with_fanart(header), len(header)) plugin.finish(sort_methods=['unsorted', 'label'])
def update(self, percent): if not self.overlay.visible: return heading = "%s - %d%%" % (self.state.localized, percent) self.heading.setLabel(heading) self.title.setLabel(self.name) lines = [] if self.state in [ TorrentStatus.DOWNLOADING, TorrentStatus.CHECKING, TorrentStatus.SEEDING, TorrentStatus.PREBUFFERING ]: size = self._human_size( self.size) if self.size >= 0 else lang(33015) lines.append( lang(33016) % { 'transferred': self._human_size(self._transferred_bytes), 'total': size }) if self.state != TorrentStatus.CHECKING: lines.append( lang(33014) % { 'download_rate': self._human_rate(self.download_rate), 'upload_rate': self._human_rate(self.upload_rate), 'peers': self.peers, 'seeds': self.seeds }) self.label.setLabel("\n".join(lines))
def update(self, percent): lines = [] if self.name: lines.append(lang(33001) % {'name': self.name}) size = self._human_size(self.size) if self.size >= 0 else lang(33003) lines.append(lang(33002) % ({'transferred': self._human_size(self._transferred_bytes), 'total': size})) return self.handler.update(percent, *lines)
def library_menu(s): """ :type s: Series """ items = library_items() if s.id in items: return [(lang(40310), actions.background(plugin.url_for('remove_from_library', series_id=s.id)))] else: return [(lang(40309), actions.background(plugin.url_for('add_to_library', series_id=s.id)))]
def update(self, percent): lines = [] if self.name: lines.append(lang(33001) % {'name': self.name}) size = self._human_size(self.size) if self.size >= 0 else lang(33003) lines.append( lang(33002) % ({ 'transferred': self._human_size(self._transferred_bytes), 'total': size })) return self.handler.update(percent, *lines)
def select_quality_menu(e): """ :type e: Episode """ if plugin.get_setting('quality', int) > 0: url = episode_url(e, True) if e.is_complete_season: return [(lang(40303), actions.update_view(url))] else: return [(lang(40301), actions.play_media(url))] else: return []
def index(): plugin.set_content('episodes') skip = plugin.request.arg('skip') per_page = plugin.get_setting('per-page', int) scraper = get_scraper() episodes = scraper.browse_episodes(skip) if episodes and not skip: check_last_episode(episodes[0]) check_first_start() new_episodes = library_new_episodes() new_str = "(%s) " % tf.color(str( len(new_episodes)), NEW_LIBRARY_ITEM_COLOR) if new_episodes else "" total = len(episodes) header = [ { 'label': lang(40401), 'path': plugin.url_for('browse_all_series') }, { 'label': lang(40407) % new_str, 'path': plugin.url_for('browse_library'), 'context_menu': update_library_menu() }, ] items = [] if skip: skip_prev = max(skip - per_page, 0) total += 1 items.append({ 'label': lang(34003), 'path': plugin.request.url_with_params(skip=skip_prev) }) elif header: items.extend(header) total += len(header) plugin.add_items(with_fanart(items), total) for batch_res in batch(episodes, BATCH_EPISODES_COUNT): if abort_requested(): break items = itemify_episodes(batch_res) plugin.add_items(with_fanart(items), total) items = [] if scraper.has_more: skip_next = (skip or 0) + per_page items.append({ 'label': lang(34004), 'path': plugin.request.url_with_params(skip=skip_next) }) plugin.finish(items=with_fanart(items), cache_to_disc=False, update_listing=skip is not None)
def create_lostfilm_source(): from support.sources import Sources, TvDbScraperSettings, SourceAlreadyExists sources = Sources() plugin.log.info("Creating LostFilm.TV source...") try: sources.add_video(plugin.get_setting('library-path', unicode), 'LostFilm.TV', TvDbScraperSettings()) except SourceAlreadyExists: plugin.set_setting('lostfilm-source-created', True) raise LocalizedError(40408, "Source is already exist") plugin.log.info("LostFilm.TV source created, restart needed...") plugin.set_setting('lostfilm-source-created', True) d = xbmcgui.Dialog() if d.yesno(lang(40404), lang(40405)): xbmc.executebuiltin('Quit')
def safe_update_library(): try: if is_authorized(): return update_library() except LocalizedError as e: e.log() if e.kwargs.get('dialog'): xbmcgui.Dialog().ok(lang(30000), *e.localized.split("|")) else: notify(e.localized) except Exception as e: plugin.log.exception(e) notify(lang(40410)) finally: plugin.close_storages() return False
def mark_series_watched_menu(series): """ :type series: Series """ return [(lang(40312), actions.background( plugin.url_for('mark_series_watched', series_id=series.id)))]
def update_library(): plugin.log.info("Starting LostFilm.TV library update...") progress = xbmcgui.DialogProgressBG() scraper = get_scraper() series_ids = library_items() if plugin.get_setting('sync_favorites', bool) and plugin.get_setting( 'enable_sync', bool): fav_ids = scraper.get_favorite_series() series_ids = list(set(series_ids + fav_ids)) total = len(series_ids) lib = get_library() processed = 0 with closing(progress): progress.create(lang(30000), lang(40409)) series_episodes = {} for ids in batch(series_ids, BATCH_SERIES_COUNT): series_episodes.update(scraper.get_series_episodes_bulk(ids)) processed += len(ids) progress.update(processed * 100 / total) if abort_requested(): return medias = [] for series_id, episodes in series_episodes.iteritems(): medias.extend( library.Episode(folder=e.series_title, title=e.episode_title.replace(u'й', u'й'), season_number=e.season_number, episode_number=e.episode_numbers, url=episode_url(e), time_added=e.release_date, episode=e) for e in episodes if not e.is_complete_season) lib.sync(medias) new_episodes = library_new_episodes() new_episodes |= NewEpisodes(lib.added_medias) if plugin.get_setting('update-xbmc-library', bool): if lib.added_medias or lib.created_medias or lib.updated_medias: plugin.wait_library_scan() plugin.log.info("Starting XBMC library update...") plugin.update_library('video', plugin.get_setting('library-path', unicode)) if lib.removed_files: plugin.wait_library_scan() plugin.log.info("Starting XBMC library clean...") plugin.clean_library('video') plugin.log.info("LostFilm.TV library update finished.") return lib.added_medias or lib.created_medias or lib.updated_medias or lib.removed_files
def toggle_episode_watched_menu(episode): """ :type episode: Episode """ return [(lang(40151), actions.background(plugin.url_for('toggle_episode_watched', series_id=episode.series_id, episode=episode.episode_number, season=episode.season_number)))]
def authorize(self): with Timer(logger=self.log, name='Authorization'): if '@' not in self.login: raise ScraperError(32019, "E-Mail %s not contain @" % self.login, self.login, check_settings=True) if not self.authorized(): res = self.api.auth(mail=self.login, password=self.password) self.log.error(repr(res)) if res['result'] == 'ok' and res.get('success'): self.session.cookies['hash'] = self.authorization_hash elif res.get('need_captcha'): self.log.debug('NEED CAPTCHA') dialog = xbmcgui.Dialog() dialog.ok(lang(30000), lang(40412)) raise ScraperError(32003, "Authorization failed. Captcha", check_settings=False) else: self.log.debug(res) raise ScraperError(32003, "Authorization failed", check_settings=True)
def download_menu(e): from xbmcswift2 import actions if plugin.get_setting('torrent-client', int): return [(lang(40308), actions.background(plugin.url_for('download', series=e.series_id, season=e.season_number, episode=e.episode_number)))] else: return []
def update(self, percent): if not self.overlay.visible: return heading = "%s - %d%%" % (self.state.localized, percent) self.heading.setLabel(heading) self.title.setLabel(self.name) lines = [] if self.state in [TorrentStatus.DOWNLOADING, TorrentStatus.CHECKING, TorrentStatus.SEEDING, TorrentStatus.PREBUFFERING]: size = self._human_size(self.size) if self.size >= 0 else lang(33015) lines.append(lang(33016) % {'transferred': self._human_size(self._transferred_bytes), 'total': size}) if self.state != TorrentStatus.CHECKING: lines.append(lang(33014) % {'download_rate': self._human_rate(self.download_rate), 'upload_rate': self._human_rate(self.upload_rate), 'peers': self.peers, 'seeds': self.seeds}) self.label.setLabel("\n".join(lines))
def update(self, percent): lines = [] if self.name is not None: lines.append(lang(33011) % {'name': self.name}) if self.state in [TorrentStatus.DOWNLOADING, TorrentStatus.SEEDING, TorrentStatus.CHECKING, TorrentStatus.PREBUFFERING]: size = self._human_size(self.size) if self.size >= 0 else lang(33015) lines.append(lang(33013) % {'transferred': self._human_size(self._transferred_bytes), 'total': size, 'state': self.state.localized}) if self.state != TorrentStatus.CHECKING: lines.append(lang(33014) % {'download_rate': self._human_rate(self.download_rate), 'upload_rate': self._human_rate(self.upload_rate), 'peers': self.peers, 'seeds': self.seeds}) else: lines.append(lang(33012) % {'state': self.state.localized}) return self.handler.update(percent, *lines)
def fetch(self, url, params=None, data=None, **request_params): try: with Timer(logger=self.log, name='Fetching URL %s with params %r' % (url, params)): response = self.session.request('post' if data else 'get', url, params=params, data=data, **request_params) response.raise_for_status() self.save_cookies() return response except Timeout as e: raise ScraperError(32000, "Timeout while fetching URL: %s (%%s)" % url, lang(30000), cause=e) except NoValidProxiesFound as e: raise ScraperError(32005, "Can't find anonymous proxy", cause=e) except RequestException as e: raise ScraperError(32001, "Can't fetch URL: %s (%%s)" % url, lang(30000), cause=e) except ProxyListException as e: plugin.set_setting('use-proxy', 0) raise ScraperError(32004, "Can't load anonymous proxy list", cause=e)
def index(): plugin.set_content('episodes') skip = plugin.request.arg('skip') per_page = plugin.get_setting('per-page', int) scraper = get_scraper() episodes = scraper.browse_episodes(skip) if episodes and not skip: check_last_episode(episodes[0]) check_first_start() new_episodes = library_new_episodes() new_str = "(%s) " % tf.color(str(len(new_episodes)), NEW_LIBRARY_ITEM_COLOR) if new_episodes else "" total = len(episodes) header = [ {'label': lang(40401), 'path': plugin.url_for('browse_all_series')}, {'label': lang(40407) % new_str, 'path': plugin.url_for('browse_library'), 'context_menu': update_library_menu()}, ] items = [] if skip: skip_prev = max(skip - per_page, 0) total += 1 items.append({ 'label': lang(34003), 'path': plugin.request.url_with_params(skip=skip_prev) }) elif header: items.extend(header) total += len(header) plugin.add_items(with_fanart(items), total) for batch_res in batch(episodes, BATCH_EPISODES_COUNT): if abort_requested(): break items = itemify_episodes(batch_res) plugin.add_items(with_fanart(items), total) items = [] if scraper.has_more: skip_next = (skip or 0) + per_page items.append({ 'label': lang(34004), 'path': plugin.request.url_with_params(skip=skip_next) }) plugin.finish(items=with_fanart(items), cache_to_disc=False, update_listing=skip is not None)
def fetch(self, url, params=None, data=None, **request_params): try: with Timer(logger=self.log, name='Fetching URL %s with params %r' % (url, params)): response = self.session.request('post' if data else 'get', url, params=params, data=data, headers={'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/601.4.4 (KHTML, like Gecko) Version/9.0.3 Safari/601.4.4'}, **request_params) response.raise_for_status() self.save_cookies() return response except Timeout as e: raise ScraperError(32000, "Timeout while fetching URL: %s (%%s)" % url, lang(30000), cause=e) except NoValidProxiesFound as e: raise ScraperError(32005, "Can't find anonymous proxy", cause=e) except RequestException as e: raise ScraperError(32001, "Can't fetch URL: %s (%%s)" % url, lang(30000), cause=e) except ProxyListException as e: plugin.set_setting('use-proxy', 0) raise ScraperError(32004, "Can't load anonymous proxy list", cause=e)
def update_library(): plugin.log.info("Starting LostFilm.TV library update...") progress = xbmcgui.DialogProgressBG() scraper = get_scraper() series_ids = library_items() total = len(series_ids) lib = get_library() processed = 0 with closing(progress): progress.create(lang(30000), lang(40409)) series_episodes = {} for ids in batch(series_ids, BATCH_SERIES_COUNT): series_episodes.update(scraper.get_series_episodes_bulk(ids)) sleep(2000) processed += len(ids) progress.update(processed * 100 / total) if abort_requested(): return medias = [] for series_id, episodes in series_episodes.iteritems(): medias.extend(library.Episode(folder=e.series_title, title=e.episode_title, season_number=e.season_number, episode_number=e.episode_numbers, url=episode_url(e), time_added=e.release_date, episode=e) for e in episodes if not e.is_complete_season) lib.sync(medias) new_episodes = library_new_episodes() new_episodes |= NewEpisodes(lib.added_medias) if plugin.get_setting('update-xbmc-library', bool): if lib.added_medias or lib.created_medias or lib.updated_medias: plugin.wait_library_scan() plugin.log.info("Starting XBMC library update...") plugin.update_library('video', plugin.get_setting('library-path', unicode)) if lib.removed_files: plugin.wait_library_scan() plugin.log.info("Starting XBMC library clean...") plugin.clean_library('video') plugin.log.info("LostFilm.TV library update finished.") return lib.added_medias or lib.created_medias or lib.updated_medias or lib.removed_files
def fetch(self, url, params=None, data=None, **request_params): try: with Timer(logger=self.log, log_level=logging.DEBUG, name='Fetching URL %s with params %r' % (url, params)): response = self.session.request('post' if data else 'get', url, params=params, data=data, **request_params) response.raise_for_status() self.save_cookies() return response except Timeout as e: raise ScraperError(32000, "Timeout while fetching URL: %s (%%s)" % url, lang(30000), cause=e) except RequestException as e: raise ScraperError(32001, "Can't fetch URL: %s (%%s)" % url, lang(30000), cause=e)
def select_torrent_link(series, season, episode, force=False): scraper = get_scraper() links = scraper.get_torrent_links(series, season, episode) qualities = sorted(Quality) quality = plugin.get_setting('quality', int) ordered_links = [next((l for l in links if l.quality == q), None) for q in qualities] if not quality or force or not ordered_links[quality - 1]: filtered_links = [l for l in ordered_links if l] if not filtered_links: return options = ["%s / %s" % (tf.color(l.quality.localized, 'white'), tf.human_size(l.size)) for l in filtered_links] res = xbmcgui.Dialog().select(lang(40400), options) if res < 0: return return filtered_links[res] else: return ordered_links[quality - 1]
def search(): skbd = xbmc.Keyboard() skbd.setHeading(lang(40423)) skbd.doModal() if skbd.isConfirmed(): query = skbd.getText() else: return None plugin.set_content('tvshows') scraper = get_scraper() library = scraper.search_serial(query) total = len(library) for batch_ids in batch(library, BATCH_SERIES_COUNT): if abort_requested(): break series = scraper.get_series_bulk(batch_ids) items = [itemify_series(series[i]) for i in batch_ids] plugin.add_items(with_fanart(items), total) plugin.finish(sort_methods=['unsorted', 'label'])
def __init__(self, name=None, size=-1, heading=None): AbstractTorrentTransferProgress.__init__(self, name, size) heading = heading or lang(33010) self.handler = XbmcProgress(heading)
def get_series_episodes(self, series_id, series_alias=None): if not series_alias: series_alias = self.shows_ids_dict[int(series_id)] doc = self._get_episodes_doc(series_alias) episodes = [] with Timer(logger=self.log, name='Parsing episodes of series with ID %s' % series_alias): title = doc.find('div', {'class': 'header'}) series_title = title.find('h2', {'class': 'title-en'}).text image = img_url(series_id) icon = image.replace('/poster.jpg', '/image.jpg') episodes_data = doc.find('div', {'class': 'series-block'}) seasons = episodes_data.find('div', {'class': 'serie-block'}) year = seasons.last.find('div', {'class': 'details'}).text year = re.search('Год: (\d{4})', year) year = year.group(1) if year else None if year: series_title += " (%s)" % year for s in seasons: fullseason = s.find('div', {'class': 'movie-details-block'}) inactive = fullseason.find('div', {'class': 'external-btn inactive'}) if not inactive: button = fullseason.find('div', {'class': 'haveseen-btn.*?'}).attr('data-code') if button: series_id, season_number, episode_number = parse_data_code(button) episode_title = lang(40424) % season_number orig_title = "" release_date=str_to_date("17.09.1989", "%d.%m.%Y") poster = img_url(series_id, season_number, episode_number) episode = Episode(series_id, series_title, season_number, episode_number, episode_title, orig_title, release_date, icon, poster, image) episodes.append(episode) episodes_table = s.find('table', {'class': 'movie-parts-list'}) if not episodes_table.attrs('id')[0]: self.log.warning("No ID for table. New season of {0}".format(series_title)) continue if episodes_table.attrs('id')[0][-6:] == u'999999': pass # IS SPECIAL SEASON titles = episodes_table.find('td', {'class': 'gamma.*?'}) orig_titles = titles.find('span').strings episode_titles = [t.split('\n')[0].strip().replace(u"й", u"й").replace(u"И", u"Й") for t in titles.strings] #episode_dates = [str(d.split(':')[-1])[1:] for d in episodes_table.find('td', {'class': 'delta'}).strings] episode_dates = [] for d in episodes_table.find('td', {'class': 'delta'}).strings: d = d.split(':') d = d[-1] d = d[1:] d = d.replace('янв ', '01.01.').replace('фев ', '01.02.').replace('мар ', '01.03').replace('апр','01.04')\ .replace('май','01.05').replace('июн','01.06').replace('июл','01.07').replace('авг','01.08').replace('сен','01.09')\ .replace('окт','01.10').replace('ноя','01.11').replace('дек','01.12') it = str(d) episode_dates.append(it) onclick = episodes_table.find('div', {'class': 'haveseen-btn.*?'}).attrs('data-code') for e in range(len(onclick)): data_code = onclick[e] if not data_code: continue _, season_number, episode_number = parse_data_code(onclick[e]) episode_title = episode_titles[e] orig_title = orig_titles[e] release_date = str_to_date(episode_dates[e], "%d.%m.%Y") poster = img_url(series_id, season_number, episode_number) episode = Episode(series_id, series_title, season_number, episode_number, episode_title, orig_title, release_date, icon, poster, image) episodes.append(episode) self.log.info("Got %d episode(s) successfully" % (len(episodes))) self.log.debug(repr(episodes).decode("unicode-escape")) return episodes
def mark_series_watched_menu(series): """ :type series: Series """ return [(lang(40312), actions.background(plugin.url_for('mark_series_watched', series_id=series.id)))]
def info_menu(obj): lang_id = 40306 if isinstance(obj, Series) else 40300 return [(lang(lang_id), "Action(Info)")]
def go_to_series_menu(s): return [(lang(40307), actions.update_view(series_url(s)))]
def check_first_start(): if is_authorized() and not plugin.get_setting('first-start', bool): d = xbmcgui.Dialog() plugin.set_setting('first-start', 'true') if d.yesno(lang(40402), *(lang(40403).split("|"))): create_lostfilm_source()
def update_library_menu(): return [(lang(40311), actions.background(plugin.url_for('update_library_on_demand')))]