def koalasetup(): if not os.path.exists(const.userdatafolder): os.makedirs(const.userdatafolder) if not os.path.exists(utils.os_join(const.libpath, "%s shows" % const.provider)): os.makedirs(utils.os_join(const.libpath, "%s shows" % const.provider)) if not os.path.exists(utils.os_join(const.libpath, "%s movies" % const.provider)): os.makedirs(utils.os_join(const.libpath, "%s movies" % const.provider))
def rpc(method, multifilter=False, **kwargs): if method == "VideoLibrary.GetMovies": filename = multifilter.values()[0][0][2] path = multifilter.values()[0][1][2] filepath = utils.os_join(path, filename) files = glob.glob(filepath) result = {"movies": []} for filepath in files: if filepath in nfo_needed and not os.path.isfile(filepath.replace(".htm", ".nfo")): continue result['movies'].append({"movieid": filepath, "file": filepath, 'playcount': playcounts.get(filepath, 0)}) return result elif method == "VideoLibrary.GetEpisodes": # get_koala_stored_eps if kwargs["filter"]["field"] == "path": showpath = kwargs["filter"]["value"] files = glob.glob(utils.os_join(showpath, "*", "*.htm")) # no stored koala episode, get any stored episode elif kwargs["filter"]["field"] == "filename": filename = kwargs["filter"]["value"] files = glob.glob(utils.os_join(mock_constants.libpath, "%s shows" % const.provider, "*", "*", filename)) # all_stored_episodes elif kwargs["filter"]["field"] == "tvshow": showtitle = kwargs["filter"]["value"] files = glob.glob(utils.os_join(mock_constants.libpath, "%s shows" % const.provider, utils.stringtofile(showtitle), "*", "*.htm")) result = {"episodes": []} for filepath in files: seasonnr, episodenr, = re.match(r".*S(\d\d)E(\d\d).htm", filepath).groups() if filepath in nfo_needed and not os.path.isfile(filepath.replace(".htm", ".nfo")): continue result["episodes"].append({"episodeid": filepath, "file": filepath, 'playcount': playcounts.get(filepath, 0), "season": int(seasonnr), 'episode': int(episodenr)}) return result # any_episode, episodeid=any_ep_kodiid elif method == "VideoLibrary.GetEpisodeDetails": filepath = kwargs["episodeid"] path, filename = os.path.split(filepath) showtitle = re.match(r"(.*) S\d\dE\d\d.htm", filename).groups()[0] return {'episodedetails': {"episodeid": filepath, "showtitle": showtitle}}
def load_playcount(self): jsonfilepath = utils.os_join(self.path, self.jsonfilename) if os.path.exists(jsonfilepath): with open(jsonfilepath, "r") as f: playcount = json.load(f) kodi.rpc("VideoLibrary.Set%sDetails" % self.mediatype.capitalize(), playcount=playcount, **{self.mediatype + "id": self.kodiid}) os.remove(jsonfilepath)
def __init__(self, mediaclass, name, retain_order=False): self.lock = threading.Lock() self.backend = set() if retain_order is False else OrderedSet() self.mediaclass = mediaclass self.mediatype = mediaclass.mediatype self.name = name self.filepath = utils.os_join(const.userdatafolder, "%s.json" % self.name) self.edited = False self.loaded = False
def read_external_player_config(player): playerfilername = "chrome" if player == "Chrome" else "iexplore" root = ET.parse(os_join(const.masterprofilefolder, "playercorefactory.xml")).getroot() for player in root.findall("./players/player"): filename = player.find("filename").text args = player.find("args").text.replace('"{1}"', '').split() if playerfilername in filename: return filename, args raise Exception("Could not found player file for %s" % player)
def write_nfo(self, metadata): root = ET.Element("tvshow") ET.SubElement(root, "title").text = self.title ET.SubElement(root, "plot").text = metadata["plot"] ET.SubElement(root, "premiered").text = "01.01.%s" % metadata["year"] ET.SubElement(root, "thumb", aspect="poster").text = metadata["poster"] fanart = ET.SubElement(root, "fanart") ET.SubElement(fanart, "thumb").text = metadata["fanart"] as_string = ET.tostring(root, method='xml') pretty_xml_as_string = xml.dom.minidom.parseString(as_string).toprettyxml() with open(utils.os_join(self.path, self.nfofilename), "w") as nfo: nfo.write(pretty_xml_as_string.encode("utf-8"))
def write_nfo(self): root = ET.Element("episodedetails") ET.SubElement(root, "title").text = self.metadata["title"] ET.SubElement(root, "showtitle").text = self.showtitle ET.SubElement(root, "season").text = unicode(self.seasonnr) ET.SubElement(root, "episode").text = unicode(self.episodenr) ET.SubElement(root, "plot").text = self.metadata["plot"] ET.SubElement(root, "runtime").text = unicode(int(self.metadata["runtime"].seconds/60)) ET.SubElement(root, "thumb").text = self.metadata['thumb'] as_string = ET.tostring(root, method='xml') pretty_xml_as_string = xml.dom.minidom.parseString(as_string).toprettyxml() with open(utils.os_join(self.path, self.nfofilename), "w") as nfo: nfo.write(pretty_xml_as_string.encode("utf-8"))
def write_nfo(self, metadata): root = ET.Element("movie") ET.SubElement(root, "title").text = self.title ET.SubElement(root, "plot").text = metadata["plot"] ET.SubElement(root, "year").text = unicode(metadata["year"]) ET.SubElement(root, "runtime").text = unicode(int(metadata["runtime"].seconds/60)) ET.SubElement(root, "thumb", aspect="poster").text = metadata["poster"] fanart = ET.SubElement(root, "fanart") ET.SubElement(fanart, "thumb").text = metadata["fanart"] as_string = ET.tostring(root, method='xml') pretty_xml_as_string = xml.dom.minidom.parseString(as_string).toprettyxml() with open(utils.os_join(self.path, self.nfofilename), "w") as nfo: nfo.write(pretty_xml_as_string.encode("utf-8"))
def load_mapping(self): try: with open(utils.os_join(const.userdatafolder, "remotemapping.json")) as j: stored = json.load(j) except IOError: stored = {} no_keys = {"code": None, "char": None} mapping = [ self.Button(name="Play", func=self.playpause, **stored.get("Play", no_keys)), self.Button(name="Pause", func=self.playpause, **stored.get("Pause", no_keys)), self.Button(name="Stop", func=self.stop, **stored.get("Stop", no_keys)), self.Button(name="Next", func=self.next, **stored.get("Next", no_keys)), self.Button(name="Forward", func=self.forward, **stored.get("Forward", no_keys)), self.Button(name="Rewind", func=self.rewind, **stored.get("Rewind", no_keys)), self.Button(name="Continue playing at prompt", func=self.cont, **stored.get("Continue playing at prompt", no_keys)), ] return mapping
def setUpModule(): library.databases.stored_movies.filepath = utils.os_join(mock_constants.userdatafolder, "%s.json" % library.databases.stored_movies.name) library.databases.excluded_movies.filepath = utils.os_join(mock_constants.userdatafolder, "%s.json" % library.databases.excluded_movies.name) library.databases.stored_shows.filepath = utils.os_join(mock_constants.userdatafolder, "%s.json" % library.databases.stored_shows.name) library.databases.excluded_shows.filepath = utils.os_join(mock_constants.userdatafolder, "%s.json" % library.databases.excluded_shows.name) library.databases.prioritized_shows.filepath = utils.os_join(mock_constants.userdatafolder, "%s.json" % library.databases.prioritized_shows.name) library.databases.mediatypes.const = mock_constants library.databases.mediatypes.kodi = mock_kodi library.kodi = mock_kodi library.scraper = mock_scraper if os.path.exists(mock_constants.userdatafolder): # delete mock userdata folder shutil.rmtree(mock_constants.userdatafolder) # copy mock userdata folder to userdata so it can be modified shutil.copytree(utils.os_join(const.addonpath, "tests", "mock userdata"), mock_constants.userdatafolder) main.main(argv={"mode": "library", "action": "startup"})
def write_htm(self): with open(utils.os_join(self.path, self.htmfilename), "w") as txt: txt.write('<meta http-equiv="REFRESH" content="0;' 'url=%s"> <body bgcolor="#ffffff">' % self.url)
def delete_htm(self): os.remove(utils.os_join(self.path, self.htmfilename)) try: os.removedirs(utils.os_join(self.path)) except OSError: pass
def save_playcount(self): if self.playcount > 0: jsonfilepath = utils.os_join(self.path, self.jsonfilename) with open(jsonfilepath, "w") as f: json.dump(self.playcount, f)
def test_movie_excluded(self): """Was movie (Blood Diamond) still excluded?""" path = utils.os_join(mock_constants.libpath, "%s movies" % const.provider, "Blood Diamond.htm") self.assertFalse(isfile(path), msg="File created:\n%s" % path)
def check_movie(name, ext, season=None, episode=None): path = utils.os_join(mock_constants.libpath, "%s movies" % const.provider, "%s.%s" % (utils.stringtofile(name), ext)) return path
def browse(): xbmc.Player().play(utils.os_join(const.addonpath, "resources", "%s.htm" % const.provider))
def test_show_excluded(self): """Was show (Master of None) still excluded?""" path = utils.os_join(mock_constants.libpath, "%s shows" % const.provider, "Master of None") self.assertFalse(isfile(path), msg="File created:\n%s" % path)
#! /usr/bin/env python2 # -*- coding: utf-8 -*- from __future__ import (unicode_literals, absolute_import, division) import glob import re import os from lib import constants as const from lib import utils from lib import kodi from tests import mock_constants playcounts = { utils.os_join(mock_constants.libpath, "%s movies" % const.provider, "Kill Bill Vol. 2.htm"): 1, utils.os_join(mock_constants.libpath, "%s shows" % const.provider, "Bones", "Season 2", "Bones S02E02.htm"): 2, utils.os_join(mock_constants.libpath, "%s shows" % const.provider, "Arrested Development", "Season 1", "Arrested Development S01E01.htm"): 3, } nfo_needed = { utils.os_join(mock_constants.libpath, "%s movies" % const.provider, "Starsky & Hutch.htm"), utils.os_join(mock_constants.libpath, "%s shows" % const.provider, "Archer", "Season 1", "Archer S01E01.htm") } def rpc(method, multifilter=False, **kwargs): if method == "VideoLibrary.GetMovies": filename = multifilter.values()[0][0][2] path = multifilter.values()[0][1][2]
def store_mapping(self, mapping): dict_for_storage = {button.name: {'code': button.code, 'char': button.char} for button in mapping if any([button.code, button.char])} with open(utils.os_join(const.userdatafolder, "remotemapping.json"), "w") as j: json.dump(dict_for_storage, j)
def check_episode(name, ext, season=None, episode=None): path = utils.os_join(mock_constants.libpath, "%s shows" % const.provider, utils.stringtofile(name), "Season %s" % season, "%s S%02dE%02d.%s" % (utils.stringtofile(name), season, episode, ext)) return path
def mock_watchlistpage(): with open(utils.os_join(const.addonpath, "tests", "mock_watchlistpage.json"), "r") as js: page = json.load(js) return page
def setUp(self): self.playerargs.append(os_join(const.addonpath, "resources", "Example episode.htm")) self.playerprocess = subprocess.Popen([self.playerfile] + self.playerargs) self.browser = playback.InternetExplorer() self.remote = remote.Remote() self.remote.run(browser=self.browser)