def __init__(self, kodidb=None):
     """Initialize - optionaly provide KodiDb object"""
     if not kodidb:
         from kodidb import KodiDb
         self.kodidb = KodiDb()
     else:
         self.kodidb = kodidb
Exemplo n.º 2
0
class Imdb(object):
    """Info from IMDB (currently only top250)"""
    def __init__(self, simplecache=None, kodidb=None):
        """Initialize - optionaly provide simplecache object"""
        if not simplecache:
            from simplecache import SimpleCache
            self.cache = SimpleCache()
        else:
            self.cache = simplecache
        if not kodidb:
            if sys.version_info.major == 3:
                from .kodidb import KodiDb
            else:
                from kodidb import KodiDb
            self.kodidb = KodiDb()
        else:
            self.kodidb = kodidb

    @use_cache(2)
    def get_top250_rating(self, imdb_id):
        """get the top250 rating for the given imdbid"""
        return {"IMDB.Top250": self.get_top250_db().get(imdb_id, 0)}

    @use_cache(7)
    def get_top250_db(self):
        """
            get the top250 listing for both movies and tvshows as dict with imdbid as key
            uses 7 day cache to prevent overloading the server
        """
        results = {}
        for listing in [("top", "chttp_tt_"), ("toptv", "chttvtp_tt_")]:
            html = requests.get("http://www.imdb.com/chart/%s" % listing[0],
                                headers={'User-agent': 'Mozilla/5.0'},
                                timeout=20)
            soup = BeautifulSoup.BeautifulSoup(html.text,
                                               features="html.parser")
            for table in soup.findAll('table'):
                if table.get("class") == "chart full-width":
                    for td_def in table.findAll('td'):
                        if td_def.get("class") == "titleColumn":
                            a_link = td_def.find("a")
                            if a_link:
                                url = a_link["href"]
                                imdb_id = url.split("/")[2]
                                imdb_rank = url.split(listing[1])[1]
                                results[imdb_id] = try_parse_int(imdb_rank)
        self.write_kodidb(results)
        return results

    def write_kodidb(self, results):
        """store the top250 position in kodi database to access it with ListItem.Top250"""
        for imdb_id in results:
            kodi_movie = self.kodidb.movie_by_imdbid(imdb_id)
            if kodi_movie:
                params = {
                    "movieid": kodi_movie["movieid"],
                    "top250": results[imdb_id]
                }
                self.kodidb.set_json('VideoLibrary.SetMovieDetails', params)
 def __init__(self, kodidb=None):
     """Initialize - optionaly provide KodiDb object"""
     if not kodidb:
         if sys.version_info.major == 3:
             from .kodidb import KodiDb
         else:
             from kodidb import KodiDb
         self.kodidb = KodiDb()
     else:
         self.kodidb = kodidb
Exemplo n.º 4
0
 def __init__(self, simplecache=None, kodidb=None):
     '''Initialize - optionaly provide simplecache object'''
     if not simplecache:
         from simplecache import SimpleCache
         self.cache = SimpleCache()
     else:
         self.cache = simplecache
     if not kodidb:
         from kodidb import KodiDb
         self.kodidb = KodiDb(self.cache)
     else:
         self.kodidb = kodidb
Exemplo n.º 5
0
    def __init__(self, simplecache=None, kodidb=None):
        """Initialize - optionaly provide SimpleCache and KodiDb object"""

        if not kodidb:
            from kodidb import KodiDb
            self.kodidb = KodiDb()
        else:
            self.kodidb = kodidb

        if not simplecache:
            from simplecache import SimpleCache
            self.cache = SimpleCache()
        else:
            self.cache = simplecache
 def __init__(self, simplecache=None, kodidb=None):
     """Initialize - optionaly provide simplecache object"""
     if not simplecache:
         from simplecache import SimpleCache
         self.cache = SimpleCache()
     else:
         self.cache = simplecache
     if not kodidb:
         if sys.version_info.major == 3:
             from .kodidb import KodiDb
         else:
             from kodidb import KodiDb
         self.kodidb = KodiDb()
     else:
         self.kodidb = kodidb
Exemplo n.º 7
0
class Albums(object):
    def __init__(self, addon, options):
        self.addon = addon
        self.options = options
        self.kodidb = KodiDb()

    def search(self):
        '''search for albums that match a given string'''
        if 'artistid' in self.options:
            all_items = self.kodidb.albums(self.options['artistid'])
        else:
            all_items = self.kodidb.albums()
        return process_method_on_list(self.process_album, all_items)

    def process_album(self, item):
        '''transform the json received from kodi into something we can use'''
        item['file'] = 'musicdb://albums/%s' % item['albumid']
        item['isFolder'] = True
        return item
Exemplo n.º 8
0
class Songs(object):
    def __init__(self, addon, options):
        self.addon = addon
        self.options = options
        self.kodidb = KodiDb()

    def search(self):
        '''search for songs that match a given string'''
        if 'artistid' in self.options:
            all_items = self.kodidb.songs(self.options['artistid'])
        else:
            all_items = self.kodidb.songs()
        return process_method_on_list(self.process_song, all_items)

    def process_song(self, item):
        '''transform the json received from kodi into something we can use'''
        # Not the real file -- abusing this to get at the song id
        item['file'] = 'musicdb://songs/%s' % item['songid']
        return item
Exemplo n.º 9
0
class Movies(object):
    def __init__(self, addon, options):
        self.addon = addon
        self.options = options
        self.kodidb = KodiDb()

    def search(self):
        '''search for movies that match a given string'''
        all_items = self.kodidb.movies()
        return process_method_on_list(self.process_movie, all_items)

    def process_movie(self, item):
        '''transform the json received from kodi into something we can use'''
        return item
Exemplo n.º 10
0
    def __init__(self, simplecache=None, kodidb=None):
        '''Initialize - optionaly provide SimpleCache and KodiDb object'''

        if not kodidb:
            from kodidb import KodiDb
            self.kodidb = KodiDb()
        else:
            self.kodidb = kodidb

        if not simplecache:
            from simplecache import SimpleCache
            self.cache = SimpleCache()
        else:
            self.cache = simplecache
Exemplo n.º 11
0
class Addons(object):
    def __init__(self, addon, options):
        self.addon = addon
        self.options = options
        self.kodidb = KodiDb()

    def search(self):
        '''search for addons that match a given string'''
        all_items = self.kodidb.addons()
        return process_method_on_list(self.process_addon, all_items)

    def process_addon(self, item):
        '''transform the json received from kodi into something we can use'''
        item['label'] = item['name']
        # abusing this to get at the addon id..
        item['file'] = item['addonid']
        return item
class ChannelLogos(object):
    """get channellogo"""
    def __init__(self, kodidb=None):
        """Initialize - optionaly provide KodiDb object"""
        if not kodidb:
            if sys.version_info.major == 3:
                from .kodidb import KodiDb
            else:
                from kodidb import KodiDb
            self.kodidb = KodiDb()
        else:
            self.kodidb = kodidb

    def get_channellogo(self, channelname):
        """get channellogo for the supplied channelname"""
        result = {}
        for searchmethod in [self.search_kodi]:
            if result:
                break
            result = searchmethod(channelname)
        return result

    def search_kodi(self, searchphrase):
        """search kodi json api for channel logo"""
        result = ""
        if xbmc.getCondVisibility("PVR.HasTVChannels"):
            results = self.kodidb.get_json('PVR.GetChannels',
                                           fields=["thumbnail"],
                                           returntype="tvchannels",
                                           optparam=("channelgroupid",
                                                     "alltv"))
            for item in results:
                if item["label"] == searchphrase:
                    channelicon = get_clean_image(item['thumbnail'])
                    if channelicon and xbmcvfs.exists(channelicon):
                        result = channelicon
                        break
        return result
Exemplo n.º 13
0
def detect_plugin_content(plugin_path):
    '''based on the properties of a vfspath we try to detect the content type'''
    content_type = ""
    if not plugin_path:
        return ""
    # detect content based on the path
    if "listing" in plugin_path:
        content_type = "folder"
    elif "movie" in plugin_path.lower():
        content_type = "movies"
    elif "album" in plugin_path.lower():
        content_type = "albums"
    elif "show" in plugin_path.lower():
        content_type = "tvshows"
    elif "episode" in plugin_path.lower():
        content_type = "episodes"
    elif "song" in plugin_path.lower():
        content_type = "songs"
    elif "musicvideo" in plugin_path.lower():
        content_type = "musicvideos"
    elif "pvr" in plugin_path.lower():
        content_type = "pvr"
    elif "type=dynamic" in plugin_path.lower():
        content_type = "movies"
    elif "videos" in plugin_path.lower():
        content_type = "movies"
    elif "type=both" in plugin_path.lower():
        content_type = "movies"
    elif "media" in plugin_path.lower():
        content_type = "movies"
    elif "favourites" in plugin_path.lower():
        content_type = "movies"
    elif ("box" in plugin_path.lower() or "dvd" in plugin_path.lower()
          or "rentals" in plugin_path.lower()
          or "incinemas" in plugin_path.lower()
          or "comingsoon" in plugin_path.lower()
          or "upcoming" in plugin_path.lower()
          or "opening" in plugin_path.lower()
          or "intheaters" in plugin_path.lower()):
        content_type = "movies"
    # if we didn't get the content based on the path, we need to probe the addon...
    if not content_type and not xbmc.getCondVisibility(
            "Window.IsMedia"):  # safety check
        from kodidb import KodiDb
        media_array = KodiDb().files(plugin_path, limits=(0, 1))
        for item in media_array:
            if item.get("filetype", "") == "directory":
                content_type = "folder"
                break
            elif item.get("type") and item["type"] != "unknown":
                content_type = item["type"] + "s"
                break
            elif "showtitle" not in item and "artist" not in item:
                # these properties are only returned in the json response if we're looking at actual file content...
                # if it's missing it means this is a main directory listing and no need to
                # scan the underlying listitems.
                content_type = "files"
                break
            if "showtitle" not in item and "artist" in item:
                # AUDIO ITEMS
                if item["type"] == "artist":
                    content_type = "artists"
                    break
                elif (isinstance(item["artist"], list)
                      and len(item["artist"]) > 0
                      and item["artist"][0] == item["title"]):
                    content_type = "artists"
                    break
                elif item["type"] == "album" or item["album"] == item["title"]:
                    content_type = "albums"
                    break
                elif ((item["type"] == "song"
                       and "play_album" not in item["file"])
                      or (item["artist"] and item["album"])):
                    content_type = "songs"
                    break
            else:
                # VIDEO ITEMS
                if item["showtitle"] and not item.get("artist"):
                    # this is a tvshow, episode or season...
                    if item["type"] == "season" or (item["season"] > -1
                                                    and item["episode"] == -1):
                        content_type = "seasons"
                        break
                    elif item["type"] == "episode" or item[
                            "season"] > -1 and item["episode"] > -1:
                        content_type = "episodes"
                        break
                    else:
                        content_type = "tvshows"
                        break
                elif item.get("artist"):
                    # this is a musicvideo!
                    content_type = "musicvideos"
                    break
                elif (item["type"] == "movie" or item.get("imdbnumber")
                      or item.get("mpaa") or item.get("trailer")
                      or item.get("studio")):
                    content_type = "movies"
                    break
        log_msg("detect_plugin_path_content for: %s  - result: %s" %
                (plugin_path, content_type))
    return content_type
Exemplo n.º 14
0
class AnimatedArt(object):
    '''get animated artwork'''
    ignore_cache = False

    def __init__(self, simplecache=None, kodidb=None):
        '''Initialize - optionaly provide SimpleCache and KodiDb object'''

        if not kodidb:
            from kodidb import KodiDb
            self.kodidb = KodiDb()
        else:
            self.kodidb = kodidb

        if not simplecache:
            from simplecache import SimpleCache
            self.cache = SimpleCache()
        else:
            self.cache = simplecache

    @use_cache(14)
    def get_animated_artwork(self, imdb_id, manual_select=False, ignore_cache=False):
        '''returns all available animated art for the given imdbid/tmdbid'''
        # prefer local result
        kodi_movie = self.kodidb.movie_by_imdbid(imdb_id)
        if not manual_select and kodi_movie and kodi_movie["art"].get("animatedposter"):
            result = {
                "animatedposter": kodi_movie["art"].get("animatedposter"),
                "animatedfanart": kodi_movie["art"].get("animatedfanart")
            }
        else:
            result = {
                "animatedposter": self.poster(imdb_id, manual_select),
                "animatedfanart": self.fanart(imdb_id, manual_select),
                "imdb_id": imdb_id
            }
            self.write_kodidb(result)
        log_msg("get_animated_artwork for imdbid: %s - result: %s" % (imdb_id, result))
        return result

    def poster(self, imdb_id, manual_select=False):
        '''return preferred animated poster, optionally show selectdialog for manual selection'''
        img = self.select_art(self.posters(imdb_id), manual_select, "poster")
        return self.process_image(img, "poster", imdb_id)

    def fanart(self, imdb_id, manual_select=False):
        '''return preferred animated fanart, optionally show selectdialog for manual selection'''
        img = self.select_art(self.fanarts(imdb_id), manual_select, "fanart")
        return self.process_image(img, "fanart", imdb_id)

    def posters(self, imdb_id):
        '''return all animated posters for the given imdb_id (imdbid can also be tmdbid)'''
        return self.get_art(imdb_id, "posters")

    def fanarts(self, imdb_id):
        '''return animated fanarts for the given imdb_id (imdbid can also be tmdbid)'''
        return self.get_art(imdb_id, "fanarts")

    def get_art(self, imdb_id, art_type):
        '''get the artwork'''
        art_db = self.get_animatedart_db()
        if art_db.get(imdb_id):
            return art_db[imdb_id][art_type]
        return []

    def get_animatedart_db(self):
        '''get the full animated art database as dict with imdbid and tmdbid as key
        uses 7 day cache to prevent overloading the server'''
        # get all animated posters from the online json file
        cache = self.cache.get("animatedartdb")
        if cache:
            return cache
        art_db = {}
        data = get_json('http://www.consiliumb.com/animatedgifs/movies.json', None)
        base_url = data.get("baseURL", "")
        if data and data.get('movies'):
            for item in data['movies']:
                for db_id in ["imdbid", "tmdbid"]:
                    key = item[db_id]
                    art_db[key] = {"posters": [], "fanarts": []}
                    for entry in item['entries']:
                        entry_new = {
                            "contributedby": entry["contributedBy"],
                            "dateadded": entry["dateAdded"],
                            "language": entry["language"],
                            "source": entry["source"],
                            "image": "%s/%s" % (base_url, entry["image"].replace(".gif", "_original.gif")),
                            "thumb": "%s/%s" % (base_url, entry["image"])}
                        if entry['type'] == 'poster':
                            art_db[key]["posters"].append(entry_new)
                        elif entry['type'] == 'background':
                            art_db[key]["fanarts"].append(entry_new)
            self.cache.set("animatedartdb", art_db, expiration=timedelta(days=7))
        return art_db

    @staticmethod
    def select_art(items, manual_select=False, art_type=""):
        '''select the preferred image from the list'''
        image = None
        if manual_select:
            # show selectdialog to manually select the item
            results_list = []
            # add none and browse entries
            listitem = xbmcgui.ListItem(label=xbmc.getLocalizedString(231), iconImage="DefaultAddonNone.png")
            results_list.append(listitem)
            listitem = xbmcgui.ListItem(label=xbmc.getLocalizedString(1030), iconImage="DefaultFolder.png")
            results_list.append(listitem)
            for item in items:
                labels = [item["contributedby"], item["dateadded"], item["language"], item["source"]]
                label = " / ".join(labels)
                listitem = xbmcgui.ListItem(label=label, iconImage=item["thumb"])
                results_list.append(listitem)
            if manual_select and results_list:
                dialog = DialogSelect("DialogSelect.xml", "", listing=results_list, window_title=art_type)
                dialog.doModal()
                selected_item = dialog.result
                del dialog
                if selected_item == 0:
                    image = ""
                if selected_item == 1:
                    # browse for image
                    dialog = xbmcgui.Dialog()
                    image = dialog.browse(2, xbmc.getLocalizedString(1030), 'files', mask='.gif').decode("utf-8")
                    del dialog
                elif selected_item > 1:
                    # user has selected an image from online results
                    image = items[selected_item - 2]["image"]
        elif items:
            # just grab the first item as best match
            image = items[0]["image"]
        return image

    @staticmethod
    def process_image(image_url, art_type, imdb_id):
        '''animated gifs need to be stored locally, otherwise they won't work'''
        # make sure that our local path for the gif images exists
        addon = xbmcaddon.Addon(ADDON_ID)
        gifs_path = "%sanimatedgifs/" % addon.getAddonInfo('profile')
        del addon
        if not xbmcvfs.exists(gifs_path):
            xbmcvfs.mkdirs(gifs_path)
        # only process existing images
        if not image_url or not xbmcvfs.exists(image_url):
            return None
        # copy the image to our local path and return the new path as value
        local_filename = "%s%s_%s.gif" % (gifs_path, imdb_id, art_type)
        if xbmcvfs.exists(local_filename):
            xbmcvfs.delete(local_filename)
        # we don't use xbmcvfs.copy because we want to wait for the action to complete
        img = xbmcvfs.File(image_url)
        img_data = img.readBytes()
        img.close()
        img = xbmcvfs.File(local_filename, 'w')
        img.write(img_data)
        img.close()
        return local_filename

    def write_kodidb(self, artwork):
        '''store the animated artwork in kodi database to access it with ListItem.Art(animatedartX)'''
        kodi_movie = self.kodidb.movie_by_imdbid(artwork["imdb_id"])
        if kodi_movie:
            params = {
                "movieid": kodi_movie["movieid"],
                "art": {"animatedfanart": artwork["animatedfanart"], "animatedposter": artwork["animatedposter"]}
            }
            self.kodidb.set_json('VideoLibrary.SetMovieDetails', params)
Exemplo n.º 15
0
 def __init__(self, addon, options):
     self.addon = addon
     self.options = options
     self.kodidb = KodiDb()
class ChannelLogos(object):
    """get channellogo"""
    def __init__(self, kodidb=None):
        """Initialize - optionaly provide KodiDb object"""
        if not kodidb:
            from kodidb import KodiDb
            self.kodidb = KodiDb()
        else:
            self.kodidb = kodidb

    def get_channellogo(self, channelname):
        """get channellogo for the supplied channelname"""
        result = {}
        for searchmethod in [self.search_kodi, self.search_logosdb]:
            if result:
                break
            result = searchmethod(channelname)
        return result

    def search_logosdb(self, searchphrase):
        """search logo on thelogosdb"""
        result = ""
        for searchphrase in [
                searchphrase,
                searchphrase.lower().replace(" hd", "")
        ]:
            if result:
                break
            for item in self.get_data_from_logosdb(searchphrase):
                img = item['strLogoWide']
                if img:
                    if ".jpg" in img or ".png" in img:
                        result = img
                        break
        return result

    def search_kodi(self, searchphrase):
        """search kodi json api for channel logo"""
        result = ""
        if xbmc.getCondVisibility("PVR.HasTVChannels"):
            results = self.kodidb.get_json('PVR.GetChannels',
                                           fields=["thumbnail"],
                                           returntype="tvchannels",
                                           optparam=("channelgroupid",
                                                     "alltv"))
            for item in results:
                if item["label"] == searchphrase:
                    channelicon = get_clean_image(item['thumbnail'])
                    if channelicon and xbmcvfs.exists(channelicon):
                        result = channelicon
                        break
        return result

    @staticmethod
    def get_data_from_logosdb(searchphrase):
        """helper method to get data from thelogodb json API"""
        params = {"s": searchphrase}
        data = get_json(
            'http://www.thelogodb.com/api/json/v1/3241/tvchannel.php', params)
        if data and data.get('channels'):
            return data["channels"]
        else:
            return []
Exemplo n.º 17
0
class AnimatedArt(object):
    '''get animated artwork'''
    ignore_cache = False

    def __init__(self, simplecache=None, kodidb=None):
        '''Initialize - optionaly provide SimpleCache and KodiDb object'''

        if not kodidb:
            from kodidb import KodiDb
            self.kodidb = KodiDb()
        else:
            self.kodidb = kodidb

        if not simplecache:
            from simplecache import SimpleCache
            self.cache = SimpleCache()
        else:
            self.cache = simplecache

    @use_cache(14)
    def get_animated_artwork(self,
                             imdb_id,
                             manual_select=False,
                             ignore_cache=False):
        '''returns all available animated art for the given imdbid/tmdbid'''
        # no cache so grab the results
        result = {
            "animatedposter": self.poster(imdb_id, manual_select),
            "animatedfanart": self.fanart(imdb_id, manual_select),
            "imdb_id": imdb_id
        }
        self.write_kodidb(result)
        log_msg("get_animated_artwork for imdbid: %s - result: %s" %
                (imdb_id, result))
        return result

    def poster(self, imdb_id, manual_select=False):
        '''return preferred animated poster, optionally show selectdialog for manual selection'''
        img = self.select_art(self.posters(imdb_id), manual_select, "poster")
        return self.process_image(img, "poster", imdb_id)

    def fanart(self, imdb_id, manual_select=False):
        '''return preferred animated fanart, optionally show selectdialog for manual selection'''
        img = self.select_art(self.fanarts(imdb_id), manual_select, "fanart")
        return self.process_image(img, "fanart", imdb_id)

    def posters(self, imdb_id):
        '''return all animated posters for the given imdb_id (imdbid can also be tmdbid)'''
        return self.get_art(imdb_id, "posters")

    def fanarts(self, imdb_id):
        '''return animated fanarts for the given imdb_id (imdbid can also be tmdbid)'''
        return self.get_art(imdb_id, "fanarts")

    def get_art(self, imdb_id, art_type):
        '''get the artwork'''
        art_db = self.get_animatedart_db()
        if art_db.get(imdb_id):
            return art_db[imdb_id][art_type]
        return []

    def get_animatedart_db(self):
        '''get the full animated art database as dict with imdbid and tmdbid as key
        uses 7 day cache to prevent overloading the server'''
        # get all animated posters from the online json file
        cache = self.cache.get("animatedartdb")
        if cache:
            return cache
        art_db = {}
        data = get_json('http://www.consiliumb.com/animatedgifs/movies.json',
                        None)
        base_url = data.get("baseURL", "")
        if data and data.get('movies'):
            for item in data['movies']:
                for db_id in ["imdbid", "tmdbid"]:
                    key = item[db_id]
                    art_db[key] = {"posters": [], "fanarts": []}
                    for entry in item['entries']:
                        entry_new = {
                            "contributedby":
                            entry["contributedBy"],
                            "dateadded":
                            entry["dateAdded"],
                            "language":
                            entry["language"],
                            "source":
                            entry["source"],
                            "image":
                            "%s/%s" % (base_url, entry["image"].replace(
                                ".gif", "_original.gif")),
                            "thumb":
                            "%s/%s" % (base_url, entry["image"])
                        }
                        if entry['type'] == 'poster':
                            art_db[key]["posters"].append(entry_new)
                        elif entry['type'] == 'background':
                            art_db[key]["fanarts"].append(entry_new)
            self.cache.set("animatedartdb",
                           art_db,
                           expiration=timedelta(days=7))
        return art_db

    @staticmethod
    def select_art(items, manual_select=False, art_type=""):
        '''select the preferred image from the list'''
        image = None
        if manual_select:
            # show selectdialog to manually select the item
            results_list = []
            # add none and browse entries
            listitem = xbmcgui.ListItem(label=xbmc.getLocalizedString(231),
                                        iconImage="DefaultAddonNone.png")
            results_list.append(listitem)
            listitem = xbmcgui.ListItem(label=xbmc.getLocalizedString(1030),
                                        iconImage="DefaultFolder.png")
            results_list.append(listitem)
            for item in items:
                labels = [
                    item["contributedby"], item["dateadded"], item["language"],
                    item["source"]
                ]
                label = " / ".join(labels)
                listitem = xbmcgui.ListItem(label=label,
                                            iconImage=item["thumb"])
                results_list.append(listitem)
            if manual_select and results_list:
                dialog = DialogSelect("DialogSelect.xml",
                                      "",
                                      listing=results_list,
                                      window_title=art_type)
                dialog.doModal()
                selected_item = dialog.result
                del dialog
                if selected_item == 1:
                    # browse for image
                    dialog = xbmcgui.Dialog()
                    image = dialog.browse(2,
                                          xbmc.getLocalizedString(1030),
                                          'files',
                                          mask='.gif').decode("utf-8")
                    del dialog
                elif selected_item > 1:
                    # user has selected an image from online results
                    image = items[selected_item - 2]["image"]
        elif items:
            # just grab the first item as best match
            image = items[0]["image"]
        return image

    @staticmethod
    def process_image(image_url, art_type, imdb_id):
        '''animated gifs need to be stored locally, otherwise they won't work'''
        # make sure that our local path for the gif images exists
        addon = xbmcaddon.Addon(ADDON_ID)
        gifs_path = "%s/animatedgifs/" % addon.getAddonInfo('profile')
        del addon
        if not xbmcvfs.exists(gifs_path):
            xbmcvfs.mkdirs(gifs_path)
        # only process existing images
        if not image_url or not xbmcvfs.exists(image_url):
            return None
        # copy the image to our local path and return the new path as value
        local_filename = "%s%s_%s.gif" % (gifs_path, imdb_id, art_type)
        if xbmcvfs.exists(local_filename):
            xbmcvfs.delete(local_filename)
        # we don't use xbmcvfs.copy because we want to wait for the action to complete
        img = xbmcvfs.File(image_url)
        img_data = img.readBytes()
        img.close()
        img = xbmcvfs.File(local_filename, 'w')
        img.write(img_data)
        img.close()
        return local_filename

    def write_kodidb(self, artwork):
        '''store the animated artwork in kodi database to access it with ListItem.Art(animatedartX)'''
        kodi_movie = self.kodidb.movie_by_imdbid(artwork["imdb_id"])
        if kodi_movie:
            params = {
                "movieid": kodi_movie["movieid"],
                "art": {
                    "animatedfanart": artwork["animatedfanart"],
                    "animatedposter": artwork["animatedposter"]
                }
            }
            self.kodidb.set_json('VideoLibrary.SetMovieDetails', params)