diff --git a/plugin.video.alfa/channels/tvmoviedb.py b/plugin.video.alfa/channels/tvmoviedb.py old mode 100755 new mode 100644 index f2ee9322..16d8e5bd --- a/plugin.video.alfa/channels/tvmoviedb.py +++ b/plugin.video.alfa/channels/tvmoviedb.py @@ -10,6 +10,7 @@ from core import jsontools from core import scrapertools from core.item import Item from core.tmdb import Tmdb +from core import trakt_tools from platformcode import config, logger from platformcode import platformtools @@ -250,7 +251,7 @@ def filmaf(item): def trakt(item): itemlist = [] item.text_color = color1 - token_auth = config.get_setting("token_trakt", "tvmoviedb") + token_auth = config.get_setting("token_trakt", "trakt") page = "?page=1&limit=20&extended=full" if not item.extra: item.extra = "movie" @@ -279,7 +280,7 @@ def trakt(item): item.extra = "movie" # Se comprueba si existe un token guardado y sino se ejecuta el proceso de autentificación if not token_auth: - folder = (config.get_platform() == "plex") + #folder = (config.get_platform() == "plex") itemlist.append(item.clone(title="Vincula tu cuenta trakt", action="auth_trakt", folder=folder)) else: itemlist.append(item.clone(title="Watchlists", action="", text_color=color2)) @@ -589,7 +590,7 @@ def detalles(item): except: pass - token_auth = config.get_setting("token_trakt", "tvmoviedb") + token_auth = config.get_setting("token_trakt", "trakt") if token_auth: itemlist.append(item.clone(title="Gestionar con tu cuenta Trakt", action="menu_trakt")) @@ -1550,7 +1551,7 @@ def detalles_fa(item): except: pass - token_auth = config.get_setting("token_trakt", "tvmoviedb") + token_auth = config.get_setting("token_trakt", "trakt") if token_auth and ob_tmdb.result: itemlist.append(item.clone(title="[Trakt] Gestionar con tu cuenta", action="menu_trakt")) # Acciones si se configura cuenta en FA (Votar y añadir/quitar en listas) @@ -2065,118 +2066,13 @@ def fanartv(item): ##-------------------- SECCION TRAKT.TV ------------------------## def auth_trakt(item): - # Autentificación de cuenta Trakt, proceso parecido a real-debrid - client_id = "a83c1a92d1313bd7ac7baa37a3fc83add26833d4b006f9f9562cae213a761260" - headers = {'Content-Type': 'application/json', 'trakt-api-key': client_id, 'trakt-api-version': '2'} - try: - post = {'client_id': client_id} - post = jsontools.dump(post) - # Se solicita url y código de verificación para conceder permiso a la app - url = "http://api-v2launch.trakt.tv/oauth/device/code" - data = httptools.downloadpage(url, post=post, headers=headers, replace_headers=True).data - data = jsontools.load(data) - item.verify_url = data["verification_url"] - item.user_code = data["user_code"] - item.device_code = data["device_code"] - item.intervalo = data["interval"] - if not item.folder: - token_trakt(item) - else: - itemlist = [] - title = "Accede a esta página: %s" % item.verify_url - itemlist.append(item.clone(title=title, action="")) - title = "Ingresa este código y acepta: %s" % item.user_code - itemlist.append(item.clone(title=title, action="")) - title = "Una vez hecho, pulsa aquí!" - itemlist.append(item.clone(title=title, action="token_trakt")) - return itemlist - except: - import traceback - logger.error(traceback.format_exc()) - - -def token_trakt(item): - client_id = "a83c1a92d1313bd7ac7baa37a3fc83add26833d4b006f9f9562cae213a761260" - client_secret = "cb22e3c36547ba375e5de077fa4aa497daf486e29b92a5b9c25bb17ac39b98bf" - headers = {'Content-Type': 'application/json', 'trakt-api-key': client_id, 'trakt-api-version': '2'} - try: - if item.extra == "renew": - refresh = config.get_setting("refresh_token_trakt", "tvmoviedb") - url = "http://api-v2launch.trakt.tv/oauth/device/token" - post = {'refresh_token': refresh, 'client_id': client_id, 'client_secret': client_secret, - 'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob', 'grant_type': 'refresh_token'} - post = jsontools.dump(post) - data = httptools.downloadpage(url, post, headers, replace_headers=True).data - data = jsontools.load(data) - elif item.action == "token_trakt": - url = "http://api-v2launch.trakt.tv/oauth/device/token" - post = {'code': item.device_code, 'client_id': client_id, 'client_secret': client_secret} - post = jsontools.dump(post) - post = "code=%s&client_id=%s&client_secret=%s" % (item.device_code, client_id, client_secret) - data = httptools.downloadpage(url, post, headers, replace_headers=True).data - data = jsontools.load(data) - else: - import time - dialog_auth = platformtools.dialog_progress("Autentificación. No cierres esta ventana!!", - "1. Entra en la siguiente url: %s" % item.verify_url, - "2. Ingresa este código en la página y acepta: %s" % item.user_code, - "3. Espera a que se cierre esta ventana") - - # Generalmente cada 5 segundos se intenta comprobar si el usuario ha introducido el código - while True: - time.sleep(item.intervalo) - try: - if dialog_auth.iscanceled(): - return - - url = "http://api-v2launch.trakt.tv/oauth/device/token" - post = {'code': item.device_code, 'client_id': client_id, 'client_secret': client_secret} - post = jsontools.dump(post) - data = httptools.downloadpage(url, post, headers, replace_headers=True).data - data = jsontools.load(data) - if "access_token" in data: - # Código introducido, salimos del bucle - break - except: - pass - - try: - dialog_auth.close() - except: - pass - - token = data["access_token"] - refresh = data["refresh_token"] - - config.set_setting("token_trakt", token, "tvmoviedb") - config.set_setting("refresh_token_trakt", refresh, "tvmoviedb") - if not item.folder: - platformtools.dialog_notification("Éxito", "Cuenta vinculada correctamente") - if config.is_xbmc(): - import xbmc - xbmc.executebuiltin("Container.Refresh") - return - - except: - import traceback - logger.error(traceback.format_exc()) - if not item.folder: - return platformtools.dialog_notification("Error", "Fallo en el proceso de vinculación") - token = "" - - itemlist = [] - if token: - itemlist.append(item.clone("Cuenta vinculada con éxito", action="")) - else: - itemlist.append(item.clone("Fallo en el proceso de vinculación", action="")) - - return itemlist + return trakt_tools.auth_trakt() def menu_trakt(item): # Menú con acciones de cuenta trakt (vistas, watchlist, coleccion) itemlist = [] - token_auth = config.get_setting("token_trakt", "tvmoviedb") + token_auth = config.get_setting("token_trakt", "trakt") tipo = item.extra.replace("tv", "show") + "s" title = item.contentType.replace("movie", "película").replace("tvshow", "serie") try: @@ -2219,13 +2115,13 @@ def menu_trakt(item): def acciones_trakt(item): - token_auth = config.get_setting("token_trakt", "tvmoviedb") + token_auth = config.get_setting("token_trakt", "trakt") itemlist = [] item.text_color = color1 item.contentType = item.extra.replace("show", "tvshow") - client_id = "a83c1a92d1313bd7ac7baa37a3fc83add26833d4b006f9f9562cae213a761260" + client_id = "c40ba210716aee87f6a9ddcafafc56246909e5377b623b72c15909024448e89d" headers = [['Content-Type', 'application/json'], ['trakt-api-key', client_id], ['trakt-api-version', '2']] if token_auth: @@ -2238,8 +2134,8 @@ def acciones_trakt(item): url = "http://api-v2launch.trakt.tv/%s" % item.url data = httptools.downloadpage(url, post, headers=headers, replace_headers=True) if data.code == "401": - token_trakt(item.clone(extra="renew")) - token_auth = config.get_setting("token_trakt", "tvmoviedb") + trakt_tools.token_trakt(item.clone(extra="renew")) + token_auth = config.get_setting("token_trakt", "trakt") headers[3][1] = "Bearer %s" % token_auth data = httptools.downloadpage(url, post, headers=headers, replace_headers=True) @@ -2612,7 +2508,7 @@ def detalles_mal(item): except: pass - token_auth = config.get_setting("token_trakt", "tvmoviedb") + token_auth = config.get_setting("token_trakt", "trakt") if token_auth and ob_tmdb.result: itemlist.append(item.clone(title="[Trakt] Gestionar con tu cuenta", action="menu_trakt")) diff --git a/plugin.video.alfa/core/trakt_tools.py b/plugin.video.alfa/core/trakt_tools.py new file mode 100644 index 00000000..c88bd958 --- /dev/null +++ b/plugin.video.alfa/core/trakt_tools.py @@ -0,0 +1,269 @@ +# -*- coding: utf-8 -*- +# -*- Tools for trakt sync -*- +# -*- Created for Alfa-addon -*- +# -*- By the Alfa Develop Group -* + +import os +import xbmc +from core import httptools +from core.item import Item +from platformcode.platformtools import logger, config +from core import jsontools + +client_id = "c40ba210716aee87f6a9ddcafafc56246909e5377b623b72c15909024448e89d" +client_secret = "999164f25832341f0214453bb11c915adb18e9490d6b5e9a707963a5a1bee43e" + +def auth_trakt(): + item = Item() + folder = (config.get_platform() == "plex") + item.folder=folder + # Autentificación de cuenta Trakt + headers = {'Content-Type': 'application/json', 'trakt-api-key': client_id, 'trakt-api-version': '2'} + try: + post = {'client_id': client_id} + post = jsontools.dump(post) + # Se solicita url y código de verificación para conceder permiso a la app + url = "http://api-v2launch.trakt.tv/oauth/device/code" + data = httptools.downloadpage(url, post=post, headers=headers, replace_headers=True).data + data = jsontools.load(data) + item.verify_url = data["verification_url"] + item.user_code = data["user_code"] + item.device_code = data["device_code"] + item.intervalo = data["interval"] + if not item.folder: + token_trakt(item) + + else: + itemlist = [] + title = "Accede a esta página: %s" % item.verify_url + itemlist.append(item.clone(title=title, action="")) + title = "Ingresa este código y acepta: %s" % item.user_code + itemlist.append(item.clone(title=title, action="")) + title = "Una vez hecho, pulsa aquí!" + itemlist.append(item.clone(title=title, action="token_trakt")) + return itemlist + except: + import traceback + logger.error(traceback.format_exc()) + + +def token_trakt(item): + + from platformcode import platformtools + + headers = {'Content-Type': 'application/json', 'trakt-api-key': client_id, 'trakt-api-version': '2'} + try: + if item.extra == "renew": + refresh = config.get_setting("refresh_token_trakt", "trakt") + url = "http://api-v2launch.trakt.tv/oauth/device/token" + post = {'refresh_token': refresh, 'client_id': client_id, 'client_secret': client_secret, + 'redirect_uri': 'urn:ietf:wg:oauth:2.0:oob', 'grant_type': 'refresh_token'} + post = jsontools.dump(post) + data = httptools.downloadpage(url, post, headers, replace_headers=True).data + data = jsontools.load(data) + elif item.action == "token_trakt": + url = "http://api-v2launch.trakt.tv/oauth/device/token" + post = {'code': item.device_code, 'client_id': client_id, 'client_secret': client_secret} + post = jsontools.dump(post) + post = "code=%s&client_id=%s&client_secret=%s" % (item.device_code, client_id, client_secret) + data = httptools.downloadpage(url, post, headers, replace_headers=True).data + data = jsontools.load(data) + else: + import time + dialog_auth = platformtools.dialog_progress("Sincronizar con Trakt. No cierres esta ventana", + "1. Entra en la siguiente url: %s" % item.verify_url, + "2. Ingresa este código en la página y acepta: %s" % item.user_code, + "3. Espera a que se cierre esta ventana") + + # Generalmente cada 5 segundos se intenta comprobar si el usuario ha introducido el código + while True: + time.sleep(item.intervalo) + try: + if dialog_auth.iscanceled(): + config.set_setting("trakt_sync", 'false' ) + return + + url = "http://api-v2launch.trakt.tv/oauth/device/token" + post = {'code': item.device_code, 'client_id': client_id, 'client_secret': client_secret} + post = jsontools.dump(post) + data = httptools.downloadpage(url, post, headers, replace_headers=True).data + data = jsontools.load(data) + if "access_token" in data: + # Código introducido, salimos del bucle + break + except: + pass + + try: + dialog_auth.close() + except: + pass + + token = data["access_token"] + refresh = data["refresh_token"] + + config.set_setting("token_trakt", token, "trakt") + config.set_setting("refresh_token_trakt", refresh, "trakt") + if not item.folder: + platformtools.dialog_notification("Éxito", "Cuenta vinculada correctamente") + if config.is_xbmc(): + import xbmc + xbmc.executebuiltin("Container.Refresh") + return + + except: + import traceback + logger.error(traceback.format_exc()) + if not item.folder: + return platformtools.dialog_notification("Error", "Fallo en el proceso de vinculación") + token = "" + + itemlist = [] + if token: + itemlist.append(item.clone("Cuenta vinculada con éxito", action="")) + else: + itemlist.append(item.clone("Fallo en el proceso de vinculación", action="")) + + return itemlist + + +def get_trakt_watched(id_type, mediatype, update=False): + + logger.info() + + id_list = [] + id_dict = dict() + + token_auth = config.get_setting("token_trakt", "trakt") + + if token_auth: + sync_path = os.path.join(config.get_data_path(), 'settings_channels', 'trakt') + + if os.path.exists(sync_path) and not update: + trakt_node = jsontools.get_node_from_file('trakt', "TRAKT") + if mediatype == 'shows': + return trakt_node['shows'] + if mediatype == 'movies': + return trakt_node['movies'] + + else: + token_auth = config.get_setting("token_trakt", "trakt") + if token_auth: + try: + token_auth = config.get_setting("token_trakt", "trakt") + headers = [['Content-Type', 'application/json'], ['trakt-api-key', client_id], ['trakt-api-version', '2']] + if token_auth: + headers.append(['Authorization', "Bearer %s" % token_auth]) + url = "https://api.trakt.tv/sync/watched/%s" % mediatype + data = httptools.downloadpage(url, headers=headers, replace_headers=True).data + watched_dict = jsontools.load(data) + + if mediatype == 'shows': + + dict_show = dict() + for item in watched_dict: + temp =[] + id = str(item['show']['ids']['tmdb']) + season_dict=dict() + for season in item['seasons']: + ep=[] + number = str(season['number']) + #season_dict = dict() + for episode in season['episodes']: + ep.append(str(episode['number'])) + season_dict[number]=ep + temp.append(season_dict) + dict_show[id] = season_dict + id_dict=dict_show + return id_dict + + elif mediatype == 'movies': + for item in watched_dict: + id_list.append(str(item['movie']['ids'][id_type])) + except: + pass + + return id_list + + +def trakt_check(itemlist): + id_result = '' + #check = u'\u221a' + check = 'v' + get_sync_from_file() + try: + for item in itemlist: + info = item.infoLabels + + if info != '' and info['mediatype'] in ['movie', 'episode'] and item.channel !='videolibrary': + + mediatype = 'movies' + id_type = 'tmdb' + + if info['mediatype'] == 'episode': + mediatype = 'shows' + + if id_result == '': + id_result = get_trakt_watched(id_type, mediatype) + if info['mediatype'] == 'movie': + if info[id_type+'_id'] in id_result: + item.title ='[COLOR limegreen][%s][/COLOR] %s' % (check, item.title) + + elif info['mediatype']=='episode': + if info[id_type+'_id'] in id_result: + id= info[id_type+'_id'] + if info['season'] != '' and info['episode'] != '': + season = str(info['season']) + + if season in id_result[id]: + episode = str(info['episode']) + + if episode in id_result[id][season]: + season_watched = id_result[id][season] + + if episode in season_watched: + item.title = '[B][COLOR limegreen][[I]%s[/I]][/COLOR][/B] %s' % (check, + item.title) + else: + break + except: + pass + + return itemlist + +def get_sync_from_file(): + logger.info() + sync_path = os.path.join(config.get_data_path(),'settings_channels' ,'trakt') + trakt_node = {} + if os.path.exists(sync_path): + trakt_node = jsontools.get_node_from_file('trakt', "TRAKT") + + trakt_node['movies']=get_trakt_watched('tmdb', 'movies') + trakt_node['shows']=get_trakt_watched('tmdb', 'shows') + jsontools.update_node(trakt_node, 'trakt', 'TRAKT') + +def update_trakt_data(mediatype, trakt_data): + logger.info() + + sync_path = os.path.join(config.get_data_path(), 'settings_channels', 'trakt') + trakt_node = {} + if os.path.exists(sync_path): + trakt_node = jsontools.get_node_from_file('trakt', "TRAKT") + trakt_node[mediatype] = trakt_data + jsontools.update_node(trakt_node, 'trakt', 'TRAKT') + +def ask_install_script(): + logger.info() + import xbmc + from platformcode import platformtools + + respuesta = platformtools.dialog_yesno("Alfa", "Puedes instalar el script de Trakt a continuacíon, " + "una vez instalado y configurado lo que " + "veas se sincronizara con tu cuenta automaticamente.", + "¿Deseas continuar?") + if respuesta: + xbmc.executebuiltin("InstallAddon(script.trakt)") + return + else: + config.set_setting('install_trakt','false') + return diff --git a/plugin.video.alfa/platformcode/launcher.py b/plugin.video.alfa/platformcode/launcher.py index d9eabd37..6b61cea8 100644 --- a/plugin.video.alfa/platformcode/launcher.py +++ b/plugin.video.alfa/platformcode/launcher.py @@ -11,6 +11,7 @@ from core import channeltools from core import scrapertools from core import servertools from core import videolibrarytools +from core import trakt_tools from core.item import Item from platformcode import config, logger from platformcode import platformtools @@ -149,6 +150,7 @@ def run(item=None): # Entry point for a channel is the "mainlist" action, so here we check parental control if item.action == "mainlist": + # Parental control # If it is an adult channel, and user has configured pin, asks for it if channeltools.is_adult(item.channel) and config.get_setting("adult_request_password"): @@ -280,6 +282,19 @@ def run(item=None): # menu = Item(channel="channelselector", action="getmainlist", viewmode="movie", thumbnail=menu_icon, # title='Menu') # itemlist.insert(0, menu) + if config.get_setting('trakt_sync'): + token_auth = config.get_setting("token_trakt", "trakt") + if not token_auth: + trakt_tools.auth_trakt() + else: + import xbmc + if not xbmc.getCondVisibility('System.HasAddon(script.trakt)') and config.get_setting( + 'install_trakt'): + trakt_tools.ask_install_script() + itemlist = trakt_tools.trakt_check(itemlist) + else: + config.set_setting('install_trakt', 'true') + platformtools.render_items(itemlist, item) except urllib2.URLError, e: diff --git a/plugin.video.alfa/platformcode/platformtools.py b/plugin.video.alfa/platformcode/platformtools.py index 28f550c2..16be8c87 100644 --- a/plugin.video.alfa/platformcode/platformtools.py +++ b/plugin.video.alfa/platformcode/platformtools.py @@ -17,10 +17,30 @@ import xbmc import xbmcgui import xbmcplugin from core.item import Item +from core import scrapertools +from core import httptools +from core import jsontools from platformcode import logger from channelselector import get_thumb +from core import trakt_tools +class XBMCPlayer( xbmc.Player ): + + def __init__( self, *args ): + pass + + def onPlaybackEnded(self): + logger.info() + from time import sleep + sleep(20) + for mediatype in ['movies', 'shows']: + trakt_data = trakt_tools.get_trakt_watched('tmdb', mediatype, True) + trakt_tools.update_trakt_data(mediatype, trakt_data) + + +xbmc_player = XBMCPlayer() + def dialog_ok(heading, line1, line2="", line3=""): dialog = xbmcgui.Dialog() return dialog.ok(heading, line1, line2, line3) @@ -156,6 +176,7 @@ def render_items(itemlist, parent_item): listitem.setThumbnailImage(item.thumbnail) listitem.setProperty('fanart_image', fanart) + # No need it, use fanart instead # xbmcplugin.setPluginFanart(int(sys.argv[1]), os.path.join(config.get_runtime_path(), "fanart.jpg")) @@ -500,7 +521,7 @@ def set_context_commands(item, parent_item): def is_playing(): - return xbmc.Player().isPlaying() + return xbmc_player.isPlaying() def play_video(item, strm=False, force_direct=False, autoplay=False): @@ -516,7 +537,7 @@ def play_video(item, strm=False, force_direct=False, autoplay=False): xlistitem.setThumbnailImage(item.thumbnail) set_infolabels(xlistitem, item, True) - xbmc.Player().play(item.url, xlistitem) + xbmc_player.play(item.url, xlistitem) return default_action = config.get_setting("default_action") @@ -573,14 +594,17 @@ def play_video(item, strm=False, force_direct=False, autoplay=False): playlist.add(mediaurl, xlistitem) # Reproduce - xbmc_player = xbmc.Player() + xbmc_player = XBMCPlayer() xbmc_player.play(playlist, xlistitem) else: set_player(item, xlistitem, mediaurl, view, strm) + + def stop_video(): - xbmc.Player().stop() + from time import sleep + xbmc_player.stop() def get_seleccion(default_action, opciones, seleccion, video_urls): @@ -731,7 +755,6 @@ def get_dialogo_opciones(item, default_action, strm, autoplay): # Si no puedes ver el vídeo te informa else: - logger.debug('no puedes verlo :P') if not autoplay: if item.server != "": if "
" in motivo: @@ -870,7 +893,7 @@ def set_player(item, xlistitem, mediaurl, view, strm): xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, xlistitem) if item.subtitle != "": xbmc.sleep(2000) - xbmc.Player().setSubtitles(item.subtitle) + xbmc_player.setSubtitles(item.subtitle) else: logger.info("player_mode=%s" % config.get_setting("player_mode")) @@ -888,8 +911,11 @@ def set_player(item, xlistitem, mediaurl, view, strm): playlist.add(mediaurl, xlistitem) # Reproduce - xbmc_player = xbmc.Player() + #xbmc_player = xbmc_player xbmc_player.play(playlist, xlistitem) + while xbmc_player.isPlaying(): + xbmc.sleep(200) + xbmc_player.onPlaybackEnded() # elif config.get_setting("player_mode") == 1 or item.isPlayable: elif config.get_setting("player_mode") == 1: logger.info("mediaurl :" + mediaurl) @@ -908,7 +934,7 @@ def set_player(item, xlistitem, mediaurl, view, strm): if item.subtitle != "" and view: logger.info("Subtítulos externos: " + item.subtitle) xbmc.sleep(2000) - xbmc.Player().setSubtitles(item.subtitle) + xbmc_player.setSubtitles(item.subtitle) # si es un archivo de la videoteca enviar a marcar como visto if strm or item.strm_path: @@ -977,7 +1003,7 @@ def play_torrent(item, xlistitem, mediaurl): client_tmp_path = config.get_data_path() # Iniciamos el cliente: - c = Client(url=mediaurl, is_playing_fnc=xbmc.Player().isPlaying, wait_time=None, timeout=10, + c = Client(url=mediaurl, is_playing_fnc=xbmc_player.isPlaying, wait_time=None, timeout=10, temp_path=os.path.join(client_tmp_path, "alfa-torrent"), print_status=debug) # Mostramos el progreso @@ -1041,7 +1067,7 @@ def play_torrent(item, xlistitem, mediaurl): playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO) playlist.clear() playlist.add(videourl, xlistitem) - xbmc_player = xbmc.Player() + #xbmc_player = xbmc_player xbmc_player.play(playlist) # Marcamos como reproducido para que no se vuelva a iniciar @@ -1053,7 +1079,7 @@ def play_torrent(item, xlistitem, mediaurl): xbmc_videolibrary.mark_auto_as_watched(item) # Y esperamos a que el reproductor se cierre - while xbmc.Player().isPlaying(): + while xbmc_player.isPlaying(): time.sleep(1) # Cuando este cerrado, Volvemos a mostrar el dialogo diff --git a/plugin.video.alfa/resources/settings.xml b/plugin.video.alfa/resources/settings.xml index 3026412d..588682e8 100644 --- a/plugin.video.alfa/resources/settings.xml +++ b/plugin.video.alfa/resources/settings.xml @@ -5,6 +5,7 @@ +