
# -*- coding: utf-8 -*-
#------------------------------------------------------------
# pelisalacarta - XBMC Plugin
# Canal para series.ly
# http://blog.tvalacarta.info/plugin-xbmc/pelisalacarta/
#------------------------------------------------------------
import re
import sys
import os
import urllib2
import xbmcgui


from core import logger
from core import config
from core import scrapertools
from core.item import Item
from servers import servertools
from lib import simplejson as json

__channel__ = "seriesly"
__category__ = "S,A"
__type__ = "generic"
__title__ = "Series.ly"
__language__ = "ES"
__creationdate__ = "20111119"

DEBUG = config.get_setting("debug")


def isGeneric():
    return True

"""Handler para library_service"""
def episodios(item):
    # Obtiene de nuevo los tokens
    episode_list = serie_capitulos(item)
    for episode in episode_list:
        episode.extra = item.extra
    return episode_list

"""Handler para launcher (library)"""
def findvideos(item):
    return multiple_links(item)

"""Handler para launcher (library)"""
def play(item):
    return links(item)

def mainlist(item):
    logger.info("[seriesly.py] mainlist")
   
    itemlist = []

    if config.get_setting("serieslyaccount")!="true":
        itemlist.append( Item( channel=__channel__ , title="Habilita tu cuenta en la configuración..." , action="openconfig" , url="" , folder=False ) )
    else:
        auth_token, user_token = getCredentials()
       
        if user_token:
           
            extra_params = '%s|%s' % ( auth_token, user_token )

            itemlist.append( Item(channel=__channel__, title="Buscar", action="search") )
            itemlist.append( Item(channel=__channel__, title="Mis series", action="categorias", extra=extra_params, url="series" ) )
            itemlist.append( Item(channel=__channel__, title="Mis pelis", action="categorias", extra=extra_params, url="movies" ) )
            itemlist.append( Item(channel=__channel__, title="Mis documentales", action="categorias", extra=extra_params, url="documentaries" ) )
            itemlist.append( Item(channel=__channel__, title="Mis tvshows", action="categorias", extra=extra_params, url="tvshows" ) )
            

        else:
            itemlist.append( Item( channel=__channel__ , title="Cuenta incorrecta, revisa la configuración..." , action="" , url="" , folder=False ) )

    return itemlist

def openconfig(item):
    if "xbmc" in config.get_platform() or "boxee" in config.get_platform():
        config.open_settings( )
    return []

def getCredentials():
          
    auth_token,user_token = perform_login()
   
    return [auth_token,user_token]

def categorias(item):
   
    itemlist = []
    if item.url=="movies": 
        itemlist.append( Item(channel=__channel__, title="Vistas", action="categoria", url='Vistas', extra=item.url) )
        itemlist.append( Item(channel=__channel__, title="Favoritas", action="categoria", url='Favouritas', extra=item.url) )
        itemlist.append( Item(channel=__channel__, title="Pendientes", action="categoria", url='Pendientes', extra=item.url) )
        itemlist.append( Item(channel=__channel__, title="Peliculas Mas Vistas", action="mas_vistas", url=item.url ) )
        itemlist.append( Item(channel=__channel__, title="Peliculas Por Categorias", action="menu_cat", url=item.url, extra="cat" ) )
        
   
    elif item.url=="series":
        itemlist.append( Item(channel=__channel__, title="Viendo", action="categoria", url='Viendo', extra=item.url) )
        itemlist.append( Item(channel=__channel__, title="Finalizadas", action="categoria", url='Finalizada', extra=item.url) )
        itemlist.append( Item(channel=__channel__, title="Pendientes", action="categoria", url='Pendiente', extra=item.url) )
        itemlist.append( Item(channel=__channel__, title="Series Mas Vistas", action="mas_vistas" , url=item.url ) )
        itemlist.append( Item(channel=__channel__, title="Series Por Categorias", action="menu_cat", url=item.url, extra="cat" ) )
        
    elif item.url=="documentaries":
        itemlist.append( Item(channel=__channel__, title="Vistos", action="categoria", url='Vistas', extra=item.url) )
        itemlist.append( Item(channel=__channel__, title="Favoritas", action="categoria", url='Favoritas', extra=item.url) )
        itemlist.append( Item(channel=__channel__, title="Pendientes", action="categoria", url='Pendientes', extra=item.url) )
        itemlist.append( Item(channel=__channel__, title="Documentales Mas Vistos", action="mas_vistas" , url=item.url ) )
        #itemlist.append( Item(channel=__channel__, title="Documentales Por Categorias", action="menu_cat", url=item.url, extra="cat" ) )

    elif item.url=="tvshows":
        itemlist.append( Item(channel=__channel__, title="Viendo", action="categoria", url='Viendo', extra=item.url) )
        itemlist.append( Item(channel=__channel__, title="Finalizadas", action="categoria", url='Finalizada', extra=item.url) )
        itemlist.append( Item(channel=__channel__, title="Pendientes", action="categoria", url='Pendiente', extra=item.url) )
        itemlist.append( Item(channel=__channel__, title="Tvshows Mas Vistos", action="mas_vistas" , url=item.url ) )
        itemlist.append( Item(channel=__channel__, title="Tvshows Por Categorias", action="menu_cat", url=item.url, extra="cat" ) )

        

    itemlist.append( Item(channel=__channel__, title="Buscar", action="search", url=item.url) )

    return itemlist

def menu_cat(item):

    itemlist=[]

    categorias=get_constant("categorias")

    for c in categorias:
        itemlist.append( Item(channel=__channel__, title=categorias[c], action="search_cat", extra=c, url=item.url, plot="1") )

    itemlist = sorted( itemlist , key=lambda item: item.title)

    return itemlist

def categoria(item):

    logger.info("[seriesly.py] categoria")

    # Obtiene de nuevo los tokens
    auth_token, user_token = getCredentials()
   
    # Extrae las entradas (carpetas)
    post = 'auth_token=%s&user_token=%s' % ( qstr(auth_token), qstr(user_token) )

    tipo=item.extra

    # Videos Usuario (Filtradas por categoria)
    url='http://api.series.ly/v2/user/media/%s'%tipo
    data = scrapertools.cache_page(url, post=post)
    List = load_json(data)

    if "error" in List:
        if List["error"]!=0:
            error_message(List["error"])
            return []
    else:
        return []


    if List[tipo] == None : List[tipo] = []   
    logger.info("hay %d %s" % (len(List[tipo]), tipo ))
   
    cat_filter = item.url

    itemlist = []
    default = '2'


    if tipo=="series" or tipo =="tvshows":
        if item.url == 'Pendiente' : cat_filter = 2
        elif item.url == 'Viendo' : cat_filter = 1
        elif item.url == 'Finalizada' : cat_filter = 3

    if tipo=="movies" or tipo=="documentaries":
        if item.url == 'Favouritas' : cat_filter = 2
        elif item.url == 'Vistas' : cat_filter = 1
        elif item.url == 'Pendientes' : cat_filter = 3

   
    for movieItem in List[tipo]:
            # Añade al listado de XBMC filtrando por categoria

            status = movieItem['status']           
            if status == cat_filter:

                itemlist.append( generate_item(movieItem, tipo, auth_token))
               

    itemlist = sorted( itemlist , key=lambda item: item.title)
    return itemlist

def serie_capitulos(item):
   
    logger.info('[seriesly.py] serie_capitulos')
   
    # Obtiene de nuevo los tokens
    auth_token, user_token = getCredentials()
   
    # Extrae las entradas (carpetas)
    post = 'auth_token=%s&user_token=%s' % ( qstr(auth_token), qstr(user_token) )
    serieInfo = load_json(scrapertools.cache_page(item.url, post=post))
    
    if "error" in serieInfo:
        if serieInfo["error"]!=0:
            error_message(serieInfo["error"])
            return []
    else:
        return []

    if serieInfo == None : serieInfo = {}
    if (not serieInfo.has_key('seasons_episodes')) or serieInfo['seasons_episodes'] == None : serieInfo['seasons_episodes'] = []
   
    logger.info(serieInfo)

    # Juntamos todos los episodios con enlaces en una sola lista
    episodeList=[]
    for i in serieInfo["seasons_episodes"]:
        for j in serieInfo["seasons_episodes"][i]:
            if j['haveLinks']: episodeList.append(j)
           

    logger.info('[seriesly serie_capitulos]hay %d capitulos' % len(episodeList))

    itemlist = []
    for episode in episodeList :


        if episode.has_key('watched'):
            viewed = episode['watched']
            if viewed == False : episode['estado'] = ' [Pendiente]'
            elif viewed == True : episode['estado'] = ' [Visto]'
            else : episode['estado'] = ' [?]'
        else:
            episode['estado'] = ''

        # Añadimos un 0 al principo de la temporada y capitulo para su ordenacion
        if len(episode["episode"])==1 : episode["episode"]="0"+episode["episode"]
        if len(episode["season"])==1 : episode["season"]="0"+episode["season"]
       
        itemlist.append(
            Item(channel=__channel__,
                action = 'multiple_links',
                title = '%(season)sx%(episode)s %(title)s%(estado)s' % episode,
               
                url = 'http://api.series.ly/v2/media/episode/links?&idm=%(idm)s&mediaType=5' % episode,
                thumbnail = item.thumbnail,
                plot = "",
                show = item.show,
                extra = item.extra
               
            )
        )
   
    itemlist = sorted( itemlist , key=lambda item: item.title)

    if config.get_platform().startswith("xbmc") or config.get_platform().startswith("boxee"):
        itemlist.append( Item(channel='seriesly', title="Añadir esta serie a la biblioteca de XBMC", url=item.url, action="add_serie_to_library", extra="serie_capitulos###", show=item.show) )

    return itemlist


def mas_vistas(item):

    logger.info("[seriesly.py] mas_vistas")
   
    # Obtiene de nuevo los tokens
    auth_token, user_token = getCredentials()
    post = 'auth_token=%s&user_token=%s&limit=100' % ( qstr(auth_token), qstr(user_token) )
   
    # Extrae las entradas (carpetas)
    tipo=item.url
    url="http://api.series.ly/v2/media/most_seen/"+tipo
    topInfo = load_json(scrapertools.cache_page(url, post=post))

    if "error" in topInfo:
        if topInfo["error"]!=0:
            error_message(topInfo["error"])
            return []
    else:
        return []

    if topInfo == None : topInfo = {}
    if topInfo[tipo] == None : topInfo[tipo] = []
   
    logger.info("hay %d videos" % len(topInfo[tipo]))
   
    itemlist = []
    for movieItem in topInfo[tipo]:
        # Añade al listado de XBMC
        itemlist.append( generate_item(movieItem, tipo, auth_token)) 
   
    return itemlist

def generate_item(video , tipo, auth_token):
   
   
   
    if tipo=="series" or tipo == "tvshows":  
        logger.info(str(video))
        url = 'http://api.series.ly/v2/media/full_info?auth_token='+ auth_token+'&idm=%s&mediaType=%s' %(video["idm"],get_constant("mediaType")[tipo])
        action = 'serie_capitulos'
        title = '%(name)s (%(seasons)d Temporadas) (%(episodes)d Episodios)' % video

    elif tipo =="movies" or tipo == "documentaries":
                url = 'http://api.series.ly/v2/media/episode/links?auth_token='+ auth_token+'&idm=%s&mediaType=%s' %(video["idm"],get_constant("mediaType")[tipo])
                if "year" not in video: video["year"]= ""
                title = '%(name)s (%(year)s)' % video
                action= 'multiple_links'

   

    if "plot_es" not in video : video["plot_es"]= " "

    logger.info(action)
    item=Item(channel=__channel__,
                 action = action,
                 title = title,
                 url = url,
                 thumbnail = video['poster']["large"],
                 plot = video["plot_es"],
                 show = video['name'],
                 extra = ""
            )

   
    return item

def multiple_links(item):
    logger.info("[seriesly.py] multiple_links")
   
    # Obtiene de nuevo los tokens
    auth_token, user_token = getCredentials()
   
    # Extrae las entradas (carpetas)
    post = 'auth_token=%s&user_token=%s' % ( qstr(auth_token), qstr(user_token) )
    data = scrapertools.cache_page(item.url+"&"+post)
    linkList = load_json(data)

    if "error" in linkList:
        if linkList["error"]!=0:
            error_message(linkList["error"])
            return []
    else:
        return []
   
    if linkList == None : linkList = []
   
    logger.info("hay %d videos" % len(linkList))
   
    tipoList=["streaming","direct_download"]
    itemlist = [] 

    for tipo in tipoList:
       
        if tipo in linkList:
            for link in linkList[tipo]:
                if "quality" not in link: link["quality"]= " "

                itemlist.append(
                    Item(channel=__channel__,
                        action = "links",
                        title = '%(host)s - %(lang)s(sub %(subtitles)s) %(quality)s' % link,
                        url = link['video_url']+"?"+post,
                        thumbnail = item.thumbnail,
                        plot = "",
                        extra=link["date_created"]
                    )
                )

   
    return itemlist

def links(item):   
       
    itemlist = []
    try:
        count = 0
        exit = False
        while(not exit and count < 5):
            #A veces da error al intentar acceder
            try:
                logger.info(str(item.url))
                page = urllib2.urlopen(item.url)
                urlvideo = "\"" + page.geturl() + "\""
                logger.info(str(page.read()))
                logger.info(item.url)
                exit = True
            except:
                import traceback
                logger.info(traceback.format_exc())
                count = count + 1
       

        logger.info("urlvideo="+urlvideo)
        for video in servertools.findvideos(urlvideo) :
            #scrapedtitle = title.strip() + " " + match[1] + " " + match[2] + " " + video[0]
            scrapedtitle = scrapertools.htmlclean(video[0])
            scrapedurl = video[1]
            server = video[2]
            itemlist.append( Item(channel=__channel__, action="play" , title=scrapedtitle, url=scrapedurl, thumbnail=item.thumbnail, plot="", server=server, extra="", category=item.category, fanart=item.thumbnail, folder=False))
    except: 
        import sys
        for line in sys.exc_info():
            logger.error( "%s" % line )
               
       
    return itemlist

def search_cat(item):
    return search_videos(item)


def search(item,texto="", categoria="*"):

   
    item.channel="seriesly"
    res = search_videos(item, texto)
   
   
    return res

def search_videos(item, texto=None):
    logger.info("[seriesly.py] search")
   
    # Obtiene de nuevo los tokens
    auth_token, user_token = getCredentials()
    post = 'auth_token=%s' % ( qstr(auth_token) )
    logger.info(str(item.url))

    #Añadido por culpa del if de la paginacion
    if texto is None:
        query=""
    else:
        query=texto

    #busqueda general
    url="http://api.series.ly/v2/media/search"
    post="auth_token="+auth_token+"&order=votes_num&onlyTitle=true&q="+query

    

    #busquda por tipo
    if item.url != "" :
        mediaType=get_constant("mediaType")[item.url]
        post=post+"&mediaType=%s" % mediaType

    #busqueda por genero
    if item.extra != "":
        post=post+"&genere="+item.extra



    #paginacion
    if item.plot != "":
        post=post+"&page="+item.plot
        plot=int(item.plot)+1
        item.plot=str(plot)
   
    # Extrae las entradas (carpetas)
    serieList = load_json(scrapertools.cache_page(url, post))

    if "error" in serieList:
        if serieList["error"]!=0:
            error_message(serieList["error"])
            return []
    else:
        return []
   

    if serieList == None : serieList = []
   
    logger.info("hay %d series" % len(serieList))
   
    itemlist = []
    for serieItem in serieList['results']:

        tipo=get_constant("mediaType")[serieItem["mediaType"]]
       
       
        itemlist.append(generate_item(serieItem, tipo, auth_token))
         
    
    #Añadimos Pagina Siguiente
    if texto is None:
        itemlist.append( Item(channel=__channel__, title="Pagina Siguiente", action="search_videos", extra=item.extra, url=item.url, plot=item.plot ))

    return itemlist




def load_json(data):
    # callback to transform json string values to utf8
    def to_utf8(dct):
        rdct = {}
        for k, v in dct.items() :
            if isinstance(v, (str, unicode)) :
                rdct[k] = v.encode('utf8', 'ignore')
            else :
                rdct[k] = v
        return rdct
    try :       
        import json
        json_data = json.loads(data, object_hook=to_utf8)
        return json_data
    except:
        import sys
        for line in sys.exc_info():
            logger.error( "%s" % line )

''' URLEncode a string '''
def qstr(string):
    return string # urllib2.quote(string)   

def perform_login():

        auth_token,user_token=check_token()

        """url="http://api.series.ly/v2/app/show_quota"
        post="auth_token=%s&user_token=%s"%(auth_token,user_token)
        logger.info(url)
        data = scrapertools.cache_page(url,post=post)
        logger.info("****")
        logger.info(data)
        logger.info("****")"""

        if not auth_token or not user_token :
   
            auth_token=generate_authtoken()

            user_token=generate_usertoken(auth_token)
            if not user_token:
                return [auth_token,user_token]
       
       
        logger.info("****")
        logger.info(auth_token)
        logger.info("****")
        logger.info(user_token)
        logger.info("****")

        url="http://api.series.ly/v2/app/show_quota"
        post="auth_token=%s&user_token=%s"%(user_token,auth_token)
                   
        return [auth_token,user_token]

def generate_authtoken():


        url = "http://api.series.ly/v2/auth_token/"
        #post='id_api=1363&secret=zHX3TPEW2tvZRFneAAU7'
        post='id_api=8&secret=N5X54c4OeDUwU8dWBbMW'
        data = scrapertools.cache_page(url,post=post)
        logger.info("****")
        logger.info(data)
        logger.info("****")
       
        auth_data= json.loads(data)

        if "error" in auth_data:
            if auth_data["error"]!=0:
                error_message(auth_data["error"])
                return False
        else:
            return False


        auth_token = auth_data["auth_token"]

        path=config.get_data_path()
        f =open(path+"seriesly_auth", "w+")
        f.write(str(data+";"))
        f.close()

       
        return auth_token

def generate_usertoken(auth_token):

       
        LOGIN = config.get_setting("serieslyuser")
        PASSWORD = config.get_setting("serieslypassword")

        url = "http://api.series.ly/v2/user/user_token"
        post = "auth_token=%s&username=%s&password=%s&remember=1&user_agent=''" % ( auth_token, qstr(LOGIN), qstr(PASSWORD) )
        data = scrapertools.cache_page(url,post=post)
        logger.info("****")
        logger.info(data)
        logger.info("****")
       
        user_data=json.loads(data)


        if "error" in user_data:
            if user_data["error"]!=0:
                error_message(user_data["error"])
                return False
        else:
            return False

        path=config.get_data_path()
        logger.info(path)
        f =open(path+"seriesly_auth", "a")
        f.write(str(data))
        logger.info(str(data))
        f.close()

        user_token=user_data["user_token"]

        return user_token


def check_token():

   
    path=config.get_data_path()
    try:
        f =open(path+"seriesly_auth", "r")
        data= f.read()
        f.close()
    
        auth, user=data.split(";")
        
        logger.info(data)

        auth = json.loads(auth)
        user = json.loads(user)

        import time
        t=time.time()
        logger.info(str(auth["auth_expires_date"]-t))
        if auth["auth_expires_date"]>t and user["user_expires_date"]>t:
            return auth["auth_token"], user["user_token"]
    except:
        pass
    return False, False 


def get_constant(texto):

    constants={}

    constants["categorias"]={   "action":       "Acción",
                                "comedy":       "Comedia",
                                "family":       "Familiar",
                                "history":      "Histórico",
                                "mystery":      "Misterio",
                                "sci":          "Ciencia Ficción",
                                "war":          "Guerra",
                                "adventure":    "Aventura",
                                "crime":        "Crimen",
                                "fantasy":      "Fantasía",
                                "horror":       "Horror",
                                "news":         "Actualidad",
                                "sport":        "Deportes",
                                "western":      "Western",
                                "animation":    "Animación",
                                "documentary":  "Documental",
                                "film-noir":    "Cine Negro",
                                "music":        "Música",
                                "drama":        "Drama",
                                "musical":      "Musical",
                                "romance":      "Romance",
                                "thriller":     "Thriller",
                                "reallity":     "Reallity Show"}

    constants["mediaType"]= {"1":"series",
                            "2":"movies",
                            "3":"documentaries",
                            "4":"tvshows",
                            "5":"episode",
                            "series":"1",
                            "movies":"2",
                            "documentaries":"3",
                            "tvshows":"4",
                            "episode":"5",
                            "":""}

    constants["error"]= {    "0":"Success response code",
                            "1":"INVALID_AUTH_TOKEN",
                            "2":"EMPTY_API_OR_SECRET",
                            "3":"EMPTY_USR_OR_PWD",
                            "4":"BAD_QUERY_SYNTAX",
                            "5":"OPERATION_DENIED",
                            "7":"INVALID_USER_TOKEN",
                            "8":"INVALID_MEDIATYPE",
                            "9":"MISSING_MEDIATYPE",
                            "10":"MISSING_IDM",
                            "11":"INVALID_HOST",
                            "12":"MISSING_IDV",
                            "13":"INVALID_LANGUAGE",
                            "15":"APP_NOT_FOUND",
                            "16":"APP_INACTIVE",
                            "17":"APP_CANT_LOGIN",
                            "18":"APP_MISSCONFIGURED",
                            "19":"METHOD_NOT_EXIST",
                            "20":"QUOTA_EXCEEDED",
                            "21":"APP_NOT_ALLOWED",
                            "22":"VIDEO_NOT_FOUND",
                            "30":"USER_OPERATION_DENIED",
                            "31":"USER_NOT_FOUND",
                            "32":"USER_INACTIVE",
                            "42":"NO_RESULTS_FOUND",
                            "50":"MEDIA_NOT_FOUND",
                            "51":"EMPTY_LINKS",
                            "52":"INVALID_EPISODES_IDS"}

    return constants[texto]

def error_message(error):
    
    dialog=xbmcgui.Dialog()
    
    text=get_constant("error")[str(error)]

    dialog.ok("SERIES.LY", text)
