Files
addon/specials/searchall.py
2019-05-24 23:19:40 +02:00

867 lines
33 KiB
Python

# -*- coding: utf-8 -*-
import datetime
import glob
import os
import re
import threading
import time
import urllib
from threading import Thread
from unicodedata import normalize
import Queue
import xbmc
from lib.fuzzywuzzy import fuzz
from core import channeltools, httptools, tmdb, servertools
from platformcode import platformtools
try:
import json
except:
import simplejson as json
from platformcode import config
from platformcode import logger
from core.item import Item
TMDB_KEY = tmdb.tmdb_auth_key ######TMDB_KEY = '92db8778ccb39d825150332b0a46061d'
# TMDB_KEY = '92db8778ccb39d825150332b0a46061d'
TMDB_URL_BASE = 'http://api.themoviedb.org/3/'
TMDB_IMAGES_BASEURL = 'http://image.tmdb.org/t/p/'
INCLUDE_ADULT = True if config.get_setting("enableadultmode") else False
LANGUAGE_ID = 'it'
DTTIME = (datetime.datetime.utcnow() - datetime.timedelta(hours=5))
SYSTIME = DTTIME.strftime('%Y%m%d%H%M%S%f')
TODAY_TIME = DTTIME.strftime('%Y-%m-%d')
MONTH_TIME = (DTTIME - datetime.timedelta(days=30)).strftime('%Y-%m-%d')
MONTH2_TIME = (DTTIME - datetime.timedelta(days=60)).strftime('%Y-%m-%d')
YEAR_DATE = (DTTIME - datetime.timedelta(days=365)).strftime('%Y-%m-%d')
TIMEOUT_TOTAL = config.get_setting("timeout")
MAX_THREADS = config.get_setting("maxthreads")
# TIMEOUT_TOTAL = config.get_setting("timeout", default=90)
# MAX_THREADS = config.get_setting("maxthreads", default=24)
NLS_Search_by_Channel = config.get_localized_string(30974)
NLS_Alternative_Search = config.get_localized_string(70021)
NLS_Search_by_Title = config.get_localized_string(30980)
NLS_Search_by_Person = config.get_localized_string(30981)
NLS_Search_by_Company = config.get_localized_string(30982)
NLS_Now_Playing = config.get_localized_string(30983)
NLS_Popular = config.get_localized_string(30984)
NLS_Top_Rated = config.get_localized_string(30985)
NLS_Search_by_Collection = config.get_localized_string(30986)
NLS_List_by_Genre = config.get_localized_string(30987)
NLS_Search_by_Year = config.get_localized_string(30988)
NLS_Search_Similar_by_Title = config.get_localized_string(30989)
NLS_Search_Tvshow_by_Title = config.get_localized_string(30990)
NLS_Most_Voted = config.get_localized_string(30996)
NLS_Oscar = config.get_localized_string(30997)
NLS_Last_2_months = config.get_localized_string(60534)
NLS_Library = config.get_localized_string(30991)
NLS_Next_Page = config.get_localized_string(30992)
NLS_Looking_For = config.get_localized_string(30993)
NLS_Searching_In = config.get_localized_string(30994)
NLS_Found_So_Far = config.get_localized_string(30995)
NLS_Info_Title = config.get_localized_string(30975)
NLS_Info_Person = config.get_localized_string(30979)
NLS_New_TVShow = config.get_localized_string(30978)
NLS_TVShow_onair = config.get_localized_string(30977)
NLS_TVShow_airing_today = config.get_localized_string(30976)
TMDb_genres = {}
def mainlist(item):
logger.info(" mainlist")
itemlist = [Item(channel="search",
title="[COLOR lightgreen]%s[/COLOR]" % NLS_Search_by_Channel,
action="mainlist",
thumbnail="http://i.imgur.com/pE5WSZp.png"),
Item(channel="tvmoviedb",
title="[COLOR yellow]%s[/COLOR]" % NLS_Alternative_Search,
action="mainlist",
url="search_movie_by_title",
thumbnail="https://s6.postimg.cc/6lll9b8c1/searching.png"),
Item(channel=item.channel,
title="[COLOR yellow]%s[/COLOR]" % NLS_Search_by_Title,
action="search",
url="search_movie_by_title",
thumbnail="http://i.imgur.com/B1H1G8U.png"),
Item(channel=item.channel,
title="[COLOR yellow]%s[/COLOR]" % NLS_Search_by_Person,
action="search",
url="search_person_by_name",
thumbnail="http://i.imgur.com/efuEeNu.png"),
Item(channel=item.channel,
title="[COLOR yellow]%s[/COLOR]" % NLS_Search_by_Year,
action="search_movie_by_year",
url="search_movie_by_year",
thumbnail="https://d1kz0yd1invg7i.cloudfront.net/uploads/app/icon/1/calendar-icon-big.png"),
Item(channel=item.channel,
title="[COLOR yellow]%s[/COLOR]" % NLS_Search_by_Collection,
action="search",
url="search_collection_by_name",
thumbnail="http://i.imgur.com/JmcvZDL.png"),
Item(channel=item.channel,
title="[COLOR yellow]%s[/COLOR]" % NLS_Search_Similar_by_Title,
action="search",
url="search_similar_movie_by_title",
thumbnail="http://i.imgur.com/JmcvZDL.png"),
Item(channel=item.channel,
title="[COLOR lime]%s[/COLOR]" % NLS_Search_Tvshow_by_Title,
action="search",
url="search_tvshow_by_title",
thumbnail="https://i.imgur.com/2ZWjLn5.jpg?1"),
Item(channel=item.channel,
title="(TV Shows) [COLOR lime]%s[/COLOR]" % NLS_New_TVShow,
action="list_tvshow",
url='discover/tv?sort_by=popularity.desc&first_air_date.gte=%s&first_air_date.lte=%s&' % (
MONTH2_TIME, TODAY_TIME),
plot="1",
type="tvshow",
thumbnail="https://i.imgur.com/2ZWjLn5.jpg?1"),
Item(channel=item.channel,
title="(TV Shows) [COLOR lime]%s[/COLOR]" % NLS_TVShow_onair,
action="list_tvshow",
url="tv/on_the_air?",
plot="1",
type="tvshow",
thumbnail="https://i.imgur.com/2ZWjLn5.jpg?1"),
Item(channel=item.channel,
title="(TV Shows) [COLOR lime]%s[/COLOR]" % NLS_Popular,
action="list_tvshow",
url="tv/popular?",
plot="1",
type="tvshow",
thumbnail="https://i.imgur.com/2ZWjLn5.jpg?1"),
Item(channel=item.channel,
title="(TV Shows) [COLOR lime]%s[/COLOR]" % NLS_Top_Rated,
action="list_tvshow",
url="tv/top_rated?",
plot="1",
type="tvshow",
thumbnail="https://i.imgur.com/2ZWjLn5.jpg?1"),
Item(channel=item.channel,
title="(TV Shows) [COLOR lime]%s[/COLOR]" % NLS_TVShow_airing_today,
action="list_tvshow",
url="tv/airing_today?",
plot="1",
type="tvshow",
thumbnail="https://i.imgur.com/2ZWjLn5.jpg?1"),
Item(channel=item.channel,
title="(Movies) [COLOR yellow]%s[/COLOR]" % NLS_Now_Playing,
action="list_movie",
url="movie/now_playing?",
plot="1",
type="movie",
thumbnail="http://i.imgur.com/B16HnVh.png"),
Item(channel=item.channel,
title="(Movies) [COLOR yellow]%s[/COLOR]" % NLS_Popular,
action="list_movie",
url="movie/popular?",
plot="1",
type="movie",
thumbnail="http://i.imgur.com/8IBjyzw.png"),
Item(channel=item.channel,
title="(Movies) [COLOR yellow]%s[/COLOR]" % NLS_Top_Rated,
action="list_movie",
url="movie/top_rated?",
plot="1",
type="movie",
thumbnail="http://www.clipartbest.com/cliparts/RiG/6qn/RiG6qn79T.png"),
Item(channel=item.channel,
title="(Movies) [COLOR yellow]%s[/COLOR]" % NLS_Most_Voted,
action="list_movie",
url='discover/movie?certification_country=US&sort_by=vote_count.desc&',
plot="1",
type="movie",
thumbnail="http://i.imgur.com/5ShnO8w.png"),
Item(channel=item.channel,
title="(Movies) [COLOR yellow]%s[/COLOR]" % NLS_Oscar,
action="list_movie",
url='list/509ec17b19c2950a0600050d?',
plot="1",
type="movie",
thumbnail="http://i.imgur.com/5ShnO8w.png"),
Item(channel=item.channel,
title="(Movies) [COLOR yellow]%s[/COLOR]" % NLS_Last_2_months,
action="list_movie",
url='discover/movie?primary_release_date.gte=%s&primary_release_date.lte=%s&' % (
YEAR_DATE, MONTH2_TIME),
plot="1",
type="movie",
thumbnail="http://i.imgur.com/CsizqUI.png"),
Item(channel=item.channel,
title="(Movies) [COLOR yellow]%s[/COLOR]" % NLS_List_by_Genre,
action="list_genres",
type="movie",
thumbnail="http://i.imgur.com/uotyBbU.png")]
return itemlist
def list_movie(item):
logger.info(" list_movie '%s/%s'" % (item.url, item.plot))
results = [0, 0]
page = int(item.plot)
itemlist = build_movie_list(item, tmdb_get_data('%s&page=%d&' % (item.url, page), results=results))
if page < results[0]:
itemlist.append(Item(
channel=item.channel,
title="[COLOR orange]%s (%d/%d)[/COLOR]" % (NLS_Next_Page, page * len(itemlist), results[1]),
action="list_movie",
url=item.url,
plot="%d" % (page + 1),
type=item.type,
viewmode="" if page <= 1 else "paged_list"))
return itemlist
def list_tvshow(item):
logger.info(" list_tvshow '%s/%s'" % (item.url, item.plot))
results = [0, 0]
page = int(item.plot)
itemlist = build_movie_list(item, tmdb_get_data('%spage=%d&' % (item.url, page), results=results))
if page < results[0]:
itemlist.append(Item(
channel=item.channel,
title="[COLOR orange]%s (%d/%d)[/COLOR]" % (NLS_Next_Page, page * len(itemlist), results[1]),
action="list_tvshow",
url=item.url,
plot="%d" % (page + 1),
type=item.type,
viewmode="" if page <= 1 else "paged_list"))
return itemlist
def list_genres(item):
logger.info(" list_genres")
tmdb_genre(1)
itemlist = []
for genre_id, genre_name in TMDb_genres.iteritems():
itemlist.append(
Item(channel=item.channel,
title=genre_name,
action="list_movie",
url='genre/%d/movies?primary_release_date.gte=%s&primary_release_date.lte=%s&language=it' % (
genre_id, YEAR_DATE, TODAY_TIME),
plot="1"))
return itemlist
def discover_list(item):
from platformcode import unify
from core import scrapertools
itemlist = []
result = tmdb.discovery(item)
tvshow = False
logger.debug(item)
for elem in result:
elem['tmdb_id'] = elem['id']
if 'title' in elem:
title = unify.normalize(elem['title']).capitalize()
elem['year'] = scrapertools.find_single_match(elem['release_date'], '(\d{4})-\d+-\d+')
else:
title = unify.normalize(elem['name']).capitalize()
tvshow = True
new_item = Item(channel='searchall', title=title, infoLabels=elem, action='search_tmdb', extra=title,
category=config.get_localized_string(70695), context='')
if tvshow:
new_item.contentSerieName = title
else:
new_item.contentTitle = title
itemlist.append(new_item)
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
if item.page != '' and len(itemlist) > 0:
next_page = str(int(item.page) + 1)
# if not 'similar' in item.list_type:
# itemlist.append(item.clone(title='Pagina Siguente', page=next_page))
# else:
itemlist.append(Item(channel=item.channel, action='discover_list', title=config.get_localized_string(30992),
text_color="orange", search_type=item.search_type, list_type=item.list_type,
type=item.type, page=next_page))
return itemlist
# Do not change the name of this function otherwise launcher.py won't create the keyboard dialog required to enter the search terms
def search(item, search_terms):
if item.url == '': return []
return globals()[item.url](item, search_terms) if item.url in globals() else []
def search_tvshow_by_title(item, search_terms):
logger.info(" search_tvshow_by_title '%s'" % (search_terms))
return list_movie(
Item(channel=item.channel,
url='search/tv?query=%s&' % search_terms,
plot="1",
type="tvshow"))
def search_movie_by_title(item, search_terms):
logger.info(" search_movie_by_title '%s'" % (search_terms))
return list_movie(
Item(channel=item.channel,
url='search/movie?query=%s&' % search_terms,
plot="1",
type="movie"))
def search_similar_movie_by_title(item, search_terms):
logger.info(" search_similar_movie_by_title '%s'" % (search_terms))
return list_movie(
Item(channel=item.channel,
url='search/movie?append_to_response=similar_movies,alternative_title&query=%s&' % search_terms,
plot="1",
type='movie'))
def search_movie_by_year(item):
logger.info(" search_movie_by_year")
now = datetime.datetime.now()
year = int(now.year)
result = []
for i in range(150):
year_to_search = year - i
result.append(Item(channel=item.channel,
url='discover/movie?primary_release_year=%s&' % year_to_search,
plot="1",
type="movie",
title="%s" % year_to_search,
action="list_movie"))
return result
def search_person_by_name(item, search_terms):
logger.info(" search_person_by_name '%s'" % (search_terms))
persons = tmdb_get_data("search/person?query=%s&" % search_terms)
itemlist = []
for person in persons:
name = normalize_unicode(tmdb_tag(person, 'name'))
poster = tmdb_image(person, 'profile_path')
fanart = ''
for movie in tmdb_tag(person, 'known_for', []):
if tmdb_tag_exists(movie, 'backdrop_path'):
fanart = tmdb_image(movie, 'backdrop_path', 'w1280')
break
# extracmds = [
# (NLS_Info_Person, "RunScript(script.extendedinfo,info=extendedactorinfo,id=%s)" % str(tmdb_tag(person, 'id')))] \
# if xbmc.getCondVisibility('System.HasAddon(script.extendedinfo)') else []
itemlist.append(Item(
channel=item.channel,
action='search_movie_by_person',
extra=str(tmdb_tag(person, 'id')),
title=name,
thumbnail=poster,
viewmode='list',
fanart=fanart,
type='movie'
# extracmds=extracmds
))
return itemlist
def search_movie_by_person(item):
logger.info(" search_movie_by_person '%s'" % (item.extra))
# return list_movie(
# Item(channel=item.channel,
# url="discover/movie?with_people=%s&primary_release_date.lte=%s&sort_by=primary_release_date.desc&" % (
# item.extra, TODAY_TIME),
# plot="1"))
person_movie_credits = tmdb_get_data(
"person/%s/movie_credits?primary_release_date.lte=%s&sort_by=primary_release_date.desc&" % (
item.extra, TODAY_TIME))
movies = []
if person_movie_credits:
movies.extend(tmdb_tag(person_movie_credits, 'cast', []))
movies.extend(tmdb_tag(person_movie_credits, 'crew', []))
# Movie person list is not paged
return build_movie_list(item, movies)
def search_collection_by_name(item, search_terms):
logger.info(" search_collection_by_name '%s'" % (search_terms))
collections = tmdb_get_data("search/collection?query=%s&" % search_terms)
itemlist = []
for collection in collections:
name = normalize_unicode(tmdb_tag(collection, 'name'))
poster = tmdb_image(collection, 'poster_path')
fanart = tmdb_image(collection, 'backdrop_path', 'w1280')
itemlist.append(Item(
channel=item.channel,
action='search_movie_by_collection',
extra=str(tmdb_tag(collection, 'id')),
title=name,
thumbnail=poster,
viewmode='list',
fanart=fanart,
type='movie'
))
return itemlist
def search_movie_by_collection(item):
logger.info(" search_movie_by_collection '%s'" % (item.extra))
collection = tmdb_get_data("collection/%s?" % item.extra)
# Movie collection list is not paged
return build_movie_list(item, collection['parts']) if 'parts' in collection else []
def build_movie_list(item, movies):
if movies is None: return []
itemlist = []
for movie in movies:
t = tmdb_tag(movie, 'title')
if t == '':
t = re.sub('\s(|[(])(UK|US|AU|\d{4})(|[)])$', '', tmdb_tag(movie, 'name'))
title = normalize_unicode(t)
title_search = normalize_unicode(t, encoding='ascii')
if not all(ord(char) < 128 for char in title): continue
poster = tmdb_image(movie, 'poster_path')
fanart = tmdb_image(movie, 'backdrop_path', 'w1280')
jobrole = normalize_unicode(
' [COLOR yellow][' + tmdb_tag(movie, 'job') + '][/COLOR]' if tmdb_tag_exists(movie, 'job') else '')
genres = normalize_unicode(
' / '.join([tmdb_genre(genre).upper() for genre in tmdb_tag(movie, 'genre_ids', [])]))
year = tmdb_tag(movie, 'release_date')[0:4] if tmdb_tag_exists(movie, 'release_date') else ''
plot = normalize_unicode(tmdb_tag(movie, 'overview'))
rating = tmdb_tag(movie, 'vote_average')
votes = tmdb_tag(movie, 'vote_count')
extrameta = {'plot': plot}
if year != "": extrameta["Year"] = year
if genres != "": extrameta["Genre"] = genres
if votes:
extrameta["Rating"] = rating
extrameta["Votes"] = "%d" % votes
# extracmds = [(NLS_Info_Title, "RunScript(script.extendedinfo,info=extendedinfo,id=%s)" % str(tmdb_tag(movie, 'id')))] \
# if xbmc.getCondVisibility('System.HasAddon(script.extendedinfo)') else [('Movie/Show Info', 'XBMC.Action(Info)')]
found = False
kodi_db_movies = kodi_database_movies(title)
for kodi_db_movie in kodi_db_movies:
logger.info('Kod.database set for local playing(%s):\n%s' % (title, str(kodi_db_movie)))
if year == str(kodi_db_movie["year"]):
found = True
# If some, less relevant, keys are missing locally
# try to get them through TMDB anyway.
try:
poster = kodi_db_movie["art"]["poster"]
fanart = kodi_db_movie["art"]["fanart"]
except KeyError:
poster = poster
fanart = fanart
itemlist.append(Item(
channel=item.channel,
action='play',
url=kodi_db_movie["file"],
title='[COLOR orange][%s][/COLOR] ' % NLS_Library + kodi_db_movie["title"] + jobrole,
thumbnail=poster,
category=genres,
plot=plot,
viewmode='movie_with_plot',
fanart=fanart,
infoLabels=extrameta,
folder=False,
))
if not found:
logger.info('Kod.database set for channels search(%s)' % title)
itemlist.append(Item(
channel=item.channel,
action='do_channels_search',
extra=url_quote_plus(title_search) + '{}' + item.type + '{}' + year,
title=title + jobrole,
thumbnail=poster,
category=genres,
plot=plot,
viewmode='movie_with_plot',
fanart=fanart,
infoLabels=extrameta,
))
return itemlist
def normalize_unicode(string, encoding='utf-8'):
if string is None: string = ''
return normalize('NFKD', string if isinstance(string, unicode) else unicode(string, encoding, 'ignore')).encode(
encoding, 'ignore')
def tmdb_get_data(url="", results=[0, 0], language=True):
url = TMDB_URL_BASE + "%sinclude_adult=%s&api_key=%s" % (url, INCLUDE_ADULT, TMDB_KEY)
# Temporary fix until tmdb fixes the issue with getting the genres by language!
if language: url += "&language=%s" % LANGUAGE_ID
response = get_json_response(url)
results[0] = response['total_pages'] if 'total_pages' in response else 0
results[1] = response['total_results'] if 'total_results' in response else 0
if response:
if "results" in response:
return response["results"]
elif "items" in response:
return response["items"]
elif "tv_credits" in response:
return response["tv_credits"]["cast"]
else:
return response
def tmdb_tag_exists(entry, tag):
return isinstance(entry, dict) and tag in entry and entry[tag] is not None
def tmdb_tag(entry, tag, default=""):
return entry[tag] if isinstance(entry, dict) and tag in entry else default
def tmdb_image(entry, tag, width='original'):
return TMDB_IMAGES_BASEURL + width + '/' + tmdb_tag(entry, tag) if tmdb_tag_exists(entry, tag) else ''
def tmdb_genre(id):
if id not in TMDb_genres:
genres = tmdb_get_data("genre/list?", language="it")
for genre in tmdb_tag(genres, 'genres', []):
TMDb_genres[tmdb_tag(genre, 'id')] = tmdb_tag(genre, 'name')
return TMDb_genres[id] if id in TMDb_genres and TMDb_genres[id] != None else str(id)
def kodi_database_movies(title):
json_query = \
'{"jsonrpc": "2.0",\
"params": {\
"sort": {"order": "ascending", "method": "title"},\
"filter": {"operator": "is", "field": "title", "value": "%s"},\
"properties": ["title", "art", "file", "year"]\
},\
"method": "VideoLibrary.GetMovies",\
"id": "libMovies"\
}' % title
response = get_xbmc_jsonrpc_response(json_query)
return response["result"]["movies"] if response and "result" in response and "movies" in response["result"] else []
def get_xbmc_jsonrpc_response(json_query=""):
try:
response = xbmc.executeJSONRPC(json_query)
response = unicode(response, 'utf-8', errors='ignore')
response = json.loads(response)
logger.info(" jsonrpc %s" % response)
except Exception, e:
logger.info(" jsonrpc error: %s" % str(e))
response = None
return response
def url_quote_plus(input_string):
try:
return urllib.quote_plus(input_string.encode('utf8', 'ignore'))
except:
return urllib.quote_plus(unicode(input_string, "utf-8").encode("utf-8"))
def get_json_response(url=""):
response = httptools.downloadpage(url).data
try:
results = json.loads(response)
except:
logger.info(" Exception: Could not get new JSON data from %s" % url)
results = []
return results
def channel_search(queue, channel_parameters, category, title_year, tecleado):
try:
search_results = []
title_search = urllib.unquote_plus(tecleado)
exec "from specials import " + channel_parameters["channel"] + " as module"
mainlist = module.mainlist(Item(channel=channel_parameters["channel"]))
for item in mainlist:
if item.action != "search" or category and item.extra != category:
continue
for res_item in module.search(item.clone(), tecleado):
title = res_item.fulltitle
# If the release year is known, check if it matches the year found in the title
if title_year > 0:
year_match = re.search('\(.*(\d{4}).*\)', title)
if year_match and abs(int(year_match.group(1)) - title_year) > 1:
continue
# Clean up a bit the returned title to improve the fuzzy matching
title = re.sub(r'\(.*\)', '', title) # Anything within ()
title = re.sub(r'\[.*\]', '', title) # Anything within []
# Check if the found title fuzzy matches the searched one
if fuzz.token_sort_ratio(title_search, title) > 85:
res_item.title = "[COLOR azure]" + res_item.title + "[/COLOR][COLOR orange] su [/COLOR][COLOR green]" + \
channel_parameters["title"] + "[/COLOR]"
search_results.append(res_item)
queue.put(search_results)
except:
logger.error("No se puede buscar en: " + channel_parameters["title"])
import traceback
logger.error(traceback.format_exc())
def do_channels_search(item):
logger.info(" do_channels_search")
tecleado, category, title_year = item.extra.split('{}')
try:
title_year = int(title_year)
except:
title_year = 0
itemlist = []
channels_path = os.path.join(config.get_runtime_path(), "channels", '*.json')
logger.info(" channels_path=" + channels_path)
# channel_language = config.get_setting("channel_language")
channel_language = auto_filter()
logger.info(" channel_language=" + channel_language)
if channel_language == "":
channel_language = "all"
logger.info(" channel_language=" + channel_language)
progreso = platformtools.dialog_progress_bg(NLS_Looking_For % urllib.unquote_plus(tecleado))
channel_files = sorted(glob.glob(channels_path))
search_results = Queue.Queue()
completed_channels = 0
number_of_channels = 0
start_time = int(time.time())
for infile in channel_files:
basename_without_extension = os.path.basename(infile)[:-5]
channel_parameters = channeltools.get_channel_parameters(basename_without_extension)
# No busca si es un canal inactivo
if channel_parameters["active"] != True:
continue
# En caso de busqueda por categorias
if category and category not in channel_parameters["categories"]:
continue
# No busca si el canal es en un idioma filtrado
if channel_language != "all" and channel_parameters["language"] != channel_language:
continue
# No busca si es un canal excluido de la busqueda global
include_in_global_search = channel_parameters["include_in_global_search"]
if include_in_global_search == True:
# Buscar en la configuracion del canal
include_in_global_search = config.get_setting("include_in_global_search", basename_without_extension)
if include_in_global_search == False:
continue
t = Thread(target=channel_search, args=[search_results, channel_parameters, category, title_year, tecleado])
t.setDaemon(True)
t.start()
number_of_channels += 1
while threading.active_count() >= MAX_THREADS:
delta_time = int(time.time()) - start_time
if len(itemlist) <= 0:
timeout = None # No result so far,lets the thread to continue working until a result is returned
elif delta_time >= TIMEOUT_TOTAL:
progreso.close()
itemlist = sorted(itemlist, key=lambda item: item.fulltitle)
return itemlist
else:
timeout = TIMEOUT_TOTAL - delta_time # Still time to gather other results
progreso.update(completed_channels * 100 / number_of_channels)
try:
itemlist.extend(search_results.get(timeout=timeout))
completed_channels += 1
except:
progreso.close()
itemlist = sorted(itemlist, key=lambda item: item.fulltitle)
return itemlist
while completed_channels < number_of_channels:
delta_time = int(time.time()) - start_time
if len(itemlist) <= 0:
timeout = None # No result so far,lets the thread to continue working until a result is returned
elif delta_time >= TIMEOUT_TOTAL:
break # At least a result matching the searched title has been found, lets stop the search
else:
timeout = TIMEOUT_TOTAL - delta_time # Still time to gather other results
progreso.update(completed_channels * 100 / number_of_channels)
try:
itemlist.extend(search_results.get(timeout=timeout))
completed_channels += 1
except:
# Expired timeout raise an exception
break
progreso.close()
# todo 1 : impostare una visualizzazione % di avanzamento (serve?)
# todo 2 : verificare la formattazione dei titoli estratti
# todo 3 : gestione numero threads e timeout
if config.get_setting("findlinks") == True and "{}movie{}" in item.extra:
itemlist = links_list(itemlist)
itemlist = sorted(itemlist, key=lambda item: item.title.lower())
else:
itemlist = sorted(itemlist, key=lambda item: item.fulltitle)
return itemlist
def links_list(itemlist):
logger.info(" links_list")
itemlistresults = []
itemlistlist = []
allthreads = []
global_search_results = Queue.Queue()
# create and collect threads
for item in itemlist:
t = Thread(target=list_single_site, args=[global_search_results, item])
t.setDaemon(True)
allthreads.append(t)
# start threads
for thread in allthreads:
try:
thread.start()
except:
logger.error("thread error !")
# join threads, to wait all threads end before going on
for thread in allthreads:
thread.join()
# collect results
while not global_search_results.empty():
for item in global_search_results.get():
if not item_url_in_itemlist(item, itemlistresults):
channelformatteditem = rewrite_item_title(item)
if channelformatteditem is not None:
itemlistresults.append(channelformatteditem)
return itemlistresults
def list_single_site(queue, item):
logger.info(" list_single_site")
channelitemlist = []
try:
# logger.info(item.channel + " start channel search " + time.strftime("%Y-%m-%d %H:%M:%S"))
module_to_call = getattr(__import__("channels"), item.channel)
channelitemlist = module_to_call.findvideos(item)
queue.put(channelitemlist)
# logger.info(item.channel + " end channel search " + time.strftime("%Y-%m-%d %H:%M:%S"))
except:
try:
# logger.info(item.channel + " start servertools search " + time.strftime("%Y-%m-%d %H:%M:%S"))
# logger.info("no findvideos defined in channel functions, calling servertools.findvideos to find links")
servertools_itemlist = []
headers = [['Referer', item.channel]]
data = httptools.downloadpage(item.url, headers=headers).data
list_servertools = servertools.findvideos(data)
for item_servertools in list_servertools:
servertools_itemlist.append(Item(channel=item.channel,
action="play",
fulltitle=item.title,
server=item_servertools[0],
thumbnail=item_servertools[3],
title=item.title,
url=item_servertools[1]))
queue.put(servertools_itemlist)
# logger.info(item.channel + " end servertools search " + time.strftime("%Y-%m-%d %H:%M:%S"))
except Exception, e:
logger.error('exception in list_single_site: ' + str(e))
return channelitemlist
# utility function
def item_url_in_itemlist(item, itemlist):
logger.info(" item_url_in_itemlist")
i = 0
while i < len(itemlist):
if itemlist[i].url == item.url:
# logger.info("elemento eliminato : " + item.url)
return True
i = i + 1
return False
# utility function, optional
def rewrite_item_title(item):
logger.info(" rewrite_item_title")
if "download" not in item.title.lower():
item.title = "[COLOR yellow][%s][/COLOR][COLOR orange][%s][/COLOR] %s" % (
item.server, item.channel, item.fulltitle)
else:
return None
return item