- Aggiunto menu globale opzioni di KoD\n- Aggiunto canale tapmovie e server annessi\n- Notifica quando il tipo di vista viene salvata (con indicazione del tipo di contenuto)\n\n
This commit is contained in:
mac12m99
2021-06-10 17:40:17 +02:00
parent 7c261c26b2
commit 114fed7f31
43 changed files with 1632 additions and 821 deletions

View File

@@ -1,4 +1,4 @@
<addon id="plugin.video.kod" name="Kodi on Demand" version="1.6.3" provider-name="KoD Team">
<addon id="plugin.video.kod" name="Kodi on Demand" version="1.7" provider-name="KoD Team">
<requires>
<!-- <import addon="script.module.libtorrent" optional="true"/> -->
<import addon="metadata.themoviedb.org"/>
@@ -11,14 +11,10 @@
</extension>
<extension point="kodi.context.item">
<menu id="kodi.core.main">
<item library="updatetvshow.py">
<label>70269</label>
<visible>String.IsEqual(ListItem.dbtype,tvshow)</visible>
<item library="contextmenu.py">
<label>90001</label>
<visible>!String.StartsWith(ListItem.FileNameAndPath, plugin://plugin.video.kod/) + [ String.IsEqual(ListItem.dbtype, tvshow) | String.IsEqual(ListItem.dbtype, movie) | String.IsEqual(ListItem.dbtype, season) | String.IsEqual(ListItem.dbtype, episode) ]</visible>
</item>
<!-- <item library="externalsearch.py">-->
<!-- <label>90001</label>-->
<!-- <visible>!String.StartsWith(ListItem.FileNameAndPath, plugin://plugin.video.kod/) + [String.IsEqual(ListItem.dbtype,tvshow) | String.IsEqual(ListItem.dbtype,movie)]</visible>-->
<!-- </item>-->
</menu>
</extension>
<extension point="xbmc.addon.metadata">
@@ -31,8 +27,10 @@
<screenshot>resources/media/screenshot-2.png</screenshot>
<screenshot>resources/media/screenshot-3.png</screenshot>
</assets>
<news>- Corretto blocco nella ricerca globale
- migliorie e fix vari ai canali e al core</news>
<news>- Aggiunto menu globale &quot;opzioni di KoD&quot;
- Aggiunto canale tapmovie e server annessi
- Notifica quando il tipo di vista viene salvata (con indicazione del tipo di contenuto)
</news>
<description lang="it">Naviga velocemente sul web e guarda i contenuti presenti</description>
<disclaimer>[COLOR red]The owners and submitters to this addon do not host or distribute any of the content displayed by these addons nor do they have any affiliation with the content providers.[/COLOR]
[COLOR yellow]Kodi © is a registered trademark of the XBMC Foundation. We are not connected to or in any other way affiliated with Kodi, Team Kodi, or the XBMC Foundation. Furthermore, any software, addons, or products offered by us will receive no support in official Kodi channels, including the Kodi forums and various social networks.[/COLOR]</disclaimer>

View File

@@ -1,7 +1,7 @@
{
"direct": {
"altadefinizione01": "https://www.altadefinizione01.games",
"altadefinizione01_link": "https://altadefinizione01.cheap",
"altadefinizione01_link": "https://altadefinizione01.travel",
"animealtadefinizione": "https://www.animealtadefinizione.it",
"animeforce": "https://www.animeforce.it",
"animeleggendari": "https://animezeus.com",
@@ -12,7 +12,7 @@
"casacinema": "https://www.casacinema.page",
"cb01anime": "https://www.cineblog01.red",
"cineblog01": "https://cb01.uno",
"cinemalibero": "https://cinemalibero.monster",
"cinemalibero": "https://cinemalibero.blog",
"cinetecadibologna": "http://cinestore.cinetecadibologna.it",
"discoveryplus": "https://www.discoveryplus.com",
"dreamsub": "https://dreamsub.stream",
@@ -26,11 +26,11 @@
"ilcorsaronero": "https://ilcorsaronero.link",
"ilgeniodellostreaming": "https://ilgeniodellostreaming.ist",
"ilgeniodellostreaming_cam": "https://ilgeniodellostreaming.shop",
"italiaserie": "https://italiaserie.work",
"italiaserie": "https://italiaserie.cam",
"mediasetplay": "https://www.mediasetplay.mediaset.it",
"mondoserietv": "https://mondoserietv.club",
"paramount": "https://www.paramountnetwork.it",
"piratestreaming": "https://www.piratestreaming.bar",
"piratestreaming": "https://www.piratestreaming.shop",
"polpotv": "https://roma.polpo.tv",
"raiplay": "https://www.raiplay.it",
"serietvonline": "https://serietvonline.art",

View File

@@ -20,6 +20,7 @@ def get_cookie(data):
def get_data(item):
# support.dbg()
url = httptools.downloadpage(item.url, headers=headers, follow_redirects=True, only_headers=True).url
data = support.match(url, headers=headers, follow_redirects=True).data
if 'AWCookieVerify' in data:

View File

@@ -29,6 +29,7 @@ def mainlist(item):
def menu(item):
item.contentType = ''
action = 'peliculas'
patronBlock = r'<div class="filter-header"><b>%s</b>(?P<block>.*?)<div class="filter-box">' % item.args
patronMenu = r'<a class="[^"]+" data-state="[^"]+" (?P<other>[^>]+)>[^>]+></i>[^>]+></i>[^>]+></i>(?P<title>[^>]+)</a>'
@@ -89,7 +90,7 @@ def peliculas(item):
patronBlock = r'<div id="%s"[^>]+>(?P<block>.*?)<div class="vistaDettagliata"' % item.args[1]
patron = r'<li>\s*<a href="(?P<url>[^"]+)" title="(?P<title>[^"]+)" class="thumb">[^>]+>[^>]+>[^>]+>\s*[EePp]+\s*(?P<episode>\d+)[^>]+>\s<img src="(?P<thumb>[^"]+)"'
else:
patron = r'<div class="showStreaming"> +<b>(?P<title>[^<]+)[^>]+>[^>]+>\s*<span>Lingua:\s*(?P<lang>[^>]+)?>[<>br\s]+a href="(?P<url>[^"]+)"[^>]+>.*?--image-url:url\(/*(?P<thumb>[^\)]+).*?Anno di inizio</b>:\s*(?P<year>[0-9]{4})'
patron = r'<div class="showStreaming">\s*<b>(?P<title>[^<]+)[^>]+>[^>]+>\s*<span>Lingua:\s*(?:DUB|JAP)?\s*(?P<lang>(?:SUB )?ITA)[^>]+>[<>br\s]+a href="(?P<url>[^"]+)"[^>]+>.*?--image-url:url\(/*(?P<thumb>[^\)]+).*?Anno di inizio</b>:\s*(?P<year>[0-9]{4})'
patronNext = '<li class="currentPage">[^>]+><li[^<]+<a href="([^"]+)">'
def itemHook(item):
@@ -128,7 +129,6 @@ def findvideos(item):
if 'vvvvid' in matches.data:
itemlist.append(item.clone(action="play", title='VVVVID', url=support.match(matches.data, patron=r'(http://www.vvvvid[^"]+)').match, server='vvvvid'))
else:
# matches.matches.sort()
support.info('VIDEO')
for url in matches.matches:
lang = url.split('/')[-2]
@@ -139,8 +139,6 @@ def findvideos(item):
quality = url.split('/')[-1].split('?')[0]
url += '|User-Agent=' + support.httptools.get_user_agent() + '&Referer=' + url
itemlist.append(item.clone(action="play", title=language, url=url, contentLanguage = language, quality = quality, order = quality.replace('p','').zfill(4), server='directo',))
itemlist.sort(key=lambda x: (x.title, x.order), reverse=False)
itemlist.append(item.clone(action="play", title='', url=url, contentLanguage = language, quality = quality, order = quality.replace('p','').zfill(4), server='directo',))
return support.server(item, itemlist=itemlist)

View File

@@ -2,7 +2,7 @@
"id": "guardaseriecam",
"name": "GuardaSerie Cam",
"language": ["ita", "sub-ita"],
"active": true,
"active": false,
"thumbnail": "https://raw.githubusercontent.com/32Dexter/DexterRepo/master/media/guardaserie_live.png",
"banner": "",
"categories": ["tvshow"],

View File

@@ -1,7 +1,7 @@
{
"id": "ilgeniodellostreaming_cam",
"name": "IlGenioDelloStreaming CAM",
"active": true,
"active": false,
"language": ["ita"],
"thumbnail": "ilgeniodellostreaming.png",
"banner": "ilgeniodellostreaming.png",

11
channels/tapmovie.json Normal file
View File

@@ -0,0 +1,11 @@
{
"id": "tapmovie",
"name": "Tap Movie",
"language": ["ita", "sub-ita"],
"active": true,
"thumbnail": "tapmovie.png",
"banner": "tapmovie.png",
"categories": ["movie", "tvshow", "anime"],
"not_active": ["include_in_newest"],
"settings": []
}

102
channels/tapmovie.py Normal file
View File

@@ -0,0 +1,102 @@
# -*- coding: utf-8 -*-
# ------------------------------------------------------------
# Canale per 'dvdita'
from core import support, httptools
from core.item import Item
import sys
if sys.version_info[0] >= 3: from concurrent import futures
else: from concurrent_py2 import futures
host = support.config.get_channel_url()
api_url = '/api/v2/'
per_page = 24
@support.menu
def mainlist(item):
film = ['/browse/movie']
tvshow = ['/browse/tvshow']
search = ''
# [Voce Menu,['url','action','args',contentType]
top = [('Generi', ['', 'genres', '', 'undefined'])]
return locals()
def episodios(item):
support.info(item)
itemlist = []
with futures.ThreadPoolExecutor() as executor:
thL = []
for season in httptools.downloadpage(host + api_url + 'tvshow', post={'tvshow_id': item.id}).json.get('season', []):
season_id = season['season_number']
thL.append(executor.submit(httptools.downloadpage, host + api_url + 'episodes', post={'tvshow_id': item.id, 'season_id': season_id}))
for th in futures.as_completed(thL):
for episode in th.result().json.get('episodes', []):
itemlist.append(item.clone(action="findvideos", contentSeason=episode['season_id'], contentEpisodeNumber=episode['episode_number'], id=item.id,
title=episode['season_id']+'x'+episode['episode_number'], contentType='episode'))
support.scraper.sort_episode_list(itemlist)
support.videolibrary(itemlist, item)
support.download(itemlist, item)
return itemlist
def genres(item):
itemlist = []
for n, genre in enumerate(httptools.downloadpage(host + api_url + 'categories', post={}).json.get('categories', [])):
itemlist.append(item.clone(action="peliculas", genre=genre.get('name'), title=genre.get('value'), n=n))
return support.thumb(itemlist, genre=True)
def peliculas(item, text=''):
support.info('search', item)
itemlist = []
filter_type = False
if item.genre:
text = item.genre
cmd = 'search/category'
else:
cmd = 'search'
if not text:
filter_type = True
try:
page = int(item.url.split('?p=')[1])
except:
page = 1
results = httptools.downloadpage(host + api_url + cmd, post={'search': text, 'page': page}).json.get('results', [])
for result in results:
contentType = 'movie' if result['type'] == 'FILM' else 'tvshow'
if not filter_type or (filter_type and contentType == item.contentType):
itemlist.append(item.clone(id=result.get('id'), title=result.get('title'), contentTitle=result.get('title'),
contentSerieName='' if contentType == 'movie' else result.get('title'),
contentPlot=result.get('description'), thumbnail=result.get('poster'),
fanart=result.get('backdrop'), year=result.get('year'), action='episodios' if contentType == 'tvshow' else 'findvideos',
url='{}/{}/{}-{}'.format('https://filmigratis.org', contentType, result.get('id'), support.scrapertools.slugify(result.get('title'))),
contentType=contentType))
support.tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
if len(results) >= per_page:
page += 1
support.nextPage(itemlist, item, next_page='https://filmigratis.org/category/' + str(item.n) + '/' + item.genre + '?p=' + str(page))
return itemlist
def search(item, text):
return peliculas(item, text)
def findvideos(item):
itemlist = []
if not item.contentSeason: # film
json = httptools.downloadpage(host + api_url + 'movie', post={'movie_id': item.id}).json
else:
json = httptools.downloadpage(host + api_url + 'episode/links', post={'tvshow_id': item.id, 'season_id': item.contentSeason, 'episode_id': item.contentEpisodeNumber}).json
for i in json.get('links', []) + json.get('special', []):
itemlist.append(Item(url=i.get('link')))
return support.server(item, itemlist=itemlist)

63
contextmenu.py Normal file
View File

@@ -0,0 +1,63 @@
from platformcode import config, logger
import xbmc, sys, xbmcgui, os
librerias = xbmc.translatePath(os.path.join(config.get_runtime_path(), 'lib'))
sys.path.insert(0, librerias)
from core import jsontools, support
addon_id = config.get_addon_core().getAddonInfo('id')
LOCAL_FILE = os.path.join(config.get_runtime_path(), "platformcode/contextmenu/contextmenu.json")
f = open(LOCAL_FILE)
contextmenu_settings = jsontools.load(open(LOCAL_FILE).read())
f.close()
def build_menu():
tmdbid = xbmc.getInfoLabel('ListItem.Property(tmdb_id)')
mediatype = xbmc.getInfoLabel('ListItem.DBTYPE')
title = xbmc.getInfoLabel('ListItem.Title')
year = xbmc.getInfoLabel('ListItem.Year')
imdb = xbmc.getInfoLabel('ListItem.IMDBNumber')
filePath = xbmc.getInfoLabel('ListItem.FileNameAndPath')
containerPath = xbmc.getInfoLabel('Container.FolderPath')
logstr = "Selected ListItem is: 'IMDB: {}' - TMDB: {}' - 'Title: {}' - 'Year: {}'' - 'Type: {}'".format(imdb, tmdbid, title, year, mediatype)
logger.info(logstr)
logger.info(filePath)
logger.info(containerPath)
contextmenuitems = []
contextmenuactions = []
for itemmodule in contextmenu_settings:
logger.debug('check contextmenu', itemmodule)
module = __import__(itemmodule, None, None, [itemmodule])
logger.info('Add contextmenu item ->', itemmodule)
module_item_actions = module.get_menu_items()
contextmenuitems.extend([item for item, fn in module_item_actions])
contextmenuactions.extend([fn for item, fn in module_item_actions])
if len(contextmenuitems) == 0:
logger.info('No contextmodule found, build an empty one')
contextmenuitems.append(empty_item())
contextmenuactions.append(lambda: None)
ret = xbmcgui.Dialog().contextmenu(contextmenuitems)
if ret > -1:
logger.info('Contextmenu module index', ret, ', label=' + contextmenuitems[ret])
contextmenuactions[ret]()
def empty_item():
return config.get_localized_string(90004)
if __name__ == '__main__':
build_menu()

View File

@@ -114,7 +114,7 @@ class CipherSuiteAdapter(host_header_ssl.HostHeaderSSLAdapter):
ret = super(CipherSuiteAdapter, self).send(request, **kwargs)
if 400 <= ret.status_code < 500:
raise Exception
except Exception as e:
except (requests.exceptions.HTTPError, requests.exceptions.ConnectionError, requests.exceptions.SSLError) as e:
logger.info('Request for ' + domain + ' with ip ' + ip + ' failed')
logger.info(e)
# if 'SSLError' in str(e):

View File

@@ -152,6 +152,7 @@ def cleantitle(title):
cleantitle = ''
if title:
if type(title) != str: title.decode('UTF-8')
title = scrapertools.unescape(title)
title = scrapertools.decodeHtmlentities(title)
cleantitle = title.replace('"', "'").replace('×', 'x').replace('', '-').strip()
return cleantitle
@@ -386,7 +387,8 @@ def scrapeBlock(item, args, block, patron, headers, action, pagination, debug, t
contentSerieName= title if 'movie' not in [contentType] and function != 'episodios' else item.contentSerieName,
contentTitle= title if 'movie' in [contentType] and function == 'peliculas' else item.contentTitle,
contentLanguage = lang1,
contentEpisodeNumber=episode if episode else '',
contentSeason= infolabels.get('season', ''),
contentEpisodeNumber=infolabels.get('episode', ''),
news= item.news if item.news else '',
other = scraped['other'] if scraped['other'] else '',
grouped=group
@@ -531,15 +533,25 @@ def scrape(func):
itemlist = newFunc()
itemlist = [i for i in itemlist if i.action not in ['add_pelicula_to_library', 'add_serie_to_library']]
if action != 'play' and function != 'episodios' and 'patronMenu' not in args and item.contentType in ['movie', 'tvshow', 'episode', 'undefined'] and not disabletmdb:
if anime and inspect.stack()[1][3] not in ['find_episodes']:
from platformcode import autorenumber
if function == 'episodios': autorenumber.start(itemlist, item)
else: autorenumber.start(itemlist)
if action != 'play' and 'patronMenu' not in args and not disabletmdb and function != 'episodios' and item.contentType in ['movie', 'tvshow', 'episode', 'undefined']:
tmdb.set_infoLabels_itemlist(itemlist, seekTmdb=True)
if not group and not args.get('groupExplode') and ((pagination and len(matches) <= pag * pagination) or not pagination): # next page with pagination
if patronNext and inspect.stack()[1][3] not in ['newest'] and len(inspect.stack()) > 2 and inspect.stack()[2][3] not in ['get_channel_results']:
nextPage(itemlist, item, data, patronNext, function)
# if function == 'episodios':
# scraper.sort_episode_list(itemlist)
for it in itemlist:
if it.contentEpisodeNumber and it.contentSeason:
it.title = '[B]{:d}x{:02d} - {}[/B]'.format(it.contentSeason, it.contentEpisodeNumber, it.infoLabels['title'] if it.infoLabels['title'] else it.fulltitle)
if it.contentLanguage:
it.title += typo(it.contentLanguage, '_ [] color kod')
if it.quality:
it.title += typo(it.quality, '_ [] color kod')
# next page for pagination
if pagination and len(matches) > pag * pagination and not search:
@@ -557,13 +569,7 @@ def scrape(func):
thumbnail=thumb(),
prevthumb=item.prevthumb if item.prevthumb else item.thumbnail))
if anime and inspect.stack()[1][3] not in ['find_episodes']:
from platformcode import autorenumber
if function == 'episodios': autorenumber.start(itemlist, item)
else: autorenumber.start(itemlist)
# if anime and autorenumber.check(item) == False and len(itemlist)>0 and not scrapertools.find_single_match(itemlist[0].title, r'(\d+.\d+)'):
# pass
# else:
if inspect.stack()[1][3] not in ['find_episodes']:
if addVideolibrary and (item.infoLabels["title"] or item.fulltitle):
# item.fulltitle = item.infoLabels["title"]
@@ -1139,7 +1145,10 @@ def nextPage(itemlist, item, data='', patron='', function_or_level=1, next_page=
if next_page != "":
if resub: next_page = re.sub(resub[0], resub[1], next_page)
if 'http' not in next_page:
next_page = scrapertools.find_single_match(item.url, 'https?://[a-z0-9.-]+') + (next_page if next_page.startswith('/') else '/' + next_page)
if '/' in next_page:
next_page = scrapertools.find_single_match(item.url, 'https?://[a-z0-9.-]+') + (next_page if next_page.startswith('/') else '/' + next_page)
else:
next_page = '/'.join(item.url.split('/')[:-1]) + '/' + next_page
next_page = next_page.replace('&amp;', '&')
logger.debug('NEXT= ', next_page)
itemlist.append(
@@ -1362,15 +1371,27 @@ def addQualityTag(item, itemlist, data, patron):
info('nessun tag qualità trovato')
def get_jwplayer_mediaurl(data, srvName, onlyHttp=False, dataIsBlock=False):
from core import jsontools
video_urls = []
block = scrapertools.find_single_match(data, r'sources:\s*\[([^\]]+)\]') if not dataIsBlock else data
block = scrapertools.find_single_match(data, r'sources:\s*([^\]]+\])') if not dataIsBlock else data
if block:
if 'file:' in block:
sources = scrapertools.find_multiple_matches(block, r'file:\s*"([^"]+)"(?:,label:\s*"([^"]+)")?')
elif 'src:' in block:
sources = scrapertools.find_multiple_matches(block, r'src:\s*"([^"]+)",\s*type:\s*"[^"]+"(?:,[^,]+,\s*label:\s*"([^"]+)")?')
json = jsontools.load(block)
if json:
sources = []
for s in json:
if 'file' in s.keys():
src = s['file']
else:
src = s['src']
sources.append((src, s.get('label')))
else:
sources =[(block.replace('"',''), '')]
if 'file:' in block:
sources = scrapertools.find_multiple_matches(block, r'file:\s*"([^"]+)"(?:,label:\s*"([^"]+)")?')
elif 'src:' in block:
sources = scrapertools.find_multiple_matches(block, r'src:\s*"([^"]+)",\s*type:\s*"[^"]+"(?:,[^,]+,\s*label:\s*"([^"]+)")?')
else:
sources =[(block.replace('"',''), '')]
for url, quality in sources:
quality = 'auto' if not quality else quality
if url.split('.')[-1] != 'mpd':

File diff suppressed because it is too large Load Diff

View File

@@ -585,10 +585,17 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
# process local episodes
local_episodes_path = ''
local_episodelist = []
update = False
nfo_path = filetools.join(path, "tvshow.nfo")
head_nfo, item_nfo = read_nfo(nfo_path)
local_episodelist = item_nfo.local_episodes_list if item_nfo.local_episodes_list else []
if config.get_setting('videolibrary_kodi'):
from platformcode.xbmc_videolibrary import check_db
for p in check_db(item_nfo.infoLabels['code']):
local_episodelist += get_local_content(p)
item_nfo.local_episodes_list = local_episodelist
filetools.write(nfo_path, head_nfo + item_nfo.tojson())
if item_nfo.update_last:
local_episodes_path = item_nfo.local_episodes_path
@@ -601,47 +608,7 @@ def save_episodes(path, episodelist, serie, silent=False, overwrite=True):
filetools.write(nfo_path, head_nfo + item_nfo.tojson())
if local_episodes_path:
from platformcode.xbmc_videolibrary import check_db, clean
# check if the local episodes are in the Kodi video library
if check_db(local_episodes_path):
local_episodelist += get_local_content(local_episodes_path)
clean_list = []
for f in filetools.listdir(path):
match = scrapertools.find_single_match(f, r'[Ss]?(\d+)(?:x|_|\s+)?[Ee]?[Pp]?(\d+)')
if match:
ep = '%dx%02d' % (int(match[0]), int(match[1]))
if ep in local_episodelist:
del_file = filetools.join(path, f)
filetools.remove(del_file)
if f.endswith('strm'):
sep = '\\' if '\\' in path else '/'
clean_path = path[:-len(sep)] if path.endswith(sep) else path
clean_path = '%/' + clean_path.split(sep)[-1] + '/' + f
clean_list.append(clean_path)
clean_list.append(clean_path.replace('/','\\'))
if clean_list:
clean(clean_list)
update = True
if item_nfo.local_episodes_list:
difference = [x for x in item_nfo.local_episodes_list if (x not in local_episodelist)]
if len(difference) > 0:
clean_list = []
for f in difference:
sep = '\\' if '\\' in local_episodes_path else '/'
clean_path = local_episodes_path[:-len(sep)] if local_episodes_path.endswith(sep) else local_episodes_path
clean_path = '%/' + clean_path.split(sep)[-1] + '/%' + f.replace('x','%') + '%'
clean_list.append(clean_path)
clean_list.append(clean_path.replace('/','\\'))
clean(clean_list)
update = True
item_nfo.local_episodes_list = sorted(local_episodelist)
filetools.write(nfo_path, head_nfo + item_nfo.tojson())
# the local episodes are not in the Kodi video library
else:
process_local_episodes(local_episodes_path, path)
process_local_episodes(local_episodes_path, path, local_episodelist)
insertados = 0
sobreescritos = 0
@@ -930,24 +897,22 @@ def config_local_episodes_path(path, item, silent=False):
return 0, local_episodes_path
def process_local_episodes(local_episodes_path, path):
def process_local_episodes(local_episodes_path, path, local_episodes_list):
logger.debug()
sub_extensions = ['.srt', '.sub', '.sbv', '.ass', '.idx', '.ssa', '.smi']
artwork_extensions = ['.jpg', '.jpeg', '.png']
extensions = sub_extensions + artwork_extensions
local_episodes_list = []
files_list = []
for root, folders, files in filetools.walk(local_episodes_path):
for file in files:
if os.path.splitext(file)[1] in extensions:
continue
season_episode = scrapertools.get_season_and_episode(file)
if season_episode == "":
continue
local_episodes_list.append(season_episode)
files_list.append(file)
if season_episode and season_episode not in local_episodes_list:
local_episodes_list.append(season_episode)
files_list.append(file)
nfo_path = filetools.join(path, "tvshow.nfo")
head_nfo, item_nfo = read_nfo(nfo_path)

View File

@@ -1,80 +0,0 @@
import xbmc, sys, xbmcgui, os
from platformcode import config, logger
# incliuding folder libraries
librerias = xbmc.translatePath(os.path.join(config.get_runtime_path(), 'lib'))
sys.path.insert(0, librerias)
from core import tmdb
from core.item import Item
def execute_search():
"""
Gather the selected ListItem's attributes in order to compute the `Item` parameters
and perform the KOD's globalsearch.
Globalsearch will be executed specifing the content-type of the selected ListItem
NOTE: this method needs the DBTYPE and TMDB_ID specified as ListItem's properties
"""
# These following lines are commented and keep in the code just as reminder.
# In future, they could be used to filter the search outcome
# ADDON: maybe can we know if the current windows is related to a specific addon?
# we could skip the ContextMenu if we already are in KOD's window
tmdbid = xbmc.getInfoLabel('ListItem.Property(tmdb_id)')
mediatype = xbmc.getInfoLabel('ListItem.DBTYPE')
title = xbmc.getInfoLabel('ListItem.Title')
year = xbmc.getInfoLabel('ListItem.Year')
imdb = xbmc.getInfoLabel('ListItem.IMDBNumber')
# folderPath = xbmc.getInfoLabel('Container.FolderPath')
# filePath = xbmc.getInfoLabel('ListItem.FileNameAndPath')
# logger.info("****")
# logger.info( xbmc.getCondVisibility("String.Contains(Container.FolderPath, 'plugin.video.kod')") )
# logger.info( xbmc.getCondVisibility("String.Contains(ListItem.FileNameAndPath, 'plugin.video.kod')") )
# logger.info( xbmc.getCondVisibility("String.IsEqual(ListItem.dbtype,tvshow)") )
# logger.info( xbmc.getCondVisibility("String.IsEqual(ListItem.dbtype,movie)") )
# logger.info("****")
# visible = xbmc.getCondVisibility("!String.StartsWith(ListItem.FileNameAndPath, 'plugin://plugin.video.kod/') + [String.IsEqual(ListItem.dbtype,tvshow) | String.IsEqual(ListItem.dbtype,movie)]")
logstr = "Selected ListItem is: 'IMDB: {}' - TMDB: {}' - 'Title: {}' - 'Year: {}'' - 'Type: {}'".format(imdb, tmdbid, title, year, mediatype)
logger.info(logstr)
if not tmdbid and imdb:
logger.info('No TMDBid found. Try to get by IMDB')
it = Item(contentType= mediatype, infoLabels={'imdb_id' : imdb})
tmdb.set_infoLabels(it)
tmdbid = it.infoLabels.get('tmdb_id', '')
if not tmdbid:
logger.info('No TMDBid found. Try to get by Title/Year')
it = Item(contentTitle= title, contentType= mediatype, infoLabels={'year' : year})
tmdb.set_infoLabels(it)
tmdbid = it.infoLabels.get('tmdb_id', '')
item = Item(
action="Search",
channel="globalsearch",
contentType= mediatype,
mode="search",
text= title,
type= mediatype,
infoLabels= {
'tmdb_id': tmdbid,
'year': year
},
folder= False
)
logger.info("Invoking Item: {}".format(item.tostring()))
itemurl = item.tourl()
xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + itemurl + ")")
if __name__ == '__main__':
execute_search()

View File

@@ -178,6 +178,8 @@ class autorenumber():
if number:
if not number in self.episodes: self.makelist()
item.title = '{} - {}'.format(typo(self.episodes[number], 'bold'), item.title)
item.contentSeason = int(self.episodes[number].split('x')[0])
item.contentEpisodeNumber = int(self.episodes[number].split('x')[1])
else:
self.makelist()

View File

@@ -0,0 +1,5 @@
[
"platformcode.contextmenu.search",
"platformcode.contextmenu.tvshow_options",
"platformcode.contextmenu.trailer"
]

View File

@@ -0,0 +1,127 @@
import xbmc, sys, os
from platformcode import config, logger
import re
# incliuding folder libraries
librerias = xbmc.translatePath(os.path.join(config.get_runtime_path(), 'lib'))
sys.path.insert(0, librerias)
from core import tmdb
from core.item import Item
addon_id = config.get_addon_core().getAddonInfo('id')
global item_is_coming_from_kod
def check_condition():
global item_is_coming_from_kod
logger.debug('check item condition')
mediatype = xbmc.getInfoLabel('ListItem.DBTYPE')
folderPath = xbmc.getInfoLabel('Container.FolderPath')
filePath = xbmc.getInfoLabel('ListItem.Path')
fileNameAndPath = xbmc.getInfoLabel('ListItem.FileNameAndPath')
logger.debug('Container:',folderPath )
logger.debug('listitem mediatype:',mediatype )
logger.debug('filenamepath:', fileNameAndPath )
logger.info('filepath:', filePath )
item_is_coming_from_kod = addon_id in filePath
if not item_is_coming_from_kod:
videolibpath = config.get_setting("videolibrarypath")
if filePath.startswith(videolibpath):
pattern = re.compile("\[.*\][\\\/]?$")
item_is_coming_from_kod = pattern.search(filePath)
if item_is_coming_from_kod:
logger.debug("item IS already managed by KOD")
return mediatype
def get_menu_items():
logger.debug('get menu item')
if check_condition():
return [(config.get_localized_string(90003 if item_is_coming_from_kod else 90005), execute)]
else:
return []
def execute():
"""
Gather the selected ListItem's attributes in order to compute the `Item` parameters
and perform the KOD's globalsearch.
Globalsearch will be executed specifing the content-type of the selected ListItem
NOTE: this method needs the DBTYPE and TMDB_ID specified as ListItem's properties
"""
# These following lines are commented and keep in the code just as reminder.
# In future, they could be used to filter the search outcome
# ADDON: maybe can we know if the current windows is related to a specific addon?
# we could skip the ContextMenu if we already are in KOD's window
tmdbid = xbmc.getInfoLabel('ListItem.Property(tmdb_id)')
mediatype = xbmc.getInfoLabel('ListItem.DBTYPE')
title = xbmc.getInfoLabel('ListItem.Title')
year = xbmc.getInfoLabel('ListItem.Year')
imdb = xbmc.getInfoLabel('ListItem.IMDBNumber')
if mediatype in ('episode', 'season'):
mediatype = 'tvshow'
title = xbmc.getInfoLabel('ListItem.TVShowTitle')
logstr = "Selected ListItem is: 'IMDB: {}' - TMDB: {}' - 'Title: {}' - 'Year: {}'' - 'Type: {}'".format(imdb, tmdbid, title, year, mediatype)
logger.info(logstr)
if not tmdbid and imdb:
logger.info('No TMDBid found. Try to get by IMDB')
it = Item(contentType= mediatype, infoLabels={'imdb_id' : imdb})
try:
tmdb.set_infoLabels(it)
tmdbid = it.infoLabels.get('tmdb_id', '')
except:
logger.info("Cannot find TMDB via imdb")
if not tmdbid:
logger.info('No TMDBid found. Try to get by Title/Year')
it = Item(contentTitle= title, contentType= mediatype, infoLabels={'year' : year})
try:
tmdb.set_infoLabels(it)
tmdbid = it.infoLabels.get('tmdb_id', '')
except:
logger.info("Cannot find TMDB via title/year")
if not tmdbid:
# We can continue searching by 'title (year)'
logger.info( "No TMDB found, proceed with title/year:", title , "(" , year, ")" )
# User wants to search on other channels
logger.info("Search on other channels")
item = Item(
action="from_context",
channel="search",
contentType= mediatype,
mode="search",
contextual= True,
text=title,
type= mediatype,
infoLabels= {
'tmdb_id': tmdbid,
'year': year,
'mediatype': mediatype
},
folder= False
)
logger.info("Invoking Item: ", item.tostring() )
itemurl = item.tourl()
xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + itemurl + ")")

View File

@@ -0,0 +1,23 @@
import xbmc
from core.item import Item
from platformcode import config
def get_menu_items():
return [(config.get_localized_string(60359), execute)]
def execute():
tmdbid = xbmc.getInfoLabel('ListItem.Property(tmdb_id)')
year = xbmc.getInfoLabel('ListItem.Year')
mediatype = xbmc.getInfoLabel('ListItem.DBTYPE')
title = xbmc.getInfoLabel('ListItem.Title')
if mediatype in ('episode', 'season'):
mediatype = 'tvshow'
title = xbmc.getInfoLabel('ListItem.TVShowTitle')
item = Item(channel="trailertools", action="buscartrailer", search_title=title, contentType=mediatype,
year=year, contentTitle=title, contextual=True)
item.infoLabels['tmdb_id'] = tmdbid
xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + item.tourl() + ")")

View File

@@ -0,0 +1,214 @@
# -*- coding: utf-8 -*-
import xbmc, sys, xbmcgui, os, xbmcvfs, traceback
from platformcode import config, logger
librerias = xbmc.translatePath(os.path.join(config.get_runtime_path(), 'lib'))
sys.path.insert(0, librerias)
from core.item import Item
from lib.sambatools import libsmb as samba
from core import scrapertools, support
path = ''
mediatype = ''
def exists(path, silent=False, vfs=True):
path = xbmc.translatePath(path)
try:
if vfs:
result = bool(xbmcvfs.exists(path))
if not result and not path.endswith('/') and not path.endswith('\\'):
result = bool(xbmcvfs.exists(join(path, ' ').rstrip()))
return result
elif path.lower().startswith("smb://"):
return samba.exists(path)
else:
return os.path.exists(path)
except:
logger.error("ERROR when checking the path: %s" % path)
if not silent:
logger.error(traceback.format_exc())
return False
def join(*paths):
list_path = []
if paths[0].startswith("/"):
list_path.append("")
for path in paths:
if path:
list_path += path.replace("\\", "/").strip("/").split("/")
if scrapertools.find_single_match(paths[0], r'(^\w+:\/\/)'):
return str("/".join(list_path))
else:
return str(os.sep.join(list_path))
def search_paths(Id):
records = execute_sql('SELECT idPath FROM tvshowlinkpath WHERE idShow LIKE "%s"' % Id)
if len(records) >= 1:
for record in records:
path_records = execute_sql('SELECT strPath FROM path WHERE idPath LIKE "%s"' % record[0])
for path in path_records:
if config.get_setting('videolibrarypath') in path[0] and exists(join(path[0], 'tvshow.nfo')):
return path[0]
return ''
def execute_sql(sql):
logger.debug()
file_db = ""
records = None
# We look for the archive of the video database according to the version of kodi
video_db = config.get_platform(True)['video_db']
if video_db:
file_db = os.path.join(xbmc.translatePath("special://userdata/Database"), video_db)
# alternative method to locate the database
if not file_db or not os.path.exists(file_db):
file_db = ""
for f in os.path.listdir(xbmc.translatePath("special://userdata/Database")):
path_f = os.path.join(xbmc.translatePath("special://userdata/Database"), f)
if os.path.pathoos.pathols.isfile(path_f) and f.lower().startswith('myvideos') and f.lower().endswith('.db'):
file_db = path_f
break
if file_db:
logger.debug("DB file: %s" % file_db)
conn = None
try:
import sqlite3
conn = sqlite3.connect(file_db)
cursor = conn.cursor()
logger.debug("Running sql: %s" % sql)
cursor.execute(sql)
conn.commit()
records = cursor.fetchall()
if sql.lower().startswith("select"):
if len(records) == 1 and records[0][0] is None:
records = []
conn.close()
logger.debug("Query executed. Records: %s" % len(records))
except:
logger.error("Error executing sql query")
if conn:
conn.close()
else:
logger.debug("Database not found")
return records
def get_id():
global mediatype
mediatype = xbmc.getInfoLabel('ListItem.DBTYPE')
if mediatype == 'tvshow':
dbid = xbmc.getInfoLabel('ListItem.DBID')
elif mediatype in ('season', 'episode'):
dbid = xbmc.getInfoLabel('ListItem.TvShowDBID')
else:
dbid = ''
return dbid
def check_condition():
# support.dbg()
global path
path = search_paths(get_id())
return path
def get_menu_items():
logger.debug('get menu item')
if check_condition():
items = [(config.get_localized_string(70269), update)]
from core import videolibrarytools
nfo = path + 'tvshow.nfo'
item = videolibrarytools.read_nfo(nfo)[1]
if item:
item.nfo = nfo
item_url = item.tourl()
# Context menu: Automatically search for new episodes or not
if item.active and int(item.active) > 0:
update_text = config.get_localized_string(60022)
value = 0
else:
update_text = config.get_localized_string(60023)
value = 1
items.append((update_text,
lambda: xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?{}&title={}&action=mark_tvshow_as_updatable&channel=videolibrary&active={})".format(item_url, update_text, str(value)))))
if item.local_episodes_path == "":
items.append((config.get_localized_string(80048), lambda: xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?{}&action=add_local_episodes&channel=videolibrary&path={})".format(item_url, path))))
else:
items.append((config.get_localized_string(80049), lambda: xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?{}&action=remove_local_episodes&channel=videolibrary&path={})".format(item_url, path))))
# Context menu: Delete series / channel
channels_num = len(item.library_urls)
if channels_num > 1:
delete_text = config.get_localized_string(60024)
multichannel = True
else:
delete_text = config.get_localized_string(60025)
multichannel = False
items.append((delete_text, lambda: xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?{}&action=delete&channel=videolibrary&multichannel={}&path={})".format(item_url, str(multichannel), path))))
# if config.get_setting('downloadenabled'):
# from core import videolibrarytools
# from core import filetools
# if xbmc.getInfoLabel('ListItem.FilenameAndPath'):
# item = Item().fromurl(filetools.read(xbmc.getInfoLabel('ListItem.FilenameAndPath')))
# else:
# item = videolibrarytools.read_nfo(path + 'tvshow.nfo')[1]
# if item:
# item_url = item.tourl()
#
# Download movie
# if mediatype == "movie":
# items.append((config.get_localized_string(60354), lambda: xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?%s&%s)" % (item_url,
# 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action))))
#
# elif item.contentSerieName:
# Download series
# if mediatype == "tvshow" and item.action not in ['findvideos']:
# if item.channel == 'videolibrary':
# items.append((config.get_localized_string(60003), lambda: xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?%s&%s)" % (
# item_url,
# 'channel=downloads&action=save_download&unseen=true&from_channel=' + item.channel + '&from_action=' + item.action))))
# items.append((config.get_localized_string(60355), lambda: xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?%s&%s)" % (
# item_url,
# 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action))))
# items.append((config.get_localized_string(60357), lambda: xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?%s&%s)" % (
# item_url,
# 'channel=downloads&action=save_download&download=season&from_channel=' + item.channel + '&from_action=' + item.action))))
# Download episode
# elif mediatype == "episode" and item.action in ['findvideos']:
# items.append((config.get_localized_string(60356), lambda: xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?%s&%s)" % (
# item_url,
# 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action))))
# Download season
# elif mediatype == "season":
# items.append((config.get_localized_string(60357), lambda: xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?%s&%s)" % (
# item_url,
# 'channel=downloads&action=save_download&download=season&from_channel=' + item.channel + '&from_action=' + item.action))))
return items
else:
return []
def update():
dbid = get_id()
path = search_paths(dbid)
if path:
item = Item(action="update_tvshow", channel="videolibrary", path=path)
# Why? I think it is not necessary, just commented
# item.tourl()
xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + item.tourl() + ")")

View File

@@ -107,7 +107,7 @@ class MainWindow(xbmcgui.WindowXMLDialog):
Trailer(info)
elif control_id in [IMAGES]:
info = self.getControl(RECOMANDED).getSelectedItem()
images = tmdb.Tmdb(id_Tmdb=info.getProperty('tmdb_id'), tipo='movie' if mode == 'movie' else 'tv').result.get("images", {})
images = tmdb.Tmdb(id_Tmdb=info.getProperty('tmdb_id'), search_type='movie' if mode == 'movie' else 'tv').result.get("images", {})
for key, value in list(images.items()):
if not value: images.pop(key)
ImagesWindow(tmdb = images).doModal()
@@ -287,7 +287,7 @@ def Trailer(info):
trailers_list = []
Type = info.getProperty('mediatype')
if Type != "movie": Type = "tv"
trailers_list = tmdb.Tmdb(id_Tmdb=info.getProperty('tmdb_id'), tipo=Type).get_videos()
trailers_list = tmdb.Tmdb(id_Tmdb=info.getProperty('tmdb_id'), search_type=Type).get_videos()
if trailers_list:
for i, trailer in enumerate(trailers_list):
item = xbmcgui.ListItem(trailer['name'])
@@ -444,7 +444,7 @@ def get_recomendations(info):
Type = info.getProperty('mediatype')
if Type != "movie": Type = "tv"
search = {'url': '%s/%s/recommendations' % (Type, info.getProperty('tmdb_id')), 'language': 'it', 'page': 1}
tmdb_res = tmdb.Tmdb(discover=search, tipo=Type, idioma_Search='it').results
tmdb_res = tmdb.Tmdb(discover=search, search_type=Type, idioma_Search='it').results
for result in tmdb_res:
if Type == 'movie':
title = result.get("title", '')
@@ -473,7 +473,7 @@ def get_cast(info):
cast_list = []
actors_list = []
Type = "movie" if info.getProperty('mediatype') == 'movie' else 'tv'
otmdb = tmdb.Tmdb(id_Tmdb=info.getProperty('tmdb_id'), tipo=Type)
otmdb = tmdb.Tmdb(id_Tmdb=info.getProperty('tmdb_id'), search_type=Type)
actors = otmdb.result.get("credits", {}).get("cast", [])
cast = otmdb.result.get("credits", {}).get("crew", []) if Type == 'movie' else otmdb.result.get("created_by", [])
for i, crew in enumerate(cast):

View File

@@ -33,8 +33,8 @@ def start():
def run(item=None):
# from core.support import dbg;dbg()
logger.debug()
if not item:
# Extract item from sys.argv
if sys.argv[2]:

View File

@@ -67,9 +67,18 @@ def dialog_multiselect(heading, _list, autoclose=0, preselect=[], useDetails=Fal
def dialog_progress(heading, message):
dialog = xbmcgui.DialogProgress()
dialog.create(heading, message)
return dialog
if get_window() in ('WINDOW_HOME', 'WINDOW_SETTINGS_MENU', 'WINDOW_SETTINGS_INTERFACE', 'WINDOW_SKIN_SETTINGS', 'SKIN'):
# in widget, hide any progress
class Dummy(object):
def __getattr__(self, name):
def _missing(*args, **kwargs):
pass
return _missing
return Dummy()
else:
dialog = xbmcgui.DialogProgress()
dialog.create(heading, message)
return dialog
def dialog_progress_bg(heading, message=""):
@@ -177,6 +186,7 @@ def dialog_register(heading, user=False, email=False, password=False, user_defau
dialog = Register('Register.xml', config.get_runtime_path()).Start(heading, user, email, password, user_default, email_default, password_default, captcha_img)
return dialog
def dialog_info(item, scraper):
class TitleOrIDWindow(xbmcgui.WindowXMLDialog):
def Start(self, item, scraper):
@@ -231,6 +241,7 @@ def dialog_info(item, scraper):
dialog = TitleOrIDWindow('TitleOrIDWindow.xml', config.get_runtime_path()).Start(item, scraper)
return dialog
def dialog_select_group(heading, _list, preselect=0):
class SelectGroup(xbmcgui.WindowXMLDialog):
def start(self, heading, _list, preselect):
@@ -311,13 +322,6 @@ def render_items(itemlist, parent_item):
default_fanart = config.get_fanart()
def_context_commands = shortcuts.context()
# for adding extendedinfo to contextual menu, if it's used
has_extendedinfo = xbmc.getCondVisibility('System.HasAddon(script.extendedinfo)')
# for adding superfavourites to contextual menu, if it's used
sf_file_path = xbmc.translatePath("special://home/addons/plugin.program.super.favourites/LaunchSFMenu.py")
check_sf = os.path.exists(sf_file_path)
superfavourites = check_sf and xbmc.getCondVisibility('System.HasAddon("plugin.program.super.favourites")')
# if there's no item, add "no elements" item
if not len(itemlist):
itemlist.append(Item(title=config.get_localized_string(60347), thumbnail=get_thumb('nofolder.png')))
@@ -332,8 +336,11 @@ def render_items(itemlist, parent_item):
if not item.title:
item.title = ''
# If there is no action or it is findvideos / play, folder = False because no listing will be returned
if item.action in ['play', '']:
item.folder = False
if item.folder == "": # not set
if item.action in ['play', '']:
item.folder = False
else:
item.folder = True
if item.fanart == "":
item.fanart = parent_item.fanart
if item.action == 'play' and thumb_type == 1 and not item.forcethumb:
@@ -354,14 +361,13 @@ def render_items(itemlist, parent_item):
listitem.setArt({'icon': icon_image, 'thumb': item.thumbnail, 'poster': item.thumbnail,
'fanart': item.fanart if item.fanart else default_fanart})
if config.get_setting("player_mode") == 1 and item.action == "play" and not item.nfo:
listitem.setProperty('IsPlayable', 'true')
listitem.setProperty('IsPlayable', str(config.get_setting("player_mode") == 1 and item.action == "play" and not item.nfo).lower())
set_infolabels(listitem, item)
# context menu
if parent_item.channel != 'special':
context_commands = def_context_commands + set_context_commands(item, item_url, parent_item, has_extendedinfo=has_extendedinfo, superfavourites=superfavourites)
context_commands = def_context_commands + set_context_commands(item, item_url, parent_item)
else:
context_commands = def_context_commands
listitem.addContextMenuItems(context_commands)
@@ -388,6 +394,26 @@ def render_items(itemlist, parent_item):
logger.debug('END render_items')
def viewmodeMonitor():
try:
currentModeName = xbmc.getInfoLabel('Container.Viewmode')
win = xbmcgui.Window(xbmcgui.getCurrentWindowId())
currentMode = int(win.getFocusId())
if currentModeName and 'plugin.video.kod' in xbmc.getInfoLabel('Container.FolderPath') and currentMode < 1000 and currentMode >= 50: # inside addon and in itemlist view
content, Type = getCurrentView()
if content:
defaultMode = int(config.get_setting('view_mode_%s' % content).split(',')[-1])
if currentMode != defaultMode:
logger.debug('viewmode changed: ' + currentModeName + '-' + str(currentMode) + ' - content: ' + content)
config.set_setting('view_mode_%s' % content, currentModeName + ', ' + str(currentMode))
dialog_notification(config.get_localized_string(70153),
config.get_localized_string(70187) % (content, currentModeName),
sound=False)
except:
import traceback
logger.error(traceback.print_exc())
def getCurrentView(item=None, parent_item=None):
if not parent_item:
info = xbmc.getInfoLabel('Container.FolderPath')
@@ -395,7 +421,7 @@ def getCurrentView(item=None, parent_item=None):
return None, None
parent_item = Item().fromurl(info)
if not item:
info = xbmc.getInfoLabel('Container.ListItem(1).FileNameAndPath')
info = xbmc.getInfoLabel('Container.ListItemPosition(2).FileNameAndPath') # first addon listitem (consider "..")
if not info:
return None, None
item = Item().fromurl(info) if info else Item()
@@ -424,12 +450,12 @@ def getCurrentView(item=None, parent_item=None):
return 'episode', 'tvshows'
else:
return 'addon', 'addons' if config.get_setting('touch_view') else ''
return 'menu', 'addons' if config.get_setting('touch_view') else ''
def set_view_mode(item, parent_item):
def reset_view_mode():
for mode in ['addon','channel','movie','tvshow','season','episode','server']:
for mode in ['menu','channel','movie','tvshow','season','episode','server']:
config.set_setting('skin_name', xbmc.getSkinDir())
config.set_setting('view_mode_%s' % mode, config.get_localized_string(70003) + ' , 0')
@@ -481,13 +507,13 @@ def set_infolabels(listitem, item, player=False):
'top250': 'top250', 'tracknumber': 'tracknumber', 'trailer': 'trailer', 'thumbnail': 'None',
'tvdb_id': 'None', 'tvshowtitle': 'tvshowtitle', 'type': 'None', 'userrating': 'userrating',
'url_scraper': 'None', 'votes': 'votes', 'writer': 'writer', 'year': 'year'}
if item.infoLabels:
try:
infoLabels_kodi = {infoLabels_dict[label_tag]: item.infoLabels[label_tag] for label_tag, label_value in list(item.infoLabels.items()) if infoLabels_dict[label_tag] != 'None'}
listitem.setInfo("video", infoLabels_kodi)
except:
listitem.setInfo("video", item.infoLabels)
# logger.error(item.infoLabels)
# if item.infoLabels:
try:
infoLabels_kodi = {infoLabels_dict[label_tag]: item.infoLabels[label_tag] for label_tag, label_value in list(item.infoLabels.items()) if infoLabels_dict[label_tag] != 'None'}
listitem.setInfo("video", infoLabels_kodi)
except:
listitem.setInfo("video", item.infoLabels)
# logger.error(item.infoLabels)
def set_context_commands(item, item_url, parent_item, **kwargs):
@@ -563,25 +589,6 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
# if item.infoLabels['plot'] and (num_version_xbmc < 17.0 or item.contentType == 'season'):
# context_commands.append((config.get_localized_string(60348), "Action(Info)"))
# ExtendedInfo: If the addon is installed and a series of conditions are met
if kwargs.get('has_extendedinfo') \
and config.get_setting("extended_info") == True:
if item.contentType == "episode" and item.contentEpisodeNumber and item.contentSeason and (item.infoLabels['tmdb_id'] or item.contentSerieName):
param = "tvshow_id =%s, tvshow=%s, season=%s, episode=%s" % (item.infoLabels['tmdb_id'], item.contentSerieName, item.contentSeason, item.contentEpisodeNumber)
context_commands.append(("ExtendedInfo", "RunScript(script.extendedinfo,info=extendedepisodeinfo,%s)" % param))
elif item.contentType == "season" and item.contentSeason and (item.infoLabels['tmdb_id'] or item.contentSerieName):
param = "tvshow_id =%s,tvshow=%s, season=%s" % (item.infoLabels['tmdb_id'], item.contentSerieName, item.contentSeason)
context_commands.append(("ExtendedInfo", "RunScript(script.extendedinfo,info=seasoninfo,%s)" % param))
elif item.contentType == "tvshow" and (item.infoLabels['tmdb_id'] or item.infoLabels['tvdb_id'] or item.infoLabels['imdb_id'] or item.contentSerieName):
param = "id =%s,tvdb_id=%s,imdb_id=%s,name=%s" % (item.infoLabels['tmdb_id'], item.infoLabels['tvdb_id'], item.infoLabels['imdb_id'], item.contentSerieName)
context_commands.append(("ExtendedInfo", "RunScript(script.extendedinfo,info=extendedtvinfo,%s)" % param))
elif item.contentType == "movie" and (item.infoLabels['tmdb_id'] or item.infoLabels['imdb_id'] or item.contentTitle):
param = "id =%s,imdb_id=%s,name=%s" % (item.infoLabels['tmdb_id'], item.infoLabels['imdb_id'], item.contentTitle)
context_commands.append(("ExtendedInfo", "RunScript(script.extendedinfo,info=extendedinfo,%s)" % param))
# InfoPlus
if config.get_setting("infoplus"):
#if item.infoLabels['tmdb_id'] or item.infoLabels['imdb_id'] or item.infoLabels['tvdb_id'] or \
@@ -591,8 +598,6 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
# Open in browser and previous menu
if parent_item.channel not in ["news", "channelselector", "downloads", "search"] and item.action != "mainlist" and not parent_item.noMainMenu:
if parent_item.action != "mainlist":
context_commands.insert(0, (config.get_localized_string(60349), "Container.Refresh (%s?%s)" % (sys.argv[0], Item(channel=item.channel, action="mainlist").tourl())))
context_commands.insert(1, (config.get_localized_string(70739), "Container.Update (%s?%s)" % (sys.argv[0], Item(action="open_browser", url=item.url).tourl())))
# Add to kodfavoritos (My links)
@@ -635,7 +640,7 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
context_commands.append((config.get_localized_string(60354), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&from_channel=' + item.channel + '&from_action=' + item.action)))
elif item.contentSerieName:
# Descargar series
# Download series
if item.contentType == "tvshow" and item.action not in ['findvideos']:
if item.channel == 'videolibrary':
context_commands.append((config.get_localized_string(60003), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, 'channel=downloads&action=save_download&unseen=true&from_channel=' + item.channel + '&from_action=' + item.action)))
@@ -652,9 +657,6 @@ def set_context_commands(item, item_url, parent_item, **kwargs):
if (item.contentTitle and item.contentType in ['movie', 'tvshow']) or "buscar_trailer" in context:
context_commands.append((config.get_localized_string(60359), "RunPlugin(%s?%s&%s)" % (sys.argv[0], item_url, urllib.urlencode({ 'channel': "trailertools", 'action': "buscartrailer", 'search_title': item.contentTitle if item.contentTitle else item.fulltitle, 'contextual': True}))))
if kwargs.get('superfavourites'):
context_commands.append((config.get_localized_string(60361), "RunScript(special://home/addons/plugin.program.super.favourites/LaunchSFMenu.py)"))
if config.dev_mode():
context_commands.insert(0, ("item info", "Container.Update (%s?%s)" % (sys.argv[0], Item(action="itemInfo", parent=item.tojson()).tourl())))
return context_commands
@@ -664,6 +666,265 @@ def is_playing():
return xbmc_player.isPlaying()
def get_window():
"""
Return if addon is used as widget
For doing so, it check current window ID (https://kodi.wiki/view/Window_IDs)
"""
winId = xbmcgui.getCurrentWindowId()
if winId == 9999:
return 'WINDOW_INVALID'
elif winId == 10000:
return 'WINDOW_HOME'
elif winId == 10001:
return 'WINDOW_PROGRAMS'
elif winId == 10002:
return 'WINDOW_PICTURES'
elif winId == 10003:
return 'WINDOW_FILES'
elif winId == 10004:
return 'WINDOW_SETTINGS_MENU'
elif winId == 10007:
return 'WINDOW_SYSTEM_INFORMATION'
elif winId == 10011:
return 'WINDOW_SCREEN_CALIBRATION'
elif winId == 10016:
return 'WINDOW_SETTINGS_START'
elif winId == 10016:
return 'WINDOW_SETTINGS_SYSTEM'
elif winId == 10018:
return 'WINDOW_SETTINGS_SERVICE'
elif winId == 10021:
return 'WINDOW_SETTINGS_MYPVR'
elif winId == 10022:
return 'WINDOW_SETTINGS_MYGAMES'
elif winId == 10025:
return 'WINDOW_VIDEO_NAV'
elif winId == 10028:
return 'WINDOW_VIDEO_PLAYLIST'
elif winId == 10029:
return 'WINDOW_LOGIN_SCREEN'
elif winId == 10030:
return 'WINDOW_SETTINGS_PLAYER'
elif winId == 10031:
return 'WINDOW_SETTINGS_MEDIA'
elif winId == 10032:
return 'WINDOW_SETTINGS_INTERFACE'
elif winId == 10034:
return 'WINDOW_SETTINGS_PROFILES'
elif winId == 10035:
return 'WINDOW_SKIN_SETTINGS'
elif winId == 10040:
return 'WINDOW_ADDON_BROWSER'
elif winId == 10050:
return 'WINDOW_EVENT_LOG'
elif winId == 97:
return 'WINDOW_SCREENSAVER_DIM'
elif winId == 98:
return 'WINDOW_DEBUG_INFO'
elif winId == 10099:
return 'WINDOW_DIALOG_POINTER'
elif winId == 10100:
return 'WINDOW_DIALOG_YES_NO'
elif winId == 10101:
return 'WINDOW_DIALOG_PROGRESS'
elif winId == 10103:
return 'WINDOW_DIALOG_KEYBOARD'
elif winId == 10104:
return 'WINDOW_DIALOG_VOLUME_BAR'
elif winId == 10105:
return 'WINDOW_DIALOG_SUB_MENU'
elif winId == 10106:
return 'WINDOW_DIALOG_CONTEXT_MENU'
elif winId == 10107:
return 'WINDOW_DIALOG_KAI_TOAST'
elif winId == 10109:
return 'WINDOW_DIALOG_NUMERIC'
elif winId == 10110:
return 'WINDOW_DIALOG_GAMEPAD'
elif winId == 10111:
return 'WINDOW_DIALOG_BUTTON_MENU'
elif winId == 10114:
return 'WINDOW_DIALOG_PLAYER_CONTROLS'
elif winId == 10115:
return 'WINDOW_DIALOG_SEEK_BAR'
elif winId == 10116:
return 'WINDOW_DIALOG_PLAYER_PROCESS_INFO'
elif winId == 10120:
return 'WINDOW_DIALOG_MUSIC_OSD'
elif winId == 10121:
return 'WINDOW_DIALOG_VIS_SETTINGS'
elif winId == 10122:
return 'WINDOW_DIALOG_VIS_PRESET_LIST'
elif winId == 10123:
return 'WINDOW_DIALOG_VIDEO_OSD_SETTINGS'
elif winId == 10124:
return 'WINDOW_DIALOG_AUDIO_OSD_SETTINGS'
elif winId == 10125:
return 'WINDOW_DIALOG_VIDEO_BOOKMARKS'
elif winId == 10126:
return 'WINDOW_DIALOG_FILE_BROWSER'
elif winId == 10128:
return 'WINDOW_DIALOG_NETWORK_SETUP'
elif winId == 10129:
return 'WINDOW_DIALOG_MEDIA_SOURCE'
elif winId == 10130:
return 'WINDOW_DIALOG_PROFILE_SETTINGS'
elif winId == 10131:
return 'WINDOW_DIALOG_LOCK_SETTINGS'
elif winId == 10132:
return 'WINDOW_DIALOG_CONTENT_SETTINGS'
elif winId == 10133:
return 'WINDOW_DIALOG_LIBEXPORT_SETTINGS'
elif winId == 10134:
return 'WINDOW_DIALOG_FAVOURITES'
elif winId == 10135:
return 'WINDOW_DIALOG_SONG_INFO'
elif winId == 10136:
return 'WINDOW_DIALOG_SMART_PLAYLIST_EDITOR'
elif winId == 10137:
return 'WINDOW_DIALOG_SMART_PLAYLIST_RULE'
elif winId == 10138:
return 'WINDOW_DIALOG_BUSY'
elif winId == 10139:
return 'WINDOW_DIALOG_PICTURE_INFO'
elif winId == 10140:
return 'WINDOW_DIALOG_ADDON_SETTINGS'
elif winId == 10142:
return 'WINDOW_DIALOG_FULLSCREEN_INFO'
elif winId == 10145:
return 'WINDOW_DIALOG_SLIDER'
elif winId == 10146:
return 'WINDOW_DIALOG_ADDON_INFO'
elif winId == 10147:
return 'WINDOW_DIALOG_TEXT_VIEWER'
elif winId == 10148:
return 'WINDOW_DIALOG_PLAY_EJECT'
elif winId == 10149:
return 'WINDOW_DIALOG_PERIPHERALS'
elif winId == 10150:
return 'WINDOW_DIALOG_PERIPHERAL_SETTINGS'
elif winId == 10151:
return 'WINDOW_DIALOG_EXT_PROGRESS'
elif winId == 10152:
return 'WINDOW_DIALOG_MEDIA_FILTER'
elif winId == 10153:
return 'WINDOW_DIALOG_SUBTITLES'
elif winId == 10156:
return 'WINDOW_DIALOG_KEYBOARD_TOUCH'
elif winId == 10157:
return 'WINDOW_DIALOG_CMS_OSD_SETTINGS'
elif winId == 10158:
return 'WINDOW_DIALOG_INFOPROVIDER_SETTINGS'
elif winId == 10159:
return 'WINDOW_DIALOG_SUBTITLE_OSD_SETTINGS'
elif winId == 10160:
return 'WINDOW_DIALOG_BUSY_NOCANCEL'
elif winId == 10500:
return 'WINDOW_MUSIC_PLAYLIST'
elif winId == 10502:
return 'WINDOW_MUSIC_NAV'
elif winId == 10503:
return 'WINDOW_MUSIC_PLAYLIST_EDITOR'
elif winId == 10550:
return 'WINDOW_DIALOG_OSD_TELETEXT'
# PVR related Window and Dialog ID's
elif 10600 < winId < 10613:
return 'WINDOW_DIALOG_PVR'
elif 10700 < winId < 10711:
return 'WINDOW_PVR_ID'
# virtual windows for PVR specific keymap bindings in fullscreen playback
elif winId == 10800:
return 'WINDOW_FULLSCREEN_LIVETV'
elif winId == 10801:
return 'WINDOW_FULLSCREEN_RADIO'
elif winId == 10802:
return 'WINDOW_FULLSCREEN_LIVETV_PREVIEW'
elif winId == 10803:
return 'WINDOW_FULLSCREEN_RADIO_PREVIEW'
elif winId == 10804:
return 'WINDOW_FULLSCREEN_LIVETV_INPUT'
elif winId == 10805:
return 'WINDOW_FULLSCREEN_RADIO_INPUT'
elif winId == 10820:
return 'WINDOW_DIALOG_GAME_CONTROLLERS'
elif winId == 10821:
return 'WINDOW_GAMES'
elif winId == 10822:
return 'WINDOW_DIALOG_GAME_OSD'
elif winId == 10823:
return 'WINDOW_DIALOG_GAME_VIDEO_FILTER'
elif winId == 10824:
return 'WINDOW_DIALOG_GAME_STRETCH_MODE'
elif winId == 10825:
return 'WINDOW_DIALOG_GAME_VOLUME'
elif winId == 10826:
return 'WINDOW_DIALOG_GAME_ADVANCED_SETTINGS'
elif winId == 10827:
return 'WINDOW_DIALOG_GAME_VIDEO_ROTATION'
elif 11100 < winId < 11199:
return 'SKIN' # WINDOW_ID's from 11100 to 11199 reserved for Skins
elif winId == 12000:
return 'WINDOW_DIALOG_SELECT'
elif winId == 12001:
return 'WINDOW_DIALOG_MUSIC_INFO'
elif winId == 12002:
return 'WINDOW_DIALOG_OK'
elif winId == 12003:
return 'WINDOW_DIALOG_VIDEO_INFO'
elif winId == 12005:
return 'WINDOW_FULLSCREEN_VIDEO'
elif winId == 12006:
return 'WINDOW_VISUALISATION'
elif winId == 12007:
return 'WINDOW_SLIDESHOW'
elif winId == 12600:
return 'WINDOW_WEATHER'
elif winId == 12900:
return 'WINDOW_SCREENSAVER'
elif winId == 12901:
return 'WINDOW_DIALOG_VIDEO_OSD'
elif winId == 12902:
return 'WINDOW_VIDEO_MENU'
elif winId == 12905:
return 'WINDOW_VIDEO_TIME_SEEK' # virtual window for time seeking during fullscreen video
elif winId == 12906:
return 'WINDOW_FULLSCREEN_GAME'
elif winId == 12997:
return 'WINDOW_SPLASH' # splash window
elif winId == 12998:
return 'WINDOW_START' # first window to load
elif winId == 12999:
return 'WINDOW_STARTUP_ANIM' # for startup animations
elif 13000 < winId < 13099:
return 'PYTHON' # WINDOW_ID's from 13000 to 13099 reserved for Python
elif 14000 < winId < 14099:
return 'ADDON' # WINDOW_ID's from 14000 to 14099 reserved for Addons
def play_video(item, strm=False, force_direct=False, autoplay=False):
logger.debug()
logger.debug(item.tostring('\n'))

View File

@@ -11,7 +11,7 @@ def context():
# pre-serialised
if config.get_setting('quick_menu'): context.append((config.get_localized_string(60360), 'RunPlugin(plugin://plugin.video.kod/?ewogICAgImFjdGlvbiI6ICJzaG9ydGN1dF9tZW51IiwgCiAgICAiY2hhbm5lbCI6ICJzaG9ydGN1dHMiLCAKICAgICJpbmZvTGFiZWxzIjoge30KfQ%3D%3D)'))
if config.get_setting('kod_menu'): context.append((config.get_localized_string(60026), 'RunPlugin(plugin://plugin.video.kod/?ewogICAgImFjdGlvbiI6ICJzZXR0aW5nc19tZW51IiwgCiAgICAiY2hhbm5lbCI6ICJzaG9ydGN1dHMiLCAKICAgICJpbmZvTGFiZWxzIjoge30KfQ%3D%3D)'))
# if config.get_setting('kod_menu'): context.append((config.get_localized_string(60026), 'RunPlugin(plugin://plugin.video.kod/?ewogICAgImFjdGlvbiI6ICJzZXR0aW5nc19tZW51IiwgCiAgICAiY2hhbm5lbCI6ICJzaG9ydGN1dHMiLCAKICAgICJpbmZvTGFiZWxzIjoge30KfQ%3D%3D)'))
return context

View File

@@ -1072,18 +1072,15 @@ def clean(path_list=[]):
progress.close()
def check_db(path):
if '\\' in path: sep = '\\'
else: sep = '/'
if path.endswith(sep): path = path[:-len(sep)]
ret = False
sql_path = '%' + sep + path.split(sep)[-1] + sep + '%'
sql = 'SELECT idShow FROM tvshow_view where strPath LIKE "%s"' % sql_path
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
if records:
ret = True
return ret
def check_db(code):
path_list = []
for _id in code:
sql = 'SELECT strPath FROM tvshow_view where uniqueid_value = "%s"' % _id.replace('tmdb_','').replace('tvdb_','')
logger.debug('sql: ' + sql)
nun_records, records = execute_sql_kodi(sql)
if records:
path_list += [xbmc.translatePath(r[0]) for r in records]
return path_list
def execute_sql_kodi(sql):

View File

@@ -3433,7 +3433,7 @@ msgid "Show ExtendedInfo"
msgstr ""
msgctxt "#70153"
msgid ""
msgid "View mode saved"
msgstr ""
msgctxt "#70154"
@@ -3569,7 +3569,7 @@ msgid "Getting episodes..."
msgstr ""
msgctxt "#70187"
msgid ""
msgid "For content %s -> %s"
msgstr ""
msgctxt "#70188"
@@ -6481,5 +6481,21 @@ msgid "Downloading..."
msgstr ""
msgctxt "#90001"
msgid "KOD options"
msgstr "KOD options..."
msgctxt "#90002"
msgid "No TMDB found"
msgstr "No TmdbId found, cannot continue"
msgctxt "#90003"
msgid "Already on KOD, continue searching on other channels?"
msgstr "Item is coming from KOD, continue searching on other channels?"
msgctxt "#90004"
msgid "No contextmenu option"
msgstr "No options"
msgctxt "#90005"
msgid "Search on KOD"
msgstr "Search on KOD..."
msgstr "Search with KOD"

View File

@@ -3432,8 +3432,8 @@ msgid "Show ExtendedInfo"
msgstr "Mostra ExtendedInfo"
msgctxt "#70153"
msgid ""
msgstr ""
msgid "View mode saved"
msgstr "Tipo di vista salvato"
msgctxt "#70154"
msgid "TMDB search"
@@ -3568,8 +3568,8 @@ msgid "Getting episodes..."
msgstr "Ottenimento episodi..."
msgctxt "#70187"
msgid ""
msgstr ""
msgid "For content %s -> %s"
msgstr "Per contenuto %s -> %s"
msgctxt "#70188"
msgid "Obtaining data for the TV show"
@@ -6481,7 +6481,22 @@ msgctxt "#80050"
msgid "Downloading..."
msgstr "Download in corso..."
msgctxt "#90001"
msgid "KOD options"
msgstr "Opzioni di KOD..."
msgctxt "#90002"
msgid "No TMDB found"
msgstr "Non sono riuscito a trovare le informazioni su TMDB"
msgctxt "#90003"
msgid "Already on KOD, continue searching on other channels?"
msgstr "Preferisci cercare su altri canali?"
msgctxt "#90004"
msgid "No contextmenu option"
msgstr "Nessuna opzione possibile"
msgctxt "#90005"
msgid "Search on KOD"
msgstr "Cerca con KOD..."
msgstr "Cerca con KOD"

View File

@@ -138,7 +138,7 @@
<setting id="touch_view" label='30002' type="bool" default="false"/>
<!-- View Mode (hidden)-->
<setting id="skin_name" label='Skin Name' type="text" default="skin.estuary" visible="false"/>
<setting id="view_mode_addon" type="action" label="70009" default= "Default, 0" visible="false"/>
<setting id="view_mode_menu" type="action" label="70009" default= "Default, 0" visible="false"/>
<setting id="view_mode_channel" type="action" label="30118" default= "Default, 0" visible="false"/>
<setting id="view_mode_movie" type="action" label="30122" default= "Default, 0" visible="false"/>
<setting id="view_mode_tvshow" type="action" label="30123" default= "Default, 0" visible="false"/>
@@ -149,7 +149,7 @@
<setting label="30024" type="lsep"/>
<setting id="quick_menu" type="bool" label="60360" default="true"/>
<!-- <setting id="side_menu" type="bool" label="70737" default="false"/> -->
<setting id="kod_menu" type="bool" label="60026" default="true"/>
<!-- <setting id="kod_menu" type="bool" label="60026" default="true"/>-->
<setting id="infoplus" type="bool" label="70151" default="false"/>
<!-- <setting id="infoplus_set" type="bool" label="70128" visible="eq(-1,true)" default="false" subsetting="true"/> -->
<setting id="extended_info" type="bool" label="70152" default="false"/>

View File

@@ -10,11 +10,14 @@ def test_video_exists(page_url):
global data
# page_url = re.sub('://[^/]+/', '://feurl.com/', page_url)
data = httptools.downloadpage(page_url).data
page = httptools.downloadpage(page_url)
data = page.data
if "Sorry 404 not found" in data or "This video is unavailable" in data or "Sorry this video is unavailable:" in data:
return False, config.get_localized_string(70449) % "fembed"
page_url = page_url.replace("/f/","/v/")
page_url = page_url.replace("/v/","/api/source/")
page_url = page.url
page_url = page_url.replace("/f/", "/v/")
page_url = page_url.replace("/v/", "/api/source/")
data = httptools.downloadpage(page_url, post={}).json
logger.debug(data)
if "Video not found or" in data or "We are encoding this video" in data:
@@ -26,9 +29,9 @@ def get_video_url(page_url, user="", password="", video_password=""):
logger.debug("(page_url='%s')" % page_url)
video_urls = []
for file in data['data']:
media_url = file['file']
label = file['label']
extension = file['type']
video_urls.append([ extension + ' ' + label + ' [Fembed]', media_url])
media_url = file['file']
label = file['label']
extension = file['type']
video_urls.append([ extension + ' ' + label + ' [Fembed]', media_url])
video_urls.sort(key=lambda x: int(x[0].split()[1].replace('p','')))
return video_urls

42
servers/hxfile.json Normal file
View File

@@ -0,0 +1,42 @@
{
"active": true,
"find_videos": {
"ignore_urls": [],
"patterns": [
{
"pattern": "https?://hxfile.co/(?!api)(?:embed-)?([A-z0-9]+)",
"url": "https://hxfile.co/embed-\\1.html"
}
]
},
"free": true,
"id": "hxfile",
"name": "HxFile",
"settings": [
{
"default": false,
"enabled": true,
"id": "black_list",
"label": "@70708",
"type": "bool",
"visible": true
},
{
"default": 0,
"enabled": true,
"id": "favorites_servers_list",
"label": "@60655",
"lvalues": [
"No",
"1",
"2",
"3",
"4",
"5"
],
"type": "list",
"visible": false
}
],
"thumbnail": "hxfile.png"
}

25
servers/hxfile.py Normal file
View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
from core import httptools, scrapertools, servertools, support
from platformcode import logger, config
from lib import jsunpack
def test_video_exists(page_url):
logger.debug("(page_url='%s')" % page_url)
global data
data = httptools.downloadpage(page_url).data
if "Can't create video code" in data:
return False, config.get_localized_string(70292) % 'HxFile'
return True, ""
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
logger.debug("url=" + page_url)
global data
video_urls = []
packed = scrapertools.find_single_match(data, r'(eval\s?\(function\(p,a,c,k,e,d\).*?\n)')
data = jsunpack.unpack(packed)
video_urls.extend(support.get_jwplayer_mediaurl(data, 'HxFile'))
return video_urls

View File

@@ -6,6 +6,10 @@
{
"pattern": "mixdrop[s]?.[^/]+/(?:f|e)/([a-z0-9]+)",
"url": "https://mixdrop.co/e/\\1"
},
{
"pattern": "(mixdrop[s]?.[^/]+/player\\.php\\?id=[a-z0-9-]+)",
"url": "https://\\1"
}
]
},

43
servers/playtube.json Normal file
View File

@@ -0,0 +1,43 @@
{
"active": true,
"find_videos": {
"ignore_urls": [],
"patterns": [
{
"pattern": "playtube.ws/(?:embed-|)(\\w+)",
"url": "https://playtube.ws/embed-\\1.html"
}
]
},
"free": true,
"id": "playtube",
"name": "PlayTube",
"settings": [
{
"default": false,
"enabled": true,
"id": "black_list",
"label": "@60654",
"type": "bool",
"visible": true
},
{
"default": 0,
"enabled": true,
"id": "favorites_servers_list",
"label": "@60655",
"lvalues": [
"No",
"1",
"2",
"3",
"4",
"5"
],
"type": "list",
"visible": false
}
],
"thumbnail": "playtube.png"
}

29
servers/playtube.py Normal file
View File

@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# --------------------------------------------------------
# Conector playtube By Alfa development Group
# --------------------------------------------------------
import re
import codecs
from core import httptools
from core import scrapertools
from lib import jsunpack
from platformcode import logger
def test_video_exists(page_url):
logger.info("(page_url='%s')" % page_url)
global data
data = httptools.downloadpage(page_url)
if data.code == 404 or "File is no longer available" in data.data:
return False, config.get_localized_string(70449) % 'PlayTube'
return True, ""
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
logger.info("url=" + page_url)
video_urls = []
pack = scrapertools.find_single_match(data.data, 'p,a,c,k,e,d.*?</script>')
unpacked = jsunpack.unpack(pack)
url = scrapertools.find_single_match(unpacked, 'file:"([^"]+)') + "|referer=%s" %(page_url)
video_urls.append(['m3u8 [PlayTube]', url] )
return video_urls

View File

@@ -4,16 +4,19 @@
from core import httptools, scrapertools
from platformcode import config, logger
def test_video_exists(page_url):
logger.debug("(page_url='%s')" % page_url)
data = httptools.downloadpage(page_url).data
if "File was deleted" in data or "Video is transfer on streaming server now." in data:
if "File was deleted" in data or "Video is transfer on streaming server now." in data \
or 'Conversione video in corso' in data:
return False, config.get_localized_string(70449) % "Speedvideo"
return True, ""
def get_video_url(page_url, premium=False, user="", password="", video_password=""):
logger.debug("url=" + page_url)
video_urls = []

View File

@@ -4,7 +4,7 @@
"ignore_urls": [],
"patterns": [
{
"pattern": "https?://vidmoly.net/(?:embed-)?(\\w+)\\.html",
"pattern": "https?://vidmoly.(?:net|to)/(?:embed-)?(\\w+)\\.html",
"url": "https://vidmoly.net/embed-\\1.html"
},
{

View File

@@ -4,8 +4,8 @@
"ignore_urls": [],
"patterns": [
{
"pattern": "(https://youdbox.com/embed-[A-z0-9-]+.html)",
"url": "\\1"
"pattern": "https://youdbox.(?:com|net)/embed-([A-z0-9-]+.html)",
"url": "https://youdbox.net/embed-\\1"
}
]
},
@@ -37,5 +37,6 @@
"type": "list",
"visible": false
}
]
],
"thumbnail": "youdbox.png"
}

View File

@@ -89,21 +89,18 @@ def update(path, p_dialog, i, t, serie, overwrite):
# serie.infoLabels['playcount'] = serie.playcount
insertados_total += insertados
except Exception as ex:
except:
import traceback
logger.error("Error when saving the chapters of the series")
template = "An exception of type %s occured. Arguments:\n%r"
message = template % (type(ex).__name__, ex.args)
logger.error(message)
logger.error(traceback.format_exc())
except Exception as ex:
except:
import traceback
logger.error("Error in obtaining the episodes of: %s" % serie.show)
template = "An exception of type %s occured. Arguments:\n%r"
message = template % (type(ex).__name__, ex.args)
logger.error(message)
logger.error(traceback.format_exc())
else:
logger.debug("Channel %s not active is not updated" % serie.channel)
# Synchronize the episodes seen from the Kodi video library with that of KoD
try:
if config.is_xbmc(): # If it's Kodi, we do it
@@ -127,7 +124,7 @@ def check_for_update(overwrite=True):
if config.get_setting("update", "videolibrary") != 0 or overwrite:
config.set_setting("updatelibrary_last_check", hoy.strftime('%Y-%m-%d'), "videolibrary")
heading = config.get_localized_string(60389)
heading = config.get_localized_string(60601)
p_dialog = platformtools.dialog_progress_bg(config.get_localized_string(20000), heading)
p_dialog.update(0, '')
show_list = []
@@ -286,22 +283,6 @@ def check_for_update(overwrite=True):
trakt_tools.update_all()
def viewmodeMonitor():
try:
currentModeName = xbmc.getInfoLabel('Container.Viewmode')
win = xbmcgui.Window(xbmcgui.getCurrentWindowId())
currentMode = int(win.getFocusId())
if currentModeName and 'plugin.video.kod' in xbmc.getInfoLabel('Container.FolderPath') and currentMode < 1000 and currentMode >= 50: # inside addon and in itemlist view
content, Type = platformtools.getCurrentView()
if content:
defaultMode = int(config.get_setting('view_mode_%s' % content).split(',')[-1])
if currentMode != defaultMode:
logger.debug('viewmode changed: ' + currentModeName + '-' + str(currentMode) + ' - content: ' + content)
config.set_setting('view_mode_%s' % content, currentModeName + ', ' + str(currentMode))
except:
logger.error(traceback.print_exc())
def updaterCheck():
# updater check
updated, needsReload = updater.check(background=True)
@@ -441,7 +422,7 @@ class AddonMonitor(xbmc.Monitor):
logger.debug('scheduled videolibrary at ' + str(self.update_hour).zfill(2) + ':00')
def scheduleScreenOnJobs(self):
schedule.every().second.do(viewmodeMonitor).tag('screenOn')
schedule.every().second.do(platformtools.viewmodeMonitor).tag('screenOn')
schedule.every().second.do(torrent.elementum_monitor).tag('screenOn')
def onDPMSActivated(self):

View File

@@ -161,7 +161,7 @@ class SearchWindow(xbmcgui.WindowXML):
tmdb_info = tmdb.discovery(self.item, dict_=self.item.discovery)
results = tmdb_info.results.get('cast',[])
else:
tmdb_info = tmdb.Tmdb(texto_buscado=self.item.text, tipo=self.item.mode.replace('show', ''))
tmdb_info = tmdb.Tmdb(searched_text=self.item.text, search_type=self.item.mode.replace('show', ''))
results = tmdb_info.results
for result in results:

View File

@@ -23,13 +23,9 @@ from channelselector import get_thumb
from platformcode import logger, config, platformtools, unify
from core.support import typo, thumb
import xbmcgui
import gc
import xbmc
from threading import Thread
from core.support import dbg
gc.disable()
info_language = ["de", "en", "es", "fr", "it", "pt"] # from videolibrary.json
def_lang = info_language[config.get_setting("info_language", "videolibrary")]
@@ -38,7 +34,8 @@ def_lang = info_language[config.get_setting("info_language", "videolibrary")]
def mainlist(item):
logger.debug()
if config.get_setting('new_search'):
if platformtools.get_window() not in ('WINDOW_SETTINGS_MENU', 'WINDOW_SETTINGS_INTERFACE', 'WINDOW_SKIN_SETTINGS')\
and xbmc.getInfoLabel('System.CurrentWindow') in ('Home', '') and config.get_setting('new_search'):
itemlist = [Item(channel='globalsearch', title=config.get_localized_string(70276), action='Search', mode='all', thumbnail=get_thumb("search.png"), folder=False),
Item(channel='globalsearch', title=config.get_localized_string(70741) % config.get_localized_string(30122), action='Search', mode='movie', thumbnail=get_thumb("search_movie.png"),folder=False),
Item(channel='globalsearch', title=config.get_localized_string(70741) % config.get_localized_string(30123), action='Search', mode='tvshow', thumbnail=get_thumb("search_tvshow.png"), folder=False),
@@ -135,7 +132,7 @@ def new_search(item):
return actor_list(item)
if item.mode != 'all':
tmdb_info = tmdb.Tmdb(texto_buscado=searched_text, tipo=item.mode.replace('show', ''))
tmdb_info = tmdb.Tmdb(searched_text=searched_text, search_type=item.mode.replace('show', ''))
results = tmdb_info.results
for result in results:
result = tmdb_info.get_infoLabels(result, origen=result)
@@ -563,7 +560,7 @@ def genres_menu(item):
itemlist = []
mode = item.mode.replace('show', '')
genres = tmdb.get_genres(mode)
genres = tmdb.get_dic_genres(mode)
for key, value in list(genres[mode].items()):
discovery = {'url': 'discover/%s' % mode, 'with_genres': key,
'language': def_lang, 'page': '1'}

View File

@@ -6,6 +6,7 @@
from __future__ import division
# from builtins import str
import random
import sys
from channelselector import get_thumb
@@ -165,9 +166,9 @@ def tmdb_trailers(item, dialog, tipo="movie"):
itemlist = []
tmdb_search = None
if item.infoLabels['tmdb_id']:
tmdb_search = Tmdb(id_Tmdb=item.infoLabels['tmdb_id'], tipo=tipo, idioma_busqueda=def_lang)
tmdb_search = Tmdb(id_Tmdb=item.infoLabels['tmdb_id'], tipo=tipo, search_language=def_lang)
elif item.infoLabels['year']:
tmdb_search = Tmdb(texto_buscado=item.contentTitle, tipo=tipo, year=item.infoLabels['year'])
tmdb_search = Tmdb(searched_text=item.contentTitle, tipo=tipo, year=item.infoLabels['year'])
if tmdb_search:
found = False
@@ -199,6 +200,8 @@ def youtube_search(item):
else:
title = urllib.quote(title)
title = title.replace("%20", "+")
httptools.set_cookies({'domain': 'youtube.com', 'name': 'CONSENT',
'value': 'YES+cb.20210328-17-p0.en+FX+' + str(random.randint(100, 999))})
data = httptools.downloadpage("https://www.youtube.com/results?sp=EgIQAQ%253D%253D&search_query=" + title).data
patron = r'thumbnails":\[\{"url":"(https://i.ytimg.com/vi[^"]+).*?'
patron += r'text":"([^"]+).*?'

View File

@@ -3,7 +3,7 @@
"name": "TvMovieDB",
"active": false,
"language": ["*"],
"thumbnail": "http://i.imgur.com/HA7fvgD.png",
"thumbnail": "https://i.imgur.com/5CETVTV.jpg",
"categories": [
"movie",
"tvshow",
@@ -92,4 +92,4 @@
"visible": true
}
]
}
}

View File

@@ -242,7 +242,7 @@ def mal(item):
itemlist.append(item.clone(title=config.get_localized_string(70058), url="https://myanimelist.net/topanime.php?type=tv&limit=0", action="top_mal", contentType="tvshow", args="tv"))
itemlist.append(item.clone(title=config.get_localized_string(70059), url="https://myanimelist.net/topanime.php?type=movie&limit=0", action="top_mal", contentType="movie", args="movie"))
itemlist.append(item.clone(title=config.get_localized_string(70061), url="https://myanimelist.net/topanime.php?type=ova&limit=0", action="top_mal", contentType="tvshow", args="tv", tipo="ova"))
itemlist.append(item.clone(title=config.get_localized_string(70061), url="https://myanimelist.net/topanime.php?type=ova&limit=0", action="top_mal", contentType="tvshow", args="tv", Type="ova"))
itemlist.append(item.clone(title=config.get_localized_string(70028), url="https://myanimelist.net/topanime.php?type=bypopularity&limit=0", action="top_mal"))
itemlist.append(item.clone(title=config.get_localized_string(70060), url="https://myanimelist.net/topanime.php?type=upcoming&limit=0", action="top_mal"))
itemlist.append(item.clone(title=config.get_localized_string(70062), url="", action="indices_mal"))
@@ -267,15 +267,15 @@ def list_tmdb(item):
# List of actors
if 'nm' in item.infoLabels['imdb_id']:
try:
ob_tmdb = Tmdb(discover=item.search, tipo=item.args, idioma_busqueda=langt)
ob_tmdb = Tmdb(discover=item.search, search_type=item.args, search_language=langt)
id_cast = ob_tmdb.result["person_results"][0]["id"]
if item.contentType == "movie": item.search = {'url': 'discover/movie', 'with_cast': id_cast, 'page': item.pagina, 'sort_by': 'primary_release_date.desc', 'language': langt}
else:item.search = {'url': 'person/%s/tv_credits' % id_cast, 'language': langt}
ob_tmdb = Tmdb(discover=item.search, tipo=item.args, idioma_busqueda=langt)
ob_tmdb = Tmdb(discover=item.search, search_type=item.args, search_language=langt)
except:
pass
else:
ob_tmdb = Tmdb(discover=item.search, tipo=item.args, idioma_busqueda=langt)
ob_tmdb = Tmdb(discover=item.search, search_type=item.args, search_language=langt)
# Sagas and collections
if "collection" in item.search["url"]:
@@ -307,8 +307,8 @@ def list_tmdb(item):
new_item.infoLabels = ob_tmdb.get_infoLabels(new_item.infoLabels, origen=ob_tmdb.results[i])
# If there is no synopsis in the chosen language, search in the alternative
if not new_item.infoLabels["plot"] and not 'person' in item.search["url"]:
ob_tmdb2 = Tmdb(id_Tmdb=new_item.infoLabels["tmdb_id"], tipo=item.args, idioma_busqueda=langt_alt)
new_item.infoLabels["plot"] = ob_tmdb2.get_sinopsis()
ob_tmdb2 = Tmdb(id_Tmdb=new_item.infoLabels["tmdb_id"], search_type=item.args, search_language=langt_alt)
new_item.infoLabels["plot"] = ob_tmdb2.get_plot()
if new_item.infoLabels['thumbnail']:
new_item.thumbnail = new_item.infoLabels['thumbnail']
elif new_item.infoLabels['profile_path']:
@@ -375,10 +375,10 @@ def details(item):
pics = match(data, patron=r'showAllVidsAndPics.*?href=".*?(tt\d+)').match
if pics: images["imdb"] = {'url': 'http://www.imdb.com/_json/title/%s/mediaviewer' % pics}
ob_tmdb = Tmdb(external_id=item.infoLabels["imdb_id"], external_source="imdb_id", tipo=item.args, idioma_busqueda=langt)
ob_tmdb = Tmdb(external_id=item.infoLabels["imdb_id"], external_source="imdb_id", search_type=item.args, search_language=langt)
item.infoLabels["tmdb_id"] = ob_tmdb.get_id()
ob_tmdb = Tmdb(id_Tmdb=item.infoLabels["tmdb_id"], tipo=item.args, idioma_busqueda=langt)
ob_tmdb = Tmdb(id_Tmdb=item.infoLabels["tmdb_id"], search_type=item.args, search_language=langt)
try:
item.infoLabels = ob_tmdb.get_infoLabels(item.infoLabels)
@@ -420,7 +420,7 @@ def details(item):
itemlist.append(item.clone(channel='search', action="search", search_text=item.infoLabels['originaltitle'], title=config.get_localized_string(70070) % item.infoLabels['originaltitle'], mode=item.contentType))
# if langt != "es" and langt != "en" and item.infoLabels["tmdb_id"]:
# tmdb_lang = Tmdb(id_Tmdb=item.infoLabels["tmdb_id"], tipo=item.args, idioma_busqueda=def_lang)
# tmdb_lang = Tmdb(id_Tmdb=item.infoLabels["tmdb_id"], search_type=item.args, search_language=def_lang)
# if tmdb_lang.result.get("title") and tmdb_lang.result["title"] != item.contentTitle and tmdb_lang.result["title"] != item.infoLabels['originaltitle']:
# tmdb_lang = tmdb_lang.result["title"]
# itemlist.append(item.clone(channel='search', action="search", title=config.get_localized_string(70066) % tmdb_lang, contentTitle=tmdb_lang, mode=item.contentType))
@@ -500,7 +500,7 @@ def distribution(item):
itemlist = []
item.args=item.contentType.replace('tvshow','tv')
item.search = {'url': '%s/%s/credits' % (item.args, item.infoLabels['tmdb_id'])}
ob_tmdb = Tmdb(discover=item.search, tipo=item.args, idioma_busqueda=langt)
ob_tmdb = Tmdb(discover=item.search, search_type=item.args, search_language=langt)
try:
cast = ob_tmdb.result["cast"]
@@ -545,7 +545,7 @@ def distribution(item):
def info_seasons(item):
# Season and episode info
itemlist = []
ob_tmdb = Tmdb(id_Tmdb=item.infoLabels["tmdb_id"], tipo="tv", idioma_busqueda=langt)
ob_tmdb = Tmdb(id_Tmdb=item.infoLabels["tmdb_id"], search_type="tv", search_language=langt)
logger.info(item.infoLabels)
for temp in range(int(item.infoLabels["number_of_seasons"]), 0, -1):
@@ -1217,19 +1217,19 @@ def indices_imdb(item):
# item_tmdb = item.clone()
# if item.contentType == "movie":
# ob_tmdb = Tmdb(text_buscado=item_tmdb.contentTitle, year=item_tmdb.infoLabels['year'], tipo=item_tmdb.args,
# idioma_busqueda=langt)
# ob_tmdb = Tmdb(text_buscado=item_tmdb.contentTitle, year=item_tmdb.infoLabels['year'], search_type=item_tmdb.args,
# search_language=langt)
# if not ob_tmdb.result:
# ob_tmdb = Tmdb(text_buscado=item_tmdb.infoLabels['originaltitle'], year=item_tmdb.infoLabels['year'],
# tipo=item_tmdb.args, idioma_busqueda=langt)
# search_type=item_tmdb.args, search_language=langt)
# else:
# ob_tmdb = Tmdb(text_buscado=item_tmdb.contentTitle, tipo=item_tmdb.args, idioma_busqueda=langt)
# ob_tmdb = Tmdb(text_buscado=item_tmdb.contentTitle, search_type=item_tmdb.args, search_language=langt)
# if not ob_tmdb.result:
# ob_tmdb = Tmdb(text_buscado=item_tmdb.infoLabels['tvshowtitle'], tipo=item_tmdb.args,
# idioma_busqueda=langt)
# ob_tmdb = Tmdb(text_buscado=item_tmdb.infoLabels['tvshowtitle'], search_type=item_tmdb.args,
# search_language=langt)
# if ob_tmdb.result:
# ob_tmdb = Tmdb(id_Tmdb=ob_tmdb.get_id(), tipo=item_tmdb.args, idioma_busqueda=langt)
# ob_tmdb = Tmdb(id_Tmdb=ob_tmdb.get_id(), search_type=item_tmdb.args, search_language=langt)
# item.infoLabels = ob_tmdb.get_infoLabels(item.infoLabels)
# # If there is no synopsis in the chosen language, search in the alternative
@@ -1289,7 +1289,7 @@ def indices_imdb(item):
# title=config.get_localized_string(70070) % item.infoLabels['originaltitle']))
# if langt != "es" and langt != "en" and item.infoLabels["tmdb_id"]:
# tmdb_lang = Tmdb(id_Tmdb=item.infoLabels["tmdb_id"], tipo=item.args, idioma_busqueda=def_lang)
# tmdb_lang = Tmdb(id_Tmdb=item.infoLabels["tmdb_id"], search_type=item.args, search_language=def_lang)
# if tmdb_lang.result.get("title") and tmdb_lang.result["title"] != item.contentTitle:
# tmdb_lang = tmdb_lang.result["title"]
# itemlist.append(item.clone(action="searching", title=config.get_localized_string(70066) % tmdb_lang,
@@ -1778,11 +1778,11 @@ def imagenes(item):
for key, value in item.images.items():
if key == "tmdb" and "Tmdb" in item.title:
if item.folder:
for tipo, child in value.iteritems():
for Type, child in value.iteritems():
for i, imagen in enumerate(child):
thumb = 'https://image.tmdb.org/t/p/w500' + imagen["file_path"]
fanart = 'https://image.tmdb.org/t/p/original' + imagen["file_path"]
title = " %s %s [%sx%s]" % (tipo.capitalize(), i + 1, imagen["width"], imagen["height"])
title = " %s %s [%sx%s]" % (Type.capitalize(), i + 1, imagen["width"], imagen["height"])
itemlist.append(Item(channel=item.channel, action="", thumbnail=thumb, fanart=fanart,
title=title, infoLabels=item.infoLabels))
else:
@@ -1790,11 +1790,11 @@ def imagenes(item):
elif key == "fanart.tv":
if item.folder:
for tipo, child in value.iteritems():
for Type, child in value.iteritems():
for i, imagen in enumerate(child):
thumb = imagen["url"].replace("/fanart/", "/preview/")
fanart = imagen["url"]
title = " %s %s [%s]" % (tipo.capitalize(), i + 1, imagen["lang"])
title = " %s %s [%s]" % (Type.capitalize(), i + 1, imagen["lang"])
itemlist.append(Item(channel=item.channel, action="", thumbnail=thumb, fanart=fanart,
title=title, infoLabels=item.infoLabels))
else:
@@ -1838,7 +1838,7 @@ def fanartv(item):
id_search = item.infoLabels['tmdb_id']
if item.contentType == "tvshow" and id_search:
search = {'url': 'tv/%s/external_ids' % item.infoLabels['tmdb_id'], 'language': langt}
ob_tmdb = Tmdb(discover=search, idioma_busqueda=langt)
ob_tmdb = Tmdb(discover=search, search_language=langt)
id_search = ob_tmdb.result.get("tvdb_id")
resultado = False
@@ -1869,27 +1869,27 @@ def menu_trakt(item):
# Menu with trakt account actions (views, watchlist, collection)
itemlist = []
token_auth = config.get_setting("token_trakt", "trakt")
tipo = item.args.replace("tv", "show") + "s"
Type = item.args.replace("tv", "show") + "s"
title = item.contentType.replace("movie", config.get_localized_string(70283)).replace("tvshow", config.get_localized_string(30123))
try:
result = acciones_trakt(item.clone(url="sync/watched/%s" % tipo))
post = {tipo: [{"ids": {"tmdb": item.infoLabels["tmdb_id"]}}]}
result = acciones_trakt(item.clone(url="sync/watched/%s" % Type))
post = {Type: [{"ids": {"tmdb": item.infoLabels["tmdb_id"]}}]}
if '"tmdb":%s' % item.infoLabels["tmdb_id"] in result: itemlist.append(item.clone(title=config.get_localized_string(70341) % title, action="acciones_trakt", url="sync/history/remove", post=post))
else: itemlist.append(item.clone(title=config.get_localized_string(70342) % title, action="acciones_trakt", url="sync/history", post=post))
except:
pass
try:
result = acciones_trakt(item.clone(url="sync/watchlist/%s" % tipo))
post = {tipo: [{"ids": {"tmdb": item.infoLabels["tmdb_id"]}}]}
result = acciones_trakt(item.clone(url="sync/watchlist/%s" % Type))
post = {Type: [{"ids": {"tmdb": item.infoLabels["tmdb_id"]}}]}
if '"tmdb":%s' % item.infoLabels["tmdb_id"] in result: itemlist.append(item.clone(title=config.get_localized_string(70343) % title, action="acciones_trakt", url="sync/watchlist/remove", post=post))
else: itemlist.append(item.clone(title=config.get_localized_string(70344) % title, action="acciones_trakt", url="sync/watchlist", post=post))
except:
pass
try:
result = acciones_trakt(item.clone(url="sync/collection/%s" % tipo))
post = {tipo: [{"ids": {"tmdb": item.infoLabels["tmdb_id"]}}]}
result = acciones_trakt(item.clone(url="sync/collection/%s" % Type))
post = {Type: [{"ids": {"tmdb": item.infoLabels["tmdb_id"]}}]}
if '"tmdb":%s' % item.infoLabels["tmdb_id"] in result: itemlist.append(item.clone(title=config.get_localized_string(70345) % title, action="acciones_trakt", url="sync/collection/remove", post=post))
else: itemlist.append(item.clone(title=config.get_localized_string(70346) % title, action="acciones_trakt", url="sync/collection", post=post))
except:
@@ -2104,7 +2104,7 @@ def details_mal(item):
title_mal = item.contentTitle
if not item.args:
args = match(data, patron=r'Type:</span>.*?>([^<]+)</a>').match.lower()
item.tipo = args
item.type = args
if args == "movie" or args == "special":
item.args = "movie"
item.contentType = "movie"
@@ -2124,25 +2124,25 @@ def details_mal(item):
item_tmdb = item.clone()
if item.contentType == "movie":
ob_tmdb = Tmdb(text_buscado=item_tmdb.contentTitle, year=item_tmdb.infoLabels['year'], tipo=item_tmdb.args, idioma_busqueda=langt)
ob_tmdb = Tmdb(text_buscado=item_tmdb.contentTitle, year=item_tmdb.infoLabels['year'], search_type=item_tmdb.args, search_language=langt)
if not ob_tmdb.result and eng_title:
ob_tmdb = Tmdb(text_buscado=eng_title, year=item_tmdb.infoLabels['year'], tipo=item_tmdb.args, idioma_busqueda=langt)
if not ob_tmdb.result and ("Special (" in item.title or item.tipo == "special"):
ob_tmdb = Tmdb(text_buscado=eng_title, year=item_tmdb.infoLabels['year'], search_type=item_tmdb.args, search_language=langt)
if not ob_tmdb.result and ("Special (" in item.title or item.type == "special"):
item_tmdb.args = "tv"
search = {'url': 'search/tv', 'language': langt, 'query': item_tmdb.contentTitle, 'first_air_date': item_tmdb.infoLabels["year"]}
ob_tmdb = Tmdb(discover=search, tipo=item_tmdb.args, idioma_busqueda=langt)
ob_tmdb = Tmdb(discover=search, search_type=item_tmdb.args, search_language=langt)
else:
search = {'url': 'search/tv', 'language': langt, 'query': eng_title, 'first_air_date': item_tmdb.infoLabels["year"]}
ob_tmdb = Tmdb(discover=search, tipo=item_tmdb.args, idioma_busqueda=langt)
ob_tmdb = Tmdb(discover=search, search_type=item_tmdb.args, search_language=langt)
if not ob_tmdb.result and eng_title:
search['query'] = eng_title
ob_tmdb = Tmdb(discover=search, tipo=item_tmdb.args, idioma_busqueda=langt)
if not ob_tmdb.result and ("OVA (" in item.title or item.tipo == "ova"):
ob_tmdb = Tmdb(discover=search, search_type=item_tmdb.args, search_language=langt)
if not ob_tmdb.result and ("OVA (" in item.title or item.type == "ova"):
item_tmdb.args = "movie"
ob_tmdb = Tmdb(text_buscado=item_tmdb.contentTitle, tipo=item_tmdb.args, idioma_busqueda=langt, year=item_tmdb.infoLabels['year'])
ob_tmdb = Tmdb(text_buscado=item_tmdb.contentTitle, search_type=item_tmdb.args, search_language=langt, year=item_tmdb.infoLabels['year'])
if ob_tmdb.result:
ob_tmdb = Tmdb(id_Tmdb=ob_tmdb.get_id(), tipo=item_tmdb.args, idioma_busqueda=langt)
ob_tmdb = Tmdb(id_Tmdb=ob_tmdb.get_id(), search_type=item_tmdb.args, search_language=langt)
item.infoLabels = ob_tmdb.get_infoLabels(item.infoLabels)
# Myanimelist synopsis is concatenated with that of tmdb if any
@@ -2389,10 +2389,10 @@ def season_mal(item):
matches = match(block, patron=patron, debug=True).matches
if matches:
itemlist.append(Item(channel=item.channel, action="", title=head_title, ))
for url, scrapedtitle, episode, genres, thumb, plot, tipo, year, score in matches:
for url, scrapedtitle, episode, genres, thumb, plot, Type, year, score in matches:
if ("Hentai" in genres or "Yaoi" in genres or "Yuri" in genres) and adult_mal: continue
scrapedtitle = scrapedtitle.replace("(TV)", "").replace("(Movie)", "")
if tipo == "Movie": title = scrapedtitle + " (%s)" % year
if Type == "Movie": title = scrapedtitle + " (%s)" % year
else: title = scrapedtitle + " %ss (%s)" % (episode, year)
infoLabels = {}
if score != "N/A":
@@ -2403,23 +2403,23 @@ def season_mal(item):
genres = match(genres, patron=r'title="([^"]+)"').matches
infoLabels["genre"] = ", ".join(genres)
tipo = tipo.lower()
if tipo == "movie" or tipo == "special":
Type = Type.lower()
if Type == "movie" or Type == "special":
args = "movie"
contentType = "movie"
else:
args = "tv"
contentType = "tvshow"
thumb = thumb.replace("r/167x242/", "") + "l.jpg"
itemlist.append(Item(channel=item.channel, action="details_mal", url=url, title=title, thumbnail=thumb, infoLabels=infoLabels, args=args, tipo=tipo, contentTitle=scrapedtitle, contentType=contentType, fanart=default_fan))
itemlist.append(Item(channel=item.channel, action="details_mal", url=url, title=title, thumbnail=thumb, infoLabels=infoLabels, args=args, Type=Type, contentTitle=scrapedtitle, contentType=contentType, fanart=default_fan))
else:
patron = r'<a href="([^"]+)" class="link-title">([^<]+)</a>.*?<span>(\? ep|\d+ ep).*?<div class="genres-inner js-genre-inner">(.*?)</div>.*?<div class="image".*?src="([^"]+).*?<span class="preline">(.*?)</span>.*?<div class="info">\s*(.*?)\s*-.*?(\d{4}).*?title="Score">\s*(N/A|\d\.\d+)'
matches = match(data, patron=patron).matches
for url, scrapedtitle, epis, scrapedgenres, thumbnail, plot, tipo, year, score in matches:
for url, scrapedtitle, epis, scrapedgenres, thumbnail, plot, Type, year, score in matches:
if ("Hentai" in scrapedgenres or "Yaoi" in scrapedgenres or "Yuri" in scrapedgenres) and not adult_mal:
continue
scrapedtitle = scrapedtitle.replace("(TV)", "").replace("(Movie)", "")
if tipo == "Movie":
if Type == "Movie":
title = scrapedtitle + " (%s)" % year
else:
title = scrapedtitle + " %ss (%s)" % (epis, year)
@@ -2432,8 +2432,8 @@ def season_mal(item):
genres = match(scrapedgenres, patron=r'title="([^"]+)"').matches
infoLabels["genre"] = ", ".join(genres)
tipo = tipo.lower()
if tipo == "movie" or tipo == "special":
Type = Type.lower()
if Type == "movie" or Type == "special":
args = "movie"
contentType = "movie"
else:
@@ -2441,7 +2441,7 @@ def season_mal(item):
contentType = "tvshow"
thumbnail = thumbnail.replace(".webp", ".jpg")
itemlist.append(Item(channel=item.channel, action="details_mal", url=url, title=title,
thumbnail=thumbnail, infoLabels=infoLabels, args=args, tipo=tipo,
thumbnail=thumbnail, infoLabels=infoLabels, args=args, Type=Type,
contentTitle=scrapedtitle, contentType=contentType,
fanart=default_fan))
next_page = match(data, patron=r'<a class="link current" href.*?href="([^"]+)"').match
@@ -2552,12 +2552,12 @@ def searching_mal(item):
data = match(item.url, headers=header_mal, cookies=False).data
patron = r'<a class="hoverinfo_trigger" href="([^"]+)".*?(?:data-src|src)="([^"]+)".*?<div class="hoverinfo".*?href.*?><strong>([^<]+)<.*?<div class="pt4">(.*?)<.*?<td.*?>(.*?)</td>.*?<td.*?>(.*?)</td>.*?<td.*?>(.*?)</td>.*?<td.*?>(.*?)</td>'
matches = match(data, patron=patron).matches
for url, thumb, title, plot, tipo, epis, rating, date in matches:
for url, thumb, title, plot, Type, epis, rating, date in matches:
infolabels = {"mediatype": "tvshow"}
contentType = "tvshow"
args = "tv"
title = title.strip()
tipo = tipo.strip()
Type = Type.strip()
rating = rating.strip()
epis = epis.strip()
infolabels["plot"] = htmlclean(plot.strip())
@@ -2578,20 +2578,20 @@ def searching_mal(item):
import traceback
logger.error(traceback.format_exc())
if tipo == "Movie" or tipo == "OVA":
if Type == "Movie" or Type == "OVA":
infolabels["mediatype"] = "movie"
contentType = "movie"
args = "movie"
show = ""
if epis and tipo != "Movie":
if epis and Type != "Movie":
title += " %s eps" % epis
if rating != "0.00" and rating != "N/A":
infolabels["rating"] = float(rating)
title += " %s" % (rating)
itemlist.append(Item(channel=item.channel, title=title, action="details_mal", url=url, show=show,
thumbnail=thumb, infoLabels=infolabels, contentTitle=contentitle,
contentType=contentType, tipo=tipo.lower(), args=args))
contentType=contentType, Type=Type.lower(), args=args))
if not "&show=" in item.url:
next_page = item.url + "&show=50"
@@ -2713,13 +2713,13 @@ def callback_mal(item, values):
genero_ids = "&".join(genero_ids)
query = values["keyword"].replace(" ", "%20")
tipo = item.valores["tipo"][values["tipo"]]
Type = item.valores["tipo"][values["tipo"]]
valoracion = item.valores["valoracion"][values["valoracion"]]
estado = item.valores["estado"][values["estado"]]
item.url = "https://myanimelist.net/anime.php?q=%s&type=%s&score=%s&status=%s" \
"&p=0&r=0&sm=0&sd=0&sy=0&em=0&ed=0&ey=0&c[0]=a&c[1]=b&c[2]=c&c[3]=d&c[4]=f&gx=0" \
% (query, tipo, valoracion, estado)
% (query, Type, valoracion, estado)
if genero_ids:
item.url += "&" + genero_ids
@@ -2851,14 +2851,14 @@ def items_mal(item):
title = title.replace("] (TV)", "]")
elif title.count("(Movie)") == 2:
title = title.replace("] (Movie)", "]")
tipo = "tvshow"
Type = "tvshow"
args = "tv"
if "Movie" in d["anime_media_type_string"]:
tipo = "movie"
Type = "movie"
args = "movie"
itemlist.append(Item(channel=item.channel, action="details_mal", url=url, title=title, thumbnail=thumbnail,
contentTitle=contentTitle, contentType=tipo, args=args, login=True))
contentTitle=contentTitle, contentType=Type, args=args, login=True))
if itemlist:
itemlist.insert(0, Item(channel=item.channel, action="", title=config.get_localized_string(70387)))

View File

@@ -1,118 +0,0 @@
# -*- coding: utf-8 -*-
import xbmc, sys, xbmcgui, os, xbmcvfs, traceback
from platformcode import config, logger
librerias = xbmc.translatePath(os.path.join(config.get_runtime_path(), 'lib'))
sys.path.insert(0, librerias)
from core.item import Item
from lib.sambatools import libsmb as samba
from core import scrapertools
def exists(path, silent=False, vfs=True):
path = xbmc.translatePath(path)
try:
if vfs:
result = bool(xbmcvfs.exists(path))
if not result and not path.endswith('/') and not path.endswith('\\'):
result = bool(xbmcvfs.exists(join(path, ' ').rstrip()))
return result
elif path.lower().startswith("smb://"):
return samba.exists(path)
else:
return os.path.exists(path)
except:
logger.error("ERROR when checking the path: %s" % path)
if not silent:
logger.error(traceback.format_exc())
return False
def join(*paths):
list_path = []
if paths[0].startswith("/"):
list_path.append("")
for path in paths:
if path:
list_path += path.replace("\\", "/").strip("/").split("/")
if scrapertools.find_single_match(paths[0], r'(^\w+:\/\/)'):
return str("/".join(list_path))
else:
return str(os.sep.join(list_path))
def search_paths(Id):
records = execute_sql('SELECT idPath FROM tvshowlinkpath WHERE idShow LIKE "%s"' % Id)
if len(records) >= 1:
for record in records:
path_records = execute_sql('SELECT strPath FROM path WHERE idPath LIKE "%s"' % record[0])
for path in path_records:
if config.get_setting('videolibrarypath') in path[0] and exists(join(path[0], 'tvshow.nfo')):
return path[0]
return ''
def execute_sql(sql):
logger.debug()
file_db = ""
records = None
# We look for the archive of the video database according to the version of kodi
video_db = config.get_platform(True)['video_db']
if video_db:
file_db = os.path.join(xbmc.translatePath("special://userdata/Database"), video_db)
# alternative method to locate the database
if not file_db or not os.path.exists(file_db):
file_db = ""
for f in os.path.listdir(xbmc.translatePath("special://userdata/Database")):
path_f = os.path.join(xbmc.translatePath("special://userdata/Database"), f)
if os.path.pathoos.pathols.isfile(path_f) and f.lower().startswith('myvideos') and f.lower().endswith('.db'):
file_db = path_f
break
if file_db:
logger.debug("DB file: %s" % file_db)
conn = None
try:
import sqlite3
conn = sqlite3.connect(file_db)
cursor = conn.cursor()
logger.debug("Running sql: %s" % sql)
cursor.execute(sql)
conn.commit()
records = cursor.fetchall()
if sql.lower().startswith("select"):
if len(records) == 1 and records[0][0] is None:
records = []
conn.close()
logger.debug("Query executed. Records: %s" % len(records))
except:
logger.error("Error executing sql query")
if conn:
conn.close()
else:
logger.debug("Database not found")
return records
if __name__ == '__main__':
path = search_paths(sys.listitem.getVideoInfoTag().getDbId())
if path:
item = Item(action="update_tvshow", channel="videolibrary", path=path)
# Why? I think it is not necessary, just commented
# item.tourl()
xbmc.executebuiltin("RunPlugin(plugin://plugin.video.kod/?" + item.tourl() + ")")
else:
dialog = xbmcgui.Dialog()
title = sys.listitem.getVideoInfoTag().getTitle()
if dialog.yesno(title, config.get_localized_string(70817) % title, nolabel=config.get_localized_string(70170), yeslabel=config.get_localized_string(30022)):
item = Item(action="new_search", channel="search", mode="tvshow", search_text=sys.listitem.getVideoInfoTag().getTitle())
xbmc.executebuiltin("ActivateWindow(10025,plugin://plugin.video.kod/?" + item.tourl() + ")")