astrXbian/.install/.kodi/addons/plugin.video.vstream/resources/lib/gui/guiElement.py

698 lines
24 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
# vStream https://github.com/Kodi-vStream/venom-xbmc-addons
# Venom.
import re
import string
import unicodedata
from resources.lib.comaddon import addon, xbmc
from resources.lib.db import cDb
from resources.lib.util import QuoteSafe
import random
# rouge E26543
# jaune F7D571
# bleu clair 87CEEC ou skyblue / hoster
# vert 37BCB5
# bleu foncer 08435A / non utiliser
class cGuiElement:
DEFAULT_FOLDER_ICON = 'icon.png'
# COUNT = 0
DB = cDb()
def __init__(self):
addons = addon()
# self.__sRootArt = cConfig().getRootArt()
self.__sFunctionName = ''
self.__sRootArt = 'special://home/addons/plugin.video.vstream/resources/art/'
self.__sType = 'Video'
self.__sMeta = 0
self.__sPlaycount = 0
self.__sTrailer = ''
self.__sMetaAddon = addons.getSetting('meta-view')
self.__sImdb = ''
self.__sTmdb = ''
self.__sMediaUrl = ''
self.__sSiteUrl = ''
# contient le titre qui sera coloré
self.__sTitle = ''
# contient le titre propre
self.__sCleanTitle = ''
# titre considéré Vu
self.__sTitleWatched = ''
# contient le titre modifié pour BDD
self.__sFileName = ''
self.__sDescription = ''
self.__sGenre = ''
self.__sThumbnail = ''
self.__sPoster = ''
self.__Season = ''
self.__Episode = ''
self.__sIcon = self.DEFAULT_FOLDER_ICON
self.__sFanart = 'special://home/addons/plugin.video.vstream/fanart.jpg'
self.__sDecoColor = addons.getSetting('deco_color')
# For meta search
# TmdbId the movie database https://developers.themoviedb.org/
self.__TmdbId = ''
# ImdbId pas d'api http://www.imdb.com/
self.__ImdbId = ''
self.__Year = ''
self.__aItemValues = {}
self.__aProperties = {}
self.__aContextElements = []
self.__sSiteName = ''
# categorie utilisé pour marque-page et recherche.
# 1 - movies/saga , 2 - tvshow/episode/anime, 5 - misc/Next
self.__sCat = ''
# def __len__(self): return self.__sCount
# def getCount(self):
# return cGuiElement.COUNT
def setType(self, sType):
self.__sType = sType
def getType(self):
return self.__sType
def setCat(self, sCat):
self.__sCat = sCat
def getCat(self):
return self.__sCat
def setMetaAddon(self, sMetaAddon):
self.__sMetaAddon = sMetaAddon
def getMetaAddon(self):
return self.__sMetaAddon
def setTrailer(self, sTrailer):
self.__sTrailer = sTrailer
def getTrailer(self):
return self.__sTrailer
def setTmdbId(self, data):
self.__TmdbId = data
def getTmdbId(self):
return self.__TmdbId
def setImdbId(self, data):
self.__ImdbId = data
def getImdbId(self):
return self.__ImdbId
def setYear(self, data):
self.__Year = data
def getYear(self):
return self.__Year
def setGenre(self, genre):
self.__sGenre = genre
def getGenre(self):
return self.__sGenre
def setMeta(self, sMeta):
self.__sMeta = sMeta
def getMeta(self):
return self.__sMeta
def setMediaUrl(self, sMediaUrl):
self.__sMediaUrl = sMediaUrl
def getMediaUrl(self):
return self.__sMediaUrl
def setSiteUrl(self, sSiteUrl):
self.__sSiteUrl = sSiteUrl
def getSiteUrl(self):
return self.__sSiteUrl
def setSiteName(self, sSiteName):
self.__sSiteName = sSiteName
def getSiteName(self):
return self.__sSiteName
def setFileName(self, sFileName):
self.__sFileName = self.str_conv(sFileName)
def getFileName(self):
return self.__sFileName
def setFunction(self, sFunctionName):
self.__sFunctionName = sFunctionName
def getFunction(self):
return self.__sFunctionName
def TraiteTitre(self, sTitle):
# Format Obligatoire a traiter via le fichier source
# -------------------------------------------------
# Episode 7 a 9 > Episode 7-9
# Saison 1 à ? > Saison 1-?
# Format de date > 11/22/3333 ou 11-22-3333
# convertion unicode ne fonctionne pas avec les accents
try:
# traitement du titre pour les caracteres spéciaux déplacé dans parser plus global
# traitement du titre pour retirer le - quand c'est une Saison. Tiret, tiret moyen et cadratin
sTitle = sTitle.replace(' - Saison', ' Saison').replace(' Saison', ' Saison').replace(' — Saison', ' Saison')
sTitle = sTitle.decode('utf-8')
except:
pass
# recherche l'année, uniquement si entre caractere special a cause de 2001 odysse de l'espace ou k2000
string = re.search('([^\w ][0-9]{4}[^\w ])', sTitle)
if string:
sTitle = sTitle.replace(string.group(0), '')
self.__Year = str(string.group(0)[1:5])
self.addItemValues('year', self.__Year)
# recherche une date
string = re.search('([\d]{2}[\/|-]\d{2}[\/|-]\d{4})', sTitle)
if string:
sTitle = sTitle.replace(string.group(0), '')
self.__Date = str(string.group(0))
sTitle = '%s (%s) ' % (sTitle, self.__Date)
#~ #recherche Lang
#~ index = {' vostfr': ' [VOSTFR]', ' vf': ' [VF]', ' truefrench': ' [TrueFrench]'}
#~ for cle in index:
#~ sTitle = sTitle.replace(cle.upper(), index[cle]).replace(cle, index[cle]).replace('(%s)' % (cle), index[cle])
#~ #recherche Qualité
#~ index = {'1080i': '(1080)', '1080p': '(1080)', '1080I': '(1080)', '1080P': '(1080)', '720i': '(720)', '720p': '(720)', '720I': '(720)', '720P': '(720)'}
#~ for cle in index:
#~ sTitle = sTitle.replace(cle, index[cle]).replace('[%s]' % (cle), index[cle])
# Recherche saison et episode a faire pr serie uniquement
if True:
m = re.search('(?i)(?:^|[^a-z])((?:E|(?:\wpisode\s?))([0-9]+(?:[\-\.][0-9\?]+)*))', sTitle, re.UNICODE)
if m:
# ok y a des episodes
sTitle = sTitle.replace(m.group(1), '')
ep = m.group(2)
if len(ep) == 1:
ep = '0' + ep
self.__Episode = ep
self.addItemValues('Episode', self.__Episode)
# pour les saisons
m = re.search('(?i)( s(?:aison +)*([0-9]+(?:\-[0-9\?]+)*))', sTitle, re.UNICODE)
if m:
sTitle = sTitle.replace(m.group(1), '')
sa = m.group(2)
if len(sa) == 1:
sa = '0' + sa
self.__Season = sa
self.addItemValues('Season', self.__Season)
else:
# pas d'episode mais y a t il des saisons ?
m = re.search('(?i)( s(?:aison +)*([0-9]+(?:\-[0-9\?]+)*))', sTitle, re.UNICODE)
if m:
sTitle = sTitle.replace(m.group(1), '')
sa = m.group(2)
if len(sa) == 1:
sa = '0' + sa
self.__Season = sa
self.addItemValues('Season', self.__Season)
# vire doubles espaces
sTitle = re.sub(' +', ' ', sTitle)
# enleve les crochets et les parentheses si elle sont vides
sTitle = sTitle.replace('()', '').replace('[]', '').replace('- -', '-')
# vire espace a la fin et les - (attention, il y a 2 tirets differents meme si invisible a l'oeil nu et un est en unicode)
sTitle = re.sub('[- ]+$', '', sTitle)
# et au debut
if sTitle.startswith(' '):
sTitle = sTitle[1:]
# recherche les Tags restant : () ou [] sauf tag couleur
sTitle = re.sub('([\(|\[](?!\/*COLOR)[^\)\(\]\[]+?[\]|\)])', '[COLOR ' + self.__sDecoColor + ']\\1[/COLOR]', sTitle)
# on reformate SXXEXX Titre [tag] (Annee)
sTitle2 = ''
if self.__Season:
sTitle2 = sTitle2 + 'S' + self.__Season
if self.__Episode:
sTitle2 = sTitle2 + 'E' + self.__Episode
# Titre unique pour pour marquer VU (avec numéro de l'épisode pour les séries)
self.__sTitleWatched = self.str_conv(sTitle).replace(' ', '')
if sTitle2:
self.__sTitleWatched += '_' + sTitle2
if sTitle2:
sTitle2 = '[COLOR %s]%s[/COLOR] ' % (self.__sDecoColor, sTitle2)
sTitle2 = sTitle2 + sTitle
if self.__Year:
sTitle2 = '%s [COLOR %s](%s)[/COLOR]' % (sTitle2, self.__sDecoColor, self.__Year)
# on repasse en utf-8
try:
return sTitle2.encode('utf-8')
except AttributeError:
return sTitle2
def getEpisodeTitre(self, sTitle):
string = re.search('(?i)(e(?:[a-z]+sode\s?)*([0-9]+))', str(sTitle))
if string:
sTitle = sTitle.replace(string.group(1), '')
self.__Episode = ('%02d' % int(string.group(2)))
sTitle = '%s [COLOR %s]E%s[/COLOR]' % (sTitle, self.__sDecoColor, self.__Episode)
self.addItemValues('Episode', self.__Episode)
return sTitle, True
return sTitle, False
def setTitle(self, sTitle):
#Convertie les bytes en strs pour le replace.
self.__sCleanTitle = sTitle.replace('[]', '').replace('()', '').strip()
try:
sTitle = sTitle.strip().decode('utf-8')
except:
pass
#Python 3 decode sTitle
try:
sTitle = sTitle.encode('latin-1').decode('utf-8')
except:
pass
if not sTitle.startswith('[COLOR'):
self.__sTitle = self.TraiteTitre(sTitle)
else:
self.__sTitle = sTitle
def getTitle(self):
return self.__sTitle
def getCleanTitle(self):
return self.__sCleanTitle
# def setTitleWatched(self, sTitleWatched):
# self.__sTitleWatched = sTitleWatched
def getTitleWatched(self):
return self.__sTitleWatched
def setDescription(self, sDescription):
#Py3
try:
self.__sDescription = sDescription.encode('latin-1')
except:
self.__sDescription = sDescription
def getDescription(self):
return self.__sDescription
def setThumbnail(self, sThumbnail):
self.__sThumbnail = sThumbnail
def getThumbnail(self):
return self.__sThumbnail
def setPoster(self, sPoster):
self.__sPoster = sPoster
def getPoster(self):
return self.__sPoster
def setFanart(self, sFanart):
if (sFanart != ''):
self.__sFanart = sFanart
def setMovieFanart(self):
self.__sFanart = self.__sFanart
def setTvFanart(self):
self.__sFanart = self.__sFanart
def setDirectTvFanart(self):
self.__sFanart = self.__sFanart
def setDirFanart(self, sIcon):
self.__sFanart = self.__sFanart
def getFanart(self):
return self.__sFanart
def setIcon(self, sIcon):
try:
self.__sIcon = unicode(sIcon, 'utf-8')
except:
self.__sIcon = sIcon
self.__sIcon = self.__sIcon.encode('utf-8')
self.__sIcon = QuoteSafe(self.__sIcon)
def getIcon(self):
# if 'http' in self.__sIcon:
# return UnquotePlus(self.__sIcon)
folder = 'special://home/addons/plugin.video.vstream/resources/art'
path = '/'.join([folder, self.__sIcon])
# return os.path.join(unicode(self.__sRootArt, 'utf-8'), self.__sIcon)
return path
def addItemValues(self, sItemKey, mItemValue):
self.__aItemValues[sItemKey] = mItemValue
def getItemValue(self, sItemKey):
if sItemKey not in self.__aItemValues:
return
return self.__aItemValues[sItemKey]
def getWatched(self):
# Fonctionne pour marquer lus un dossier
if not self.getTitleWatched():
return 0
meta = {}
meta['title'] = self.getTitleWatched()
meta['site'] = self.getSiteUrl()
data = self.DB.get_watched(meta)
return data
def str_conv(self, data):
# Pas d'autre solution pour le moment que de faire comme ca.
if isinstance(data, str):
# Must be encoded in UTF-8
try:
data = data.decode('utf8')
except AttributeError:
pass
try:
data = data.decode('utf8')
except (AttributeError, UnicodeEncodeError):
pass
data = unicodedata.normalize('NFKD', data).encode('ascii', 'ignore')
# cherche la saison et episode puis les balises [color]titre[/color]
# data, saison = self.getSaisonTitre(data)
# data, episode = self.getEpisodeTitre(data)
# supprimer les balises
data = re.sub(r'\[.*\]|\(.*\)', r'', str(data))
data = data.replace('VF', '').replace('VOSTFR', '').replace('FR', '')
# data = re.sub(r'[0-9]+?', r'', str(data))
data = data.replace('-', ' ') # on garde un espace pour que Orient-express ne devienne pas Orientexpress pour la recherche tmdb
data = data.replace('Saison', '').replace('saison', '').replace('Season', '').replace('Episode', '').replace('episode', '')
data = re.sub('[^%s]' % (string.ascii_lowercase + string.digits), ' ', data.lower())
# data = QuotePlus(data)
# data = data.decode('string-escape')
return data
def getInfoLabel(self):
meta = {
'title': xbmc.getInfoLabel('ListItem.title'),
# 'label': xbmc.getInfoLabel('ListItem.title'),
'originaltitle': xbmc.getInfoLabel('ListItem.originaltitle'),
'year': xbmc.getInfoLabel('ListItem.year'),
'genre': xbmc.getInfoLabel('ListItem.genre'),
'director': xbmc.getInfoLabel('ListItem.director'),
'country': xbmc.getInfoLabel('ListItem.country'),
'rating': xbmc.getInfoLabel('ListItem.rating'),
'votes': xbmc.getInfoLabel('ListItem.votes'),
'mpaa': xbmc.getInfoLabel('ListItem.mpaa'),
'duration': xbmc.getInfoLabel('ListItem.duration'),
'trailer': xbmc.getInfoLabel('ListItem.trailer'),
'writer': xbmc.getInfoLabel('ListItem.writer'),
'studio': xbmc.getInfoLabel('ListItem.studio'),
'tagline': xbmc.getInfoLabel('ListItem.tagline'),
'plotoutline': xbmc.getInfoLabel('ListItem.plotoutline'),
'plot': xbmc.getInfoLabel('ListItem.plot'),
'cover_url': xbmc.getInfoLabel('ListItem.Art(thumb)'),
'backdrop_url': xbmc.getInfoLabel('ListItem.Art(fanart)'),
'imdb_id': xbmc.getInfoLabel('ListItem.IMDBNumber'),
'season': xbmc.getInfoLabel('ListItem.season'),
'episode': xbmc.getInfoLabel('ListItem.episode')
}
if 'title' in meta and meta['title']:
meta['title'] = self.getTitle()
for key, value in meta.items():
self.addItemValues(key, value)
if 'backdrop_url' in meta and meta['backdrop_url']:
self.addItemProperties('fanart_image', meta['backdrop_url'])
self.__sFanart = meta['backdrop_url']
if 'trailer' in meta and meta['trailer']:
self.__sTrailer = meta['trailer']
if 'cover_url' in meta and meta['cover_url']:
self.__sThumbnail = meta['cover_url']
self.__sPoster = meta['cover_url']
return
def getMetadonne(self):
metaType = self.getMeta()
if metaType == 0: # non media -> on sort, et on enleve le fanart
self.addItemProperties('fanart_image', '')
return
from resources.lib.tmdb import cTMDb
TMDb = cTMDb()
sTitle = self.__sFileName
# sTitle = self.__sTitle.decode('latin-1').encode('utf-8')
# sTitle = re.sub(r'\[.*\]|\(.*\)', r'', str(self.__sFileName))
# sTitle = sTitle.replace('VF', '').replace('VOSTFR', '').replace('FR', '')
# On nettoie le titre pour la recherche
sTitle = sTitle.replace('version longue', '')
# Integrale de films, on nettoie le titre pour la recherche
if metaType == 3:
sTitle = sTitle.replace('integrales', '')
sTitle = sTitle.replace('integrale', '')
sTitle = sTitle.replace('2 films', '')
sTitle = sTitle.replace('6 films', '')
sTitle = sTitle.replace('7 films', '')
sTitle = sTitle.replace('trilogie', '')
sTitle = sTitle.replace('trilogy', '')
sTitle = sTitle.replace('quadrilogie', '')
sTitle = sTitle.replace('pentalogie', '')
sTitle = sTitle.replace('octalogie', '')
sTitle = sTitle.replace('hexalogie', '')
sTitle = sTitle.replace('tetralogie', '')
sTitle = sTitle.strip()
if sTitle.endswith(' les'):
sTitle = sTitle[:-4]
if sTitle.endswith(' la') or sTitle.endswith(' l') :
sTitle = sTitle[:-3]
sTitle = sTitle.strip()
sType = str(metaType).replace('1', 'movie').replace('2', 'tvshow').replace('3', 'collection').replace('4', 'anime').replace('7', 'person').replace('8', 'network')
meta = {}
if sType:
args = (sType, sTitle)
kwargs = {}
if (self.__ImdbId):
kwargs['imdb_id'] = self.__ImdbId
if (self.__TmdbId):
kwargs['tmdb_id'] = self.__TmdbId
if (self.__Year):
kwargs['year'] = self.__Year
if (self.__Season):
kwargs['season'] = self.__Season
if (self.__Episode):
kwargs['episode'] = self.__Episode
try:
meta = TMDb.get_meta(*args, **kwargs)
except:
pass
else:
return
meta['title'] = self.getTitle()
if 'media_type' in meta:
meta.pop('media_type')
if 'imdb_id' in meta:
imdb_id = meta.pop('imdb_id')
if imdb_id:
self.__ImdbId = imdb_id
if 'tmdb_id' in meta:
tmdb_id = meta.pop('tmdb_id')
if tmdb_id:
self.__TmdbId = tmdb_id
if 'tvdb_id' in meta:
# if meta['tvdb_id']:
# self.__TvdbId = meta['tvdb_id']
meta.pop('tvdb_id')
# Si fanart trouvé dans les meta alors on l'utilise, sinon on n'en met pas
if 'backdrop_url' in meta:
url = meta.pop('backdrop_url')
if url:
self.addItemProperties('fanart_image', url)
self.__sFanart = url
else:
self.addItemProperties('fanart_image', '')
if 'backdrop_path' in meta:
meta.pop('backdrop_path')
if 'poster_path' in meta:
meta.pop('poster_path')
if 'cover_url' in meta:
cover = meta.pop('cover_url')
if cover:
self.__sThumbnail = cover
self.__sPoster = cover
if 'trailer' in meta and meta['trailer']:
self.__sTrailer = meta['trailer']
for key, value in meta.items():
self.addItemValues(key, value)
return
def getItemValues(self):
self.addItemValues('Title', self.getTitle())
# https://kodi.wiki/view/InfoLabels
# https://codedocs.xyz/xbmc/xbmc/group__python__xbmcgui__listitem.html#ga0b71166869bda87ad744942888fb5f14
# - Video Values:
# - genre : string (Comedy)
# - year : integer (2009)
# - episode : integer (4)
# - season : integer (1)
# - top250 : integer (192)
# - tracknumber : integer (3)
# - rating : float (6.4) - range is 0..10
# - watched : depreciated - use playcount instead
# - playcount : integer (2) - number of times this item has been played
# - overlay : integer (2) - range is 0..8. See GUIListItem.h for values
# - cast : list (Michal C. Hall)
# - castandrole : list (Michael C. Hall|Dexter)
# - director : string (Dagur Kari)
# - mpaa : string (PG-13)
# - plot : string (Long Description)
# - plotoutline : string (Short Description)
# - title : string (Big Fan)
# - originaltitle : string (Big Fan)
# - sorttitle : string (Big Fan)
# - duration : string (3:18)
# - studio : string (Warner Bros.)
# - tagline : string (An awesome movie) - short description of movie
# - writer : string (Robert D. Siegel)
# - tvshowtitle : string (Heroes)
# - premiered : string (2005-03-04)
# - status : string (Continuing) - status of a TVshow
# - code : string (tt0110293) - IMDb code
# - aired : string (2008-12-07)
# - credits : string (Andy Kaufman) - writing credits
# - lastplayed : string (Y-m-d h:m:s = 2009-04-05 23:16:04)
# - album : string (The Joshua Tree)
# - artist : list (['U2'])
# - votes : string (12345 votes)
# - trailer : string (/home/user/trailer.avi)
# - dateadded : string (Y-m-d h:m:s = 2009-04-05 23:16:04)
if self.getMetaAddon() == 'true':
self.getMetadonne()
# tmdbid
if self.getTmdbId():
self.addItemProperties('TmdbId', str(self.getTmdbId()))
self.addItemValues('DBID', str(self.getTmdbId()))
# imdbid
if self.getImdbId():
self.addItemProperties('ImdbId', str(self.getImdbId()))
# Utilisation des infos connues si non trouvées
if not self.getItemValue('plot') and self.getDescription():
self.addItemValues('plot', self.getDescription())
if not self.getItemValue('year') and self.getYear():
self.addItemValues('year', self.getYear())
if not self.getItemValue('genre') and self.getGenre():
self.addItemValues('genre', self.getGenre())
# if not self.getItemValue('cover_url') and self.getThumbnail():
# self.addItemValues('cover_url', self.getThumbnail())
# if not self.getItemValue('backdrop_url') and self.getPoster():
# self.addItemValues('backdrop_url', self.getPoster())
if not self.getItemValue('trailer'):
if self.getTrailer():
self.addItemValues('trailer', self.getTrailer())
# else:
# self.addItemValues('trailer', self.getDefaultTrailer())
# Used only if there is data in db, overwrite getMetadonne()
w = self.getWatched()
if w == 1:
self.addItemValues('playcount', w)
self.addItemProperties('siteUrl', self.getSiteUrl())
self.addItemProperties('sCleanTitle', self.getFileName())
self.addItemProperties('sId', self.getSiteName())
self.addItemProperties('sFav', self.getFunction())
self.addItemProperties('sCat', str(self.getCat()))
self.addItemProperties('sMeta', str(self.getMeta()))
return self.__aItemValues
def addItemProperties(self, sPropertyKey, mPropertyValue):
self.__aProperties[sPropertyKey] = mPropertyValue
def getItemProperties(self):
return self.__aProperties
def addContextItem(self, oContextElement):
self.__aContextElements.append(oContextElement)
def getContextItems(self):
return self.__aContextElements
# Des vidéos pour remplacer des bandes annnonces manquantes
def getDefaultTrailer(self):
from resources.lib.tmdb import cTMDb
trailers = ['WWkYjM3ZXxU',
'LpvKI7I5rF4',
'svTVRDgI08Y',
'DUpVqwceQaA',
'mnsMnskJ3cQ',
'M0_vxs6FPbQ']
trailer_id = random.choice(trailers)
return cTMDb.URL_TRAILER % trailer_id