Example #1
0
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")))
Example #2
0
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")))
Example #3
0
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
Example #4
0
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
Example #5
0
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
Example #6
0
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
Example #7
0
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)
Example #8
0
                        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...')
Example #9
0
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)
Example #10
0
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
Example #11
0
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)
Example #12
0
        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