def setup_images(photos_path): print("Setup files for the Photos section..") makedirs(photos_path, exist_ok=True) # expected_photo_count = 0 folders = { ("Cats", ): 3, ("Cats", "Cats in bed"): 7, ("Cats", "Cats not in bed"): 1, ("Cats", "Not cats in bed"): 1, } has_photos = 0 for folder_path, required_cnt in folders.items(): folder_path = os.path.join(photos_path, *folder_path) makedirs(folder_path, exist_ok=True) photos_in_folder = len(glob(os.path.join(folder_path, "/*.jpg"))) while photos_in_folder < required_cnt: # Dunno why this is need got permission error on photo0.jpg photos_in_folder += 1 full_path = os.path.join(folder_path, "photo%d.jpg" % photos_in_folder) copyfile(STUB_IMAGE_PATH, full_path) has_photos += photos_in_folder return len(check_ext(photos_path, (".jpg")))
def setup_music(music_path): print("Setup files for music section..") makedirs(music_path, exist_ok=True) all_music = { "Broke for free": { "Layers": [ "1 - As Colorful As Ever.mp3", #"02 - Knock Knock.mp3", #"03 - Only Knows.mp3", #"04 - If.mp3", #"05 - Note Drop.mp3", #"06 - Murmur.mp3", #"07 - Spellbound.mp3", #"08 - The Collector.mp3", #"09 - Quit Bitching.mp3", #"10 - A Year.mp3", ] }, } for artist, album in all_music.items(): for k, v in album.items(): artist_album = os.path.join(music_path, artist, k) makedirs(artist_album, exist_ok=True) for song in v: copyfile(STUB_MP3_PATH, os.path.join(artist_album, song)) return len(check_ext(music_path, (".mp3")))
def download(url, filename=None, savepath=None, session=None, chunksize=4024, unpack=False, mocked=False): """ Helper to download a thumb, videofile or other media item. Returns the local path to the downloaded file. Parameters: url (str): URL where the content be reached. filename (str): Filename of the downloaded file, default None. savepath (str): Defaults to current working dir. chunksize (int): What chunksize read/write at the time. mocked (bool): Helper to do evertything except write the file. unpack (bool): Unpack the zip file Example: >>> download(a_episode.getStreamURL(), a_episode.location) /path/to/file """ from plexapi import log # fetch the data to be saved session = session or requests.Session() response = session.get(url, stream=True) # make sure the savepath directory exists savepath = savepath or os.getcwd() compat.makedirs(savepath, exist_ok=True) # try getting filename from header if not specified in arguments (used for logs, db) if not filename and response.headers.get('Content-Disposition'): filename = re.findall(r'filename=\"(.+)\"', response.headers.get('Content-Disposition')) filename = filename[0] if filename[0] else None filename = os.path.basename(filename) fullpath = os.path.join(savepath, filename) # append file.ext from content-type if not already there extension = os.path.splitext(fullpath)[-1] if not extension: contenttype = response.headers.get('content-type') if contenttype and 'image' in contenttype: fullpath += contenttype.split('/')[1] # check this is a mocked download (testing) if mocked: log.debug('Mocked download %s', fullpath) return fullpath # save the file to disk log.info('Downloading: %s', fullpath) with open(fullpath, 'wb') as handle: for chunk in response.iter_content(chunk_size=chunksize): handle.write(chunk) # check we want to unzip the contents if fullpath.endswith('zip') and unpack: with zipfile.ZipFile(fullpath, 'r') as handle: handle.extractall(savepath) # finished; return fillpath return fullpath
def setup_movies(movies_path): print("Setup files for the Movies section..") makedirs(movies_path, exist_ok=True) if len(glob(movies_path + "/*.mkv", recursive=True)) == 4: return 4 required_movies = { "Elephants Dream": 2006, "Sita Sings the Blues": 2008, "Big Buck Bunny": 2008, "Sintel": 2010, } expected_media_count = 0 for name, year in required_movies.items(): expected_media_count += 1 if not os.path.isfile(get_movie_path(movies_path, name, year)): copyfile(STUB_MOVIE_PATH, get_movie_path(movies_path, name, year)) return expected_media_count
def setup_show(tvshows_path): print("Setup files for the TV-Shows section..") makedirs(tvshows_path, exist_ok=True) makedirs(os.path.join(tvshows_path, "Game of Thrones"), exist_ok=True) makedirs(os.path.join(tvshows_path, "The 100"), exist_ok=True) required_tv_shows = { "Game of Thrones": [list(range(1, 11)), list(range(1, 11))], "The 100": [list(range(1, 14)), list(range(1, 17))], } expected_media_count = 0 for show_name, seasons in required_tv_shows.items(): for season_id, episodes in enumerate(seasons, start=1): for episode_id in episodes: expected_media_count += 1 episode_path = get_tvshow_path(tvshows_path, show_name, season_id, episode_id) if not os.path.isfile(episode_path): copyfile(STUB_MOVIE_PATH, episode_path) return expected_media_count
def download_with_rate(url, token, filename=None, savepath=None, session=None, chunksize=4024, unpack=False, mocked=False, showstatus=False, rate_limit=None): import time, os, logging from tqdm import tqdm from plexapi import compat log = logging.getLogger('plexapi') """ Helper to download a thumb, videofile or other media item. Returns the local path to the downloaded file. Parameters: url (str): URL where the content be reached. token (str): Plex auth token to include in headers. filename (str): Filename of the downloaded file, default None. savepath (str): Defaults to current working dir. chunksize (int): What chunksize read/write at the time. mocked (bool): Helper to do evertything except write the file. unpack (bool): Unpack the zip file. showstatus(bool): Display a progressbar. Example: >>> download(a_episode.getStreamURL(), a_episode.location) /path/to/file """ # fetch the data to be saved session = session or requests.Session() headers = {'X-Plex-Token': token} response = session.get(url, headers=headers, stream=True) # make sure the savepath directory exists savepath = savepath or os.getcwd() compat.makedirs(savepath, exist_ok=True) # try getting filename from header if not specified in arguments (used for logs, db) if not filename and response.headers.get('Content-Disposition'): filename = re.findall(r'filename=\"(.+)\"', response.headers.get('Content-Disposition')) filename = filename[0] if filename[0] else None filename = os.path.basename(filename) fullpath = os.path.join(savepath, filename) # append file.ext from content-type if not already there extension = os.path.splitext(fullpath)[-1] if not extension: contenttype = response.headers.get('content-type') if contenttype and 'image' in contenttype: fullpath += contenttype.split('/')[1] # check this is a mocked download (testing) if mocked: log.debug('Mocked download %s', fullpath) return fullpath # save the file to disk log.info('Downloading: %s', fullpath) if showstatus: # pragma: no cover total = int(response.headers.get('content-length', 0)) bar = tqdm(unit='B', unit_scale=True, total=total, desc=filename) rate_limit = rate_limit * 1000 #(go from bytes to kilobytes per second) pauser_timer = 0 downloaded = 0 new = True start_time = time.time() #when it starts. with open(fullpath, 'wb') as handle: for chunk in response.iter_content(chunk_size=chunksize): handle.write(chunk) if showstatus: bar.update(len(chunk)) elapsed_time = time.time( ) - start_time # keep track of elapsed time downloaded += chunksize # keep track of how much was downloaded if (elapsed_time > 1 or new): new = False speed = (downloaded / elapsed_time) pauser_timer += (chunksize / rate_limit) - ( chunksize / speed ) #how long it should take minus how long it did take for a chunk (since pause occurs per chunk) start_time = time.time() #reset start time downloaded = 0 #reset download counter if ((pauser_timer) > 0): time.sleep(pauser_timer) if showstatus: # pragma: no cover bar.close() # check we want to unzip the contents if fullpath.endswith('zip') and unpack: with zipfile.ZipFile(fullpath, 'r') as handle: handle.extractall(savepath) return fullpath
def init(folder=None, debug=False, config=None): global DEFAULT_FOLDER, THEMES, TEMP_THEMES, LOG_FILE, INI_FILE, INI_FILE, DB_PATH, CONFIG, FP_HASHES, POOL DEFAULT_FOLDER = folder or os.environ.get( 'bw_plex_default_folder') or os.path.expanduser('~/.config/bw_plex') if os.path.isdir(DEFAULT_FOLDER) and not os.access(DEFAULT_FOLDER, os.W_OK): print('You default folder is not writeable') sys.exit() THEMES = os.path.join(DEFAULT_FOLDER, 'themes') TEMP_THEMES = os.path.join(DEFAULT_FOLDER, 'temp_themes') FP_HASHES = os.path.join(DEFAULT_FOLDER, 'hashes.pklz') LOG_FILE = os.path.join(DEFAULT_FOLDER, 'log.txt') INI_FILE = config or os.path.join(DEFAULT_FOLDER, 'config.ini') DB_PATH = os.path.join(DEFAULT_FOLDER, 'media.db') makedirs(DEFAULT_FOLDER, exist_ok=True) makedirs(THEMES, exist_ok=True) makedirs(TEMP_THEMES, exist_ok=True) from bw_plex.config import read_or_make CONFIG = read_or_make(INI_FILE) POOL = Pool(int(CONFIG.get('thread_pool_number', 10))) from bw_plex.db import db_init db_init() # Setup some logging. if debug or CONFIG['general']['level'] == 'debug': LOG.setLevel(logging.DEBUG) else: LOG.setLevel(logging.INFO) handle = logging.NullHandler() frmt = logging.Formatter( CONFIG.get( 'logformat', '%(asctime)s :: %(name)s :: %(levelname)s :: %(filename)s:%(lineno)d :: %(message)s' )) handle.setFormatter(frmt) LOG.addHandler(handle) stream_handle = logging.StreamHandler() stream_handle.setFormatter(frmt) LOG.addHandler(stream_handle) handle.setFormatter(frmt) LOG.addHandler(handle) # FILE rfh = RotatingFileHandler(LOG_FILE, 'a', 512000, 3) rfh.setFormatter(frmt) LOG.addHandler(rfh) LOG.info('default folder set to %s', DEFAULT_FOLDER) FILTER.add_secret(CONFIG['server']['token']) FILTER.add_secret(CONFIG['server']['password']) secret_args = arg_extract(keys=['username', 'token', 'password']).values() for arg in secret_args: FILTER.add_secret(arg) if not CONFIG['general']['debug'] and debug is False: LOG.addFilter(FILTER) else: LOG.info('Log is not sanitized!') packages = ['plexapi', 'requests', 'urllib3'] for pack in packages: _pack = logging.getLogger(pack) _pack.setLevel(logging.DEBUG) _pack.addHandler(rfh) _pack.addHandler(stream_handle)
action='store_true') opts = parser.parse_args() print( 'I`m going to create a plex instance named %s with advertised ip "%s", be prepared!' % (opts.server_name, opts.advertise_ip)) if call(['docker', 'pull', 'plexinc/pms-docker:%s' % opts.docker_tag]) != 0: print('Got an error when executing docker pull!') exit(1) if opts.token: account = MyPlexAccount(token=opts.token) else: account = plexapi.utils.getMyPlexAccount(opts) path = os.path.realpath(os.path.expanduser(opts.destination)) makedirs(os.path.join(path, 'media'), exist_ok=True) arg_bindings = { 'destination': path, 'hostname': opts.server_name, 'claim_token': get_claim_token(account), 'timezone': opts.timezone, 'advertise_ip': opts.advertise_ip, 'image_tag': opts.docker_tag, } docker_cmd = [c % arg_bindings for c in DOCKER_CMD] exit_code = call(docker_cmd) if exit_code != 0: exit(exit_code) print('Let`s wait while the instance register in your plex account...')
logging.basicConfig(format=frmt, level=logging.DEBUG) LOG = logging.getLogger(__file__) #LOG.setLevel(logging.DEBUG) IN_PROG = [] JUMP_LIST = [] SHOWS = defaultdict(list) # Fix this, should be all caps. ROOT = os.path.abspath('.') THEMES = os.path.join(ROOT, 'themes') #PREPROCESSED = os.path.join(ROOT, 'preprocessed') #HASHES_DIR = os.path.join(ROOT, 'hashes') FP_HASHES = os.path.join(ROOT, 'hashes.pklz') # Create default dirs. makedirs(THEMES, exist_ok=True) if os.path.exists(FP_HASHES): LOG.info('Loading existing files in db') HT = HashTable(FP_HASHES) for n in HT.names: LOG.debug('%s', n) #print(HT.names) #print(HT.table) #print(HT.) else: LOG.info('Creating new db') HT = HashTable() HT.save(FP_HASHES) HT.load(FP_HASHES)
def download(url, token, filename=None, savepath=None, session=None, chunksize=4024, unpack=False, mocked=False, showstatus=False): """ Helper to download a thumb, videofile or other media item. Returns the local path to the downloaded file. Parameters: url (str): URL where the content be reached. token (str): Plex auth token to include in headers. filename (str): Filename of the downloaded file, default None. savepath (str): Defaults to current working dir. chunksize (int): What chunksize read/write at the time. mocked (bool): Helper to do evertything except write the file. unpack (bool): Unpack the zip file. showstatus(bool): Display a progressbar. Example: >>> download(a_episode.getStreamURL(), a_episode.location) /path/to/file """ from plexapi import log # fetch the data to be saved session = session or requests.Session() headers = {'X-Plex-Token': token} response = session.get(url, headers=headers, stream=True) # make sure the savepath directory exists savepath = savepath or os.getcwd() compat.makedirs(savepath, exist_ok=True) # try getting filename from header if not specified in arguments (used for logs, db) if not filename and response.headers.get('Content-Disposition'): filename = re.findall(r'filename=\"(.+)\"', response.headers.get('Content-Disposition')) filename = filename[0] if filename[0] else None filename = os.path.basename(filename) fullpath = os.path.join(savepath, filename) # append file.ext from content-type if not already there extension = os.path.splitext(fullpath)[-1] if not extension: contenttype = response.headers.get('content-type') if contenttype and 'image' in contenttype: fullpath += contenttype.split('/')[1] # check this is a mocked download (testing) if mocked: log.debug('Mocked download %s', fullpath) return fullpath # save the file to disk log.info('Downloading: %s', fullpath) if showstatus: # pragma: no cover total = int(response.headers.get('content-length', 0)) bar = tqdm(unit='B', unit_scale=True, total=total, desc=filename) with open(fullpath, 'wb') as handle: for chunk in response.iter_content(chunk_size=chunksize): handle.write(chunk) if showstatus: bar.update(len(chunk)) if showstatus: # pragma: no cover bar.close() # check we want to unzip the contents if fullpath.endswith('zip') and unpack: with zipfile.ZipFile(fullpath, 'r') as handle: handle.extractall(savepath) return fullpath
from plexapi.compat import makedirs from .config import read_or_make #VERSION = '0.0.1' DEFAULT_FOLDER = os.path.expanduser('~/.config/bw_plex') THEMES = os.path.join(DEFAULT_FOLDER, 'themes') TEMP_THEMES = os.path.join(DEFAULT_FOLDER, 'temp_themes') FP_HASHES = os.path.join(DEFAULT_FOLDER, 'hashes.pklz') LOG_FILE = os.path.join(DEFAULT_FOLDER, 'log.txt') LOG = logging.getLogger('bw_plex') INI_FILE = os.path.join(DEFAULT_FOLDER, 'config.ini') DB_PATH = os.path.join(DEFAULT_FOLDER, 'media.db') makedirs(DEFAULT_FOLDER, exist_ok=True) makedirs(THEMES, exist_ok=True) makedirs(TEMP_THEMES, exist_ok=True) CONFIG = read_or_make(INI_FILE) if CONFIG.get('level') in ['', 'info']: # Should we just use a int? lvl = logging.INFO else: lvl = logging.DEBUG handle = logging.NullHandler() frmt = logging.Formatter(CONFIG.get('logformat', '%(asctime)s :: %(name)s :: %(levelname)s :: %(message)s')) handle.setFormatter(frmt) LOG.addHandler(handle)
default=True, dest="with_photos", action="store_false", ) # noqa parser.add_argument( "--show-token", help="Display access token after bootstrap", default=False, action="store_true", ) # noqa opts = parser.parse_args() account = get_plex_account(opts) path = os.path.realpath(os.path.expanduser(opts.destination)) media_path = os.path.join(path, "media") makedirs(media_path, exist_ok=True) # Download the Plex Docker image if opts.no_docker is False: print("Creating Plex instance named %s with advertised ip %s" % (opts.server_name, opts.advertise_ip)) if which("docker") is None: print("Docker is required to be available") exit(1) if call(["docker", "pull", "plexinc/pms-docker:%s" % opts.docker_tag]) != 0: print("Got an error when executing docker pull!") exit(1) # Start the Plex Docker container