def __init__(self, jsondata): self.label = jsondata['label'] self.file = unquotearchive(jsondata.get('file')) self.premiered = jsondata.get('premiered') self.sourcemedia = _get_sourcemedia(self.file) self.mediatype, self.dbid = get_mediatype_id(jsondata) self.skip_artwork = [] self.art = get_own_artwork(jsondata) self.uniqueids = _get_uniqueids(jsondata, self.mediatype) if self.mediatype in (mediatypes.EPISODE, mediatypes.SEASON): self.tvshowid = jsondata['tvshowid'] self.showtitle = jsondata['showtitle'] self.season = jsondata['season'] self.label = self.showtitle + ' - ' + self.label if self.mediatype == mediatypes.EPISODE: self.episode = jsondata['episode'] elif self.mediatype == mediatypes.TVSHOW: self.season = jsondata['season'] elif self.mediatype == mediatypes.MOVIESET: self.movies = jsondata.get('movies', []) if self.movies: add_movieset_movies(self) if mediatypes.central_directories[mediatypes.MOVIESET]: self.file = mediatypes.central_directories[mediatypes.MOVIESET] if settings.setartwork_subdirs: pathsep = utils.get_pathsep(self.file) self.file += utils.path_component(self.label) + pathsep + 'movieset.ext' else: self.file += utils.path_component(self.label) + '.ext' elif self.mediatype == mediatypes.MUSICVIDEO: self.label = build_music_label(jsondata) elif self.mediatype in mediatypes.audiotypes: if self.mediatype in (mediatypes.ALBUM, mediatypes.SONG): self.albumid = jsondata['albumid'] self.label = build_music_label(jsondata) self.artistid = None if self.mediatype == mediatypes.ARTIST \ else jsondata['albumartistid'][0] if jsondata.get('albumartistid') \ else jsondata['artistid'][0] if jsondata.get('artistid') \ else None self.artist = jsondata['label'] if self.mediatype == mediatypes.ARTIST \ else jsondata['albumartist'][0] if jsondata.get('albumartist') \ else jsondata['artist'][0] if jsondata.get('artist') \ else None self.album = jsondata['label'] if self.mediatype == mediatypes.ALBUM \ else jsondata['album'] if self.mediatype == mediatypes.SONG \ else None if self.mediatype == mediatypes.ALBUM: self.discfolders = {} self.seasons = None self.availableart = {} self.missingart = [] # or build this dynamically? self.selectedart = {} self.forcedart = {} self.updatedart = [] self.downloadedart = {} self.error = None self.missingid = False self.borked_filename = self.file and '\xef\xbf\xbd' in self.file
def get_exact_images(self, mediaitem): paths = (mediaitem.file, find_central_infodir(mediaitem)) if not paths[0] and not paths[1]: return {} if settings.albumartwithmediafiles: paths = (paths[1], paths[0]) if mediaitem.file: check_inputbase = os.path.splitext(os.path.basename( mediaitem.file))[0].lower() result = {} for path in paths: if not path: continue centraldir = path != mediaitem.file path = os.path.dirname(path) + get_pathsep(path) _, files = xbmcvfs.listdir(path) for filename in files: check_filename = filename.lower() if not check_filename.endswith(ARTWORK_EXTS): continue basefile = os.path.splitext(check_filename)[0] if '-' not in basefile: continue firstbit, arttype = basefile.rsplit('-', 1) if not arttype.isalnum(): continue if not centraldir and firstbit != check_inputbase: continue if centraldir and firstbit not in ( i.lower() for i in iter_possible_cleannames(mediaitem.label)): continue result[arttype] = self.buildimage(path + filename, filename, centraldir) return result
def get_exact_images(self, mediaitem): path, inputfilename = os.path.split(mediaitem.file) sep = get_pathsep(path) path += sep dirs, files = xbmcvfs.listdir(path) check_inputbase = os.path.splitext( inputfilename)[0] if inputfilename else '' result = {} if inputfilename: dirname = next( (name for name in dirs if name in iter_possible_cleannames(check_inputbase)), None) if dirname: # '[centraldir]/[set name]/[arttype].[ext]' dirname = path + dirname + sep _, dfiles = xbmcvfs.listdir(dirname) for filename in dfiles: if not filename.endswith(ARTWORK_EXTS): continue arttype = os.path.splitext(filename)[0] if not arttype.isalnum() or len( arttype) > ARTTYPE_MAXLENGTH: continue if settings.identify_alternatives and arttype in self.alttypes.keys( ): arttype = self.alttypes[arttype] if arttype in result.keys(): continue result[arttype] = self.buildimage(dirname + filename, filename) if not result: for filename in files: if not filename.endswith(ARTWORK_EXTS): continue basefile = os.path.splitext(filename)[0] if check_inputbase: # '[centraldir]/[set name]-[arttype].[ext]' if '-' not in basefile: continue firstbit, arttype = basefile.rsplit('-', 1) if not arttype.isalnum( ) or firstbit not in iter_possible_cleannames( check_inputbase): continue else: # parent of movie directory if not basefile.isalnum() or len( basefile) > ARTTYPE_MAXLENGTH: continue arttype = basefile if settings.identify_alternatives and arttype in self.alttypes.keys( ): arttype = self.alttypes[arttype] if arttype in result.keys(): continue result[arttype] = self.buildimage(path + filename, filename) return result
def _identify_parent_movieset(mediaitem): # Identify set folder among movie parent dirs add_movieset_movies(mediaitem) for cleanlabel in utils.iter_possible_cleannames(mediaitem.label): for movie in mediaitem.movies: pathsep = utils.get_pathsep(movie['file']) setmatch = pathsep + cleanlabel + pathsep if setmatch in movie['file']: result = movie['file'].split(setmatch)[0] + setmatch mediaitem.file = result return
def _identify_album_folders(mediaitem): songs = get_cached_songs(mediaitem.albumid) folders = set(os.path.dirname(song['file']) for song in songs) if len(folders) == 1: # all songs only in one folder folder = folders.pop() if not _shared_albumfolder(folder): return folder + utils.get_pathsep(folder), {} elif len(folders) > 1: # split to multiple folders discs = {} for folder in folders: if _shared_albumfolder(folder): return discnum = next(s['disc'] for s in songs if os.path.dirname(s['file']) == folder) if discnum: discs[discnum] = folder + utils.get_pathsep(folder) commonpath = os.path.dirname(os.path.commonprefix(folders)) if commonpath: commonpath += utils.get_pathsep(commonpath) if commonpath or discs: return commonpath, discs
def get_exact_images(self, mediaitem): path, inputfilename = os.path.split(mediaitem.file) path += get_pathsep(path) dirs, files = xbmcvfs.listdir(path) check_inputbase = os.path.splitext(inputfilename)[0].lower() paths = get_movie_path_list(path) result = {} sep = get_pathsep(path) path = os.path.dirname(paths[0]) + sep havespecific = [] for filename in files: check_filename = filename.lower() if not check_filename.endswith(ARTWORK_EXTS): continue basefile = os.path.splitext(check_filename)[0] specific = False if '-' in basefile: firstbit, basefile = basefile.rsplit('-', 1) if firstbit != check_inputbase: continue specific = True if not basefile.isalnum() or len(basefile) > ARTTYPE_MAXLENGTH: continue arttype = basefile if settings.identify_alternatives and arttype in self.alttypes.keys( ): arttype = self.alttypes[arttype] if arttype in result.keys(): continue if specific or arttype not in havespecific: result[arttype] = self.buildimage(path + filename, filename) if specific: havespecific.append(arttype) if dirs: if 'extrafanart' in dirs: result.update(self.getextra(path, result.keys())) if 'extrathumbs' in dirs: result.update(self.getextra(path, result.keys(), True)) return result
def recyclefile(filename): firstdir = utils.parent_dir(filename) directory = TEMP_DIR pathsep = utils.get_pathsep(directory) if firstdir in ('extrafanart', 'extrathumbs'): directory += utils.parent_dir(os.path.dirname(filename)) + pathsep directory += firstdir if not xbmcvfs.exists(directory): xbmcvfs.mkdirs(directory) recycled_filename = directory + pathsep + os.path.basename(filename) if not xbmcvfs.copy(filename, recycled_filename): raise FileError(L(CANT_WRITE_TO_FILE).format(recycled_filename))
def get_exact_images(self, mediaitem): paths = (mediaitem.file, find_central_infodir(mediaitem)) if settings.albumartwithmediafiles: paths = (paths[1], paths[0]) result = {} for path in paths: if not path: continue _, files = xbmcvfs.listdir(path) for filename in files: check_filename = filename.lower() if not check_filename.endswith(ARTWORK_EXTS): continue arttype = os.path.splitext(check_filename)[0] if not arttype.isalnum() or len(arttype) > ARTTYPE_MAXLENGTH: continue if settings.identify_alternatives and arttype in self.alttypes.keys( ): arttype = self.alttypes[arttype] if arttype in result.keys(): continue result[arttype] = self.buildimage(path + filename, filename, path != mediaitem.file) for disc in sorted(mediaitem.discfolders.keys()): path = mediaitem.discfolders[disc] _, files = xbmcvfs.listdir(path) for filename in files: check_filename = filename.lower() if not check_filename.endswith(ARTWORK_EXTS): continue arttype = os.path.splitext(check_filename)[0] if not arttype.isalnum() or len(arttype) > ARTTYPE_MAXLENGTH: continue if settings.identify_alternatives and arttype in self.alttypes.keys( ): arttype = self.alttypes[arttype] parentdir = parent_dir(path) + get_pathsep(path) if arttype == 'discart': if 'discart' not in result: result['discart'] = self.buildimage( path + filename, parentdir + filename) if not disc: continue arttype += str(disc) if arttype in result: continue result[arttype] = self.buildimage(path + filename, parentdir + filename) return result
def find_central_infodir(mediaitem): fromtv = mediaitem.mediatype in (mediatypes.SEASON, mediatypes.EPISODE) fromartist = mediaitem.mediatype in mediatypes.audiotypes fromalbum = mediaitem.mediatype in (mediatypes.ALBUM, mediatypes.SONG) cdtype = mediatypes.TVSHOW if fromtv else mediatypes.ARTIST if fromartist else mediaitem.mediatype basedir = mediatypes.central_directories.get(cdtype) if not basedir: return None slug1 = _get_uniqueslug(mediaitem, mediatypes.ARTIST) if fromartist else None slug2 = _get_uniqueslug(mediaitem, mediatypes.ALBUM) if fromalbum else None title1 = mediaitem.showtitle if fromtv \ else mediaitem.artist if fromartist else mediaitem.label title2 = mediaitem.album if fromalbum \ else mediaitem.label if mediaitem.mediatype == mediatypes.EPISODE \ else None title3 = mediaitem.label if mediaitem.mediatype == mediatypes.SONG else None sep = utils.get_pathsep(basedir) mediayear = mediaitem.year if mediaitem.mediatype == mediatypes.MOVIE else None single_dir = mediaitem.mediatype == mediatypes.MOVIESET and not settings.setartwork_subdirs thisdir = _find_existing(basedir, title1, slug1, mediayear, single_dir) if not thisdir: if mediaitem.mediatype == mediatypes.MOVIE: title1 = '{0} ({1})'.format(mediaitem.label, mediaitem.year) thisdir = utils.build_cleanest_name(title1, slug1) result = basedir + thisdir if not single_dir: result += sep if not title2: return result usefiles = mediaitem.mediatype == mediatypes.EPISODE thisdir = _find_existing(result, title2, slug2, files=usefiles) if not thisdir: thisdir = utils.build_cleanest_name(title2, slug2) result += thisdir if not usefiles: result += sep if not title3: return result final = _find_existing(result, title3, files=True) if not final: final = utils.build_cleanest_name(title3) result += final return result
def get_exact_images(self, mediaitem): path, inputfilename = os.path.split(mediaitem.file) path += get_pathsep(path) _, files = xbmcvfs.listdir(path) check_inputbase = os.path.splitext(inputfilename)[0].lower() result = {} for filename in files: check_filename = filename.lower() if not check_filename.endswith(ARTWORK_EXTS): continue basefile = os.path.splitext(check_filename)[0] if '-' not in basefile: continue firstbit, arttype = basefile.rsplit('-', 1) if firstbit != check_inputbase or not arttype.isalnum(): continue result[arttype] = self.buildimage(path + filename, filename) return result
def getextra(self, path, exacttypes, thumbs=False): arttype = 'thumb' if thumbs else 'fanart' extradir = 'extrathumbs' if thumbs else 'extrafanart' sep = get_pathsep(path) missing, nextno = getopentypes(exacttypes, arttype) path += extradir + sep _, files = xbmcvfs.listdir(path) files.sort(key=natural_sort) result = {} for filename in files: check_filename = filename.lower() if not check_filename.endswith(ARTWORK_EXTS): continue popped = missing.pop(0) if missing else None nexttype = popped if popped else format_arttype(arttype, nextno) result[nexttype] = self.buildimage(path + filename, extradir + sep + filename) if not popped: nextno += 1 return result
def build_artwork_basepath(mediaitem, arttype): if settings.albumartwithmediafiles and mediaitem.file \ and mediaitem.mediatype in (mediatypes.ALBUM, mediatypes.SONG): path = os.path.splitext(mediaitem.file)[0] else: path = find_central_infodir(mediaitem) if not path: if not mediaitem.file: return '' path = utils.get_movie_path_list(mediaitem.file)[0] \ if mediaitem.mediatype == mediatypes.MOVIE else mediaitem.file if path.startswith(blacklisted_protocols): return '' path = os.path.splitext(path)[0] sep = utils.get_pathsep(path) path, basename = os.path.split(path) path += sep use_basefilename = mediaitem.mediatype in (mediatypes.EPISODE, mediatypes.SONG) \ or mediaitem.mediatype == mediatypes.MOVIE and settings.savewith_basefilename \ or mediaitem.mediatype == mediatypes.MUSICVIDEO and settings.savewith_basefilename_mvids \ or mediaitem.mediatype == mediatypes.MOVIESET and basename and not settings.setartwork_subdirs if settings.identify_alternatives and _saveextrafanart( mediaitem.mediatype, arttype): path += 'extrafanart' + sep elif use_basefilename: path += basename + '-' def snum(num): return '-specials' if num == 0 else '-all' if num == -1 else '{0:02d}'.format( num) if mediaitem.mediatype == mediatypes.SEASON: path += 'season{0}-{1}'.format(snum(mediaitem.season), arttype) elif arttype.startswith('season.'): _, num, sarttype = arttype.split('.') path += 'season{0}-{1}'.format(snum(int(num)), sarttype) else: path += arttype return path
def _shared_albumfolder(folder): songs = get_cached_songs_bypath(folder + utils.get_pathsep(folder)) albums = set(song['albumid'] for song in songs) return len(albums) > 1