From 6e13daf4df78cade24ab422ee82b26ce72be883d Mon Sep 17 00:00:00 2001 From: angedam <37449358+thedoctor66@users.noreply.github.com> Date: Thu, 6 Sep 2018 18:48:07 +0200 Subject: [PATCH 01/29] new_icon --- .../media/themes/default/thumb_mylink.png | Bin 0 -> 36313 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 plugin.video.alfa/resources/media/themes/default/thumb_mylink.png diff --git a/plugin.video.alfa/resources/media/themes/default/thumb_mylink.png b/plugin.video.alfa/resources/media/themes/default/thumb_mylink.png new file mode 100644 index 0000000000000000000000000000000000000000..8802eb5c6e727836d3954e4c09383324c56b2d32 GIT binary patch literal 36313 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 B@>u`? literal 0 HcmV?d00001 From 487c24c4661bf863f9c02f0ba8fcc31626a9ea40 Mon Sep 17 00:00:00 2001 From: angedam <37449358+thedoctor66@users.noreply.github.com> Date: Thu, 6 Sep 2018 19:40:25 +0200 Subject: [PATCH 02/29] added localized string --- plugin.video.alfa/channelselector.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/plugin.video.alfa/channelselector.py b/plugin.video.alfa/channelselector.py index ceb35d29..db7306a3 100644 --- a/plugin.video.alfa/channelselector.py +++ b/plugin.video.alfa/channelselector.py @@ -24,9 +24,9 @@ def getmainlist(view="thumb_"): thumbnail=get_thumb("channels.png", view), view=view, category=config.get_localized_string(30119), viewmode="thumbnails")) - itemlist.append(Item(title='Mis enlaces', channel="alfavorites", action="mainlist", - thumbnail=get_thumb("favorites.png", view), view=view, - category='Mis enlaces', viewmode="thumbnails")) + itemlist.append(Item(title=config.get_localized_string(70527), channel="alfavorites", action="mainlist", + thumbnail=get_thumb("mylink.png", view), view=view, + category=config.get_localized_string(70527), viewmode="thumbnails")) itemlist.append(Item(title=config.get_localized_string(30103), channel="search", action="mainlist", thumbnail=get_thumb("search.png", view), @@ -267,4 +267,4 @@ def set_channel_info(parameters): content = config.get_localized_category(cat) info = '[COLOR yellow]Tipo de contenido:[/COLOR] %s\n\n[COLOR yellow]Idiomas:[/COLOR] %s' % (content, language) - return info \ No newline at end of file + return info From cb36622cbae906f744bb136e960f3ae38b269cc2 Mon Sep 17 00:00:00 2001 From: angedam <37449358+thedoctor66@users.noreply.github.com> Date: Thu, 6 Sep 2018 19:42:42 +0200 Subject: [PATCH 03/29] Update strings.po --- .../resources/language/Spanish/strings.po | 144 +++++++++++++++++- 1 file changed, 140 insertions(+), 4 deletions(-) diff --git a/plugin.video.alfa/resources/language/Spanish/strings.po b/plugin.video.alfa/resources/language/Spanish/strings.po index 39798fd8..9d7814b1 100644 --- a/plugin.video.alfa/resources/language/Spanish/strings.po +++ b/plugin.video.alfa/resources/language/Spanish/strings.po @@ -4792,13 +4792,149 @@ msgid "Verification of counters of videos seen / not seen (uncheck to verify)" msgstr "Verificación de los contadores de vídeos vistos/no vistos (desmarcar para verificar)" msgctxt "#70527" +msgid "My links" +msgstr 'Mis enlaces' + +msgctxt "#70528" +msgid "Default folder" +msgstr "Carpeta por defecto" + +msgctxt "#70529" +msgid "Repeated link" +msgstr "Enlace repetido" + +msgctxt "#70530" +msgid "You already have this link in the folder" +msgstr "Ya tienes este enlace en la carpeta" + +msgctxt "#70531" +msgid "Saved link" +msgstr "Guardado enlace" + +msgctxt "#70532" +msgid "Folder: %s" +msgstr "Carpeta: %s" + +msgctxt "#70533" +msgid "Rename folder" +msgstr "Cambiar nombre de la carpeta" + +msgctxt "#70534" +msgid "Delete folder" +msgstr "Eliminar la carpeta" + +msgctxt "#70535" +msgid "Move up all" +msgstr "Mover arriba del todo" + +msgctxt "#70536" +msgid "Move up" +msgstr "Mover hacia arriba" + +msgctxt "#70537" +msgid "Move down" +msgstr "Mover hacia abajo" + +msgctxt "#70538" +msgid "Move down all" +msgstr "Mover abajo del todo" + +msgctxt "#70539" +msgid "* Create different folders to store your favorite links within Icarus. [CR]" +msgstr "* Crea diferentes carpetas para guardar tus enlaces favoritos dentro de Icarus.[CR]]" + +msgctxt "#70540" +msgid "* To add links to folders, access the context menu from any point in Icarus.[CR]" +msgstr "* Para añadir enlaces a las carpetas accede al menú contextual desde cualquier punto de Icarus.[CR]" + +msgctxt "#70541" +msgid "* The links can be channels, sections within the channels, searches, and even movies and series although for the latter it is preferable to use the video library." +msgstr "* Los enlaces pueden ser canales, secciones dentro de los canales, búsquedas, e incluso películas y series aunque para esto último es preferible utilizar la videoteca." + +msgctxt "#70542" +msgid "Create new folder ..." +msgstr "Crear nueva carpeta ..." + +msgctxt "#70543" +msgid "Move to another folder" +msgstr "Mover a otra carpeta" + +msgctxt "#70544" +msgid "Change title" +msgstr "Cambiar título" + +msgctxt "#70545" +msgid "Change color" +msgstr "Cambiar color" + +msgctxt "#70546" +msgid "Save link in:" +msgstr "Guardar enlace en:" + +msgctxt "#70547" +msgid "Change thumbnail" +msgstr "Cambiar thumbnail" + +msgctxt "#70548" +msgid "Delete link" +msgstr "Eliminar enlace" + +msgctxt "#70549" +msgid "Select folder" +msgstr "Seleccionar carpeta" + +msgctxt "#70550" +msgid "Create new folder" +msgstr "Crear nueva carpeta" + +msgctxt "#70551" +msgid "Folder name" +msgstr "Nombre de la carpeta" + +msgctxt "#70552" +msgid "Delete the folder and links it contains?" +msgstr "¿Borrar la carpeta y los enlaces que contiene?" + +msgctxt "#70553" +msgid "Change link title" +msgstr "Cambiar título del enlace" + +msgctxt "#70554" +msgid "Select thumbnail:" +msgstr "Seleccionar thumbnail:" + +msgctxt "#70555" +msgid "Move link to:" +msgstr "Mover enlace a:" + +msgctxt "#70556" +msgid "%d links in folder" +msgstr "%d enlaces en la carpeta" + +msgctxt "#70557" +msgid "Save link" +msgstr "Guardar enlace" + +msgctxt "#70558" +msgid "Select color:" +msgstr "Seleccionar color:" + +msgctxt "#70559" msgid "Now in Theatres " msgstr "Ahora en cines" -msgctxt "#70528" +msgctxt "#70560" msgid "Movies by Genre" msgstr "Por generos" -msgctxt "#70529" -msgid "tv show" -msgstr "serie" +msgctxt "#70561" +msgid "Search Similar +msgstr "Buscar Similares" + + + + + + + + From 44d70f9dd2d5178ed26414c089b348412ad87c4e Mon Sep 17 00:00:00 2001 From: angedam <37449358+thedoctor66@users.noreply.github.com> Date: Thu, 6 Sep 2018 19:43:30 +0200 Subject: [PATCH 04/29] Update strings.po --- .../language/Spanish (Mexico)/strings.po | 145 +++++++++++++++++- 1 file changed, 141 insertions(+), 4 deletions(-) diff --git a/plugin.video.alfa/resources/language/Spanish (Mexico)/strings.po b/plugin.video.alfa/resources/language/Spanish (Mexico)/strings.po index 39798fd8..cfe95a5c 100644 --- a/plugin.video.alfa/resources/language/Spanish (Mexico)/strings.po +++ b/plugin.video.alfa/resources/language/Spanish (Mexico)/strings.po @@ -4792,13 +4792,150 @@ msgid "Verification of counters of videos seen / not seen (uncheck to verify)" msgstr "Verificación de los contadores de vídeos vistos/no vistos (desmarcar para verificar)" msgctxt "#70527" +msgid "My links" +msgstr 'Mis enlaces' + +msgctxt "#70528" +msgid "Default folder" +msgstr "Carpeta por defecto" + +msgctxt "#70529" +msgid "Repeated link" +msgstr "Enlace repetido" + +msgctxt "#70530" +msgid "You already have this link in the folder" +msgstr "Ya tienes este enlace en la carpeta" + +msgctxt "#70531" +msgid "Saved link" +msgstr "Guardado enlace" + +msgctxt "#70532" +msgid "Folder: %s" +msgstr "Carpeta: %s" + +msgctxt "#70533" +msgid "Rename folder" +msgstr "Cambiar nombre de la carpeta" + +msgctxt "#70534" +msgid "Delete folder" +msgstr "Eliminar la carpeta" + +msgctxt "#70535" +msgid "Move up all" +msgstr "Mover arriba del todo" + +msgctxt "#70536" +msgid "Move up" +msgstr "Mover hacia arriba" + +msgctxt "#70537" +msgid "Move down" +msgstr "Mover hacia abajo" + +msgctxt "#70538" +msgid "Move down all" +msgstr "Mover abajo del todo" + +msgctxt "#70539" +msgid "* Create different folders to store your favorite links within Icarus. [CR]" +msgstr "* Crea diferentes carpetas para guardar tus enlaces favoritos dentro de Icarus.[CR]]" + +msgctxt "#70540" +msgid "* To add links to folders, access the context menu from any point in Icarus.[CR]" +msgstr "* Para añadir enlaces a las carpetas accede al menú contextual desde cualquier punto de Icarus.[CR]" + +msgctxt "#70541" +msgid "* The links can be channels, sections within the channels, searches, and even movies and series although for the latter it is preferable to use the video library." +msgstr "* Los enlaces pueden ser canales, secciones dentro de los canales, búsquedas, e incluso películas y series aunque para esto último es preferible utilizar la videoteca." + +msgctxt "#70542" +msgid "Create new folder ..." +msgstr "Crear nueva carpeta ..." + +msgctxt "#70543" +msgid "Move to another folder" +msgstr "Mover a otra carpeta" + +msgctxt "#70544" +msgid "Change title" +msgstr "Cambiar título" + +msgctxt "#70545" +msgid "Change color" +msgstr "Cambiar color" + +msgctxt "#70546" +msgid "Save link in:" +msgstr "Guardar enlace en:" + +msgctxt "#70547" +msgid "Change thumbnail" +msgstr "Cambiar thumbnail" + +msgctxt "#70548" +msgid "Delete link" +msgstr "Eliminar enlace" + +msgctxt "#70549" +msgid "Select folder" +msgstr "Seleccionar carpeta" + +msgctxt "#70550" +msgid "Create new folder" +msgstr "Crear nueva carpeta" + +msgctxt "#70551" +msgid "Folder name" +msgstr "Nombre de la carpeta" + +msgctxt "#70552" +msgid "Delete the folder and links it contains?" +msgstr "¿Borrar la carpeta y los enlaces que contiene?" + +msgctxt "#70553" +msgid "Change link title" +msgstr "Cambiar título del enlace" + +msgctxt "#70554" +msgid "Select thumbnail:" +msgstr "Seleccionar thumbnail:" + +msgctxt "#70555" +msgid "Move link to:" +msgstr "Mover enlace a:" + +msgctxt "#70556" +msgid "%d links in folder" +msgstr "%d enlaces en la carpeta" + +msgctxt "#70557" +msgid "Save link" +msgstr "Guardar enlace" + +msgctxt "#70558" +msgid "Select color:" +msgstr "Seleccionar color:" + +msgctxt "#70559" msgid "Now in Theatres " msgstr "Ahora en cines" -msgctxt "#70528" +msgctxt "#70560" msgid "Movies by Genre" msgstr "Por generos" -msgctxt "#70529" -msgid "tv show" -msgstr "serie" +msgctxt "#70561" +msgid "Search Similar +msgstr "Buscar Similares" + + + + + + + + + From 1f02b33ce7929941206cdae3994c1b805fc02baf Mon Sep 17 00:00:00 2001 From: angedam <37449358+thedoctor66@users.noreply.github.com> Date: Thu, 6 Sep 2018 19:44:46 +0200 Subject: [PATCH 05/29] Update strings.po --- .../language/Spanish (Argentina)/strings.po | 145 +++++++++++++++++- 1 file changed, 141 insertions(+), 4 deletions(-) diff --git a/plugin.video.alfa/resources/language/Spanish (Argentina)/strings.po b/plugin.video.alfa/resources/language/Spanish (Argentina)/strings.po index 39798fd8..cfe95a5c 100644 --- a/plugin.video.alfa/resources/language/Spanish (Argentina)/strings.po +++ b/plugin.video.alfa/resources/language/Spanish (Argentina)/strings.po @@ -4792,13 +4792,150 @@ msgid "Verification of counters of videos seen / not seen (uncheck to verify)" msgstr "Verificación de los contadores de vídeos vistos/no vistos (desmarcar para verificar)" msgctxt "#70527" +msgid "My links" +msgstr 'Mis enlaces' + +msgctxt "#70528" +msgid "Default folder" +msgstr "Carpeta por defecto" + +msgctxt "#70529" +msgid "Repeated link" +msgstr "Enlace repetido" + +msgctxt "#70530" +msgid "You already have this link in the folder" +msgstr "Ya tienes este enlace en la carpeta" + +msgctxt "#70531" +msgid "Saved link" +msgstr "Guardado enlace" + +msgctxt "#70532" +msgid "Folder: %s" +msgstr "Carpeta: %s" + +msgctxt "#70533" +msgid "Rename folder" +msgstr "Cambiar nombre de la carpeta" + +msgctxt "#70534" +msgid "Delete folder" +msgstr "Eliminar la carpeta" + +msgctxt "#70535" +msgid "Move up all" +msgstr "Mover arriba del todo" + +msgctxt "#70536" +msgid "Move up" +msgstr "Mover hacia arriba" + +msgctxt "#70537" +msgid "Move down" +msgstr "Mover hacia abajo" + +msgctxt "#70538" +msgid "Move down all" +msgstr "Mover abajo del todo" + +msgctxt "#70539" +msgid "* Create different folders to store your favorite links within Icarus. [CR]" +msgstr "* Crea diferentes carpetas para guardar tus enlaces favoritos dentro de Icarus.[CR]]" + +msgctxt "#70540" +msgid "* To add links to folders, access the context menu from any point in Icarus.[CR]" +msgstr "* Para añadir enlaces a las carpetas accede al menú contextual desde cualquier punto de Icarus.[CR]" + +msgctxt "#70541" +msgid "* The links can be channels, sections within the channels, searches, and even movies and series although for the latter it is preferable to use the video library." +msgstr "* Los enlaces pueden ser canales, secciones dentro de los canales, búsquedas, e incluso películas y series aunque para esto último es preferible utilizar la videoteca." + +msgctxt "#70542" +msgid "Create new folder ..." +msgstr "Crear nueva carpeta ..." + +msgctxt "#70543" +msgid "Move to another folder" +msgstr "Mover a otra carpeta" + +msgctxt "#70544" +msgid "Change title" +msgstr "Cambiar título" + +msgctxt "#70545" +msgid "Change color" +msgstr "Cambiar color" + +msgctxt "#70546" +msgid "Save link in:" +msgstr "Guardar enlace en:" + +msgctxt "#70547" +msgid "Change thumbnail" +msgstr "Cambiar thumbnail" + +msgctxt "#70548" +msgid "Delete link" +msgstr "Eliminar enlace" + +msgctxt "#70549" +msgid "Select folder" +msgstr "Seleccionar carpeta" + +msgctxt "#70550" +msgid "Create new folder" +msgstr "Crear nueva carpeta" + +msgctxt "#70551" +msgid "Folder name" +msgstr "Nombre de la carpeta" + +msgctxt "#70552" +msgid "Delete the folder and links it contains?" +msgstr "¿Borrar la carpeta y los enlaces que contiene?" + +msgctxt "#70553" +msgid "Change link title" +msgstr "Cambiar título del enlace" + +msgctxt "#70554" +msgid "Select thumbnail:" +msgstr "Seleccionar thumbnail:" + +msgctxt "#70555" +msgid "Move link to:" +msgstr "Mover enlace a:" + +msgctxt "#70556" +msgid "%d links in folder" +msgstr "%d enlaces en la carpeta" + +msgctxt "#70557" +msgid "Save link" +msgstr "Guardar enlace" + +msgctxt "#70558" +msgid "Select color:" +msgstr "Seleccionar color:" + +msgctxt "#70559" msgid "Now in Theatres " msgstr "Ahora en cines" -msgctxt "#70528" +msgctxt "#70560" msgid "Movies by Genre" msgstr "Por generos" -msgctxt "#70529" -msgid "tv show" -msgstr "serie" +msgctxt "#70561" +msgid "Search Similar +msgstr "Buscar Similares" + + + + + + + + + From 3181eef6a4a98a88f02522e7a8973649d115c923 Mon Sep 17 00:00:00 2001 From: angedam <37449358+thedoctor66@users.noreply.github.com> Date: Thu, 6 Sep 2018 19:47:11 +0200 Subject: [PATCH 06/29] Update strings.po --- .../resources/language/Italian/strings.po | 137 +++++++++++++++++- 1 file changed, 133 insertions(+), 4 deletions(-) diff --git a/plugin.video.alfa/resources/language/Italian/strings.po b/plugin.video.alfa/resources/language/Italian/strings.po index 9fa6c505..21484f69 100644 --- a/plugin.video.alfa/resources/language/Italian/strings.po +++ b/plugin.video.alfa/resources/language/Italian/strings.po @@ -4792,14 +4792,143 @@ msgid "Verification of counters of videos seen / not seen (uncheck to verify)" msgstr "Verifica dei contatori di video visti/non visti (deselezionare per verificare)" msgctxt "#70527" +msgid "My links" +msgstr "I Miei Link" + +msgctxt "#70528" +msgid "Default folder" +msgstr "Cartella di Default" + +msgctxt "#70529" +msgid "Repeated link" +msgstr "Link ripetuto" + +msgctxt "#70530" +msgid "You already have this link in the folder" +msgstr "C'è già un link nella cartella" + +msgctxt "#70531" +msgid "Saved link" +msgstr "Link salvato" + +msgctxt "#70532" +msgid "Folder: %s" +msgstr "Cartella: %s" + +msgctxt "#70533" +msgid "Rename folder" +msgstr "Cambia nome alla cartella" + +msgctxt "#70534" +msgid "Delete folder" +msgstr "Elimina la cartella" + +msgctxt "#70535" +msgid "Move up all" +msgstr "Sposta tutto in alto" + +msgctxt "#70536" +msgid "Move up" +msgstr "Sposta in su" + +msgctxt "#70537" +msgid "Move down" +msgstr "Sposta in giù" + +msgctxt "#70538" +msgid "Move down all" +msgstr "Sposta tutto in basso" + +msgctxt "#70539" +msgid "* Create different folders to store your favorite links within Icarus. [CR]" +msgstr "* Crea diverse cartelle per memorizzare i tuoi collegamenti preferiti all'interno di Icarus." + +msgctxt "#70540" +msgid "* To add links to folders, access the context menu from any point in Icarus.[CR]" +msgstr "* Per aggiungere collegamenti alle cartelle accedi al menu contestuale da qualsiasi punto di Icarus." + +msgctxt "#70541" +msgid "* The links can be channels, sections within the channels, searches, and even movies and series although for the latter it is preferable to use the video library." +msgstr "* I collegamenti possono essere canali, sezioni all'interno dei canali, ricerche e persino film e serie, sebbene per quest'ultimo sia preferibile utilizzare la videoteca." + +msgctxt "#70542" +msgid "Create new folder ..." +msgstr "Crea nuova cartella ..." + +msgctxt "#70543" +msgid "Move to another folder" +msgstr "Sposta in altra cartella" + +msgctxt "#70544" +msgid "Change title" +msgstr "Cambia titolo" + +msgctxt "#70545" +msgid "Change color" +msgstr "Cambia colore" + +msgctxt "#70546" +msgid "Save link in:" +msgstr "Salva link in:" + +msgctxt "#70547" +msgid "Change thumbnail" +msgstr "Cambia thumbnail" + +msgctxt "#70548" +msgid "Delete link" +msgstr "Elimina link" + +msgctxt "#70549" +msgid "Select folder" +msgstr "Seleziona cartella" + +msgctxt "#70550" +msgid "Create new folder" +msgstr "Crea nuova cartella" + +msgctxt "#70551" +msgid "Folder name" +msgstr "Nome della cartella" + +msgctxt "#70552" +msgid "Delete the folder and links it contains?" +msgstr "Eliminare la cartella con tutti i link?" + +msgctxt "#70553" +msgid "Change link title" +msgstr "Cambia titolo del link" + +msgctxt "#70554" +msgid "Select thumbnail:" +msgstr "Seleziona thumbnail:" + +msgctxt "#70555" +msgid "Move link to:" +msgstr "Sposta link in:" + +msgctxt "#70556" +msgid "%d links in folder" +msgstr "%d link nella cartella" + +msgctxt "#70557" +msgid "Save link" +msgstr "Salva link" + +msgctxt "#70558" +msgid "Select color:" +msgstr "Seleziona colore:" + +msgctxt "#70559" msgid "Now in Theatres " msgstr "Oggi in Sala" -msgctxt "#70528" +msgctxt "#70560" msgid "Movies by Genre" msgstr "Per genere" -msgctxt "#70529" -msgid "tv show" -msgstr "serie" +msgctxt "#70561" +msgid "Search Similar +msgstr "Cerca Simili" + From 3c98be46bf36f9daa1c606f186d383fe21a46194 Mon Sep 17 00:00:00 2001 From: angedam <37449358+thedoctor66@users.noreply.github.com> Date: Thu, 6 Sep 2018 19:48:23 +0200 Subject: [PATCH 07/29] Update strings.po --- .../resources/language/English/strings.po | 134 +++++++++++++++++- 1 file changed, 131 insertions(+), 3 deletions(-) diff --git a/plugin.video.alfa/resources/language/English/strings.po b/plugin.video.alfa/resources/language/English/strings.po index ee9d9859..8cac0538 100644 --- a/plugin.video.alfa/resources/language/English/strings.po +++ b/plugin.video.alfa/resources/language/English/strings.po @@ -4804,14 +4804,142 @@ msgid "Verification of counters of videos seen / not seen (uncheck to verify)" msgstr "" msgctxt "#70527" -msgid "Now in Theatres " +msgid "My links" msgstr "" msgctxt "#70528" -msgid "Movies by Genre" +msgid "Default folder" msgstr "" msgctxt "#70529" -msgid "tv show" +msgid "Repeated link" +msgstr "" + +msgctxt "#70530" +msgid "You already have this link in the folder" +msgstr "" + +msgctxt "#70531" +msgid "Saved link" +msgstr "" + +msgctxt "#70532" +msgid "Folder: %s" +msgstr "" + +msgctxt "#70533" +msgid "Rename folder" +msgstr "" + +msgctxt "#70534" +msgid "Delete folder" +msgstr "" + +msgctxt "#70535" +msgid "Move up all" +msgstr "" + +msgctxt "#70536" +msgid "Move up" +msgstr "" + +msgctxt "#70537" +msgid "Move down" +msgstr "" + +msgctxt "#70538" +msgid "Move down all" +msgstr "" + +msgctxt "#70539" +msgid "* Create different folders to store your favorite links within Icarus. [CR]" +msgstr "" + +msgctxt "#70540" +msgid "* To add links to folders, access the context menu from any point in Icarus.[CR]" +msgstr "" + +msgctxt "#70541" +msgid "* The links can be channels, sections within the channels, searches, and even movies and series although for the latter it is preferable to use the video library." +msgstr "" + +msgctxt "#70542" +msgid "Create new folder ..." +msgstr "Creaa nuova cartella ..." + +msgctxt "#70543" +msgid "Move to another folder" +msgstr "" + +msgctxt "#70544" +msgid "Change title" +msgstr "" + +msgctxt "#70545" +msgid "Change color" +msgstr "" + +msgctxt "#70546" +msgid "Save link in:" +msgstr "" + +msgctxt "#70547" +msgid "Change thumbnail" +msgstr "" + +msgctxt "#70548" +msgid "Delete link" +msgstr "" + +msgctxt "#70549" +msgid "Select folder" +msgstr "" + +msgctxt "#70550" +msgid "Create new folder" +msgstr "" + +msgctxt "#70551" +msgid "Folder name" +msgstr "" + +msgctxt "#70552" +msgid "Delete the folder and links it contains?" +msgstr "" + +msgctxt "#70553" +msgid "Change link title" +msgstr "" + +msgctxt "#70554" +msgid "Select thumbnail:" +msgstr "" + +msgctxt "#70555" +msgid "Move link to:" +msgstr "" + +msgctxt "#70556" +msgid "%d links in folder" +msgstr "" + +msgctxt "#70557" +msgid "Save link" +msgstr "" + +msgctxt "#70558" +msgid "Select color:" +msgstr "" + +msgctxt "#70559" +msgid "Now in Theatres " +msgstr "" + +msgctxt "#70560" +msgid "Movies by Genre" +msgstr " + +msgctxt "#70561" +msgid "Search Similar msgstr "" From 839876993c19ba19b0502aab9f6a4314cb3fda60 Mon Sep 17 00:00:00 2001 From: angedam <37449358+thedoctor66@users.noreply.github.com> Date: Thu, 6 Sep 2018 19:53:38 +0200 Subject: [PATCH 08/29] update localized strings --- plugin.video.alfa/channelselector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.video.alfa/channelselector.py b/plugin.video.alfa/channelselector.py index db7306a3..da98f9ee 100644 --- a/plugin.video.alfa/channelselector.py +++ b/plugin.video.alfa/channelselector.py @@ -197,7 +197,7 @@ def filterchannels(category, view="thumb_"): thumbnail=channel_parameters["thumbnail"], type="generic", viewmode="list")) if category in ['movie', 'tvshow']: - titles = [config.get_localized_string(70028), config.get_localized_string(30985), config.get_localized_string(70527), config.get_localized_string(60264), config.get_localized_string(70528)] + titles = [config.get_localized_string(70028), config.get_localized_string(30985), config.get_localized_string(70559), config.get_localized_string(60264), config.get_localized_string(70560)] ids = ['popular', 'top_rated', 'now_playing', 'on_the_air'] for x in range(0,3): if x == 2 and category != 'movie': From b8b1b5317c81597ff8698a4b7df8ba5a80324de2 Mon Sep 17 00:00:00 2001 From: angedam <37449358+thedoctor66@users.noreply.github.com> Date: Thu, 6 Sep 2018 21:49:47 +0200 Subject: [PATCH 09/29] Update strings.po --- plugin.video.alfa/resources/language/Spanish/strings.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.video.alfa/resources/language/Spanish/strings.po b/plugin.video.alfa/resources/language/Spanish/strings.po index 9d7814b1..ab09763a 100644 --- a/plugin.video.alfa/resources/language/Spanish/strings.po +++ b/plugin.video.alfa/resources/language/Spanish/strings.po @@ -1734,7 +1734,7 @@ msgid "[COLOR %s]Filter configuration for TV series...[/COLOR]" msgstr "[COLOR %s]Configurar filtro para series...[/COLOR]" msgctxt "#60430" -msgid "FILTRO: Delete '%s'" +msgid "FILTER: Delete '%s'" msgstr "FILTRO: Borrar '%s'" msgctxt "#60431" From 995cd26bfaae6983d206668fb2bc81fdef6e754c Mon Sep 17 00:00:00 2001 From: angedam <37449358+thedoctor66@users.noreply.github.com> Date: Thu, 6 Sep 2018 21:51:41 +0200 Subject: [PATCH 10/29] Update strings.po --- .../resources/language/Spanish (Mexico)/strings.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.video.alfa/resources/language/Spanish (Mexico)/strings.po b/plugin.video.alfa/resources/language/Spanish (Mexico)/strings.po index cfe95a5c..677d30a4 100644 --- a/plugin.video.alfa/resources/language/Spanish (Mexico)/strings.po +++ b/plugin.video.alfa/resources/language/Spanish (Mexico)/strings.po @@ -1734,7 +1734,7 @@ msgid "[COLOR %s]Filter configuration for TV series...[/COLOR]" msgstr "[COLOR %s]Configurar filtro para series...[/COLOR]" msgctxt "#60430" -msgid "FILTRO: Delete '%s'" +msgid "FILTER: Delete '%s'" msgstr "FILTRO: Borrar '%s'" msgctxt "#60431" From 14a5125910e451378fcc37bcedb9143b9a507ae6 Mon Sep 17 00:00:00 2001 From: angedam <37449358+thedoctor66@users.noreply.github.com> Date: Thu, 6 Sep 2018 21:52:47 +0200 Subject: [PATCH 11/29] Update strings.po --- .../resources/language/Spanish (Argentina)/strings.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.video.alfa/resources/language/Spanish (Argentina)/strings.po b/plugin.video.alfa/resources/language/Spanish (Argentina)/strings.po index cfe95a5c..677d30a4 100644 --- a/plugin.video.alfa/resources/language/Spanish (Argentina)/strings.po +++ b/plugin.video.alfa/resources/language/Spanish (Argentina)/strings.po @@ -1734,7 +1734,7 @@ msgid "[COLOR %s]Filter configuration for TV series...[/COLOR]" msgstr "[COLOR %s]Configurar filtro para series...[/COLOR]" msgctxt "#60430" -msgid "FILTRO: Delete '%s'" +msgid "FILTER: Delete '%s'" msgstr "FILTRO: Borrar '%s'" msgctxt "#60431" From e65b4b0cee46175b8e7bacd6eb0ee0e19f93de53 Mon Sep 17 00:00:00 2001 From: angedam <37449358+thedoctor66@users.noreply.github.com> Date: Thu, 6 Sep 2018 21:55:09 +0200 Subject: [PATCH 12/29] Update strings.po --- plugin.video.alfa/resources/language/English/strings.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.video.alfa/resources/language/English/strings.po b/plugin.video.alfa/resources/language/English/strings.po index 8cac0538..35faa2f0 100644 --- a/plugin.video.alfa/resources/language/English/strings.po +++ b/plugin.video.alfa/resources/language/English/strings.po @@ -1734,7 +1734,7 @@ msgid "[COLOR %s]Filter configuration for TV series...[/COLOR]" msgstr "" msgctxt "#60430" -msgid "FILTRO: Delete '%s'" +msgid "FILTER: Delete '%s'" msgstr "" msgctxt "#60431" From 306dc80a5ce5d60f3d0b7f0691b83549b43a6011 Mon Sep 17 00:00:00 2001 From: angedam <37449358+thedoctor66@users.noreply.github.com> Date: Fri, 7 Sep 2018 16:35:08 +0200 Subject: [PATCH 13/29] Added localized strings --- plugin.video.alfa/platformcode/platformtools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin.video.alfa/platformcode/platformtools.py b/plugin.video.alfa/platformcode/platformtools.py index f0713eaa..f566eed6 100644 --- a/plugin.video.alfa/platformcode/platformtools.py +++ b/plugin.video.alfa/platformcode/platformtools.py @@ -516,7 +516,7 @@ def set_context_commands(item, parent_item): from_action=item.action).tourl()))) # Añadir a Alfavoritos (Mis enlaces) if item.channel not in ["favorites", "videolibrary", "help", ""] and parent_item.channel != "favorites": - context_commands.append(('[COLOR blue]Guardar enlace[/COLOR]', "XBMC.RunPlugin(%s?%s)" % + context_commands.append(('[COLOR blue]%s[/COLOR]' % config.get_localized_string(70557), "XBMC.RunPlugin(%s?%s)" % (sys.argv[0], item.clone(channel="alfavorites", action="addFavourite", from_channel=item.channel, from_action=item.action).tourl()))) @@ -538,7 +538,7 @@ def set_context_commands(item, parent_item): mediatype = 'tv' else: mediatype = item.contentType - context_commands.append(("[COLOR yellow]Buscar Similares[/COLOR]", "XBMC.Container.Update (%s?%s)" % ( + context_commands.append(("[COLOR yellow]%s[/COLOR]" % config.get_localized_string(70561), "XBMC.Container.Update (%s?%s)" % ( sys.argv[0], item.clone(channel='search', action='discover_list', search_type='list', page='1', list_type='%s/%s/similar' % (mediatype,item.infoLabels['tmdb_id'])).tourl()))) From 3a76265a2d677364ddd84ee735573d3d33d6ab4e Mon Sep 17 00:00:00 2001 From: pipcat Date: Wed, 12 Sep 2018 09:34:58 +0200 Subject: [PATCH 14/29] =?UTF-8?q?Di=C3=A1logo=20selecci=C3=B3n=20de=20cana?= =?UTF-8?q?les=20a=20buscar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin.video.alfa/channels/peliculasgratis.py | 1 + plugin.video.alfa/channels/search.py | 88 ++++++++++++++++++- plugin.video.alfa/channels/seriecanal.py | 2 +- plugin.video.alfa/core/tmdb.py | 2 +- 4 files changed, 87 insertions(+), 6 deletions(-) diff --git a/plugin.video.alfa/channels/peliculasgratis.py b/plugin.video.alfa/channels/peliculasgratis.py index ebc98e85..696ae554 100644 --- a/plugin.video.alfa/channels/peliculasgratis.py +++ b/plugin.video.alfa/channels/peliculasgratis.py @@ -89,6 +89,7 @@ def search(item, texto): logger.info() texto = texto.replace(" ", "+") item.url = host + "/search/%s" % texto + if item.contentType == '': item.contentType = 'movie' try: return scraper(item) # Se captura la excepción, para no interrumpir al buscador global si un canal falla diff --git a/plugin.video.alfa/channels/search.py b/plugin.video.alfa/channels/search.py index 73e3498a..5daecf53 100644 --- a/plugin.video.alfa/channels/search.py +++ b/plugin.video.alfa/channels/search.py @@ -143,6 +143,85 @@ def settings(item): def setting_channel(item): + if config.get_platform(True)['num_version'] >= 17.0: # A partir de Kodi 16 se puede usar multiselect, y de 17 con preselect + return setting_channel_new(item) + else: + return setting_channel_old(item) + +def setting_channel_new(item): + import channelselector, xbmcgui + from core import channeltools + + # Cargar lista de opciones (canales activos del usuario y que permitan búsqueda global) + # ------------------------ + lista = []; ids = []; lista_lang = [] + channels_list = channelselector.filterchannels('all') + for channel in channels_list: + channel_parameters = channeltools.get_channel_parameters(channel.channel) + + # No incluir si en la configuracion del canal no existe "include_in_global_search" + if not channel_parameters['include_in_global_search']: + continue + + lbl = '%s' % channel_parameters['language'] + lbl += ' %s' % ', '.join(config.get_localized_category(categ) for categ in channel_parameters['categories']) + + it = xbmcgui.ListItem(channel.title, lbl) + it.setArt({ 'thumb': channel.thumbnail, 'fanart': channel.fanart }) + lista.append(it) + ids.append(channel.channel) + lista_lang.append(channel_parameters['language']) + + # Diálogo para pre-seleccionar + # ---------------------------- + preselecciones_std = ['Modificar selección actual', 'Modificar partiendo de Todos', 'Modificar partiendo de Ninguno', 'Modificar partiendo de Castellano', 'Modificar partiendo de Latino'] + if item.action == 'setting_channel': + # Configuración de los canales incluídos en la búsqueda + preselecciones = preselecciones_std + presel_values = [1, 2, 3, 4, 5] + else: + # Llamada desde "buscar en otros canales" (se puede saltar la selección e ir directo a la búsqueda) + preselecciones = ['Buscar con la selección actual'] + preselecciones_std + presel_values = [0, 1, 2, 3, 4, 5] + + ret = platformtools.dialog_select(config.get_localized_string(59994), preselecciones) + if ret == -1: return False # pedido cancel + if presel_values[ret] == 0: return True # continuar sin modificar + elif presel_values[ret] == 3: preselect = [] + elif presel_values[ret] == 2: preselect = range(len(ids)) + elif presel_values[ret] in [4, 5]: + busca = 'cast' if presel_values[ret] == 4 else 'lat' + preselect = [] + for i, lg in enumerate(lista_lang): + if busca in lg or '*' in lg: + preselect.append(i) + else: + preselect = [] + for i, canal in enumerate(ids): + channel_status = config.get_setting('include_in_global_search', canal) + if channel_status: + preselect.append(i) + + # Diálogo para seleccionar + # ------------------------ + ret = xbmcgui.Dialog().multiselect(config.get_localized_string(59994), lista, preselect=preselect, useDetails=True) + if ret == None: return False # pedido cancel + seleccionados = [ids[i] for i in ret] + + # Guardar cambios en canales para la búsqueda + # ------------------------------------------- + for canal in ids: + channel_status = config.get_setting('include_in_global_search', canal) + if channel_status is None: channel_status = True + + if channel_status and canal not in seleccionados: + config.set_setting('include_in_global_search', False, canal) + elif not channel_status and canal in seleccionados: + config.set_setting('include_in_global_search', True, canal) + + return True + +def setting_channel_old(item): channels_path = os.path.join(config.get_runtime_path(), "channels", '*.json') channel_language = config.get_setting("channel_language", default="all") @@ -204,6 +283,7 @@ def save_settings(item, dict_values): config.set_setting("include_in_global_search", dict_values[v], v) progreso.close() + return True def cb_custom_button(item, dict_values): @@ -354,8 +434,8 @@ def do_search(item, categories=None): categories = ["Películas"] setting_item = Item(channel=item.channel, title=config.get_localized_string(59994), folder=False, thumbnail=get_thumb("search.png")) - setting_channel(setting_item) - + if not setting_channel(setting_item): + return False if categories is None: categories = [] @@ -474,8 +554,8 @@ def do_search(item, categories=None): # es compatible tanto con versiones antiguas de python como nuevas if multithread: pendent = [a for a in threads if a.isAlive()] - t = float(100) / len(pendent) - while pendent: + if len(pendent) > 0: t = float(100) / len(pendent) + while len(pendent) > 0: index = (len(threads) - len(pendent)) + 1 percentage = int(math.ceil(index * t)) diff --git a/plugin.video.alfa/channels/seriecanal.py b/plugin.video.alfa/channels/seriecanal.py index 0ac2bfb4..34c7adf9 100644 --- a/plugin.video.alfa/channels/seriecanal.py +++ b/plugin.video.alfa/channels/seriecanal.py @@ -9,7 +9,7 @@ from core import servertools from platformcode import config, logger __modo_grafico__ = config.get_setting('modo_grafico', "seriecanal") -__perfil__ = config.get_setting('perfil', "descargasmix") +__perfil__ = config.get_setting('perfil', "seriecanal") # Fijar perfil de color perfil = [['0xFFFFE6CC', '0xFFFFCE9C', '0xFF994D00'], diff --git a/plugin.video.alfa/core/tmdb.py b/plugin.video.alfa/core/tmdb.py index b8c1ccb0..72c709e5 100644 --- a/plugin.video.alfa/core/tmdb.py +++ b/plugin.video.alfa/core/tmdb.py @@ -319,7 +319,7 @@ def set_infoLabels_item(item, seekTmdb=True, idioma_busqueda='es', lock=None): __leer_datos(otmdb_global) - if lock: + if lock and lock.locked(): lock.release() if item.infoLabels['episode']: From 4c949d5d89b858d405acee8974caa439b5d7f8a4 Mon Sep 17 00:00:00 2001 From: Kingbox <37674310+lopezvg@users.noreply.github.com> Date: Wed, 12 Sep 2018 11:51:44 +0200 Subject: [PATCH 15/29] =?UTF-8?q?Generictools:=20c=C3=A1lculo=20tama=C3=B1?= =?UTF-8?q?o=20.torrent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin.video.alfa/channels/divxtotal.py | 26 +++- plugin.video.alfa/channels/elitetorrent.py | 31 +++-- plugin.video.alfa/channels/estrenosgo.py | 29 +++- plugin.video.alfa/channels/grantorrent.py | 16 ++- plugin.video.alfa/channels/mejortorrent1.py | 16 ++- plugin.video.alfa/channels/newpct1.py | 42 ++++-- plugin.video.alfa/lib/generictools.py | 141 ++++++++++++++++++-- 7 files changed, 258 insertions(+), 43 deletions(-) diff --git a/plugin.video.alfa/channels/divxtotal.py b/plugin.video.alfa/channels/divxtotal.py index 8e1ba213..1a0deaf5 100644 --- a/plugin.video.alfa/channels/divxtotal.py +++ b/plugin.video.alfa/channels/divxtotal.py @@ -519,17 +519,35 @@ def findvideos(item): item, itemlist = generictools.post_tmdb_findvideos(item, itemlist) #Ahora tratamos los enlaces .torrent - for scrapedurl in matches: #leemos los torrents con la diferentes calidades + for scrapedurl in matches: #leemos los torrents con la diferentes calidades #Generamos una copia de Item para trabajar sobre ella item_local = item.clone() + #Buscamos si ya tiene tamaño, si no, los buscamos en el archivo .torrent + size = scrapertools.find_single_match(item_local.quality, '\s\[(\d+,?\d*?\s\w\s?[b|B])\]') + if not size: + size = generictools.get_torrent_size(item_local.url) #Buscamos el tamaño en el .torrent + if size: + item_local.title = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item_local.title) #Quitamos size de título, si lo traía + item_local.title = '%s [%s]' % (item_local.title, size) #Agregamos size al final del título + size = size.replace('GB', 'G B').replace('Gb', 'G b').replace('MB', 'M B').replace('Mb', 'M b') + item_local.quality = re.sub(r'\s\[\d+,?\d*?\s\w\s?[b|B]\]', '', item_local.quality) #Quitamos size de calidad, si lo traía + item_local.quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final de la calidad + #Ahora pintamos el link del Torrent item_local.url = scrapedurl if host not in item_local.url and host.replace('https', 'http') not in item_local.url : item_local.url = host + item_local.url - item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.quality, str(item_local.language)) #Preparamos título de Torrent - item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title) #Quitamos etiquetas vacías - item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title) #Quitamos colores vacíos + item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.quality, str(item_local.language)) + + #Preparamos título y calidad, quitamos etiquetas vacías + item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.title) + item_local.title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.title) + item_local.title = item_local.title.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() + item_local.quality = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.quality) + item_local.quality = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.quality) + item_local.quality = item_local.quality.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() + item_local.alive = "??" #Calidad del link sin verificar item_local.action = "play" #Visualizar vídeo item_local.server = "torrent" #Seridor Torrent diff --git a/plugin.video.alfa/channels/elitetorrent.py b/plugin.video.alfa/channels/elitetorrent.py index 6842c037..1a052a4a 100644 --- a/plugin.video.alfa/channels/elitetorrent.py +++ b/plugin.video.alfa/channels/elitetorrent.py @@ -171,8 +171,11 @@ def listado(item): #Limpiamos el título de la basura innecesaria title = title.replace("Dual", "").replace("dual", "").replace("Subtitulada", "").replace("subtitulada", "").replace("Subt", "").replace("subt", "").replace("Sub", "").replace("sub", "").replace("(Proper)", "").replace("(proper)", "").replace("Proper", "").replace("proper", "").replace("#", "").replace("(Latino)", "").replace("Latino", "") - title = title.replace("- HDRip", "").replace("(HDRip)", "").replace("- Hdrip", "").replace("(microHD)", "").replace("(DVDRip)", "").replace("(HDRip)", "").replace("(BR-LINE)", "").replace("(HDTS-SCREENER)", "").replace("(BDRip)", "").replace("(BR-Screener)", "").replace("(DVDScreener)", "").replace("TS-Screener", "").replace(" TS", "").replace(" Ts", "") + title = title.replace("- HDRip", "").replace("(HDRip)", "").replace("- Hdrip", "").replace("(microHD)", "").replace("(DVDRip)", "").replace("(HDRip)", "").replace("(BR-LINE)", "").replace("(HDTS-SCREENER)", "").replace("(BDRip)", "").replace("(BR-Screener)", "").replace("(DVDScreener)", "").replace("TS-Screener", "").replace(" TS", "").replace(" Ts", "").replace("temporada", "").replace("Temporada", "").replace("capitulo", "").replace("Capitulo", "") + + title = re.sub(r'(?:\d+)?x.?\s?\d+', '', title) title = re.sub(r'\??\s?\d*?\&.*', '', title).title().strip() + item_local.from_title = title #Guardamos esta etiqueta para posible desambiguación de título if item_local.extra == "peliculas": #preparamos Item para películas @@ -190,16 +193,17 @@ def listado(item): item_local.contentType = "episode" item_local.extra = "series" epi_mult = scrapertools.find_single_match(item_local.url, r'cap.*?-\d+-al-(\d+)') - item_local.contentSeason = scrapertools.find_single_match(item_local.url, r'temp.*?-(\d+)') + item_local.contentSeason = scrapertools.find_single_match(item_local.url, r'temporada-(\d+)') item_local.contentEpisodeNumber = scrapertools.find_single_match(item_local.url, r'cap.*?-(\d+)') if not item_local.contentSeason: item_local.contentSeason = scrapertools.find_single_match(item_local.url, r'-(\d+)[x|X]\d+') if not item_local.contentEpisodeNumber: item_local.contentEpisodeNumber = scrapertools.find_single_match(item_local.url, r'-\d+[x|X](\d+)') - if item_local.contentSeason < 1: - item_local.contentSeason = 1 + if not item_local.contentSeason or item_local.contentSeason < 1: + item_local.contentSeason = 0 if item_local.contentEpisodeNumber < 1: item_local.contentEpisodeNumber = 1 + item_local.contentSerieName = title if epi_mult: title = "%sx%s al %s -" % (item_local.contentSeason, str(item_local.contentEpisodeNumber).zfill(2), str(epi_mult).zfill(2)) #Creamos un título con el rango de episodios @@ -269,11 +273,11 @@ def findvideos(item): #data = unicode(data, "utf-8", errors="replace") #Añadimos el tamaño para todos - size = scrapertools.find_single_match(item.quality, '\s\[(\d+,?\d*?\s\w[b|B]s)\]') + size = scrapertools.find_single_match(item.quality, '\s\[(\d+,?\d*?\s\w\s?[b|B]s)\]') if size: item.title = re.sub('\s\[\d+,?\d*?\s\w[b|B]s\]', '', item.title) #Quitamos size de título, si lo traía item.title = '%s [%s]' % (item.title, size) #Agregamos size al final del título - item.quality = re.sub('\s\[\d+,?\d*?\s\w[b|B]s\]', '', item.quality) #Quitamos size de calidad, si lo traía + item.quality = re.sub('\s\[\d+,?\d*?\s\w\s?[b|B]s\]', '', item.quality) #Quitamos size de calidad, si lo traía patron_t = '
Formato:<\/b>&\w+;\s?([^<]+)
'): item_local.quality = scrapertools.find_single_match(data, 'Formato:<\/b>&\w+;\s?([^<]+)
') elif "hdtv" in item_local.url.lower() or "720p" in item_local.url.lower() or "1080p" in item_local.url.lower() or "4k" in item_local.url.lower(): item_local.quality = scrapertools.find_single_match(item_local.url, '.*?_([H|7|1|4].*?)\.torrent') item_local.quality = item_local.quality.replace("_", " ") - + # Extrae el tamaño del vídeo if scrapertools.find_single_match(data, 'Tama.*?:<\/b>&\w+;\s?([^<]+B)Tama.*?:<\/b>&\w+;\s?([^<]+B)
Size:<\/strong>?\s(\d+?\.?\d*?\s\w[b|B])<\/span>') size = size.replace(".", ",") #sustituimos . por , porque Unify lo borra if not size: - size = scrapertools.find_single_match(item.quality, '\s\[(\d+,?\d*?\s\w[b|B])\]') + size = scrapertools.find_single_match(item.quality, '\s\[(\d+,?\d*?\s\w\s?[b|B])\]') + if not size: + size = generictools.get_torrent_size(item.url) #Buscamos el tamaño en el .torrent if size: item.title = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.title) #Quitamos size de título, si lo traía item.title = '%s [%s]' % (item.title, size) #Agregamos size al final del título size = size.replace('GB', 'G B').replace('Gb', 'G b').replace('MB', 'M B').replace('Mb', 'M b') - item.quality = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item.quality) #Quitamos size de calidad, si lo traía + item.quality = re.sub(r'\s\[\d+,?\d*?\s\w\s?[b|B]\]', '', item.quality) #Quitamos size de calidad, si lo traía #Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB item, itemlist = generictools.post_tmdb_findvideos(item, itemlist) @@ -1399,8 +1401,15 @@ def findvideos(item): else: quality = item_local.quality item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (quality, str(item_local.language)) #Preparamos título de Torrent - item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos etiquetas vacías - item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title).strip() #Quitamos colores vacíos + + #Preparamos título y calidad, quitamos etiquetas vacías + item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.title) + item_local.title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.title) + item_local.title = item_local.title.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() + quality = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', quality) + quality = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', quality) + quality = quality.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() + item_local.alive = "??" #Calidad del link sin verificar item_local.action = "play" #Visualizar vídeo item_local.server = "torrent" #Servidor @@ -1485,9 +1494,15 @@ def findvideos(item): item_local.action = "play" item_local.server = servidor item_local.url = enlace - item_local.title = item_local.title.replace("[]", "").strip() - item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip() - item_local.title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', item_local.title).strip() + + #Preparamos título y calidad, quitamos etiquetas vacías + item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.title) + item_local.title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.title) + item_local.title = item_local.title.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() + item_local.quality = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.quality) + item_local.quality = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.quality) + item_local.quality = item_local.quality.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() + itemlist.append(item_local.clone()) except: @@ -1582,9 +1597,16 @@ def findvideos(item): item_local.action = "play" item_local.server = servidor item_local.url = enlace - item_local.title = parte_title.replace("[]", "").strip() - item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip() - item_local.title = re.sub(r'\[COLOR \w+\]-\[\/COLOR\]', '', item_local.title).strip() + item_local.title = parte_title.strip() + + #Preparamos título y calidad, quitamos etiquetas vacías + item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.title) + item_local.title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.title) + item_local.title = item_local.title.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() + item_local.quality = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.quality) + item_local.quality = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.quality) + item_local.quality = item_local.quality.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() + itemlist.append(item_local.clone()) except: diff --git a/plugin.video.alfa/lib/generictools.py b/plugin.video.alfa/lib/generictools.py index fa6bb57c..24d7d5c9 100644 --- a/plugin.video.alfa/lib/generictools.py +++ b/plugin.video.alfa/lib/generictools.py @@ -8,6 +8,7 @@ # ------------------------------------------------------------ import re +import os import sys import urllib import urlparse @@ -236,8 +237,7 @@ def post_tmdb_listado(item, itemlist): del item.channel_alt if item.url_alt: del item.url_alt - if item.extra2: - del item.extra2 + #Ajustamos el nombre de la categoría if not item.category_new: item.category_new = '' @@ -389,8 +389,8 @@ def post_tmdb_listado(item, itemlist): if item_local.infoLabels['episodio_titulo']: item_local.infoLabels['episodio_titulo'] = item_local.infoLabels['episodio_titulo'].replace(" []", "").strip() title = title.replace("--", "").replace(" []", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() - title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', title).strip() - title = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', title).strip() + title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', title).strip() + title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', title).strip() if item.category_new == "newest": #Viene de Novedades. Marcamos el título con el nombre del canal title += ' -%s-' % scrapertools.find_single_match(item_local.url, 'http.?\:\/\/(?:www.)?(\w+)\.\w+\/').capitalize() @@ -766,6 +766,7 @@ def post_tmdb_episodios(item, itemlist): #Si no está el título del episodio, pero sí está en "title", lo rescatamos if not item_local.infoLabels['episodio_titulo'] and item_local.infoLabels['title'].lower() != item_local.infoLabels['tvshowtitle'].lower(): item_local.infoLabels['episodio_titulo'] = item_local.infoLabels['title'] + item_local.infoLabels['episodio_titulo'] = item_local.infoLabels['episodio_titulo'].replace('GB', 'G B').replace('MB', 'M B') #Preparamos el título para que sea compatible con Añadir Serie a Videoteca if "Temporada" in item_local.title: #Compatibilizamos "Temporada" con Unify @@ -792,8 +793,8 @@ def post_tmdb_episodios(item, itemlist): item_local.infoLabels['episodio_titulo'] = item_local.infoLabels['episodio_titulo'].replace(" []", "").strip() item_local.infoLabels['title'] = item_local.infoLabels['title'].replace(" []", "").strip() item_local.title = item_local.title.replace(" []", "").strip() - item_local.title = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', item_local.title).strip() - item_local.title = re.sub(r'\s\[COLOR \w+\]-\[\/COLOR\]', '', item_local.title).strip() + item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?-?\s?\]?\]\[\/COLOR\]', '', item_local.title).strip() + item_local.title = re.sub(r'\s?\[COLOR \w+\]-?\s?\[\/COLOR\]', '', item_local.title).strip() #Si la información de num. total de episodios de TMDB no es correcta, tratamos de calcularla if num_episodios < item_local.contentEpisodeNumber: @@ -1054,8 +1055,8 @@ def post_tmdb_findvideos(item, itemlist): title_gen = item.title #Limpiamos etiquetas vacías - title_gen = re.sub(r'\s\[COLOR \w+\]\[\[?\]?\]\[\/COLOR\]', '', title_gen).strip() #Quitamos etiquetas vacías - title_gen = re.sub(r'\s\[COLOR \w+\]\[\/COLOR\]', '', title_gen).strip() #Quitamos colores vacíos + title_gen = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', title_gen).strip() #Quitamos etiquetas vacías + title_gen = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', title_gen).strip() #Quitamos colores vacíos title_gen = title_gen.replace(" []", "").strip() #Quitamos etiquetas vacías title_videoteca = title_gen #Salvamos el título para Videoteca @@ -1103,7 +1104,131 @@ def post_tmdb_findvideos(item, itemlist): return (item, itemlist) + +def get_torrent_size(url): + logger.info() + + """ + + Módulo extraido del antiguo canal ZenTorrent + + Calcula el tamaño de los archivos que contienen un .torrent. Descarga el archivo .torrent en una carpeta, + lo lee y descodifica. Si contiene múltiples archivos, suma el tamaño de todos ellos + + Llamada: generictools.get_torrent_size(url) + Entrada: url: url del archivo .torrent + Salida: size: str con el tamaño y tipo de medida ( MB, GB, etc) + + """ + + def convert_size(size): + import math + if (size == 0): + return '0B' + size_name = ("B", "KB", "M B", "G B", "TB", "PB", "EB", "ZB", "YB") + i = int(math.floor(math.log(size, 1024))) + p = math.pow(1024, i) + s = round(size / p, 2) + return '%s %s' % (s, size_name[i]) + + def decode(text): + try: + src = tokenize(text) + data = decode_item(src.next, src.next()) + for token in src: # look for more tokens + raise SyntaxError("trailing junk") + except (AttributeError, ValueError, StopIteration): + try: + data = data + except: + data = src + return data + + def tokenize(text, match=re.compile("([idel])|(\d+):|(-?\d+)").match): + i = 0 + while i < len(text): + m = match(text, i) + s = m.group(m.lastindex) + i = m.end() + if m.lastindex == 2: + yield "s" + yield text[i:i + int(s)] + i = i + int(s) + else: + yield s + + def decode_item(next, token): + if token == "i": + # integer: "i" value "e" + data = int(next()) + if next() != "e": + raise ValueError + elif token == "s": + # string: "s" value (virtual tokens) + data = next() + elif token == "l" or token == "d": + # container: "l" (or "d") values "e" + data = [] + tok = next() + while tok != "e": + data.append(decode_item(next, tok)) + tok = next() + if token == "d": + data = dict(zip(data[0::2], data[1::2])) + else: + raise ValueError + return data + + + #Móludo principal + size = "" + try: + torrents_path = config.get_videolibrary_path() + '/torrents' #path para dejar el .torrent + + if not os.path.exists(torrents_path): + os.mkdir(torrents_path) #si no está la carpeta la creamos + + urllib.URLopener.version = 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36 SE 2.X MetaSr 1.0' + urllib.urlretrieve(url, torrents_path + "/generictools.torrent") #desacargamos el .torrent a la carpeta + torrent_file = open(torrents_path + "/generictools.torrent", "rb").read() #leemos el .torrent + + if "used CloudFlare" in torrent_file: #Si tiene CloudFlare, usamos este proceso + try: + urllib.urlretrieve("http://anonymouse.org/cgi-bin/anon-www.cgi/" + url.strip(), + torrents_path + "/generictools.torrent") + torrent_file = open(torrents_path + "/generictools.torrent", "rb").read() + except: + torrent_file = "" + + torrent = decode(torrent_file) #decodificamos el .torrent + + #si sólo tiene un archivo, tomamos la longitud y la convertimos a una unidad legible, si no dará error + try: + sizet = torrent["info"]['length'] + size = convert_size(sizet) + except: + pass + + #si tiene múltiples archivos sumamos la longitud de todos + if not size: + check_video = scrapertools.find_multiple_matches(str(torrent["info"]["files"]), "'length': (\d+)}") + sizet = sum([int(i) for i in check_video]) + size = convert_size(sizet) + + except: + logger.error('ERROR al buscar el tamaño de un .Torrent: ' + url) + + try: + os.remove(torrents_path + "/generictools.torrent") #borramos el .torrent + except: + pass + + #logger.debug(url + ' / ' + size) + + return size + + def get_field_from_kodi_DB(item, from_fields='*', files='file'): logger.info() """ From ce3690f06b046435bf3af0b070d6ad02951184f2 Mon Sep 17 00:00:00 2001 From: Kingbox <37674310+lopezvg@users.noreply.github.com> Date: Wed, 12 Sep 2018 11:54:44 +0200 Subject: [PATCH 16/29] =?UTF-8?q?ZonaTorrent:=20canal=20redise=C3=B1ado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Películas por géneros, calidades, idiomas y alfabeto - Series completas agrupadas por temporadas - Búsquedas - Videoteca de Series - Control de página inteligente, en función de los items y del tiempo de proceso Mejoras de títulos, con calidades --- plugin.video.alfa/channels/zonatorrent.json | 67 +- plugin.video.alfa/channels/zonatorrent.py | 1096 ++++++++++++++--- .../media/channels/thumb/zonatorrent.png | Bin 0 -> 36220 bytes 3 files changed, 948 insertions(+), 215 deletions(-) create mode 100644 plugin.video.alfa/resources/media/channels/thumb/zonatorrent.png diff --git a/plugin.video.alfa/channels/zonatorrent.json b/plugin.video.alfa/channels/zonatorrent.json index 31f31200..ce829a98 100644 --- a/plugin.video.alfa/channels/zonatorrent.json +++ b/plugin.video.alfa/channels/zonatorrent.json @@ -5,28 +5,59 @@ "adult": false, "language": ["cast", "lat"], "banner": "", - "thumbnail": "https://zonatorrent.org/wp-content/uploads/2017/04/zonatorrent-New-Logo.png", + "thumbnail": "zonatorrent.png", "version": 1, "categories": [ - "torrent", - "movie" + "torrent", + "movie", + "tvshow", + "vos" ], "settings": [ - { - "id": "include_in_global_search", - "type": "bool", - "label": "Incluir en busqueda global", - "default": true, - "enabled": true, - "visible": true - }, - { - "id": "modo_grafico", - "type": "bool", - "label": "Buscar información extra", - "default": true, - "enabled": true, - "visible": true + { + "id": "include_in_global_search", + "type": "bool", + "label": "Incluir en busqueda global", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "modo_grafico", + "type": "bool", + "label": "Buscar información extra", + "default": true, + "enabled": true, + "visible": true + }, + { + "id": "timeout_downloadpage", + "type": "list", + "label": "Timeout (segs.) en descarga de páginas o verificación de servidores", + "default": 5, + "enabled": true, + "visible": true, + "lvalues": [ + "None", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10" + ] + }, + { + "id": "seleccionar_ult_temporadda_activa", + "type": "bool", + "label": "Seleccionar para Videoteca si estará activa solo la última Temporada", + "default": true, + "enabled": true, + "visible": true }, { "id": "include_in_newest_peliculas", diff --git a/plugin.video.alfa/channels/zonatorrent.py b/plugin.video.alfa/channels/zonatorrent.py index d3a85b28..6bee0e95 100644 --- a/plugin.video.alfa/channels/zonatorrent.py +++ b/plugin.video.alfa/channels/zonatorrent.py @@ -1,197 +1,899 @@ -# -*- coding: utf-8 -*- -# -*- Channel TioTorrent -*- -# -*- Created for Alfa-addon -*- -# -*- By the Alfa Develop Group -*- - -import re - -from channelselector import get_thumb -from core import httptools -from core import scrapertools -from core import servertools -from core import tmdb -from core.item import Item -from platformcode import logger - -__channel__ = "zonatorrent" - -HOST = 'https://zonatorrent.org' - -try: - __modo_grafico__ = config.get_setting('modo_grafico', __channel__) -except: - __modo_grafico__ = True - - -def mainlist(item): - logger.info() - - itemlist = list() - itemlist.append(Item(channel=item.channel, title="Últimas Películas", action="listado", url=HOST, page=False)) - itemlist.append(Item(channel=item.channel, title="Alfabético", action="alfabetico")) - itemlist.append(Item(channel=item.channel, title="Géneros", action="generos", url=HOST)) - itemlist.append(Item(channel=item.channel, title="Más vistas", action="listado", url=HOST + "/peliculas-mas-vistas/")) - itemlist.append(Item(channel=item.channel, title="Más votadas", action="listado", url=HOST + "/peliculas-mas-votadas/")) - itemlist.append(Item(channel=item.channel, title="Castellano", action="listado", url=HOST + "/?s=spanish", - page=True)) - itemlist.append(Item(channel=item.channel, title="Latino", action="listado", url=HOST + "/?s=latino", page=True)) - itemlist.append(Item(channel=item.channel, title="Subtitulado", action="listado", url=HOST + "/?s=Subtitulado", - page=True)) - itemlist.append(Item(channel=item.channel, title="Con Torrent", action="listado", url=HOST + "/?s=torrent", - page=True)) - itemlist.append(Item(channel=item.channel, title="Buscar", action="search", url=HOST + "/?s=", - page=False)) - - return itemlist - - -def alfabetico(item): - logger.info() - - itemlist = [] - - for letra in "#ABCDEFGHIJKLMNOPQRSTUVWXYZ": - itemlist.append(Item(channel=item.channel, action="listado", title=letra, page=True, - url=HOST + "/letters/%s/" % letra.replace("#", "0-9"))) - - return itemlist - - -def generos(item): - logger.info() - - itemlist = [] - - data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item.url).data) - data = scrapertools.find_single_match(data, 'Generos(.*?)') - matches = scrapertools.find_multiple_matches(data, '(.*?)') - - for url, title in matches: - itemlist.append(Item(channel=item.channel, action="listado", title=title, url=url, page=True)) - - return itemlist - - -def search(item, texto): - logger.info() - item.url = item.url + texto.replace(" ", "+") - - try: - itemlist = listado(item) - except: - import sys - for line in sys.exc_info(): - logger.error("%s" % line) - return [] - - return itemlist - - -def listado(item): - logger.info() - - itemlist = [] - - data = re.sub(r"\n|\r|\t|\s{2}|()", "", httptools.downloadpage(item.url).data) - - pattern = ']+>]+>]+src="(?P[^"]+)"[^>]+>
' \ - '

(?P.*?)</h2>.*?<span class="Time[^>]+>(?P<duration>.*?)</span><span ' \ - 'class="Date[^>]+>(?P<year>.*?)</span><span class="Qlty">(?P<quality>.*?)</span></p><div ' \ - 'class="Description"><p>.*?\:\s*(?P<plot>.*?)</p>' - matches = re.compile(pattern, re.DOTALL).findall(data) - - for url, thumb, title, duration, year, quality, plot in matches: - #title = title.strip().replace("Spanish Online Torrent", "").replace("Latino Online Torrent", "").replace(r'\d{4}','') - title = re.sub('Online|Spanish|Latino|Torrent|\d{4}','',title) - infoLabels = {"year": year} - - aux = scrapertools.find_single_match(duration, "(\d+)h\s*(\d+)m") - duration = "%s" % ((int(aux[0]) * 3600) + (int(aux[1]) * 60)) - infoLabels["duration"] = duration - - itemlist.append(Item(channel=item.channel, action="findvideos", title=title, url=url, thumbnail=thumb, - contentTitle=title, plot=plot, infoLabels=infoLabels)) - tmdb.set_infoLabels_itemlist(itemlist, __modo_grafico__) - if item.page: - pattern = "<span class='page-numbers current'>[^<]+</span><a class='page-numbers' href='([^']+)'" - url = scrapertools.find_single_match(data, pattern) - - itemlist.append(Item(channel=item.channel, action="listado", title=">> Página siguiente", url=url, page=True, - thumbnail=get_thumb("next.png"))) - - return itemlist - - -def findvideos(item): - logger.info() - - itemlist = [] - language = '' - quality = '' - data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url).data) - data = re.sub(r""", '"', data) - data = re.sub(r"<", '<', data) - - titles = re.compile('data-TPlayerNv="Opt\d+">.*? <span>(.*?)</span></li>', re.DOTALL).findall(data) - urls = re.compile('id="Opt\d+"><iframe[^>]+src="([^"]+)"', re.DOTALL).findall(data) - - if len(titles) == len(urls): - for i in range(0, len(titles)): - if i > 0: - logger.debug('titles: %s' % titles[i].strip()) - language, quality = titles[i].split(' - ') - title = "%s" % titles[i].strip() - else: - title = titles[0] - - if "goo.gl" in urls[i]: - urls[i] = httptools.downloadpage(urls[i], follow_redirects=False, only_headers=True)\ - .headers.get("location", "") - videourl = servertools.findvideos(urls[i]) - if len(videourl) > 0: - server = videourl[0][0].capitalize() - title = '%s %s' % (server, title) - itemlist.append(Item(channel=item.channel, action="play", title=title, url=videourl[0][1], - server=server, thumbnail=videourl[0][3], fulltitle=item.title, - language=language, quality=quality )) - - pattern = '<a[^>]+href="([^"]+)"[^<]+</a></td><td><span><img[^>]+>(.*?)</span></td><td><span><img[^>]+>(.*?)' \ - '</span></td><td><span>(.*?)</span>' - torrents = re.compile(pattern, re.DOTALL).findall(data) - - if len(torrents) > 0: - for url, text, lang, quality in torrents: - title = "%s %s - %s" % (text, lang, quality) - itemlist.append(Item(channel=item.channel, action="play", title=title, url=url, server="torrent", - fulltitle=item.title, thumbnail=get_thumb("channels_torrent.png"))) - - return itemlist - -def newest(categoria): - logger.info() - itemlist = [] - item = Item() - try: - if categoria == 'peliculas': - item.url = HOST - elif categoria == 'infantiles': - item.url = HOST + "/animacion" - elif categoria == 'terror': - item.url = HOST + "/terror/" - elif categoria == 'torrent': - item.url = HOST + "/?s=torrent" - else: - return [] - - itemlist = listado(item) - if itemlist[-1].title == ">> Página siguiente": - itemlist.pop() - - # Se captura la excepción, para no interrumpir al canal novedades si un canal falla - except: - import sys - for line in sys.exc_info(): - logger.error("{0}".format(line)) - return [] - - return itemlist +# -*- coding: utf-8 -*- + +import re +import sys +import urllib +import urlparse +import time + +from channelselector import get_thumb +from core import httptools +from core import scrapertools +from core import servertools +from core.item import Item +from platformcode import config, logger +from core import tmdb +from lib import generictools + + +host = 'https://zonatorrent.tv/' +channel = "zonatorrent" + +categoria = channel.capitalize() +__modo_grafico__ = config.get_setting('modo_grafico', channel) +modo_ultima_temp = config.get_setting('seleccionar_ult_temporadda_activa', channel) #Actualización sólo últ. Temporada? +timeout = config.get_setting('timeout_downloadpage', channel) + + +def mainlist(item): + logger.info() + itemlist = [] + + thumb_pelis = get_thumb("channels_movie.png") + thumb_series = get_thumb("channels_tvshow.png") + thumb_buscar = get_thumb("search.png") + thumb_separador = get_thumb("next.png") + + + itemlist.append(Item(channel=item.channel, title="Películas", action="submenu", url=host, thumbnail=thumb_pelis, extra="peliculas")) + + itemlist.append(Item(channel=item.channel, url=host, title="Series", action="submenu", thumbnail=thumb_series, extra="series")) + + itemlist.append(Item(channel=item.channel, title="Buscar...", action="search", url=host + "?s=", thumbnail=thumb_buscar, extra="search")) + + return itemlist + + +def submenu(item): + logger.info() + itemlist = [] + + thumb_cartelera = get_thumb("now_playing.png") + thumb_pelis_az = get_thumb("channels_movie_az.png") + thumb_pelis = get_thumb("channels_movie.png") + thumb_pelis_hd = get_thumb("channels_movie_hd.png") + thumb_pelis_vos = get_thumb("channels_vos.png") + thumb_popular = get_thumb("popular.png") + thumb_generos = get_thumb("genres.png") + thumb_spanish = get_thumb("channels_spanish.png") + thumb_latino = get_thumb("channels_latino.png") + thumb_torrent = get_thumb("channels_torrent.png") + thumb_series = get_thumb("channels_tvshow.png") + thumb_series_az = get_thumb("channels_tvshow_az.png") + + + if item.extra != "series": + item.url_plus = "movies" + itemlist.append(item.clone(title="Últimas Películas", action="listado", url=host + "estrenos-de-cine-2", url_plus=item.url_plus, thumbnail=thumb_cartelera)) + itemlist.append(item.clone(title="Alfabético", action="alfabeto", url=host + "letters/%s", thumbnail=thumb_pelis_az, extra2 = 'alfabeto')) + itemlist.append(item.clone(title="Géneros", action="categorias", url=host + item.url_plus, url_plus=item.url_plus, extra2= "generos", thumbnail=thumb_generos)) + itemlist.append(item.clone(title="Calidades", action="categorias", url=host + item.url_plus, url_plus=item.url_plus, extra2= "calidades", thumbnail=thumb_pelis_hd)) + itemlist.append(item.clone(title="Más vistas", action="listado", url=host + "/peliculas-mas-vistas-2/", url_plus=item.url_plus, thumbnail=thumb_popular, extra2="popular")) + itemlist.append(item.clone(title="Más votadas", action="listado", url=host + "/peliculas-mas-votadas/", url_plus=item.url_plus, thumbnail=thumb_popular, extra2="popular")) + itemlist.append(item.clone(title="Castellano", action="listado", url=host + "?s=spanish", url_plus=item.url_plus, thumbnail=thumb_spanish, extra2="CAST")) + itemlist.append(item.clone(title="Latino", action="listado", url=host + "?s=latino", url_plus=item.url_plus, thumbnail=thumb_latino, lextra2="LAT")) + itemlist.append(item.clone(title="Subtitulado", action="listado", url=host + "?s=Subtitulado", url_plus=item.url_plus, thumbnail=thumb_pelis_vos, extra2="VOSE")) + + else: + item.url_plus = "serie-tv" + itemlist.append(item.clone(title="Series completas", action="listado", url=item.url + item.url_plus, url_plus=item.url_plus, thumbnail=thumb_series, extra="series")) + itemlist.append(item.clone(title="Alfabético A-Z", action="alfabeto", url=item.url + "letters/%s", url_plus=item.url_plus, thumbnail=thumb_series_az, extra="series", extra2 = 'alfabeto')) + itemlist.append(item.clone(title="Más vistas", action="listado", url=host + "/peliculas-mas-vistas-2/", url_plus=item.url_plus, thumbnail=thumb_popular, extra2="popular")) + itemlist.append(item.clone(title="Más votadas", action="listado", url=host + "/peliculas-mas-votadas/", url_plus=item.url_plus, thumbnail=thumb_popular, extra2="popular")) + itemlist.append(item.clone(title="Castellano", action="listado", url=host + "?s=spanish", url_plus=item.url_plus, thumbnail=thumb_spanish, extra2="CAST")) + itemlist.append(item.clone(title="Latino", action="listado", url=host + "?s=latino", url_plus=item.url_plus, thumbnail=thumb_latino, extra2="LAT")) + itemlist.append(item.clone(title="Subtitulado", action="listado", url=host + "?s=Subtitulado", url_plus=item.url_plus, thumbnail=thumb_pelis_vos, extra2="VOSE")) + + return itemlist + + +def categorias(item): + logger.info() + + itemlist = [] + + data = '' + try: + data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url, timeout=timeout).data) + data = unicode(data, "utf-8", errors="replace").encode("utf-8") + except: + pass + + patron = '<div id="categories-2" class="Wdgt widget_categories"><div class="Title widget-title">Categorías</div><ul>(.*?)<\/ul><\/div>' + #Verificamos si se ha cargado una página, y si además tiene la estructura correcta + if not data or not scrapertools.find_single_match(data, patron): + item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada + if item.intervencion: #Sí ha sido clausurada judicialmente + for clone_inter, autoridad in item.intervencion: + thumb_intervenido = get_thumb(autoridad) + itemlist.append(item.clone(action='', title="[COLOR yellow]" + clone_inter.capitalize() + ': [/COLOR]' + intervenido_judicial + '. Reportar el problema en el foro', thumbnail=thumb_intervenido)) + return itemlist #Salimos + + logger.error("ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL: " + item.url + data) + if not data: #Si no ha logrado encontrar nada, salimos + itemlist.append(item.clone(action='', title=item.category + ': ERROR 01: SUBMENU: La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log')) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + + data = scrapertools.find_single_match(data, patron) + patron = '<li class="[^>]+><a href="([^"]+)"\s?(?:title="[^"]+")?>(.*?)<\/a><\/li>' + matches = re.compile(patron, re.DOTALL).findall(data) + + if not matches: + logger.error("ERROR 02: SUBMENU: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.category + ': ERROR 02: SUBMENU: Ha cambiado la estructura de la Web. Reportar el error con el log')) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + + #logger.debug(item.url_plus) + #logger.debug(matches) + + for scrapedurl, scrapedtitle in matches: + + #Preguntamos por las entradas que corresponden al "extra2" + if item.extra2 == 'calidades': + if scrapedtitle.lower() in ['dvd full', 'tshq', 'bdrip', 'dvdscreener', 'brscreener r6', 'brscreener', 'webscreener', 'dvd', 'hdrip', 'screener', 'screeer', 'webrip', 'brrip', 'dvb', 'dvdrip', 'dvdsc', 'dvdsc - r6', 'hdts', 'hdtv', 'kvcd', 'line', 'ppv', 'telesync', 'ts hq', 'ts hq proper', '480p', '720p', 'ac3', 'bluray', 'camrip', 'ddc', 'hdtv - screener', 'tc screener', 'ts screener', 'ts screener alto', 'ts screener medio', 'vhs screener']: + itemlist.append(item.clone(action="listado", title=scrapedtitle.capitalize().strip(), url=scrapedurl)) + + else: + if scrapedtitle.lower() not in ['estrenos de cine', 'serie tv', 'dvd full', 'tshq', 'bdrip', 'dvdscreener', 'brscreener r6', 'brscreener', 'webscreener', 'dvd', 'hdrip', 'screener', 'screeer', 'webrip', 'brrip', 'dvb', 'dvdrip', 'dvdsc', 'dvdsc - r6', 'hdts', 'hdtv', 'kvcd', 'line', 'ppv', 'telesync', 'ts hq', 'ts hq proper', '480p', '720p', 'ac3', 'bluray', 'camrip', 'ddc', 'hdtv - screener', 'tc screener', 'ts screener', 'ts screener alto', 'ts screener medio', 'vhs screener']: + itemlist.append(item.clone(action="listado", title=scrapedtitle.capitalize().strip(), url=scrapedurl)) + + return itemlist + + +def alfabeto(item): + logger.info() + itemlist = [] + + itemlist.append(item.clone(action="listado", title="0-9", url=item.url % "0-9")) + + for letra in ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']: + itemlist.append(item.clone(action="listado", title=letra, url=item.url % letra.lower())) + + return itemlist + + +def listado(item): + logger.info() + itemlist = [] + item.category = categoria + + #logger.debug(item) + + curr_page = 1 # Página inicial + last_page = 99999 # Última página inicial + if item.curr_page: + curr_page = int(item.curr_page) # Si viene de una pasada anterior, lo usamos + del item.curr_page # ... y lo borramos + if item.last_page: + last_page = int(item.last_page) # Si viene de una pasada anterior, lo usamos + del item.last_page # ... y lo borramos + + cnt_tot = 40 # Poner el num. máximo de items por página + cnt_title = 0 # Contador de líneas insertadas en Itemlist + inicio = time.time() # Controlaremos que el proceso no exceda de un tiempo razonable + fin = inicio + 10 # Después de este tiempo pintamos (segundos) + timeout_search = timeout # Timeout para descargas + if item.extra == 'search': + timeout_search = timeout * 2 # Timeout un poco más largo para las búsquedas + if timeout_search < 5: + timeout_search = 5 # Timeout un poco más largo para las búsquedas + + #Sistema de paginado para evitar páginas vacías o semi-vacías en casos de búsquedas con series con muchos episodios + title_lista = [] # Guarda la lista de series que ya están en Itemlist, para no duplicar lineas + if item.title_lista: # Si viene de una pasada anterior, la lista ya estará guardada + title_lista.extend(item.title_lista) # Se usa la lista de páginas anteriores en Item + del item.title_lista # ... limpiamos + + if not item.extra2: # Si viene de Catálogo o de Alfabeto + item.extra2 = '' + + next_page_url = item.url + #Máximo num. de líneas permitidas por TMDB. Máx de 10 segundos por Itemlist para no degradar el rendimiento + while cnt_title <= cnt_tot * 0.45 and curr_page <= last_page and fin > time.time(): + + # Descarga la página + data = '' + try: + data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)| ", "", httptools.downloadpage(next_page_url, timeout=timeout_search).data) + data = unicode(data, "utf-8", errors="replace").encode("utf-8") + except: + pass + + if not data: #Si la web está caída salimos sin dar error + logger.error("ERROR 01: LISTADO: La Web no responde o ha cambiado de URL: " + item.url + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: LISTADO:. La Web no responde o ha cambiado de URL. Si la Web está activa, reportar el error con el log')) + break #si no hay más datos, algo no funciona, pintamos lo que tenemos + + #Patrón para todo, menos para Alfabeto + patron = '<li class="TPostMv"><article id="[^"]+" class="[^"]+"><a href="(?P<url>[^"]+)".*?><div[^>]+><figure[^>]+><img[^>]+src="(?P<thumb>[^"]+)"[^>]+><\/figure>(?:<span class="TpTv BgA">(.*?)<\/span>)?<\/div><h2 class="Title">(?P<title>.*?)<\/h2>.*?<span class="Time[^>]+>(?P<duration>.*?)<\/span><span class="Date[^>]+>(?P<year>.*?)<\/span>(?:<span class="Qlty">(?P<quality>.*?)<\/span>)?<\/p><div class="Description">.*?<\/div><\/div><\/article><\/li>' + + #Si viene de Alfabeto, ponemos un patrón especializado + if item.extra2 == 'alfabeto': + patron = '<td class="MvTbImg"><a href="(?P<url>[^"]+)".*?src="(?P<thumb>[^"]+)"[^>]+>(?:<span class="TpTv BgA">(.*?)<\/span>)?<\/a><\/td>[^>]+>[^>]+><strong>(?P<title>.*?)<\/strong><\/a><\/td><td>(?P<year>.*?)<\/td><td><p class="Info"><span class="Qlty">(?P<quality>.*?)<\/span><\/p><\/td><td>(?P<duration>.*?)<\/td>' + + matches = re.compile(patron, re.DOTALL).findall(data) + if not matches and not 'Lo sentimos, no tenemos nada que mostrar' in data: #error + item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada + if item.intervencion: #Sí ha sido clausurada judicialmente + item, itemlist = generictools.post_tmdb_episodios(item, itemlist) #Llamamos al método para el pintado del error + return itemlist #Salimos + + logger.error("ERROR 02: LISTADO: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: LISTADO: Ha cambiado la estructura de la Web. Reportar el error con el log')) + break #si no hay más datos, algo no funciona, pintamos lo que tenemos + + #logger.debug("PATRON: " + patron) + #logger.debug(matches) + #logger.debug(data) + + #Buscamos la url de paginado y la última página + if item.extra2 == 'alfabeto': #patrón especial + patron = "<div class='wp-pagenavi'><span class='pages'>Pagina \d+ of (\d+)<\/span><span class='current'>(\d+)<\/span>" + patron += '<a class="page larger" title="[^"]+" href="([^"]+)">' + else: + patron = '<div class="tr-pagnav wp-pagenavi">' + patron += "<span aria-current='page' class='page-numbers current'>(\d+)<\/span>.*?<a class='page-numbers' href='[^+]+'>(\d+)<\/a>" + patron += '<a class="next page-numbers" href="([^"]+)">Siguiente' + + if last_page == 99999: #Si es el valor inicial, buscamos + try: + if item.extra2 == 'alfabeto': #patrón especial + last_page, curr_page, next_page_url = scrapertools.find_single_match(data, patron) + else: + curr_page, last_page, next_page_url = scrapertools.find_single_match(data, patron) + curr_page = int(curr_page) + last_page = int(last_page) + except: #Si no lo encuentra, lo ponemos a 1 + #logger.error('ERROR 03: LISTADO: Al obtener la paginación: ' + patron) + curr_page = 1 + last_page = 0 + next_page_url = item.url + '/page/1' + #logger.debug('curr_page: ' + str(curr_page) + ' / last_page: ' + str(last_page) + ' / url: ' + next_page_url) + if last_page > 1: + curr_page += 1 #Apunto ya a la página siguiente + next_page_url = re.sub(r'\/page\/\d+', '/page/%s' % curr_page, next_page_url) + + #Empezamos el procesado de matches + for scrapedurl, scrapedthumb, scrapedtype, scrapedtitle, scrapedduration, scrapedyear, scrapedquality in matches: + if item.extra2 == 'alfabeto': #Cambia el orden de tres parámetros + duration = scrapedquality + year = scrapedduration + quality = scrapedyear + else: #lo estándar + duration = scrapedduration + year = scrapedyear + quality = scrapedquality + + #estandarizamos la duración + if 'h' not in duration: + duration = '0:' + duration.replace('m', '') + else: + duration = duration.replace('h ', ':').replace('m', '') + duration = re.sub(r',.*?\]', ']', duration) + if '0:0' in duration or ',' in duration: + duration = '' + else: + try: + hora, minuto = duration.split(':') + duration = '%s:%s h' % (str(hora).zfill(2), str(minuto).zfill(2)) + except: + duration = '' + + #Algunos enlaces no filtran tipos, lo hago aquí + if item.extra2 in ['alfabeto', 'CAST', 'LAT', 'VOSE', 'popular'] or item.category_new == 'newest': + if item.extra == 'peliculas' and 'tv' in scrapedtype.lower(): + continue + elif item.extra == 'series' and not 'tv' in scrapedtype.lower(): + continue + + title = scrapedtitle + title = title.replace("á", "a").replace("é", "e").replace("í", "i").replace("ó", "o").replace("ú", "u").replace("ü", "u").replace("�", "ñ").replace("ñ", "ñ").replace("ã", "a").replace("&etilde;", "e").replace("ĩ", "i").replace("õ", "o").replace("ũ", "u").replace("ñ", "ñ").replace("’", "'") + + cnt_title += 1 + + item_local = item.clone() #Creamos copia de Item para trabajar + if item_local.tipo: #... y limpiamos + del item_local.tipo + if item_local.totalItems: + del item_local.totalItems + if item_local.post_num: + del item_local.post_num + if item_local.intervencion: + del item_local.intervencion + if item_local.viewmode: + del item_local.viewmode + item_local.text_bold = True + del item_local.text_bold + item_local.text_color = True + del item_local.text_color + if item_local.url_plus: + del item_local.url_plus + + title_subs = [] #creamos una lista para guardar info importante + item_local.language = [] #iniciamos Lenguaje + item_local.quality = quality #guardamos la calidad, si la hay + item_local.url = scrapedurl #guardamos el thumb + item_local.thumbnail = scrapedthumb #guardamos el thumb + item_local.context = "['buscar_trailer']" + + item_local.contentType = "movie" #por defecto, son películas + item_local.action = "findvideos" + + #Analizamos los formatos de series + if '-serie-tv-' in scrapedurl or item_local.extra == 'series' or 'tv' in scrapedtype.lower(): + item_local.contentType = "tvshow" + item_local.action = "episodios" + item_local.season_colapse = True #Muestra las series agrupadas por temporadas + + #Buscamos calidades adicionales + if "3d" in title.lower() and not "3d" in item_local.quality.lower(): + if item_local.quality: + item_local.quality += " 3D" + else: + item_local.quality = "3D" + title = re.sub('3D', '', title, flags=re.IGNORECASE) + title = title.replace('[]', '') + if item_local.quality: + item_local.quality += ' %s' % scrapertools.find_single_match(title, '\[(.*?)\]') + else: + item_local.quality = '%s' % scrapertools.find_single_match(title, '\[(.*?)\]') + + #Detectamos idiomas + if 'LAT' in item.extra2: + item_local.language += ['LAT'] + elif 'VOSE' in item.extra2: + item_local.language += ['VOSE'] + if item_local.extra2: del item_local.extra2 + + if ("latino" in scrapedurl.lower() or "latino" in title.lower()) and "LAT" not in item_local.language: + item_local.language += ['LAT'] + elif ('subtitulado' in scrapedurl.lower() or 'subtitulado' in title.lower() or 'vose' in title.lower()) and "VOSE" not in item_local.language: + item_local.language += ['VOSE'] + elif ('version-original' in scrapedurl.lower() or 'version original' in title.lower() or 'vo' in title.lower()) and "VO" not in item_local.language: + item_local.language += ['VO'] + + if item_local.language == []: + item_local.language = ['CAST'] + + #Detectamos info interesante a guardar para después de TMDB + if scrapertools.find_single_match(title, '[m|M].*?serie'): + title = re.sub(r'[m|M]iniserie', '', title) + title_subs += ["Miniserie"] + if scrapertools.find_single_match(title, '[s|S]aga'): + title = re.sub(r'[s|S]aga', '', title) + title_subs += ["Saga"] + if scrapertools.find_single_match(title, '[c|C]olecc'): + title = re.sub(r'[c|C]olecc...', '', title) + title_subs += ["Colección"] + + if "duolog" in title.lower(): + title_subs += ["[Saga]"] + title = title.replace(" Duologia", "").replace(" duologia", "").replace(" Duolog", "").replace(" duolog", "") + if "trilog" in title.lower(): + title_subs += ["[Saga]"] + title = title.replace(" Trilogia", "").replace(" trilogia", "").replace(" Trilog", "").replace(" trilog", "") + if "extendida" in title.lower() or "v.e." in title.lower()or "v e " in title.lower(): + title_subs += ["[V. Extendida]"] + title = title.replace("Version Extendida", "").replace("(Version Extendida)", "").replace("V. Extendida", "").replace("VExtendida", "").replace("V Extendida", "").replace("V.Extendida", "").replace("V Extendida", "").replace("V.E.", "").replace("V E ", "").replace("V:Extendida", "") + + #Analizamos el año. Si no está claro ponemos '-' + try: + yeat_int = int(year) + if yeat_int >= 1970 and yeat_int <= 2040: + item_local.infoLabels["year"] = yeat_int + else: + item_local.infoLabels["year"] = '-' + except: + item_local.infoLabels["year"] = '-' + + #Empezamos a limpiar el título en varias pasadas + patron = '\s?-?\s?(line)?\s?-\s?$' + regex = re.compile(patron, re.I) + title = regex.sub("", title) + title = re.sub(r'\(\d{4}\s*?\)', '', title) + title = re.sub(r'\[\d{4}\s*?\]', '', title) + title = re.sub(r'[s|S]erie', '', title) + title = re.sub(r'- $', '', title) + + #Limpiamos el título de la basura innecesaria + title = re.sub(r'TV|Online|Spanish|Torrent|en Espa\xc3\xb1ol|Español|Latino|Subtitulado|Blurayrip|Bluray rip|\[.*?\]|R2 Pal|\xe3\x80\x90 Descargar Torrent \xe3\x80\x91|Completa|Temporada|Descargar|Torren', '', title, flags=re.IGNORECASE) + + title = title.replace("Dual", "").replace("dual", "").replace("Subtitulada", "").replace("subtitulada", "").replace("Subt", "").replace("subt", "").replace("(Proper)", "").replace("(proper)", "").replace("Proper", "").replace("proper", "").replace("#", "").replace("(Latino)", "").replace("Latino", "").replace("LATINO", "").replace("Spanish", "").replace("Trailer", "").replace("Audio", "") + title = title.replace("HDTV-Screener", "").replace("DVDSCR", "").replace("TS ALTA", "").replace("- HDRip", "").replace("(HDRip)", "").replace("- Hdrip", "").replace("(microHD)", "").replace("(DVDRip)", "").replace("HDRip", "").replace("(BR-LINE)", "").replace("(HDTS-SCREENER)", "").replace("(BDRip)", "").replace("(BR-Screener)", "").replace("(DVDScreener)", "").replace("TS-Screener", "").replace(" TS", "").replace(" Ts", "").replace(" 480p", "").replace(" 480P", "").replace(" 720p", "").replace(" 720P", "").replace(" 1080p", "").replace(" 1080P", "").replace("DVDRip", "").replace(" Dvd", "").replace(" DVD", "").replace(" V.O", "").replace(" Unrated", "").replace(" UNRATED", "").replace(" unrated", "").replace("screener", "").replace("TS-SCREENER", "").replace("TSScreener", "").replace("HQ", "").replace("AC3 5.1", "").replace("Telesync", "").replace("Line Dubbed", "").replace("line Dubbed", "").replace("LineDuB", "").replace("Line", "").replace("XviD", "").replace("xvid", "").replace("XVID", "").replace("Mic Dubbed", "").replace("HD", "").replace("V2", "").replace("CAM", "").replace("VHS.SCR", "").replace("Dvd5", "").replace("DVD5", "").replace("Iso", "").replace("ISO", "").replace("Reparado", "").replace("reparado", "").replace("DVD9", "").replace("Dvd9", "") + + #Terminamos de limpiar el título + title = re.sub(r'\??\s?\d*?\&.*', '', title) + title = re.sub(r'[\(|\[]\s+[\)|\]]', '', title) + title = title.replace('()', '').replace('[]', '').strip().lower().title() + + #Limpiamos el año del título, siempre que no sea todo el título o una cifra de más dígitos + if not scrapertools.find_single_match(title, '\d{5}'): + title_alt = title + title_alt = re.sub(r'[\[|\(]?\d{4}[\)|\]]?', '', title_alt).strip() + if title_alt: + title = title_alt + + item_local.from_title = title.strip().lower().title() #Guardamos esta etiqueta para posible desambiguación de título + + #Salvamos el título según el tipo de contenido + if item_local.contentType == "movie": + item_local.contentTitle = title.strip().lower().title() + else: + item_local.contentSerieName = title.strip().lower().title() + + item_local.title = title.strip().lower().title() + + #Añadimos la duración a la Calidad + if duration: + if item_local.quality: + item_local.quality += ' [%s]' % duration + else: + item_local.quality = '[%s]' % duration + + #Guarda la variable temporal que almacena la info adicional del título a ser restaurada después de TMDB + item_local.title_subs = title_subs + + itemlist.append(item_local.clone()) #Pintar pantalla + + #logger.debug(item_local) + + #Pasamos a TMDB la lista completa Itemlist + tmdb.set_infoLabels(itemlist, __modo_grafico__) + + #Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB + item, itemlist = generictools.post_tmdb_listado(item, itemlist) + + # Si es necesario añadir paginacion + if curr_page <= last_page: + if last_page > 1: + title = '%s de %s' % (curr_page-1, last_page) + else: + title = '%s' % curr_page-1 + + itemlist.append(Item(channel=item.channel, action="listado", title=">> Página siguiente " + title, title_lista=title_lista, url=next_page_url, extra=item.extra, extra2=item.extra2, last_page=str(last_page), curr_page=str(curr_page))) + + return itemlist + + +def findvideos(item): + logger.info() + itemlist = [] + matches = [] + item.category = categoria + + item.extra2 = 'xyz' + del item.extra2 + + #logger.debug(item) + + #Bajamos los datos de la página + data = '' + patron = '<a[^>]+href="([^"]+)"[^<]+</a></td><td><span><img[^>]+>(.*?)</span></td><td><span><img[^>]+>(.*?)</span></td><td><span>(.*?)</span>' + try: + data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)", "", httptools.downloadpage(item.url, timeout=timeout).data) + data = unicode(data, "utf-8", errors="replace").encode("utf-8") + data = re.sub(r""", '"', data) + data = re.sub(r"<", '<', data) + except: + pass + + if not data: + logger.error("ERROR 01: FINDVIDEOS: La Web no responde o la URL es erronea: " + item.url) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: FINDVIDEOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log')) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + + matches = re.compile(patron, re.DOTALL).findall(data) + if not matches and not scrapertools.find_single_match(data, 'data-TPlayerNv="Opt\d+">.*? <span>(.*?)</span></li>'): #error + logger.error("ERROR 02: FINDVIDEOS: No hay enlaces o ha cambiado la estructura de la Web " + " / PATRON: " + patron + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: FINDVIDEOS: No hay enlaces o ha cambiado la estructura de la Web. Verificar en la Web esto último y reportar el error con el log')) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + + #logger.debug("PATRON: " + patron) + #logger.debug(matches) + #logger.debug(data) + + #Llamamos al método para crear el título general del vídeo, con toda la información obtenida de TMDB + item, itemlist = generictools.post_tmdb_findvideos(item, itemlist) + + #Ahora tratamos los enlaces .torrent + for scrapedurl, scrapedserver, language, quality in matches: #leemos los torrents con la diferentes calidades + #Generamos una copia de Item para trabajar sobre ella + item_local = item.clone() + + if 'torrent' not in scrapedserver.lower(): #Si es un servidor Directo, lo dejamos para luego + continue + + item_local.url = scrapedurl + if '.io/' in item_local.url: + item_local.url = re.sub(r'http.?:\/\/\w+\.\w+\/', host, item_local.url) #Aseguramos el dominio del canal + + #Detectamos idiomas + if ("latino" in scrapedurl.lower() or "latino" in language.lower()) and "LAT" not in item_local.language: + item_local.language += ['LAT'] + elif ('subtitulado' in scrapedurl.lower() or 'subtitulado' in language.lower() or 'vose' in language.lower()) and "VOSE" not in item_local.language: + item_local.language += ['VOSE'] + elif ('version-original' in scrapedurl.lower() or 'version original' in language.lower() or 'vo' in language.lower()) and "VO" not in item_local.language: + item_local.language += ['VO'] + + if item_local.language == []: + item_local.language = ['CAST'] + + #Añadimos la calidad y copiamos la duración + item_local.quality = quality + if scrapertools.find_single_match(item.quality, '(\[\d+:\d+\ h])'): + item_local.quality += ' [/COLOR][COLOR white]%s' % scrapertools.find_single_match(item.quality, '(\[\d+:\d+\ h])') + + #Buscamos si ya tiene tamaño, si no, los buscamos en el archivo .torrent + size = scrapertools.find_single_match(item_local.quality, '\s\[(\d+,?\d*?\s\w\s?[b|B])\]') + if not size: + size = generictools.get_torrent_size(item_local.url) #Buscamos el tamaño en el .torrent + if size: + item_local.title = re.sub(r'\s\[\d+,?\d*?\s\w[b|B]\]', '', item_local.title) #Quitamos size de título, si lo traía + item_local.title = '%s [%s]' % (item_local.title, size) #Agregamos size al final del título + size = size.replace('GB', 'G B').replace('Gb', 'G b').replace('MB', 'M B').replace('Mb', 'M b') + item_local.quality = re.sub(r'\s\[\d+,?\d*?\s\w\s?[b|B]\]', '', item_local.quality) #Quitamos size de calidad, si lo traía + item_local.quality = '%s [%s]' % (item_local.quality, size) #Agregamos size al final de la calidad + + #Ahora pintamos el link del Torrent + item_local.title = '[COLOR yellow][?][/COLOR] [COLOR yellow][Torrent][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (item_local.quality, str(item_local.language)) + + #Preparamos título y calidad, quitamos etiquetas vacías + item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.title) + item_local.title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.title) + item_local.title = item_local.title.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() + item_local.quality = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.quality) + item_local.quality = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.quality).strip() + item_local.quality = item_local.quality.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() + + item_local.alive = "??" #Calidad del link sin verificar + item_local.action = "play" #Visualizar vídeo + item_local.server = "torrent" #Servidor Torrent + + itemlist.append(item_local.clone()) #Pintar pantalla + + #logger.debug("TORRENT: " + scrapedurl + " / title gen/torr: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName) + #logger.debug(item_local) + + #Ahora tratamos los Servidores Directos + titles = re.compile('data-TPlayerNv="Opt\d+">.*? <span>(.*?)</span></li>', re.DOTALL).findall(data) + urls = re.compile('id="Opt\d+"><iframe[^>]+src="([^"]+)"', re.DOTALL).findall(data) + + #Recorremos la lista de servidores Directos, excluyendo YouTube para trailers + if len(titles) == len(urls): + for i in range(0, len(titles)): + #Generamos una copia de Item para trabajar sobre ella + item_local = item.clone() + + if i > 0: + #logger.debug('titles: %s' % titles[i].strip()) + language, quality = titles[i].split(' - ') + title = "%s" % titles[i].strip() + else: + title = titles[0] + + if "goo.gl" in urls[i]: + urls[i] = httptools.downloadpage(urls[i], follow_redirects=False, only_headers=True)\ + .headers.get("location", "") + + videourl = servertools.findvideos(urls[i]) #Buscamos la url del vídeo + + #Ya tenemos un enlace, lo pintamos + if len(videourl) > 0: + server = videourl[0][0] + enlace = videourl[0][1] + mostrar_server = True + if config.get_setting("hidepremium"): #Si no se aceptan servidore premium, se ignoran + mostrar_server = servertools.is_server_enabled(server) + if mostrar_server: + item_local.alive = "??" #Se asume poe defecto que es link es dudoso + if server.lower() == 'youtube': #Pasamos de YouTube, usamos Trailers de Alfa + continue + if server.lower() != 'netutv': #Este servidor no se puede comprobar + #Llama a la subfunción de check_list_links(itemlist) para cada link de servidor + item_local.alive = servertools.check_video_link(enlace, server, timeout=timeout) + if '?' in item_local.alive: + alive = '?' #No se ha podido comprobar el vídeo + elif 'no' in item_local.alive.lower(): + continue #El enlace es malo + else: + alive = '' #El enlace está verificado + + #Detectamos idiomas + item_local.language = [] + if "latino" in language.lower() and "LAT" not in item_local.language: + item_local.language += ['LAT'] + elif ('subtitulado' in language.lower() or 'vose' in language.lower()) and "VOSE" not in item_local.language: + item_local.language += ['VOSE'] + elif ('version original' in language.lower() or 'vo' in language.lower()) and "VO" not in item_local.language: + item_local.language += ['VO'] + + if item_local.language == []: + item_local.language = ['CAST'] + + #Ahora pintamos el link del Servidor Directo + item_local.url = enlace + item_local.quality = quality #Añadimos la calidad + if scrapertools.find_single_match(item.quality, '(\[\d+:\d+\ h])'): #Añadimos la duración + item_local.quality += ' [/COLOR][COLOR white]%s' % scrapertools.find_single_match(item.quality, '(\[\d+:\d+\ h])') + item_local.title = '[COLOR yellow][%s][/COLOR] [COLOR yellow][%s][/COLOR] [COLOR limegreen][%s][/COLOR] [COLOR red]%s[/COLOR]' % (alive, server.capitalize(), item_local.quality, str(item_local.language)) + + #Preparamos título y calidad, quitamos etiquetas vacías + item_local.title = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.title) + item_local.title = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.title) + item_local.title = item_local.title.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() + item_local.quality = re.sub(r'\s?\[COLOR \w+\]\[\[?\s?\]?\]\[\/COLOR\]', '', item_local.quality) + item_local.quality = re.sub(r'\s?\[COLOR \w+\]\s?\[\/COLOR\]', '', item_local.quality) + item_local.quality = item_local.quality.replace("--", "").replace("[]", "").replace("()", "").replace("(/)", "").replace("[/]", "").strip() + + item_local.action = "play" #Visualizar vídeo + item_local.server = server #Servidor Directo + + itemlist.append(item_local.clone()) #Pintar pantalla + + #logger.debug("DIRECTO: " server + ' / ' + enlace + " / title: " + item.title + " / " + item_local.title + " / calidad: " + item_local.quality + " / content: " + item_local.contentTitle + " / " + item_local.contentSerieName) + #logger.debug(item_local) + + return itemlist + + +def episodios(item): + logger.info() + itemlist = [] + item.category = categoria + + #logger.debug(item) + + if item.from_title: + item.title = item.from_title + item.extra2 = 'xyz' + del item.extra2 + + item.quality = re.sub(r'\s?\[\d+:\d+\ h]', '', item.quality) #quitamos la duración de la serie + + #Limpiamos num. Temporada y Episodio que ha podido quedar por Novedades + season_display = 0 + if item.contentSeason: + if item.season_colapse: #Si viene del menú de Temporadas... + season_display = item.contentSeason #... salvamos el num de sesión a pintar + item.from_num_season_colapse = season_display + del item.season_colapse + item.contentType = "tvshow" + if item.from_title_season_colapse: + item.title = item.from_title_season_colapse + del item.from_title_season_colapse + if item.infoLabels['title']: + del item.infoLabels['title'] + del item.infoLabels['season'] + if item.contentEpisodeNumber: + del item.infoLabels['episode'] + if season_display == 0 and item.from_num_season_colapse: + season_display = item.from_num_season_colapse + + # Obtener la información actualizada de la Serie. TMDB es imprescindible para Videoteca + if not item.infoLabels['tmdb_id']: + tmdb.set_infoLabels(item, True) + + modo_ultima_temp_alt = modo_ultima_temp + if item.ow_force == "1": #Si hay un traspaso de canal o url, se actualiza todo + modo_ultima_temp_alt = False + + max_temp = 1 + if item.infoLabels['number_of_seasons']: + max_temp = item.infoLabels['number_of_seasons'] + y = [] + if modo_ultima_temp_alt and item.library_playcounts: #Averiguar cuantas temporadas hay en Videoteca + patron = 'season (\d+)' + matches = re.compile(patron, re.DOTALL).findall(str(item.library_playcounts)) + for x in matches: + y += [int(x)] + max_temp = max(y) + + # Descarga la página + data = '' #Inserto en num de página en la url + try: + data = re.sub(r"\n|\r|\t|\s{2}|(<!--.*?-->)| ", "", httptools.downloadpage(item.url, timeout=timeout).data) + data = unicode(data, "utf-8", errors="replace").encode("utf-8") + data = re.sub(r""", '"', data) + data = re.sub(r"<", '<', data) + data = re.sub(r">", '>', data) + except: #Algún error de proceso, salimos + pass + + if not data: + logger.error("ERROR 01: EPISODIOS: La Web no responde o la URL es erronea" + item.url) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 01: EPISODIOS:. La Web no responde o la URL es erronea. Si la Web está activa, reportar el error con el log')) + return itemlist + + #Buscamos los episodios + patron = '<tr><td><span class="Num">\d+<\/span><\/td><td class="MvTbImg B"><a href="([^"]+)" class="MvTbImg">(?:<span class="[^>]+>)?<img src="([^"]+)" alt="([^"]+)">(?:<\/span>)?<\/a><\/td><td class="MvTbTtl">[^>]+>(.*?)<\/a>' + matches = re.compile(patron, re.DOTALL).findall(data) + if not matches: #error + item = generictools.web_intervenida(item, data) #Verificamos que no haya sido clausurada + if item.intervencion: #Sí ha sido clausurada judicialmente + item, itemlist = generictools.post_tmdb_episodios(item, itemlist) #Llamamos al método para el pintado del error + return itemlist #Salimos + + logger.error("ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web " + " / PATRON: " + patron + " / DATA: " + data) + itemlist.append(item.clone(action='', title=item.channel.capitalize() + ': ERROR 02: EPISODIOS: Ha cambiado la estructura de la Web. Reportar el error con el log')) + return itemlist #si no hay más datos, algo no funciona, pintamos lo que tenemos + + #logger.debug("PATRON: " + patron) + #logger.debug(matches) + #logger.debug(data) + + season = max_temp + #Comprobamos si realmente sabemos el num. máximo de temporadas + if item.library_playcounts or (item.infoLabels['number_of_seasons'] and item.tmdb_stat): + num_temporadas_flag = True + else: + num_temporadas_flag = False + + # Recorremos todos los episodios generando un Item local por cada uno en Itemlist + for scrapedurl, scrapedthumbnail, scrapedtitle, scrapedepi_name in matches: + item_local = item.clone() + item_local.action = "findvideos" + item_local.contentType = "episode" + item_local.extra = "episodios" + if item_local.library_playcounts: + del item_local.library_playcounts + if item_local.library_urls: + del item_local.library_urls + if item_local.path: + del item_local.path + if item_local.update_last: + del item_local.update_last + if item_local.update_next: + del item_local.update_next + if item_local.channel_host: + del item_local.channel_host + if item_local.active: + del item_local.active + if item_local.contentTitle: + del item_local.infoLabels['title'] + if item_local.season_colapse: + del item_local.season_colapse + + item_local.title = '' + item_local.context = "['buscar_trailer']" + item_local.url = scrapedurl + title = scrapedtitle + item_local.language = [] + + #Buscamos calidades del episodio + if 'hdtv' in scrapedtitle.lower() or 'hdtv' in scrapedurl: + item_local.quality = 'HDTV' + elif 'hd7' in scrapedtitle.lower() or 'hd7' in scrapedurl: + item_local.quality = 'HD720p' + elif 'hd1' in scrapedtitle.lower() or 'hd1' in scrapedurl: + item_local.quality = 'HD1080p' + + #Buscamos idiomas del episodio + lang = scrapedtitle.strip() + if ('vo' in lang.lower() or 'v.o' in lang.lower() or 'vo' in scrapedurl.lower() or 'v.o' in scrapedurl.lower()) and not 'VO' in item_local.language: + item_local.language += ['VO'] + elif ('vose' in lang.lower() or 'v.o.s.e' in lang.lower() or 'vose' in scrapedurl.lower() or 'v.o.s.e' in scrapedurl.lower()) and not 'VOSE' in item_local.language: + item_local.language += ['VOSE'] + elif ('latino' in lang.lower() or 'latino' in scrapedurl.lower()) and not 'LAT' in item_local.language: + item_local.language += ['LAT'] + + if not item_local.language: + item_local.language += ['CAST'] + + #Buscamos la Temporada y el Episodio + try: + item_local.contentEpisodeNumber = 0 + if 'miniserie' in title.lower(): + item_local.contentSeason = 1 + title = title.replace('miniserie', '').replace('MiniSerie', '') + elif 'completa' in title.lower(): + patron = '[t|T].*?(\d+) [c|C]ompleta' + if scrapertools.find_single_match(title, patron): + item_local.contentSeason = int(scrapertools.find_single_match(title, patron)) + if not item_local.contentSeason: + #Extraemos los episodios + patron = '(\d{1,2})[x|X](\d{1,2})' + item_local.contentSeason, item_local.contentEpisodeNumber = scrapertools.find_single_match(title, patron) + item_local.contentSeason = int(item_local.contentSeason) + item_local.contentEpisodeNumber = int(item_local.contentEpisodeNumber) + except: + logger.error('ERROR al extraer Temporada/Episodio: ' + title) + item_local.contentSeason = 1 + item_local.contentEpisodeNumber = 0 + + #Si son episodios múltiples, lo extraemos + patron1 = '\d+[x|X]\d{1,2}.?(?:y|Y|al|Al)?(?:\d+[x|X]\d{1,2})?.?(?:y|Y|al|Al)?.?\d+[x|X](\d{1,2})' + epi_rango = scrapertools.find_single_match(title, patron1) + if epi_rango: + item_local.infoLabels['episodio_titulo'] = 'al %s %s' % (epi_rango, scrapedepi_name) + item_local.title = '%sx%s al %s -' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2), str(epi_rango).zfill(2)) + else: + item_local.title = '%sx%s -' % (str(item_local.contentSeason), str(item_local.contentEpisodeNumber).zfill(2)) + item.infoLabels['episodio_titulo'] = '%s' %scrapedepi_name + + if modo_ultima_temp_alt and item.library_playcounts: #Si solo se actualiza la última temporada de Videoteca + if item_local.contentSeason < max_temp: + continue #salta al siguiente episodio + + #Mostramos solo la temporada requerida + if season_display > 0: + if item_local.contentSeason > season_display: + break + elif item_local.contentSeason < season_display: + continue + + itemlist.append(item_local.clone()) + + #logger.debug(item_local) + + if len(itemlist) > 1: + itemlist = sorted(itemlist, key=lambda it: (int(it.contentSeason), int(it.contentEpisodeNumber))) #clasificamos + + if item.season_colapse and not item.add_videolibrary: #Si viene de listado, mostramos solo Temporadas + item, itemlist = generictools.post_tmdb_seasons(item, itemlist) + + if not item.season_colapse: #Si no es pantalla de Temporadas, pintamos todo + # Pasada por TMDB y clasificación de lista por temporada y episodio + tmdb.set_infoLabels(itemlist, True) + + #Llamamos al método para el maquillaje de los títulos obtenidos desde TMDB + item, itemlist = generictools.post_tmdb_episodios(item, itemlist) + + #logger.debug(item) + + return itemlist + + +def actualizar_titulos(item): + logger.info() + + item = generictools.update_title(item) #Llamamos al método que actualiza el título con tmdb.find_and_set_infoLabels + + #Volvemos a la siguiente acción en el canal + return item + + +def search(item, texto): + logger.info() + #texto = texto.replace(" ", "+") + + item.url = item.url + texto + + if texto != '': + return listado(item) + + try: + item.url = item.url + texto + + if texto != '': + return listado(item) + except: + import sys + for line in sys.exc_info(): + logger.error("{0}".format(line)) + return [] + + +def newest(categoria): + logger.info() + itemlist = [] + item = Item() + + try: + if categoria == 'peliculas': + item.url = host + "estrenos-de-cine-2" + item.extra = "peliculas" + item.channel = channel + item.category_new= 'newest' + + itemlist = listado(item) + if ">> Página siguiente" in itemlist[-1].title: + itemlist.pop() + + # Se captura la excepción, para no interrumpir al canal novedades si un canal falla + except: + import sys + for line in sys.exc_info(): + logger.error("{0}".format(line)) + return [] + + return itemlist diff --git a/plugin.video.alfa/resources/media/channels/thumb/zonatorrent.png b/plugin.video.alfa/resources/media/channels/thumb/zonatorrent.png new file mode 100644 index 0000000000000000000000000000000000000000..13fe418f188545625aefa84895b7aadc0df31b88 GIT binary patch literal 36220 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 yqhhd&(9KY#lLR86Btz$U;(;9bw5V8?PZ#4-X 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 aVEGU0==~|RnzggwFu>N@(W=Ul5dS}Offf(| literal 0 HcmV?d00001 From abd62471c02f06611320da87293a5fefd31b284f Mon Sep 17 00:00:00 2001 From: chivmalev <lbivan187@gmail.com> Date: Wed, 12 Sep 2018 10:52:54 -0300 Subject: [PATCH 17/29] nuevo canal --- plugin.video.alfa/channels/maxipelis24.json | 12 ++ plugin.video.alfa/channels/maxipelis24.py | 125 ++++++++++++++++++ .../media/channels/thumb/maxipelis24.png | Bin 0 -> 26399 bytes 3 files changed, 137 insertions(+) create mode 100644 plugin.video.alfa/channels/maxipelis24.json create mode 100644 plugin.video.alfa/channels/maxipelis24.py create mode 100644 plugin.video.alfa/resources/media/channels/thumb/maxipelis24.png diff --git a/plugin.video.alfa/channels/maxipelis24.json b/plugin.video.alfa/channels/maxipelis24.json new file mode 100644 index 00000000..5c93a817 --- /dev/null +++ b/plugin.video.alfa/channels/maxipelis24.json @@ -0,0 +1,12 @@ +{ +"id": "maxipelis24", + "name": "Maxipelis24", + "active": true, + "adult": false, + "language": ["lat"], + "thumbnail": "maxipelis24.png", + "banner": "", + "categories": [ + "movie" + ] +} diff --git a/plugin.video.alfa/channels/maxipelis24.py b/plugin.video.alfa/channels/maxipelis24.py new file mode 100644 index 00000000..456cd828 --- /dev/null +++ b/plugin.video.alfa/channels/maxipelis24.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- + +import re +import urlparse +import urllib + +from core import servertools +from core import httptools +from core import scrapertools +from core.item import Item +from platformcode import config, logger +from channelselector import get_thumb + +host="http://maxipelis24.com" + + +def mainlist(item): + logger.info() + + itemlist = [] + + itemlist.append(Item(channel=item.channel, title="peliculas", action="movies", url=host, thumbnail=get_thumb('movies', auto=True))) + itemlist.append(Item(channel=item.channel, action="category", title="Año de Estreno", url=host, cat='year', thumbnail=get_thumb('year', auto=True))) + itemlist.append(Item(channel=item.channel, action="category", title="Géneros", url=host, cat='genre', thumbnail=get_thumb('genres', auto=True))) + itemlist.append(Item(channel=item.channel, action="category", title="Calidad", url=host, cat='quality', thumbnail=get_thumb("quality", auto=True))) + itemlist.append(Item(channel=item.channel, title="Buscar", action="search", url=host+"?s=", thumbnail=get_thumb("search", auto=True))) + + return itemlist + +def search(item, texto): + logger.info() + texto = texto.replace(" ", "+") + item.url = host + "?s=" + texto + if texto != '': + return movies(item) + +def category(item): + logger.info() + itemlist = [] + data = httptools.downloadpage(item.url).data + data = re.sub(r"\n|\r|\t|\s{2}| ","", data) + + if item.cat == 'genre': + data = scrapertools.find_single_match(data, '<h3>Géneros.*?</div>') + patron = '<a href="([^"]+)">([^<]+)<' + elif item.cat == 'year': + data = scrapertools.find_single_match(data, '<h3>Año de estreno.*?</div>') + patron = 'li><a href="([^"]+)">([^<]+).*?<' + elif item.cat == 'quality': + data = scrapertools.find_single_match(data, '<h3>Calidad.*?</div>') + patron = 'li><a href="([^"]+)">([^<]+)<' + + matches = re.compile(patron, re.DOTALL).findall(data) + for scrapedurl , scrapedtitle in matches: + itemlist.append(Item(channel=item.channel, action='movies', title=scrapedtitle, url=scrapedurl, type='cat', first=0)) + return itemlist + +def movies(item): + logger.info() + itemlist = [] + + data = httptools.downloadpage(item.url).data + data = re.sub(r"\n|\r|\t|\s{2}| ","", data) + + patron = '<div id="mt.+?href="([^"]+)".+?' + patron += '<img src="([^"]+)" alt="([^"]+)".+?' + patron += '<span class="imdb">.*?>([^<]+)<.*?' + patron += '<span class="ttx">([^<]+).*?' + patron += 'class="year">([^<]+).+?class="calidad2">([^<]+)<' + + matches = re.compile(patron, re.DOTALL).findall(data) + for scrapedurl, img, scrapedtitle, ranking, resto, year, quality in matches: + plot = scrapertools.htmlclean(resto).strip() + title = '%s [COLOR yellow](%s)[/COLOR] [COLOR red][%s][/COLOR]'% (scrapedtitle, ranking, quality) + itemlist.append(Item(channel=item.channel, + title=title, + url=scrapedurl, + action="findvideos", + plot=plot, + thumbnail=img, + contentTitle = scrapedtitle, + contentType = "movie", + quality=quality)) + + #Paginacion + next_page = '<div class="pag_.*?href="([^"]+)">Siguiente<' + matches = re.compile(next_page, re.DOTALL).findall(data) + if matches: + url = urlparse.urljoin(item.url, matches[0]) + itemlist.append(Item(channel=item.channel, action = "movies", title = "Página siguiente >>",url = url)) + + return itemlist + +def findvideos(item): + logger.info() + itemlist=[] + + data = httptools.downloadpage(item.url).data + + data = scrapertools.get_match(data, '<div id="contenedor">(.*?)</div></div></div>') + + # Busca los enlaces a los videos + listavideos = servertools.findvideos(data) + + for video in listavideos: + videotitle = scrapertools.unescape(video[0]) + url = video[1] + server = video[2] + + itemlist.append(Item(channel=item.channel, action="play", server=server, title=videotitle, url=url, + thumbnail=item.thumbnail, plot=item.plot, fulltitle=item.title, folder=False)) + + # Opción "Añadir esta película a la biblioteca de KODI" + if config.get_videolibrary_support() and len(itemlist) > 0 and item.extra != 'findvideos': + itemlist.append( + Item(channel=item.channel, + title='[COLOR yellow]Añadir esta pelicula a la videoteca[/COLOR]', + url=item.url, + action="add_pelicula_to_library", + extra="findvideos", + contentTitle=item.contentTitle, + thumbnail=item.thumbnail + )) + + return itemlist diff --git a/plugin.video.alfa/resources/media/channels/thumb/maxipelis24.png b/plugin.video.alfa/resources/media/channels/thumb/maxipelis24.png new file mode 100644 index 0000000000000000000000000000000000000000..0fa881d1160fb6628d900507d81821f526c7694e GIT binary patch literal 26399 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 literal 0 HcmV?d00001 From 0593322cf0829c9e52cfa55c46b413951d9e366d Mon Sep 17 00:00:00 2001 From: Unknown <Delta_minion@protonmail.com> Date: Wed, 12 Sep 2018 16:42:36 -0300 Subject: [PATCH 18/29] correccion de enlaces --- plugin.video.alfa/channels/animejl.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin.video.alfa/channels/animejl.py b/plugin.video.alfa/channels/animejl.py index b02569b7..ff65b206 100644 --- a/plugin.video.alfa/channels/animejl.py +++ b/plugin.video.alfa/channels/animejl.py @@ -161,6 +161,7 @@ def findvideos(item): itemlist.extend(servertools.find_video_items(data=data)) for videoitem in itemlist: + videoitem.channel = item.channel videoitem.title = '[%s]' % videoitem.server.capitalize() return itemlist From 814a24c1ceba30bcd667c7f3f454148ef868ba1e Mon Sep 17 00:00:00 2001 From: Unknown <Delta_minion@protonmail.com> Date: Wed, 12 Sep 2018 16:42:58 -0300 Subject: [PATCH 19/29] correccion para torrent --- plugin.video.alfa/channels/cinecalidad.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.video.alfa/channels/cinecalidad.py b/plugin.video.alfa/channels/cinecalidad.py index 476b66fb..912048a7 100644 --- a/plugin.video.alfa/channels/cinecalidad.py +++ b/plugin.video.alfa/channels/cinecalidad.py @@ -324,7 +324,7 @@ def findvideos(item): url = server_url[server_id] + video_id + '.html' elif server_id == 'BitTorrent': import urllib - base_url = '%sprotect/v.php' % host + base_url = '%s/protect/v.php' % host post = {'i':video_id, 'title':item.title} post = urllib.urlencode(post) headers = {'Referer':item.url} From 78693bb5ece9d23e024bddc2a7532e298f59c605 Mon Sep 17 00:00:00 2001 From: Unknown <Delta_minion@protonmail.com> Date: Wed, 12 Sep 2018 16:43:17 -0300 Subject: [PATCH 20/29] correccion para findvideos --- plugin.video.alfa/channels/locopelis.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 plugin.video.alfa/channels/locopelis.py diff --git a/plugin.video.alfa/channels/locopelis.py b/plugin.video.alfa/channels/locopelis.py old mode 100755 new mode 100644 index 7173701f..007c3680 --- a/plugin.video.alfa/channels/locopelis.py +++ b/plugin.video.alfa/channels/locopelis.py @@ -355,7 +355,7 @@ def findvideos(item): new_url = get_link(get_source(item.url)) new_url = get_link(get_source(new_url)) video_id = scrapertools.find_single_match(new_url, 'http.*?h=(\w+)') - new_url = '%s%s' % (host, 'playeropstream/api.php') + new_url = '%s%s' % (host.replace('.com','.tv'), 'playeropstream/api.php') post = {'h': video_id} post = urllib.urlencode(post) data = httptools.downloadpage(new_url, post=post).data From 1a632b7d86b3d24654f36985cea1ceb12610deb5 Mon Sep 17 00:00:00 2001 From: Unknown <Delta_minion@protonmail.com> Date: Wed, 12 Sep 2018 16:43:52 -0300 Subject: [PATCH 21/29] agregado user agent para reproduccion --- plugin.video.alfa/channels/pelisipad.py | 2 ++ 1 file changed, 2 insertions(+) mode change 100755 => 100644 plugin.video.alfa/channels/pelisipad.py diff --git a/plugin.video.alfa/channels/pelisipad.py b/plugin.video.alfa/channels/pelisipad.py old mode 100755 new mode 100644 index 3d317d76..63034e92 --- a/plugin.video.alfa/channels/pelisipad.py +++ b/plugin.video.alfa/channels/pelisipad.py @@ -519,6 +519,7 @@ def findvideos(item): if item.video_urls: import random import base64 + item.video_urls.sort(key=lambda it: (it[1], random.random()), reverse=True) i = 0 actual_quality = "" @@ -534,6 +535,7 @@ def findvideos(item): title += " [COLOR green]Mirror %s[/COLOR] - %s" % (str(i + 1), item.fulltitle) url = vid % "%s" % base64.b64decode("dHQ9MTQ4MDE5MDQ1MSZtbT1NRzZkclhFand6QmVzbmxSMHNZYXhBJmJiPUUwb1dVVVgx" "WTBCQTdhWENpeU9paUE=") + url += '|User-Agent=%s' % httptools.get_user_agent itemlist.append(item.clone(title=title, action="play", url=url, video_urls="")) i += 1 From c78f02b3b26a4aca6f2b03b2bc8f16580f017367 Mon Sep 17 00:00:00 2001 From: Unknown <Delta_minion@protonmail.com> Date: Wed, 12 Sep 2018 16:44:07 -0300 Subject: [PATCH 22/29] correccion para autoplay --- plugin.video.alfa/channels/pelisplusco.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin.video.alfa/channels/pelisplusco.py b/plugin.video.alfa/channels/pelisplusco.py index 7b07366a..f02deda1 100644 --- a/plugin.video.alfa/channels/pelisplusco.py +++ b/plugin.video.alfa/channels/pelisplusco.py @@ -356,7 +356,7 @@ def get_links_by_language(item, data): patron = 'data-source=(.*?)data.*?srt=(.*?)data-iframe.*?Opci.*?<.*?hidden>[^\(]\((.*?)\)' matches = re.compile(patron, re.DOTALL).findall(data) if language in IDIOMAS: - language == IDIOMAS[language] + language = IDIOMAS[language] for url, sub, quality in matches: if 'http' not in url: @@ -403,7 +403,7 @@ def findvideos(item): i.quality) ) # Requerido para FilterTools - itemlist = filtertools.get_links(video_list, item, list_language) + video_list = filtertools.get_links(video_list, item, list_language) # Requerido para AutoPlay From 24f7a47fea177096c34f3a48b04b3d4f0017d709 Mon Sep 17 00:00:00 2001 From: Unknown <Delta_minion@protonmail.com> Date: Wed, 12 Sep 2018 16:46:23 -0300 Subject: [PATCH 23/29] Modificado para utilizar user agent global --- plugin.video.alfa/channels/tvvip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.video.alfa/channels/tvvip.py b/plugin.video.alfa/channels/tvvip.py index 36b7ee4c..5045272a 100644 --- a/plugin.video.alfa/channels/tvvip.py +++ b/plugin.video.alfa/channels/tvvip.py @@ -620,7 +620,7 @@ def play(item): data['a']['tt']) + \ "&mm=" + data['a']['mm'] + "&bb=" + data['a']['bb'] - url += "|User-Agent=Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Mobile Safari/537.36" + url += "|User-Agent=%s" % httptools.get_user_agent itemlist.append(item.clone(action="play", server="directo", url=url, folder=False)) From a6eeaf333d19d5590aed8dd4175add9e65144c31 Mon Sep 17 00:00:00 2001 From: Unknown <Delta_minion@protonmail.com> Date: Wed, 12 Sep 2018 16:47:09 -0300 Subject: [PATCH 24/29] Correccion de enlaces + autoplay --- .../channels/ultrapeliculashd.json | 14 ++ .../channels/ultrapeliculashd.py | 139 ++++++++++++------ 2 files changed, 107 insertions(+), 46 deletions(-) mode change 100755 => 100644 plugin.video.alfa/channels/ultrapeliculashd.json diff --git a/plugin.video.alfa/channels/ultrapeliculashd.json b/plugin.video.alfa/channels/ultrapeliculashd.json old mode 100755 new mode 100644 index 03c48a23..84ea556a --- a/plugin.video.alfa/channels/ultrapeliculashd.json +++ b/plugin.video.alfa/channels/ultrapeliculashd.json @@ -19,6 +19,20 @@ "enabled": true, "visible": true }, + { + "id": "filter_languages", + "type": "list", + "label": "Mostrar enlaces en idioma...", + "default": 0, + "enabled": true, + "visible": true, + "lvalues": [ + "No filtrar", + "LAT", + "CAST", + "VOSE" + ] + }, { "id": "include_in_newest_latino", "type": "bool", diff --git a/plugin.video.alfa/channels/ultrapeliculashd.py b/plugin.video.alfa/channels/ultrapeliculashd.py index 8c98653b..b847f081 100644 --- a/plugin.video.alfa/channels/ultrapeliculashd.py +++ b/plugin.video.alfa/channels/ultrapeliculashd.py @@ -8,6 +8,7 @@ from core import servertools from core import jsontools from core import tmdb from core.item import Item +from channels import filtertools, autoplay from platformcode import config, logger host = 'http://www.ultrapeliculashd.com' @@ -63,39 +64,51 @@ tcalidad = {'1080P': 'https://s21.postimg.cc/4h1s0t1wn/hd1080.png', '720P': 'https://s12.postimg.cc/lthu7v4q5/hd720.png', "HD": "https://s27.postimg.cc/m2dhhkrur/image.png"} +IDIOMAS = {'Latino': 'LAT', 'Español': 'CAST', 'SUB':'VOSE'} +list_language = IDIOMAS.values() +list_quality = ['default', '1080p'] +list_servers = ['openload','directo'] + +__comprueba_enlaces__ = config.get_setting('comprueba_enlaces', 'ultrapeliculashd') +__comprueba_enlaces_num__ = config.get_setting('comprueba_enlaces_num', 'ultrapeliculashd') + def mainlist(item): logger.info() + autoplay.init(item.channel, list_servers, list_quality) + itemlist = [] - itemlist.append(item.clone(title="Todas", - action="lista", - thumbnail='https://s18.postimg.cc/fwvaeo6qh/todas.png', - fanart='https://s18.postimg.cc/fwvaeo6qh/todas.png', - url=host + '/movies/' - )) + itemlist.append(Item(channel=item.channel, title="Todas", + action="lista", + thumbnail='https://s18.postimg.cc/fwvaeo6qh/todas.png', + fanart='https://s18.postimg.cc/fwvaeo6qh/todas.png', + url=host + '/movies/' + )) - itemlist.append(item.clone(title="Generos", - action="generos", - url=host, - thumbnail='https://s3.postimg.cc/5s9jg2wtf/generos.png', - fanart='https://s3.postimg.cc/5s9jg2wtf/generos.png' - )) + itemlist.append(Item(channel=item.channel, title="Generos", + action="generos", + url=host, + thumbnail='https://s3.postimg.cc/5s9jg2wtf/generos.png', + fanart='https://s3.postimg.cc/5s9jg2wtf/generos.png' + )) - itemlist.append(item.clone(title="Alfabetico", - action="seccion", - url=host, - thumbnail='https://s17.postimg.cc/fwi1y99en/a-z.png', - fanart='https://s17.postimg.cc/fwi1y99en/a-z.png', - extra='alfabetico' - )) + itemlist.append(Item(channel=item.channel, title="Alfabetico", + action="seccion", + url=host, + thumbnail='https://s17.postimg.cc/fwi1y99en/a-z.png', + fanart='https://s17.postimg.cc/fwi1y99en/a-z.png', + extra='alfabetico' + )) - itemlist.append(item.clone(title="Buscar", - action="search", - url=host + '/?s=', - thumbnail='https://s30.postimg.cc/pei7txpa9/buscar.png', - fanart='https://s30.postimg.cc/pei7txpa9/buscar.png' - )) + itemlist.append(Item(channel=item.channel, title="Buscar", + action="search", + url=host + '/?s=', + thumbnail='https://s30.postimg.cc/pei7txpa9/buscar.png', + fanart='https://s30.postimg.cc/pei7txpa9/buscar.png' + )) + + autoplay.show_option(item.channel, itemlist) return itemlist @@ -160,13 +173,13 @@ def generos(item): title = scrapedtitle url = scrapedurl if scrapedtitle not in ['PRÓXIMAMENTE', 'EN CINE']: - itemlist.append(item.clone(action="lista", - title=title, - fulltitle=item.title, - url=url, - thumbnail=thumbnail, - fanart=fanart - )) + itemlist.append(Item(channel=item.channel, action="lista", + title=title, + fulltitle=item.title, + url=url, + thumbnail=thumbnail, + fanart=fanart + )) return itemlist @@ -209,15 +222,33 @@ def alpha(item): def findvideos(item): + from lib import jsunpack logger.info() itemlist = [] data = httptools.downloadpage(item.url).data data = re.sub(r'"|\n|\r|\t| |<br>|\s{2,}', "", data) - patron = '<iframe.*?rptss src=(.*?) (?:width.*?|frameborder.*?) allowfullscreen><\/iframe>' + patron = '<div id=(option.*?) class=play.*?<iframe.*?' + patron += 'rptss src=(.*?) (?:width.*?|frameborder.*?) allowfullscreen><\/iframe>' matches = re.compile(patron, re.DOTALL).findall(data) - for video_url in matches: - if 'stream' in video_url and 'streamango' not in video_url: + for option, video_url in matches: + language = scrapertools.find_single_match(data, '#%s>.*?-->(.*?)(?:\s|<)' % option) + if 'sub' in language.lower(): + language = 'SUB' + language = IDIOMAS[language] + if 'ultrapeliculashd' in video_url: + new_data = httptools.downloadpage(video_url).data + new_data = re.sub(r'"|\n|\r|\t| |<br>|\s{2,}', "", new_data) + if 'drive' not in video_url: + quality= '1080p' + packed = scrapertools.find_single_match(new_data, '<script>(eval\(.*?)eval') + unpacked = jsunpack.unpack(packed) + url = scrapertools.find_single_match(unpacked, 'file:(http.?:.*?)\}') + else: + quality= '1080p' + url = scrapertools.find_single_match(new_data, '</div><iframe src=([^\s]+) webkitallowfullscreen') + + elif 'stream' in video_url and 'streamango' not in video_url: data = httptools.downloadpage('https:'+video_url).data if not 'iframe' in video_url: new_url=scrapertools.find_single_match(data, 'iframe src="(.*?)"') @@ -233,26 +264,42 @@ def findvideos(item): url = url.replace('download', 'preview')+headers_string sub = scrapertools.find_single_match(new_data, 'file:.*?"(.*?srt)"') - new_item = (Item(title=item.title, url=url, quality=quality, subtitle=sub, server='directo')) + new_item = (Item(title=item.title, url=url, quality=quality, subtitle=sub, server='directo', + language = language)) itemlist.append(new_item) + else: - itemlist.extend(servertools.find_video_items(data=video_url)) + url = video_url + quality = 'default' - for videoitem in itemlist: - videoitem.channel = item.channel - videoitem.action = 'play' - videoitem.thumbnail = item.thumbnail - videoitem.infoLabels = item.infoLabels - videoitem.title = item.contentTitle + ' (' + videoitem.server + ')' - if 'youtube' in videoitem.url: - videoitem.title = '[COLOR orange]Trailer en Youtube[/COLOR]' + if not config.get_setting("unify"): + title = ' [%s] [%s]' % (quality, language) + else: + title = '' - itemlist = servertools.get_servers_itemlist(itemlist) + new_item = (Item(channel=item.channel, title='%s'+title, url=url, action='play', quality=quality, + language=language, infoLabels=item.infoLabels)) + itemlist.append(new_item) + + + itemlist = servertools.get_servers_itemlist(itemlist, lambda i: i.title % i.server.capitalize()) + + if __comprueba_enlaces__: + itemlist = servertools.check_list_links(itemlist, __comprueba_enlaces_num__) + + # Requerido para FilterTools + + itemlist = filtertools.get_links(itemlist, item, list_language) + + # Requerido para AutoPlay + + autoplay.start(itemlist, item) if config.get_videolibrary_support() and len(itemlist) > 0 and item.extra != 'findvideos': itemlist.append( Item(channel=item.channel, title='[COLOR yellow]Añadir esta pelicula a la videoteca[/COLOR]', url=item.url, action="add_pelicula_to_library", extra="findvideos", contentTitle=item.contentTitle)) + return itemlist From 247e29a573c3d343fe68efa7213f325420ad126f Mon Sep 17 00:00:00 2001 From: Unknown <Delta_minion@protonmail.com> Date: Wed, 12 Sep 2018 16:47:35 -0300 Subject: [PATCH 25/29] Correccion en la deteccion de idiomas --- plugin.video.alfa/channels/wikiseries.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin.video.alfa/channels/wikiseries.py b/plugin.video.alfa/channels/wikiseries.py index 5c97a326..15240f9d 100644 --- a/plugin.video.alfa/channels/wikiseries.py +++ b/plugin.video.alfa/channels/wikiseries.py @@ -221,7 +221,7 @@ def findvideos(item): language = '' if 'latino' in link.lower(): language='Latino' - elif 'español' in link.lower(): + elif 'espaÑol' in link.lower(): language = 'Español' elif 'subtitulado' in link.lower(): language = 'VOSE' From 046241797a0e70d2ac577b087e3df11596b5ab83 Mon Sep 17 00:00:00 2001 From: Unknown <Delta_minion@protonmail.com> Date: Wed, 12 Sep 2018 16:47:59 -0300 Subject: [PATCH 26/29] nuevo metodo para obtener el user agent global --- plugin.video.alfa/core/httptools.py | 3 +++ 1 file changed, 3 insertions(+) mode change 100755 => 100644 plugin.video.alfa/core/httptools.py diff --git a/plugin.video.alfa/core/httptools.py b/plugin.video.alfa/core/httptools.py old mode 100755 new mode 100644 index 5f2f2355..bc20a2a1 --- a/plugin.video.alfa/core/httptools.py +++ b/plugin.video.alfa/core/httptools.py @@ -56,6 +56,9 @@ default_headers["Accept-Encoding"] = "gzip" HTTPTOOLS_DEFAULT_DOWNLOAD_TIMEOUT = config.get_setting('httptools_timeout', default=15) if HTTPTOOLS_DEFAULT_DOWNLOAD_TIMEOUT == 0: HTTPTOOLS_DEFAULT_DOWNLOAD_TIMEOUT = None +def get_user_agent(): + # Devuelve el user agent global para ser utilizado cuando es necesario para la url. + return default_headers["User-Agent"] def get_url_headers(url): domain_cookies = cj._cookies.get("." + urlparse.urlparse(url)[1], {}).get("/", {}) From 2a4fdcd095c8099a0ce2088caecf1fcb71575670 Mon Sep 17 00:00:00 2001 From: Kingbox <37674310+lopezvg@users.noreply.github.com> Date: Wed, 12 Sep 2018 21:51:20 +0200 Subject: [PATCH 27/29] =?UTF-8?q?Kodi=2018:=20correcci=C3=B3n=20de=20compa?= =?UTF-8?q?tibilidad=20con=20clientes=20Torrent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Evita cuelgues y cancelaciones cuando se reproducen vídeos desde una pantalla convencional (no emergente) --- .../platformcode/platformtools.py | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/plugin.video.alfa/platformcode/platformtools.py b/plugin.video.alfa/platformcode/platformtools.py index f0713eaa..0f7503d8 100644 --- a/plugin.video.alfa/platformcode/platformtools.py +++ b/plugin.video.alfa/platformcode/platformtools.py @@ -1044,6 +1044,8 @@ def torrent_client_installed(show_tuple=False): def play_torrent(item, xlistitem, mediaurl): logger.info() + import time + # Opciones disponibles para Reproducir torrents torrent_options = list() torrent_options.append(["Cliente interno (necesario libtorrent)"]) @@ -1066,28 +1068,32 @@ def play_torrent(item, xlistitem, mediaurl): # Plugins externos if seleccion > 1: + + #### Compatibilidad con Kodi 18: evita cuelgues/cancelaciones cuando el .torrent se lanza desde pantalla convencional + if xbmc.getCondVisibility('Window.IsMedia'): + xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, xlistitem) #Preparamos el entorno para evutar error Kod1 18 + time.sleep(1) #Dejamos que se ejecute + mediaurl = urllib.quote_plus(item.url) if ("quasar" in torrent_options[seleccion][1] or "elementum" in torrent_options[seleccion][1]) and item.infoLabels['tmdb_id']: #Llamada con más parámetros para completar el título if item.contentType == 'episode' and "elementum" not in torrent_options[seleccion][1]: mediaurl += "&episode=%s&library=&season=%s&show=%s&tmdb=%s&type=episode" % (item.infoLabels['episode'], item.infoLabels['season'], item.infoLabels['tmdb_id'], item.infoLabels['tmdb_id']) elif item.contentType == 'movie': mediaurl += "&library=&tmdb=%s&type=movie" % (item.infoLabels['tmdb_id']) - xbmc.executebuiltin("PlayMedia(" + torrent_options[seleccion][1] % mediaurl + ")") - if "quasar" in torrent_options[seleccion][1] or "elementum" in torrent_options[seleccion][1]: #Seleccionamos que clientes torrent soportamos - if item.strm_path: #Sólo si es de Videoteca - import time - time_limit = time.time() + 150 #Marcamos el timepo máx. de buffering - while not is_playing() and time.time() < time_limit: #Esperamos mientra buffera - time.sleep(5) #Repetimos cada intervalo - #logger.debug(str(time_limit)) - - if is_playing(): #Ha terminado de bufferar o ha cancelado - from platformcode import xbmc_videolibrary - xbmc_videolibrary.mark_auto_as_watched(item) #Marcamos como visto al terminar - #logger.debug("Llamado el marcado") - #else: - #logger.debug("Video cancelado o timeout") + xbmc.executebuiltin("PlayMedia(" + torrent_options[seleccion][1] % mediaurl + ")") + + #Seleccionamos que clientes torrent soportamos para el marcado de vídeos vistos + if "quasar" in torrent_options[seleccion][1] or "elementum" in torrent_options[seleccion][1]: + time_limit = time.time() + 150 #Marcamos el timepo máx. de buffering + while not is_playing() and time.time() < time_limit: #Esperamos mientra buffera + time.sleep(5) #Repetimos cada intervalo + #logger.debug(str(time_limit)) + + if item.strm_path and is_playing(): #Sólo si es de Videoteca + from platformcode import xbmc_videolibrary + xbmc_videolibrary.mark_auto_as_watched(item) #Marcamos como visto al terminar + #logger.debug("Llamado el marcado") if seleccion == 1: from platformcode import mct From b881e8c9e7f891098394e358d83d4677f175dd85 Mon Sep 17 00:00:00 2001 From: Intel1 <luisriverap@hotmail.com> Date: Wed, 12 Sep 2018 16:06:57 -0500 Subject: [PATCH 28/29] v2.7.4 --- plugin.video.alfa/addon.xml | 16 ++++++++-------- .../language/Spanish (Argentina)/strings.po | 2 +- .../language/Spanish (Mexico)/strings.po | 2 +- .../resources/language/Spanish/strings.po | 3 ++- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/plugin.video.alfa/addon.xml b/plugin.video.alfa/addon.xml index dde43615..8bb08a24 100755 --- a/plugin.video.alfa/addon.xml +++ b/plugin.video.alfa/addon.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<addon id="plugin.video.alfa" name="Alfa" version="2.7.3" provider-name="Alfa Addon"> +<addon id="plugin.video.alfa" name="Alfa" version="2.7.4" provider-name="Alfa Addon"> <requires> <import addon="xbmc.python" version="2.1.0"/> <import addon="script.module.libtorrent" optional="true"/> @@ -19,17 +19,17 @@ </assets> <news>[B]Estos son los cambios para esta versión:[/B] [COLOR green][B]Canales agregados y arreglos[/B][/COLOR] - ¤ allcalidad ¤ cinecalidad - ¤ repelis ¤ cumlouder - ¤ porntrex ¤ crunchyroll - ¤ pedropolis ¤ pepecine + ¤ repelis ¤ thevid + ¤ vivio ¤ danimados + ¤ sipeliculas ¤ cinecalidad + ¤ locopelis ¤ pelisipad ¤ divxtotal ¤ elitetorrent ¤ estrenosgo ¤ grantorrent ¤ mejortorrent1 ¤ newpct1 - ¤ danimados ¤ fanpelis - ¤ repelis + ¤ tvvip ¤ zonatorrent + ¤ maxipelis24 ¤ arreglos internos - ¤ Agradecimientos a @angedam, @chivmalev, @alaquepasa por colaborar en ésta versión + ¤ Agradecimientos a @angedam y @chivmalev por colaborar en ésta versión </news> <description lang="es">Navega con Kodi por páginas web para ver sus videos de manera fácil.</description> diff --git a/plugin.video.alfa/resources/language/Spanish (Argentina)/strings.po b/plugin.video.alfa/resources/language/Spanish (Argentina)/strings.po index 677d30a4..7b7cb310 100644 --- a/plugin.video.alfa/resources/language/Spanish (Argentina)/strings.po +++ b/plugin.video.alfa/resources/language/Spanish (Argentina)/strings.po @@ -4793,7 +4793,7 @@ msgstr "Verificación de los contadores de vídeos vistos/no vistos (desmarcar p msgctxt "#70527" msgid "My links" -msgstr 'Mis enlaces' +msgstr "Mis enlaces" msgctxt "#70528" msgid "Default folder" diff --git a/plugin.video.alfa/resources/language/Spanish (Mexico)/strings.po b/plugin.video.alfa/resources/language/Spanish (Mexico)/strings.po index 677d30a4..7b7cb310 100644 --- a/plugin.video.alfa/resources/language/Spanish (Mexico)/strings.po +++ b/plugin.video.alfa/resources/language/Spanish (Mexico)/strings.po @@ -4793,7 +4793,7 @@ msgstr "Verificación de los contadores de vídeos vistos/no vistos (desmarcar p msgctxt "#70527" msgid "My links" -msgstr 'Mis enlaces' +msgstr "Mis enlaces" msgctxt "#70528" msgid "Default folder" diff --git a/plugin.video.alfa/resources/language/Spanish/strings.po b/plugin.video.alfa/resources/language/Spanish/strings.po index ab09763a..7b7cb310 100644 --- a/plugin.video.alfa/resources/language/Spanish/strings.po +++ b/plugin.video.alfa/resources/language/Spanish/strings.po @@ -4793,7 +4793,7 @@ msgstr "Verificación de los contadores de vídeos vistos/no vistos (desmarcar p msgctxt "#70527" msgid "My links" -msgstr 'Mis enlaces' +msgstr "Mis enlaces" msgctxt "#70528" msgid "Default folder" @@ -4938,3 +4938,4 @@ msgstr "Buscar Similares" + From a5a6f55a1b494c858231b21f90d6989cead3416d Mon Sep 17 00:00:00 2001 From: Intel1 <luisriverap@hotmail.com> Date: Wed, 12 Sep 2018 16:18:20 -0500 Subject: [PATCH 29/29] v2.7.4 --- plugin.video.alfa/addon.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin.video.alfa/addon.xml b/plugin.video.alfa/addon.xml index 8bb08a24..82140bc8 100755 --- a/plugin.video.alfa/addon.xml +++ b/plugin.video.alfa/addon.xml @@ -20,14 +20,14 @@ <news>[B]Estos son los cambios para esta versión:[/B] [COLOR green][B]Canales agregados y arreglos[/B][/COLOR] ¤ repelis ¤ thevid - ¤ vivio ¤ danimados + ¤ vevio ¤ danimados ¤ sipeliculas ¤ cinecalidad ¤ locopelis ¤ pelisipad ¤ divxtotal ¤ elitetorrent ¤ estrenosgo ¤ grantorrent ¤ mejortorrent1 ¤ newpct1 ¤ tvvip ¤ zonatorrent - ¤ maxipelis24 + ¤ maxipelis24 ¤ wikiseries ¤ arreglos internos ¤ Agradecimientos a @angedam y @chivmalev por colaborar en ésta versión