Ejemplo n.º 1
0
    def _process_chunk(self, medialist, singleitemlist, singleitem):
        artcount = 0
        currentitem = 0
        aborted = False
        for mediaitem in medialist:
            if is_excluded(mediaitem):
                continue
            if mediaitem.mediatype in mediatypes.audiotypes and get_kodi_version(
            ) < 18:
                continue
            self.update_progress(currentitem * 100 // len(medialist),
                                 mediaitem.label)
            info.add_additional_iteminfo(mediaitem, self.processed,
                                         None if self.localmode else search)
            currentitem += 1
            try:
                services_hit = self._process_item(mediaitem, singleitem)
            except FileError as ex:
                services_hit = True
                mediaitem.error = ex.message
                log(ex.message, xbmc.LOGERROR)
                self.notify_warning(ex.message, None, True)
            reporting.report_item(mediaitem, singleitemlist or mediaitem.error)
            artcount += len(mediaitem.updatedart)

            if not services_hit:
                if self.monitor.abortRequested():
                    aborted = True
                    break
            elif self.monitor.waitForAbort(THROTTLE_TIME):
                aborted = True
                break
        return aborted, currentitem, artcount
Ejemplo n.º 2
0
def remove_texture(textureid):
    json_request = get_base_json_request('Textures.RemoveTexture')
    json_request['params']['textureid'] = textureid

    json_result = pykodi.execute_jsonrpc(json_request)
    if not check_json_result(json_result, 'OK', json_request):
        log(json_result)
def set_arttypes(root, arttype_map):
    for key, artlist in arttype_map.items():
        if key not in mediatype_map:
            if key not in unsupported_types:
                log(
                    "Can't set arttypes for '{0}' in advancedsettings.xml".
                    format(key), xbmc.LOGNOTICE)
            continue
        typemap = mediatype_map[key]
        library_elem = root.find(typemap[1])
        if library_elem is None:
            library_elem = ET.SubElement(root, typemap[1])
        mediatype_elem = library_elem.find(typemap[0])
        if artlist:
            if mediatype_elem is None:
                mediatype_elem = ET.SubElement(library_elem, typemap[0])
            else:
                mediatype_elem.clear()
            for arttype in artlist:
                if arttype in typemap[2]:
                    continue
                arttype_elem = ET.SubElement(mediatype_elem, ARTTYPE_TAG)
                arttype_elem.text = arttype
        elif mediatype_elem is not None:
            library_elem.remove(mediatype_elem)
def read_xml():
    if not xbmcvfs.exists(FILENAME):
        return ET.Element(ROOT_TAG)

    parser = ET.XMLParser(target=CommentedTreeBuilder())
    with closing(xbmcvfs.File(FILENAME)) as as_xml:
        try:
            return ET.parse(as_xml, parser).getroot()
        except ET.ParseError:
            log("Can't parse advancedsettings.xml", xbmc.LOGWARNING)
Ejemplo n.º 5
0
 def setlanguages(self):
     languages = []
     if settings.language_override:
         languages.append(settings.language_override)
     if settings.language_fallback_kodi:
         newlang = pykodi.get_language(xbmc.ISO_639_1)
         if newlang not in languages:
             languages.append(newlang)
     if settings.language_fallback_en and 'en' not in languages:
         languages.append('en')
     self.autolanguages = languages
     log("Working language filter: " + str(languages))
Ejemplo n.º 6
0
def set_item_details(dbid, mediatype, **details):
    assert mediatype in typemap

    mapped = typemap[mediatype]
    basestr = 'VideoLibrary.Set{0}Details' if mediatype not in mediatypes.audiotypes else 'AudioLibrary.Set{0}Details'
    json_request = get_base_json_request(basestr.format(mapped[0]))
    json_request['params'] = details
    json_request['params'][mediatype + 'id'] = dbid

    json_result = pykodi.execute_jsonrpc(json_request)
    if not check_json_result(json_result, 'OK', json_request):
        log(json_result)
def save_backup():
    if xbmcvfs.exists(FILENAME):
        xbmcvfs.copy(FILENAME, FILENAME_BAK)
        result = xbmcvfs.exists(FILENAME_BAK)
        if result:
            xbmcgui.Dialog().notification("Artwork Beef", L(BACKUP_SUCCESSFUL))
        else:
            xbmcgui.Dialog().notification("Artwork Beef",
                                          L(BACKUP_UNSUCCESSFUL),
                                          xbmc.LOGWARNING)
        return result
    log("advancedsettings.xml doesn't exist, can't save backup",
        xbmc.LOGNOTICE)
    return True
def restore_backup():
    if xbmcvfs.exists(FILENAME_BAK):
        xbmcvfs.copy(FILENAME_BAK, FILENAME)
        xbmcvfs.delete(FILENAME_BAK)
        result = xbmcvfs.exists(FILENAME)
        if result:
            xbmcgui.Dialog().notification("Artwork Beef",
                                          L(RESTORE_SUCCESSFUL))
        else:
            xbmcgui.Dialog().notification("Artwork Beef",
                                          L(RESTORE_UNSUCCESSFUL),
                                          xbmc.LOGWARNING)
        return result
    log("advancedsettings.xml.beef.bak doesn't exist, can't restore backup",
        xbmc.LOGWARNING)
    return False
Ejemplo n.º 9
0
 def downloadforitem(mediaitem):
     try:
         fileman.downloadfor(mediaitem)
         newart = dict((k, v)
                       for k, v in mediaitem.downloadedart.iteritems()
                       if not v or not v.startswith('http'))
         for arttype in newart:
             # remove old URL from texture cache
             if mediaitem.art.get(arttype, '').startswith('http'):
                 quickjson.remove_texture_byurl(mediaitem.art[arttype])
         return newart
     except FileError as ex:
         mediaitem.error = ex.message
         log(ex.message, xbmc.LOGERROR)
         xbmcgui.Dialog().notification("Artwork Beef", ex.message,
                                       xbmcgui.NOTIFICATION_ERROR)
         return {}
Ejemplo n.º 10
0
 def _build_imagecachebase(self):
     result = pykodi.execute_jsonrpc({
         "jsonrpc": "2.0",
         "id": 1,
         "method": "Settings.GetSettings",
         "params": {
             "filter": {
                 "category": "control",
                 "section": "services"
             }
         }
     })
     port = 80
     username = ''
     password = ''
     secure = False
     server_enabled = True
     if result.get('result', {}).get('settings'):
         for setting in result['result']['settings']:
             if setting[
                     'id'] == 'services.webserver' and not setting['value']:
                 server_enabled = False
                 break
             if setting['id'] == 'services.webserverusername':
                 username = setting['value']
             elif setting['id'] == 'services.webserverport':
                 port = setting['value']
             elif setting['id'] == 'services.webserverpassword':
                 password = setting['value']
             elif setting['id'] == 'services.webserverssl' and setting[
                     'value']:
                 secure = True
         username = '******'.format(
             username, password) if username and password else ''
     else:
         server_enabled = False
     if server_enabled:
         protocol = 'https' if secure else 'http'
         self.imagecachebase = '{0}://{1}localhost:{2}/image/'.format(
             protocol, username, port)
     else:
         self.imagecachebase = None
         log(L(REMOTE_CONTROL_REQUIRED), xbmc.LOGWARNING)
Ejemplo n.º 11
0
def get_movie_path_list(stackedpath):
    """Returns a list of filenames that can be used to find a movie's supporting files.
    The list includes the common base of all provided parts for stacked movies,
    and the parent directory of VIDEO_TS/BDMV. If neither applies, returns a list of one item,
    the original path. Check for the supporting files from each of these results.
    The first path can be used for creating files."""
    result = []
    if not stackedpath.startswith('stack://'):
        result = [stackedpath]
    else:
        firstpath, path2 = stackedpath[8:].split(' , ')[0:2]

        path, filename = split(firstpath)
        if filename:
            filename2 = basename(path2)
            for regex in moviestacking:
                offset = 0
                while True:
                    match = regex.match(filename, offset)
                    match2 = regex.match(filename2, offset)
                    if match is not None and match2 is not None and match.group(1).lower() == match2.group(1).lower():
                        if match.group(2).lower() == match2.group(2).lower():
                            offset = match.start(3)
                            continue
                        # DEPRECATED: Returning the path to part1 doesn't seem to work in Kodi.
                        #  Not sure where I got that idea, but it shouldn't be used.
                        # Also, AB created the ones missing `group(3)` for awhile, but it is wrong.
                        # Adding both here so that file scanning still finds them.
                        pathbase = path + get_pathsep(path) + filename[:offset] + match.group(1)
                        result = [
                            pathbase + match.group(3) + match.group(4),
                            pathbase + match.group(4),
                            firstpath]
                    break
        else: # folder stacking
            pass # I can't even get Kodi to add stacked VIDEO_TS rips period
        if not result:
            log("Couldn't get an unstacked path from \"{0}\"".format(stackedpath), xbmc.LOGWARNING)
            result = [firstpath]
    if parent_dir(result[0]) in ('VIDEO_TS', 'BDMV'):
        result.append(dirname(dirname(result[0])) + get_pathsep(result[0]) + basename(result[0]))
    return result
Ejemplo n.º 12
0
 def get_external_artwork(self,
                          mediatype,
                          seasons,
                          uniqueids,
                          missing=None):
     images = {}
     error = None
     for provider in providers.external.get(mediatype, ()):
         errcount = self.providererrors.get(provider.name, 0)
         if errcount == MAX_ERRORS:
             continue
         try:
             providerimages = provider.get_images(uniqueids, missing)
             self.providererrors[provider.name] = 0
         except Exception as ex:
             # gross. need to split "getting" and "parsing" then catch and wrap exceptions
             # on the latter, then leave most of this code back for "ProviderError" only
             errcount += 1
             self.providererrors[provider.name] = errcount
             if errcount != 1 and errcount != MAX_ERRORS:
                 continue
             error = {'providername': provider.name.display}
             if errcount == 1:  # notify on first error
                 error['message'] = getattr(ex, 'message', repr(ex))
             elif errcount == MAX_ERRORS:  # and on last error when we're no longer going to try this provider
                 error['message'] = L(TOO_MANY_ERRORS)
             if not isinstance(ex, ProviderError):
                 log("Error parsing provider response", xbmc.LOGWARNING)
                 log(traceback.format_exc(), xbmc.LOGWARNING)
             continue
         for arttype, artlist in providerimages.iteritems():
             if arttype.startswith('season.'):
                 season = arttype.rsplit('.', 2)[1]
                 if int(season) not in seasons:
                     # Don't add artwork for seasons we don't have
                     continue
             if arttype not in images:
                 images[arttype] = []
             images[arttype].extend(artlist)
         if self.monitor.abortRequested():
             break
     return images, error
Ejemplo n.º 13
0
def _rotate_file():
    newdate = ndate = pykodi.get_infolabel('System.Date(yyyy-mm-dd)')
    count = 0
    while _exists(newdate):
        count += 1
        newdate = ndate + '.' + str(count)
    if not xbmcvfs.copy(_get_filepath(), _get_filepath(newdate)):
        log("Could not copy latest report to new filename", xbmc.LOGWARNING, 'reporting')
        return False
    if not xbmcvfs.delete(_get_filepath()):
        log("Could not delete old copy of latest report", xbmc.LOGWARNING, 'reporting')
        return False

    # delete old reports
    _, files = xbmcvfs.listdir(settings.datapath)
    reportfiles = sorted(f[:-4] for f in files if f.startswith(REPORT_NAME))
    while len(reportfiles) > REPORT_COUNT:
        filename = reportfiles[0] + '.txt'
        if not xbmcvfs.delete(settings.datapath + filename):
            log("Could not delete old report '{0}'".format(filename), xbmc.LOGWARNING, 'reporting')
            return False
        del reportfiles[0]
    report_startup()
    return True
Ejemplo n.º 14
0
    def process_item(self, mediatype, dbid, mode):
        if self.processor_busy:
            return
        if mode == MODE_DEBUG:
            mode = MODE_AUTO
            self.set_debug(True)
        if mode == MODE_GUI:
            busy = pykodi.get_busydialog()
            busy.create()
        if mediatype in mediatypes.artinfo and (mediatype
                                                not in mediatypes.audiotypes
                                                or get_kodi_version() >= 18):
            mediaitem = info.MediaItem(
                quickjson.get_item_details(dbid, mediatype))
            log("Processing {0} '{1}' {2}.".format(
                mediatype, mediaitem.label,
                'automatically' if mode == MODE_AUTO else 'manually'))
        else:
            if mode == MODE_GUI:
                busy.close()
            xbmcgui.Dialog().notification(
                "Artwork Beef",
                L(NOT_SUPPORTED_MESSAGE).format(mediatype), '-', 6500)
            return

        self.init_run()
        if mediatype == mediatypes.EPISODE:
            series = quickjson.get_item_details(mediaitem.tvshowid,
                                                mediatypes.TVSHOW)
            if not any(uniqueid in settings.autoadd_episodes
                       for uniqueid in series['uniqueid'].itervalues()):
                mediaitem.skip_artwork = ['fanart']

        info.add_additional_iteminfo(mediaitem, self.processed, search)
        if not mediaitem.uniqueids and not mediatypes.only_filesystem(
                mediaitem.mediatype):
            if mediatype in mediatypes.require_manualid:
                self.manual_id(mediaitem)
        if mode == MODE_GUI:
            self._manual_item_process(mediaitem, busy)
        else:
            medialist = [mediaitem]
            if mediatype == mediatypes.TVSHOW and not mediatypes.disabled(
                    mediatypes.EPISODE):
                gen_epthumb = mediatypes.generatethumb(mediatypes.EPISODE)
                download_ep = mediatypes.downloadanyartwork(mediatypes.EPISODE)
                if mediaitem.uniqueids and any(
                        x in mediaitem.uniqueids.values()
                        for x in settings.autoadd_episodes):
                    medialist.extend(
                        info.MediaItem(ep)
                        for ep in quickjson.get_episodes(dbid))
                elif gen_epthumb or download_ep:
                    for episode in quickjson.get_episodes(dbid):
                        if gen_epthumb and not info.has_generated_thumbnail(episode) \
                        or download_ep and info.has_art_todownload(episode['art'], mediatypes.EPISODE):
                            episode = info.MediaItem(episode)
                            episode.skip_artwork = ['fanart']
                            medialist.append(episode)
            elif mediatype == mediatypes.ARTIST and not mediatypes.disabled(
                    mediatypes.ALBUM):
                medialist.extend(
                    info.MediaItem(album) for album in quickjson.get_albums(
                        mediaitem.label, mediaitem.dbid))
            if mediatype in (mediatypes.ALBUM, mediatypes.ARTIST) and not mediatypes.disabled(mediatypes.ALBUM) \
            and not mediatypes.disabled(mediatypes.SONG):
                medialist.extend(
                    info.MediaItem(song) for song in quickjson.get_songs(
                        mediaitem.mediatype, mediaitem.dbid))
            self.process_medialist(medialist, True)
Ejemplo n.º 15
0
            self.processor.close_progress()

def get_date():
    return pykodi.get_infolabel('System.Date(yyyy-mm-dd)')

def include_any_episode():
    return not mediatypes.disabled(mediatypes.EPISODE) \
        and (mediatypes.generatethumb(mediatypes.EPISODE) or mediatypes.downloadanyartwork(mediatypes.EPISODE) \
            or settings.autoadd_episodes)

def include_episode(episode):
    return mediatypes.generatethumb(mediatypes.EPISODE) and not info.item_has_generated_thumbnail(episode) \
        or info.has_art_todownload(episode.art, mediatypes.EPISODE)

def _buildsongs(albumgroup):
    result = {}
    if mediatypes.disabled(mediatypes.SONG):
        return result
    songfilter = {'field': 'album', 'operator': 'is',
        'value': [album.label for album in albumgroup]}
    for song in quickjson.get_songs(songfilter=songfilter):
        if song['albumid'] not in result:
            result[song['albumid']] = []
        result[song['albumid']].append(song)
    return result

if __name__ == '__main__':
    log('Service started', xbmc.LOGINFO)
    ArtworkService().run()
    log('Service stopped', xbmc.LOGINFO)
Ejemplo n.º 16
0
def notify_count(message, count):
    countmessage = message.format(count)
    log(countmessage, xbmc.LOGINFO)
    xbmcgui.Dialog().notification('Artwork Beef', countmessage)
Ejemplo n.º 17
0
 def log(self, message, level=xbmc.LOGDEBUG):
     if self.mediatype:
         log(message, level, tag='%s:%s' % (self.name.sort, self.mediatype))
     else:
         log(message, level, tag='%s' % self.name.sort)
Ejemplo n.º 18
0
    def _process_item(self, mediaitem, singleitem=False, auto=True):
        log("Processing {0} '{1}' automatically.".format(
            mediaitem.mediatype, mediaitem.label))
        mediatype = mediaitem.mediatype
        onlyfs = self.localmode or mediatypes.only_filesystem(
            mediaitem.mediatype)
        if not mediaitem.uniqueids and not onlyfs:
            mediaitem.missingid = True
            if singleitem:
                header = L(NO_IDS_MESSAGE)
                message = "{0} '{1}'".format(mediatype, mediaitem.label)
                log(header + ": " + message, xbmc.LOGNOTICE)
                xbmcgui.Dialog().notification("Artwork Beef: " + header,
                                              message,
                                              xbmcgui.NOTIFICATION_INFO)

        if auto:
            cleaned = get_simpledict_updates(mediaitem.art,
                                             cleaner.clean_artwork(mediaitem))
            if cleaned:
                if not self.debug:
                    add_art_to_library(mediatype, mediaitem.seasons,
                                       mediaitem.dbid, cleaned)
                mediaitem.art.update(cleaned)
                mediaitem.art = dict(item
                                     for item in mediaitem.art.iteritems()
                                     if item[1])

        mediaitem.missingart = list(
            info.iter_missing_arttypes(mediaitem, mediaitem.art))

        services_hit, error = self.gatherer.getartwork(mediaitem, onlyfs, auto)

        if auto:
            existingart = dict(mediaitem.art)
            selectedart = dict(
                (key, image['url'])
                for key, image in mediaitem.forcedart.iteritems())
            existingart.update(selectedart)

            # Then add the rest of the missing art
            selectedart.update(
                self.get_top_missing_art(
                    info.iter_missing_arttypes(mediaitem, existingart),
                    mediatype, existingart, mediaitem.availableart))

            selectedart = get_simpledict_updates(mediaitem.art, selectedart)
            mediaitem.selectedart = selectedart
            toset = dict(selectedart)
            if not self.localmode and mediatypes.downloadanyartwork(
                    mediaitem.mediatype):
                sh, er = self.downloader.downloadfor(mediaitem)
                services_hit = services_hit or sh
                error = error or er
                toset.update(mediaitem.downloadedart)
            if toset:
                mediaitem.updatedart = list(
                    set(mediaitem.updatedart + toset.keys()))
                if not self.debug:
                    add_art_to_library(mediatype, mediaitem.seasons,
                                       mediaitem.dbid, toset)
            self.cachelocal(mediaitem, toset)

        if error:
            if isinstance(error, dict):
                header = L(PROVIDER_ERROR_MESSAGE).format(
                    error['providername'])
                error = '{0}: {1}'.format(header, error['message'])
            mediaitem.error = error
            log(error, xbmc.LOGWARNING)
            self.notify_warning(error)
        elif auto and not self.debug and not self.localmode:
            if not (mediatype == mediatypes.EPISODE and 'fanart' in mediaitem.skip_artwork) and \
                    mediatype != mediatypes.SONG:
                self.processed.set_nextdate(
                    mediaitem.dbid, mediatype, mediaitem.label,
                    datetime_now() +
                    timedelta(days=self.get_nextcheckdelay(mediaitem)))
            if mediatype == mediatypes.TVSHOW:
                self.processed.set_data(mediaitem.dbid, mediatype,
                                        mediaitem.label, mediaitem.season)
        if mediaitem.borked_filename:
            msg = L(FILENAME_ENCODING_ERROR).format(mediaitem.file)
            if not mediaitem.error:
                mediaitem.error = msg
            log(msg, xbmc.LOGWARNING)
        if self.debug:
            log(mediaitem, xbmc.LOGNOTICE)
        return services_hit
Ejemplo n.º 19
0
 def downloadfor(self, mediaitem, allartwork=True):
     if self.fileerror_count >= FILEERROR_LIMIT:
         return False, ''
     if not info.can_saveartwork(mediaitem):
         return False, ''
     to_download = get_downloadable_art(mediaitem, allartwork)
     if not to_download:
         return False, ''
     services_hit = False
     error = ''
     localfiles = get_local_art(mediaitem, allartwork)
     for arttype, url in to_download.items():
         hostname = urlparse.urlparse(url).netloc
         if self.provider_errors.get(hostname, 0) >= PROVIDERERROR_LIMIT:
             continue
         full_basefilepath = info.build_artwork_basepath(mediaitem, arttype)
         if not full_basefilepath:
             continue
         if self.debug:
             mediaitem.downloadedart[arttype] = full_basefilepath + '.ext'
             continue
         result, err = self.doget(url)
         if err:
             error = err
             self.provider_errors[hostname] = self.provider_errors.get(
                 hostname, 0) + 1
             continue
         if not result:
             # 404 URL dead, wipe it so we can add another one later
             mediaitem.downloadedart[arttype] = None
             continue
         self.size += int(result.headers.get('content-length', 0))
         services_hit = True
         ext = get_file_extension(result.headers.get('content-type'), url)
         if not ext:
             log("Can't determine extension for '{0}'\nfor image type '{1}'"
                 .format(url, arttype))
             continue
         full_basefilepath += '.' + ext
         if xbmcvfs.exists(full_basefilepath):
             if extrafanart_name_used(full_basefilepath, localfiles):
                 # REVIEW: can this happen in any other circumstance?
                 full_basefilepath = get_next_filename(
                     full_basefilepath, localfiles)
                 localfiles.append(full_basefilepath)
             if xbmcvfs.exists(
                     full_basefilepath) and settings.recycle_removed:
                 recyclefile(full_basefilepath)
         else:
             folder = os.path.dirname(full_basefilepath)
             if not xbmcvfs.exists(folder):
                 xbmcvfs.mkdirs(folder)
         # For now this just downloads the whole thing in memory, then saves it to file.
         #  Maybe chunking it will be better when GIFs are handled
         file_ = xbmcvfs.File(full_basefilepath, 'wb')
         with closing(file_):
             if not file_.write(result.content):
                 self.fileerror_count += 1
                 raise FileError(
                     L(CANT_WRITE_TO_FILE).format(full_basefilepath))
             self.fileerror_count = 0
         mediaitem.downloadedart[arttype] = full_basefilepath
         log("downloaded '{0}'\nto image file '{1}'".format(
             url, full_basefilepath))
     return services_hit, error
Ejemplo n.º 20
0
def add_additional_iteminfo(mediaitem, processed, search=None):
    '''Get more data from the Kodi library, processed items, and look up web service IDs.'''
    if search and mediaitem.mediatype in search:
        search = search[mediaitem.mediatype]
    if mediaitem.mediatype == mediatypes.TVSHOW:
        # TODO: Split seasons out to separate items
        if not mediaitem.seasons:
            mediaitem.seasons, seasonart = _get_seasons_artwork(
                quickjson.get_seasons(mediaitem.dbid))
            mediaitem.art.update(seasonart)
        if search and settings.default_tvidsource == 'tmdb' and 'tvdb' not in mediaitem.uniqueids:
            # TODO: Set to the Kodi library if found
            resultids = search.get_more_uniqueids(mediaitem.uniqueids,
                                                  mediaitem.mediatype)
            if 'tvdb' in resultids:
                mediaitem.uniqueids['tvdb'] = resultids['tvdb']
    elif mediaitem.mediatype == mediatypes.SEASON:
        tvshow = quickjson.get_item_details(mediaitem.tvshowid,
                                            mediatypes.TVSHOW)
        mediaitem.file = tvshow['file']
    elif mediaitem.mediatype == mediatypes.EPISODE:
        if settings.default_tvidsource == 'tmdb':
            # TheMovieDB scraper sets episode IDs that can't be used in the API, but seriesID/season/episode works
            uniqueids = quickjson.get_item_details(
                mediaitem.tvshowid, mediatypes.TVSHOW)['uniqueid']
            uniqueid = uniqueids.get('tmdb', uniqueids.get('unknown'))
            if uniqueid:
                mediaitem.uniqueids['tmdbse'] = '{0}/{1}/{2}'.format(
                    uniqueid, mediaitem.season, mediaitem.episode)
    elif mediaitem.mediatype == mediatypes.MOVIESET:
        if not mediaitem.uniqueids.get('tmdb'):
            uniqueid = processed.get_data(mediaitem.dbid, mediaitem.mediatype,
                                          mediaitem.label)
            if search and not uniqueid and not mediatypes.only_filesystem(
                    mediaitem.mediatype):
                searchresults = search.search(mediaitem.label,
                                              mediaitem.mediatype)
                if searchresults:
                    for result in searchresults:
                        if result['label'] == mediaitem.label:
                            uniqueid = result['uniqueids']['tmdb']
                            break
                    uniqueid = searchresults[0]['uniqueids']['tmdb']
                if uniqueid:
                    processed.set_data(mediaitem.dbid, mediatypes.MOVIESET,
                                       mediaitem.label, uniqueid)
                else:
                    processed.set_data(mediaitem.dbid, mediatypes.MOVIESET,
                                       mediaitem.label, None)
                    mediaitem.error = L(CANT_FIND_MOVIESET)
                    log(
                        "Could not find set '{0}' on TheMovieDB".format(
                            mediaitem.label), xbmc.LOGNOTICE)

            mediaitem.uniqueids['tmdb'] = uniqueid
        if not processed.exists(mediaitem.dbid, mediaitem.mediatype,
                                mediaitem.label):
            _remove_set_movieposters(mediaitem)
        if settings.setartwork_fromparent and not mediaitem.file:
            _identify_parent_movieset(mediaitem)
    elif mediaitem.mediatype == mediatypes.MUSICVIDEO:
        if not mediaitem.uniqueids.get('mbtrack') or not mediaitem.uniqueids.get('mbgroup') \
                or not mediaitem.uniqueids.get('mbartist'):
            newdata = processed.get_data(mediaitem.dbid, mediaitem.mediatype,
                                         mediaitem.label)
            if newdata:
                mb_t, mb_al, mb_ar = newdata.split('/')
                mediaitem.uniqueids = {
                    'mbtrack': mb_t,
                    'mbgroup': mb_al,
                    'mbartist': mb_ar
                }
            elif search and not mediatypes.only_filesystem(
                    mediaitem.mediatype):
                results = search.search(mediaitem.label, mediatypes.MUSICVIDEO)
                uq = results and results[0].get('uniqueids')
                if uq and uq.get('mbtrack') and uq.get('mbgroup') and uq.get(
                        'mbartist'):
                    mediaitem.uniqueids = uq
                    processed.set_data(
                        mediaitem.dbid, mediatypes.MUSICVIDEO, mediaitem.label,
                        uq['mbtrack'] + '/' + uq['mbgroup'] + '/' +
                        uq['mbartist'])
                else:
                    processed.set_data(mediaitem.dbid, mediatypes.MUSICVIDEO,
                                       mediaitem.label, None)
                    mediaitem.error = L(CANT_FIND_MUSICVIDEO)
                    log(
                        "Could not find music video '{0}' on TheAudioDB".
                        format(mediaitem.label), xbmc.LOGNOTICE)
    elif mediaitem.mediatype == mediatypes.ALBUM:
        folders = _identify_album_folders(mediaitem)
        if folders:
            mediaitem.file, mediaitem.discfolders = folders
Ejemplo n.º 21
0
    def _manual_item_process(self, mediaitem, busy):
        self._process_item(mediaitem, True, False)
        busy.close()
        if mediaitem.availableart or mediaitem.forcedart:
            availableart = dict(mediaitem.availableart)
            if mediaitem.mediatype == mediatypes.TVSHOW and 'fanart' in availableart:
                # add unseasoned backdrops as manual-only options for each season fanart
                unseasoned_backdrops = [
                    dict(art) for art in availableart['fanart']
                    if not art.get('hasseason')
                ]
                if unseasoned_backdrops:
                    for season in mediaitem.seasons.keys():
                        key = 'season.{0}.fanart'.format(season)
                        if key in availableart:
                            availableart[key].extend(unseasoned_backdrops)
                        else:
                            availableart[key] = list(unseasoned_backdrops)
            if mediaitem.mediatype in (mediatypes.MOVIE, mediatypes.MOVIESET
                                       ) and 'poster' in availableart:
                # add no-language posters from TMDB as manual-only options for 'keyart'
                nolang_posters = [
                    dict(art) for art in availableart['poster']
                    if not art['language']
                ]
                for art in nolang_posters:
                    if art['provider'].sort == 'themoviedb.org':
                        if 'keyart' not in availableart:
                            availableart['keyart'] = []
                        availableart['keyart'].append(art)
            tag_forcedandexisting_art(availableart, mediaitem.forcedart,
                                      mediaitem.art)
            selectedarttype, selectedart = prompt_for_artwork(
                mediaitem.mediatype, mediaitem.label, availableart,
                self.monitor)
            if selectedarttype and selectedarttype not in availableart:
                self.manual_id(mediaitem)
                return
            if selectedarttype and selectedart:
                if mediatypes.get_artinfo(mediaitem.mediatype,
                                          selectedarttype)['multiselect']:
                    selectedart = info.fill_multiart(mediaitem.art,
                                                     selectedarttype,
                                                     selectedart)
                else:
                    selectedart = {selectedarttype: selectedart}

                selectedart = get_simpledict_updates(mediaitem.art,
                                                     selectedart)
                mediaitem.selectedart = selectedart
                toset = dict(selectedart)
                if settings.remove_deselected_files:
                    self.downloader.remove_deselected_files(mediaitem)
                if mediatypes.downloadanyartwork(mediaitem.mediatype):
                    try:
                        self.downloader.downloadfor(mediaitem, False)
                    except FileError as ex:
                        mediaitem.error = ex.message
                        log(ex.message, xbmc.LOGERROR)
                        xbmcgui.Dialog().notification(
                            "Artwork Beef", ex.message,
                            xbmcgui.NOTIFICATION_ERROR)
                    toset.update(mediaitem.downloadedart)
                if toset:
                    mediaitem.updatedart = toset.keys()
                    add_art_to_library(mediaitem.mediatype, mediaitem.seasons,
                                       mediaitem.dbid, toset)
                self.cachelocal(mediaitem, toset)

                reporting.report_item(mediaitem, True, True,
                                      self.downloader.size)
                if not mediaitem.error:
                    notifycount(len(toset))
        else:
            xbmcgui.Dialog().notification(
                L(NOT_AVAILABLE_MESSAGE),
                L(SOMETHING_MISSING) + ' ' + L(FINAL_MESSAGE), '-', 8000)
        self.finish_run()