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_specific_arttypes():
    options = [
        (L(M.MOVIES), lambda: quickjson.get_item_list(mediatypes.MOVIE),
         mediatypes.MOVIE),
        (L(M.SERIES), quickjson.get_tvshows, mediatypes.TVSHOW),
        (L(M.SEASONS), quickjson.get_seasons, mediatypes.SEASON),
        (L(M.MOVIESETS), lambda: quickjson.get_item_list(mediatypes.MOVIESET),
         mediatypes.MOVIESET),
        (L(M.EPISODES), quickjson.get_episodes, mediatypes.EPISODE),
        (L(M.MUSICVIDEOS),
         lambda: quickjson.get_item_list(mediatypes.MUSICVIDEO),
         mediatypes.MUSICVIDEO)
    ]
    if get_kodi_version() >= 18:
        options.extend(
            ((L(M.ARTISTS), lambda: quickjson.get_item_list(mediatypes.ARTIST),
              mediatypes.ARTIST),
             (L(M.ALBUMS), lambda: quickjson.get_item_list(mediatypes.ALBUM),
              mediatypes.ALBUM),
             (L(M.SONGS), lambda: quickjson.get_item_list(mediatypes.SONG),
              mediatypes.SONG)))

    selected = xbmcgui.Dialog().select(L(
        M.REMOVE_SPECIFIC_TYPES), [option[0] + " ..." for option in options])
    if selected < 0 or selected >= len(options):
        return
    busy = pykodi.get_busydialog()
    busy.create()
    allitems = options[selected][1]()
    counter = {}
    types_to_remove = set()
    for arttype, url in chain.from_iterable(
            d.get('art', {}).iteritems() for d in allitems):
        if '.' in arttype: continue
        counter['* all'] = counter.get('* all', 0) + 1
        counter[arttype] = counter.get(arttype, 0) + 1
        if not info.keep_arttype(options[selected][2], arttype, url):
            types_to_remove.add(arttype)
            counter['* nowhitelist'] = counter.get('* nowhitelist', 0) + 1

    arttypes = sorted(counter.keys())
    busy.close()
    ftype = lambda intype: '* ' + ', '.join(sorted(
        types_to_remove)) if intype == '* nowhitelist' else intype
    selectedarttype = xbmcgui.Dialog().select(options[selected][0], [
        "{0}: {1}".format(ftype(arttype), counter[arttype])
        for arttype in arttypes
    ])
    if selectedarttype >= 0 and selectedarttype < len(arttypes):

        def removetypes(mediaitem):
            changedart = cleaner.remove_specific_arttype(
                mediaitem, arttypes[selectedarttype])
            info.remove_local_from_texturecache(
                (mediaitem.art[arttype] for arttype in changedart), True)
            return changedart

        fixcount = runon_medialist(removetypes, L(M.REMOVE_SPECIFIC_TYPES),
                                   allitems, options[selected][0])
        notify_count(L(M.REMOVED_ART_COUNT), fixcount)
Ejemplo n.º 3
0
def show_artwork_log():
    if pykodi.get_kodi_version() < 16:
        xbmcgui.Dialog().notification("Artwork Beef",
                                      L(M.VERSION_REQUIRED).format("Kodi 16"),
                                      xbmcgui.NOTIFICATION_INFO)
        return
    xbmcgui.Dialog().textviewer("Artwork Beef: " + L(M.REPORT_TITLE),
                                reporting.get_latest_report())
Ejemplo n.º 4
0
 def update_useragent(self):
     beefversion = pykodi.get_main_addon().version
     if pykodi.get_kodi_version() < 17:
         from lib.libs import quickjson
         props = quickjson.get_application_properties(['name', 'version'])
         appversion = '{0}.{1}'.format(props['version']['major'], props['version']['minor'])
         self.useragent = 'ArtworkBeef/{0} {1}/{2}'.format(beefversion, props['name'], appversion)
         return
     self.useragent = 'ArtworkBeef/{0} '.format(beefversion) + xbmc.getUserAgent()
Ejemplo n.º 5
0
 def init_run(self, show_progress=False, chunkcount=1):
     self.setlanguages()
     self.gatherer = Gatherer(self.monitor, self.autolanguages)
     self.downloader = FileManager(self.debug, chunkcount > 1)
     self.freshstart = str(datetime_now() - timedelta(days=365))
     self.chunkcount = chunkcount
     self.currentchunk = 0
     if get_kodi_version() >= 18:
         populate_musiccentraldir()
     if show_progress:
         self.create_progress()
Ejemplo n.º 6
0
def main():
    settings.update_settings()
    mediatypes.update_settings()
    command = get_command()
    if command.get('dbid') and command.get('mediatype'):
        processor = ArtworkProcessor()
        processor.process_item(command['mediatype'], int(command['dbid']),
                               command.get('mode', 'auto'))
    elif 'command' in command:
        if command['command'] == 'set_autoaddepisodes':
            set_autoaddepisodes()
        elif command['command'] == 'show_artwork_log':
            show_artwork_log()
        elif command['command'] == 'set_download_artwork' and command.get(
                'mediatype'):
            set_download_artwork(command['mediatype'])
    else:
        processor = ArtworkProcessor()
        if processor.processor_busy:
            options = [
                (L(M.STOP),
                 'NotifyAll(script.artwork.beef:control, CancelCurrent)')
            ]
        else:
            options = [
                (L(M.ADD_MISSING_FOR), add_missing_for),
                (L(M.NEW_LOCAL_FILES),
                 'NotifyAll(script.artwork.beef:control, ProcessLocalVideos)'),
                (L(M.IDENTIFY_UNMATCHED_SETS),
                 lambda: identify_unmatched(mediatypes.MOVIESET)),
                (L(M.IDENTIFY_UNMATCHED_MVIDS),
                 lambda: identify_unmatched(mediatypes.MUSICVIDEO)),
                (L(M.REMOVE_SPECIFIC_TYPES), remove_specific_arttypes),
                (L(M.MAKE_LOCAL), make_local),
                (L(M.CACHE_VIDEO_ARTWORK), cache_artwork)
            ]
            if get_kodi_version() >= 18:
                options.append(
                    (L(M.CACHE_MUSIC_ARTWORK), lambda: cache_artwork('music')))
                options.append(
                    (L(M.SAVE_ARTTYPES_TO_ASXML), save_arttypes_to_asxml))
                if advancedsettings.has_backup():
                    options.append((L(M.RESTORE_ASXML_BACKUP),
                                    advancedsettings.restore_backup))
        selected = xbmcgui.Dialog().select('Artwork Beef',
                                           [option[0] for option in options])
        if selected >= 0 and selected < len(options):
            action = options[selected][1]
            if isinstance(action, basestring):
                pykodi.execute_builtin(action)
            else:
                action()
Ejemplo n.º 7
0
def add_missing_for():
    options = [(L(M.FOR_NEW_VIDEOS), 'ProcessNewVideos'),
               (L(M.FOR_OLD_VIDEOS), 'ProcessNewAndOldVideos'),
               (L(M.FOR_ALL_VIDEOS), 'ProcessAllVideos')]
    if get_kodi_version() >= 18:
        options.extend(((L(M.FOR_NEW_AUDIO), 'ProcessNewMusic'),
                        (L(M.FOR_OLD_AUDIO), 'ProcessNewAndOldMusic'),
                        (L(M.FOR_ALL_AUDIO), 'ProcessAllMusic')))

    selected = xbmcgui.Dialog().select(L(M.ADD_MISSING_FOR),
                                       [option[0] for option in options])
    if selected >= 0 and selected < len(options):
        pykodi.execute_builtin(
            'NotifyAll(script.artwork.beef:control, {0})'.format(
                options[selected][1]))
Ejemplo n.º 8
0
def runon_medialist(function,
                    heading,
                    medialist='videos',
                    typelabel=None,
                    fg=False):
    progress = xbmcgui.DialogProgress() if fg else xbmcgui.DialogProgressBG()
    progress.create(heading)
    monitor = xbmc.Monitor()

    if medialist == 'videos':
        steps_to_run = [
            (lambda: quickjson.get_item_list(mediatypes.MOVIE), L(M.MOVIES)),
            (info.get_cached_tvshows, L(M.SERIES)),
            (quickjson.get_seasons, L(M.SEASONS)),
            (lambda: quickjson.get_item_list(mediatypes.MOVIESET),
             L(M.MOVIESETS)), (quickjson.get_episodes, L(M.EPISODES)),
            (lambda: quickjson.get_item_list(mediatypes.MUSICVIDEO),
             L(M.MUSICVIDEOS))
        ]
    elif medialist == 'music' and get_kodi_version() >= 18:
        steps_to_run = [
            (lambda: quickjson.get_item_list(mediatypes.ARTIST), L(M.ARTISTS)),
            (lambda: quickjson.get_item_list(mediatypes.ALBUM), L(M.ALBUMS)),
            (lambda: quickjson.get_item_list(mediatypes.SONG), L(M.SONGS))
        ]
    else:
        steps_to_run = ((lambda: medialist, typelabel), )
    stepsize = 100 // len(steps_to_run)

    def update_art_for_items(items, start):
        changedcount = 0
        for i, item in enumerate(items):
            if fg:
                progress.update(start + i * stepsize // len(items),
                                item['label'])
            else:
                progress.update(start + i * stepsize // len(items))
            item = info.MediaItem(item)
            if item.mediatype == mediatypes.SEASON:
                item.file = info.get_cached_tvshow(item.tvshowid)['file']
            updates = function(item)
            if isinstance(updates, int):
                changedcount += updates
            else:
                processed = utils.get_simpledict_updates(item.art, updates)
                if processed:
                    info.update_art_in_library(item.mediatype, item.dbid,
                                               processed)
                    changedcount += len(processed)
            if monitor.abortRequested() or fg and progress.iscanceled():
                break
        return changedcount

    fixcount = 0
    for i, (list_fn, listtype) in enumerate(steps_to_run):
        start = i * stepsize
        if fg:
            progress.update(start, line1=L(M.LISTING_ALL).format(listtype))
        else:
            progress.update(start, message=L(M.LISTING_ALL).format(listtype))
        fixcount += update_art_for_items(list_fn(), start)
        if monitor.abortRequested() or fg and progress.iscanceled():
            break

    info.clear_cache()
    progress.close()
    return fixcount
Ejemplo n.º 9
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.º 10
0
 def watchitem(self, data):
     can_use_data = 'item' in data and data['item'].get('id') and data['item'].get('id') != -1
     return can_use_data and 'playcount' not in data and data['item'].get('type') in self.recentvideos \
         and (pykodi.get_kodi_version() < 18 or data.get('added'))
Ejemplo n.º 11
0
 def onNotification(self, sender, method, data):
     if method.startswith('Other.') and sender != 'script.artwork.beef:control':
         return
     if method == 'Other.CancelCurrent':
         if self.status == STATUS_PROCESSING:
             self.abort = True
         elif self.signal:
             self.signal = None
             self.processor.close_progress()
     elif method == 'Other.ProcessNewVideos':
         self.processor.create_progress()
         self.signal = 'newvideos'
     elif method == 'Other.ProcessNewAndOldVideos':
         self.processor.create_progress()
         self.signal = 'oldvideos'
     elif method == 'Other.ProcessAllVideos':
         self.processor.create_progress()
         self.signal = 'allvideos'
     elif method == 'Other.ProcessLocalVideos':
         self.processor.create_progress()
         self.signal = 'localvideos'
     elif method == 'Other.ProcessAfterSettings':
         self.processaftersettings = True
     elif method == 'Player.OnStop':
         if settings.enableservice:
             data = json.loads(data)
             if self.watchitem(data):
                 self.stoppeditems.add((data['item']['type'], data['item']['id']))
     elif method == 'VideoLibrary.OnScanStarted':
         if settings.enableservice and self.status == STATUS_PROCESSING:
             self.abort = True
     elif method == 'VideoLibrary.OnScanFinished':
         if settings.enableservice:
             scan_olditems = settings.enable_olditem_updates and get_date() > self.last_videoupdate
             self.signal = 'oldvideos' if scan_olditems else 'newvideos'
             self.processor.create_progress()
     elif method == 'VideoLibrary.OnUpdate':
         if not settings.enableservice:
             return
         data = json.loads(data)
         if not self.watchitem(data):
             return
         if (data['item']['type'], data['item']['id']) in self.stoppeditems:
             self.stoppeditems.remove((data['item']['type'], data['item']['id']))
             return
         if not self.scanning:
             self.recentvideos[data['item']['type']].append(data['item']['id'])
             self.signal = 'recentvideos'
     elif pykodi.get_kodi_version() >= 18:
         if method == 'AudioLibrary.OnScanFinished':
             if settings.enableservice_music:
                 scan_olditems = settings.enable_olditem_updates and get_date() > self.last_musicupdate
                 self.signal = 'oldmusic' if scan_olditems else 'newmusic'
         elif method == 'Other.ProcessNewMusic':
             self.processor.create_progress()
             self.signal = 'newmusic'
         elif method == 'Other.ProcessNewAndOldMusic':
             self.processor.create_progress()
             self.signal = 'oldmusic'
         elif method == 'Other.ProcessAllMusic':
             self.processor.create_progress()
             self.signal = 'allmusic'
Ejemplo n.º 12
0
def _upgradeproperties():
    if get_kodi_version() < 17:
        typemap[mediatypes.TVSHOW][1].remove('uniqueid')
        typemap[mediatypes.MOVIE][1].remove('premiered')
        typemap[mediatypes.MOVIE][1].remove('uniqueid')
        typemap[mediatypes.MOVIE][1].append('year')
Ejemplo n.º 13
0
def _needupgrade(mediatype):
    return mediatype in (mediatypes.MOVIE,
                         mediatypes.TVSHOW) and get_kodi_version() < 17
Ejemplo n.º 14
0
def get_seasons(tvshow_id=-1):
    if tvshow_id == -1 and pykodi.get_kodi_version() < 17:
        return _get_all_seasons_jarvis()
    else:
        return _inner_get_seasons(tvshow_id)