def notifycount(count):
    log(L(ARTWORK_UPDATED_MESSAGE).format(count), xbmc.LOGINFO)
    if count:
        xbmcgui.Dialog().notification(L(ARTWORK_UPDATED_MESSAGE).format(count), L(FINAL_MESSAGE), '-', 7500)
    else:
        xbmcgui.Dialog().notification(L(NO_ARTWORK_UPDATED_MESSAGE),
            L(SOMETHING_MISSING) + ' ' + L(FINAL_MESSAGE), '-', 8000)
Example #2
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 both possible filenames for stacks, and the VIDEO_TS/BDMV parent directory.
    If neither applies, returns a list of one item, the original path.
    Check for the supporting files from each of these results."""
    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 != None and match2 != None and match.group(1).lower() == match2.group(1).lower():
                        if match.group(2).lower() == match2.group(2).lower():
                            offset = match.start(3)
                            continue
                        result = [firstpath, path + '/' + filename[:offset] + match.group(1).rstrip() + match.group(4)]
                    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.LOGINFO)
            result = [firstpath]
    if basename(dirname(result[0])) in ('VIDEO_TS', 'BDMV'):
        result.append(dirname(dirname(result[0])) + '/' + basename(result[0]))
    return result
    def process_medialist(self, medialist, alwaysnotify=False, stop_on_error=False):
        self.init_run(len(medialist) > 0)
        processed = {'tvshow': {}, 'movie': [], 'episode': []}
        artcount = 0
        currentitem = 0
        if medialist:
            gatherer = Gatherer(self.monitor, self.only_filesystem)
        for mediaitem in medialist:
            if not mediainfo.is_known_mediatype(mediaitem):
                continue
            log('Processing {0}'.format(mediaitem['label']), xbmc.LOGINFO)
            if self.visible:
                self.progress.update(currentitem * 100 // len(medialist), message=mediaitem['label'])
                currentitem += 1
            self.add_additional_iteminfo(mediaitem)
            cleaned = mediaitem.get_artwork_updates(cleaner.clean_artwork(mediaitem), mediaitem['art'])
            if cleaned:
                add_art_to_library(mediaitem['mediatype'], mediaitem.get('seasons'), mediaitem['dbid'], cleaned)
                mediaitem['art'].update(cleaned)
                mediaitem['art'] = dict(item for item in mediaitem['art'].iteritems() if item[1])
            forcedart, availableart, services_hit, error = gatherer.getartwork(mediaitem)
            if error:
                header = L(PROVIDER_ERROR_MESSAGE).format(error['providername'])
                xbmcgui.Dialog().notification(header, error['message'], xbmcgui.NOTIFICATION_WARNING)
                log('{0}\n{1}'.format(header, error['message']))
                if stop_on_error:
                    break
            else:
                add_processeditem(processed, mediaitem)
            for arttype, imagelist in availableart.iteritems():
                self.sort_images(arttype, imagelist, mediaitem['file'])
            existingart = dict(mediaitem['art'])
            # Remove existing local artwork if it is no longer available
            localart = [(arttype, image['url']) for arttype, image in forcedart.iteritems() \
                if not image['url'].startswith('http')]
            selectedart = dict((arttype, None) for arttype, url in existingart.iteritems() \
                if not url.startswith('http') and (arttype, url) not in localart)

            selectedart.update((key, image['url']) for key, image in forcedart.iteritems())
            selectedart = mediainfo.renumber_all_artwork(selectedart)

            existingart.update(selectedart)
            selectedart.update(self.get_top_missing_art(mediaitem['mediatype'], existingart, availableart, mediaitem.get('seasons')))

            selectedart = mediainfo.get_artwork_updates(mediaitem['art'], selectedart)
            if selectedart:
                add_art_to_library(mediaitem['mediatype'], mediaitem.get('seasons'), mediaitem['dbid'], selectedart)
                artcount += len(selectedart)
            if not services_hit:
                if self.monitor.abortRequested():
                    break
            elif self.monitor.waitForAbort(THROTTLE_TIME):
                break
        self.finish_run()
        if alwaysnotify or artcount:
            notifycount(artcount)
        return processed
 def _get_episodeid(self, episode):
     if 'unknown' in episode['uniqueid']:
         return episode['uniqueid']['unknown']
     else:
         idsource, result = episode['uniqueid'].iteritems()[0] if episode['uniqueid'] else '', ''
         if result:
             # I don't know what this might be, I'm not even sure Kodi can do anything else at the moment, but just in case
             log("Didn't find 'unknown' uniqueid for episode, just picked the first, from '%s'." % idsource, xbmc.LOGINFO)
         else:
             log("Didn't find a uniqueid for episode '%s', can't look it up. I expect the ID from TheTVDB, which generally comes from the scraper." % episode['label'], xbmc.LOGNOTICE)
         return result
Example #5
0
 def onNotification(self, sender, method, data):
     if method.startswith("Other."):
         if sender == "script.artwork.beef":
             message = 'Received notification "{0}"'.format(method)
             if data != "null":
                 message += " - data:\n" + data
             log(message, xbmc.LOGINFO)
         else:
             return
     if method == "Other.CancelCurrent":
         if self.status == STATUS_PROCESSING:
             self.abort = True
         elif self.signal:
             self.set_signal(None)
             self.processor.close_progress()
     elif method == "Other.ProcessNewItems":
         self.processor.create_progress()
         if addon.get_setting("lastalldate") == "0":
             self.set_signal("allitems")
         else:
             self.set_signal("unprocesseditems")
     elif method == "Other.ProcessAllItems":
         self.processor.create_progress()
         self.set_signal("allitems")
     elif method == "Other.ProcessAfterSettings":
         self.processaftersettings = True
     elif method == "Player.OnStop":
         if self.serviceenabled:
             data = json.loads(data)
             if self.watchitem(data):
                 self.stoppeditems.add((data["item"]["type"], data["item"]["id"]))
     elif method == "VideoLibrary.OnScanStarted":
         if self.serviceenabled and self.status == STATUS_PROCESSING:
             self.abort = True
     elif method == "VideoLibrary.OnScanFinished":
         if self.serviceenabled:
             self.set_signal("something")
     elif method == "VideoLibrary.OnUpdate":
         if not self.serviceenabled:
             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.toomany_recentitems:
             self.recentitems[data["item"]["type"]].append(data["item"]["id"])
         if not self.scanning:
             self.set_signal("something")
    def load(self):
        self.clear()
        if xbmcvfs.exists(self.filename):
            with closing(xbmcvfs.File(self.filename)) as jsonfile:
                try:
                    processed = json.load(jsonfile)
                except ValueError:
                    log("Had trouble loading ProcessedItems, starting fresh.", xbmc.LOGWARNING, tag="json")
                    return

                if processed.get("version") == self.version:
                    tvshows = processed.get("tvshow")
                    if isinstance(tvshows, dict):
                        self.tvshow = dict((int(tvshowid), seasons) for tvshowid, seasons in tvshows.iteritems())
                movies = processed.get("movie")
                if isinstance(movies, list):
                    self.movie = movies
                episodes = processed.get("episode")
                if isinstance(episodes, list):
                    self.episode = episodes
Example #7
0
def runon_allmedia(heading, countmessage, function):
    progress = xbmcgui.DialogProgressBG()
    progress.create(heading)
    monitor = xbmc.Monitor()

    steps_to_run = ((quickjson.get_movies, L(M.LISTING_ALL).format(L(M.MOVIES))),
            (quickjson.get_tvshows, L(M.LISTING_ALL).format(L(M.SERIES))),
            (quickjson.get_seasons, L(M.LISTING_ALL).format(L(M.SEASONS))),
            (quickjson.get_episodes, L(M.LISTING_ALL).format(L(M.EPISODES))))
    stepsize = 100 // len(steps_to_run)

    def update_art_for_items(items, start):
        changedcount = 0
        for i, item in enumerate(items):
            progress.update(start + i * stepsize // len(items))
            mediainfo.prepare_mediaitem(item)

            processed = function(item)
            processed = mediainfo.get_artwork_updates(item['art'], processed)
            if processed:
                mediainfo.update_art_in_library(item['mediatype'], item['dbid'], processed)
                changedcount += len(processed)
            if monitor.abortRequested():
                break
        return changedcount

    fixcount = 0
    for i, (listfunc, message) in enumerate(steps_to_run):
        start = i * stepsize
        progress.update(start, message=message)
        fixcount += update_art_for_items(listfunc(), start)
        if monitor.abortRequested():
            break
    progress.close()

    countmessage = countmessage.format(fixcount)
    log(countmessage, xbmc.LOGINFO)
    xbmcgui.Dialog().notification('Artwork Beef', countmessage)
Example #8
0
 def log(self, message, level=xbmc.LOGDEBUG):
     log(message, level, tag='%s.%s' % (self.name.sort, self.mediatype))
Example #9
0
                    series = quickjson.get_tvshow_details(episode["tvshowid"], tvshow_properties)
                if series["imdbnumber"] in autoaddepisodes:
                    addepisodesfrom.add(episode["tvshowid"])
                    newitems.append(episode)
                else:
                    ignoreepisodesfrom.add(episode["tvshowid"])
            if self.abortRequested():
                return

        self.reset_recent()
        processed = self.processor.process_medialist(newitems)
        self.processed.extend(processed)
        self.processed.save()

    def onSettingsChanged(self):
        self.serviceenabled = addon.get_setting("enableservice")
        self.only_filesystem = addon.get_setting("only_filesystem")
        mediatypes.update_settings()
        self.processor.update_settings()
        if self.processaftersettings:
            self.processor.create_progress()
            xbmc.sleep(200)
            self.processaftersettings = False
            self.set_signal("unprocesseditems")


if __name__ == "__main__":
    log("Service started", xbmc.LOGINFO)
    ArtworkService().run()
    log("Service stopped", xbmc.LOGINFO)
    def process_item(self, mediatype, dbid, mode):
        if self.processor_busy:
            return
        if mode == MODE_GUI:
            xbmc.executebuiltin('ActivateWindow(busydialog)')
        if mediatype == mediatypes.TVSHOW:
            mediaitem = quickjson.get_tvshow_details(dbid, tvshow_properties)
        elif mediatype == mediatypes.MOVIE:
            mediaitem = quickjson.get_movie_details(dbid, movie_properties)
        elif mediatype == mediatypes.EPISODE:
            mediaitem = quickjson.get_episode_details(dbid, episode_properties)
        else:
            xbmc.executebuiltin('Dialog.Close(busydialog)')
            xbmcgui.Dialog().notification("Artwork Beef", L(NOT_SUPPORTED_MESSAGE).format(mediatype), '-', 6500)
            return

        if mode == MODE_GUI:
            self.init_run()
            self.add_additional_iteminfo(mediaitem)
            gatherer = Gatherer(self.monitor, self.only_filesystem)
            forcedart, availableart, _, error = gatherer.getartwork(mediaitem, False)
            if error:
                header = L(PROVIDER_ERROR_MESSAGE).format(error['providername'])
                xbmcgui.Dialog().notification(header, error['message'], xbmcgui.NOTIFICATION_WARNING)
                log('{0}\n{1}'.format(header, error['message']))

            for arttype, imagelist in availableart.iteritems():
                self.sort_images(arttype, imagelist, mediaitem['file'])
            xbmc.executebuiltin('Dialog.Close(busydialog)')
            if availableart:
                if 'seasons' in mediaitem and 'fanart' in availableart:
                    for season in mediaitem['seasons'].keys():
                        unseasoned_backdrops = [dict(art) for art in availableart['fanart'] if not art.get('hasseason')]
                        key = 'season.{0}.fanart'.format(season)
                        if key in availableart:
                            availableart[key].extend(unseasoned_backdrops)
                        else:
                            availableart[key] = unseasoned_backdrops
                tag_forcedandexisting_art(availableart, forcedart, mediaitem['art'])
                selectedarttype, selectedart = prompt_for_artwork(mediaitem['mediatype'],
                    mediaitem['label'], availableart, self.monitor)
                if selectedarttype:
                    if selectedarttype.startswith('season.'):
                        gentype = selectedarttype.rsplit('.', 1)[1]
                        multiselect = mediatypes.artinfo[mediatypes.SEASON].get(gentype, {}).get('multiselect', False)
                    else:
                        multiselect = mediatypes.artinfo[mediaitem['mediatype']][selectedarttype]['multiselect']
                    if multiselect:
                        existingurls = [url for exacttype, url in mediaitem['art'].iteritems() \
                            if mediainfo.arttype_matches_base(exacttype, selectedarttype)]
                        urls_toset = [url for url in existingurls if url not in selectedart[1]]
                        urls_toset.extend([url for url in selectedart[0] if url not in urls_toset])
                        selectedart = dict(mediainfo.iter_renumbered_artlist(selectedart, selectedarttype, mediaitem['art'].keys()))
                    else:
                        selectedart = {selectedarttype: selectedart}

                    selectedart = mediainfo.get_artwork_updates(mediaitem['art'], selectedart)
                    if selectedart:
                        add_art_to_library(mediaitem['mediatype'], mediaitem.get('seasons'), mediaitem['dbid'], selectedart)
                    notifycount(len(selectedart))
            else:
                xbmcgui.Dialog().notification(L(NOT_AVAILABLE_MESSAGE),
                    L(SOMETHING_MISSING) + ' ' + L(FINAL_MESSAGE), '-', 8000)
            self.finish_run()
        else:
            medialist = [mediaitem]
            autoaddepisodes = addon.get_setting('autoaddepisodes_list') if addon.get_setting('episode.fanart') else ()
            if mediatype == mediatypes.TVSHOW and mediaitem['imdbnumber'] in autoaddepisodes:
                medialist.extend(quickjson.get_episodes(dbid, properties=episode_properties))
            self.process_medialist(medialist, True)