示例#1
0
def check_file_access(m):
    """Check if we can reach the file directly
       or if we have to download it via PMS.

       Args:
            m (plexapi.video.Episode)

       Return:
            filepath or http to the file.

    """
    LOG.debug('Checking if we can reach %s directly', m._prettyfilename())

    files = list(m.iterParts())
    for file in files:
        if os.path.exists(file.file):
            LOG.debug('Found %s', file.file)
            return file.file
        else:
            LOG.warning('Downloading from pms..')
            try:
                # for plexapi 3.0.6 and above.
                return PMS.url('%s?download=1' % file.key, includeToken=True)
            except TypeError:
                return PMS.url('%s?download=1' % file.key)
示例#2
0
文件: plex.py 项目: shayward/bw_plex
def check_file_access(m):
    """Check if we can reach the file directly
       or if we have to download it via PMS.

       Args:
            m (plexapi.video.Episode)

       Return:
            filepath or http to the file.

    """
    LOG.debug('Checking if we can reach %s directly', m._prettyfilename())

    files = list(m.iterParts())
    # Now we could get the "wrong" file here.
    # If the user has duplications we might return the wrong file
    # CBA with fixing this as it requires to much work :P
    # And the use case is rather slim, you should never have dupes.
    # If the user has they can remove them using plex-cli.
    for file in files:
        if os.path.exists(file.file):
            LOG.debug('Found %s', file.file)
            return file.file
        else:
            LOG.warning('Downloading from pms..')
            try:
                # for plexapi 3.0.6 and above.
                return PMS.url('%s?download=1' % file.key, includeToken=True)
            except TypeError:
                return PMS.url('%s?download=1' % file.key)
示例#3
0
import requests
from bs4 import BeautifulSoup

from plexapi.myplex import MyPlexAccount
from plexapi.server import PlexServer

from bw_plex import THEMES, CONFIG, LOG, FP_HASHES

# Try to import the optional package.
try:
    import speech_recognition
except ImportError:
    speech_recognition = None
    LOG.warning(
        'Failed to import speech_recognition this is required to check for recaps in audio. '
        'Install the package using pip install bw_plex[audio] or bw_plex[all]')


def ignore_ratingkey(item, key):
    """Helper to check if this is in a ignorelist"""
    if item.TYPE == 'movie':
        return item.ratingKey in key
    if item.TYPE == 'episode':
        return any(
            i for i in
            [item.ratingKey, item.grandparentRatingKey, item.parentRatingKey]
            if i in key)

    return False
示例#4
0
import os
import subprocess
import re
import sys

import click
import numpy as np

from bw_plex import LOG
from bw_plex.misc import sec_to_hh_mm_ss

try:
    import cv2
except ImportError:
    cv2 = None
    LOG.warning('Scanning for credits is not supported. '
                'Install the package with pip install bw_plex[all] or bw_plex[video]')

try:
    import pytesseract
except ImportError:
    pytesseract = None
    LOG.warning('Extracting text from images is not supported. '
                'Install the package with pip install bw_plex[all] or bw_plex[video]')

try:
    import Image
except ImportError:
    from PIL import Image


color = {'yellow': (255, 255, 0),
示例#5
0
def get_chromecast_player(host=None, name=None):  # pragma: no cover
    """ Get a chromecast preferable using host direcly, if not we will use the name and mnds (slow),
        if that dont work we will grab the first one.

    """
    try:
        import pychromecast
    except ImportError:
        LOG.warning('Failed to import pychromecast')
        return None, None

    # All isnt used atm, lets keep it and
    # ill fix it later then i create a pr
    # for plexapi or pychromecast.
    MESSAGE_TYPE = 'type'
    TYPE_PLAY = 'PLAY'
    TYPE_PAUSE = 'PAUSE'
    TYPE_STOP = 'STOP'
    TYPE_STEPFORWARD = 'STEPFORWARD'
    TYPE_STEPBACKWARD = 'STEPBACK'
    TYPE_PREVIOUS = 'PREVIOUS'
    TYPE_NEXT = 'NEXT'
    TYPE_LOAD = 'LOAD'
    TYPE_DETAILS = 'SHOWDETAILS'
    TYPE_SEEK = 'SEEK'
    TYPE_MEDIA_STATUS = 'MEDIA_STATUS'
    TYPE_GET_STATUS = 'GET_STATUS'
    TYPE_EDIT_TRACKS_INFO = 'EDIT_TRACKS_INFO'

    from pychromecast.controllers import BaseController

    class PlexController(BaseController):
        """ Controller to interact with Plex namespace. """
        def __init__(self):
            super(PlexController, self).__init__('urn:x-cast:plex', '9AC194DC')
            self.app_id = '9AC194DC'
            self.namespace = 'urn:x-cast:plex'
            self.request_id = 0
            self.play_media_event = threading.Event()

        def _send_cmd(self,
                      msg,
                      namespace=None,
                      inc_session_id=False,
                      callback_function=None,
                      inc=True):
            """Wrapper the commands."""
            self.logger.debug('Sending msg %r %s %s %s %s', msg, namespace,
                              inc_session_id, callback_function, inc)

            if inc:
                self._inc_request()

            if namespace:
                old = self.namespace
                try:
                    self.namespace = namespace
                    self.send_message(msg,
                                      inc_session_id=inc_session_id,
                                      callback_function=callback_function)
                finally:
                    self.namespace = old
            else:
                self.send_message(msg,
                                  inc_session_id=inc_session_id,
                                  callback_function=callback_function)

        def _inc_request(self):
            self.request_id += 1
            return self.request_id

        def receive_message(self, message, data):
            """ Called when a messag from plex to our controller is received.

                I havnt seen any message for ut but lets keep for for now, the
                tests i have done is minimal.
            """

            self.logger.debug('Plex media receive function called.')
            if data[MESSAGE_TYPE] == TYPE_MEDIA_STATUS:
                self.logger.debug('(PlexController) MESSAGE RECEIVED: ' + data)
                return True

            return False

        def stop(self):
            """Send stop command."""
            self._send_cmd({MESSAGE_TYPE: TYPE_STOP})

        def pause(self):
            """Send pause command."""
            self._send_cmd({MESSAGE_TYPE: TYPE_PAUSE})

        def play(self):
            """Send play command."""
            self._send_cmd({MESSAGE_TYPE: TYPE_PLAY})

        def previous(self):
            """Send previous command."""
            self._send_cmd({MESSAGE_TYPE: TYPE_PREVIOUS})

        def next(self):
            self._send_cmd({MESSAGE_TYPE: TYPE_NEXT})

        def seek(self, position, resume_state='PLAYBACK_START'):
            """Send seek command"""
            self._send_cmd({
                MESSAGE_TYPE: TYPE_SEEK,
                'currentTime': position,
                'resumeState': resume_state
            })

        def rewind(self):
            """Rewind back to the start"""
            self.seek(0)

        def set_volume(self, percent):
            # Feels dirty..
            self._socket_client.receiver_controller.set_volume(
                float(percent / 100))

        def volume_up(self, delta=0.1):
            """ Increment volume by 0.1 (or delta) unless it is already maxed.
            Returns the new volume.
            """
            if delta <= 0:
                raise ValueError(
                    "volume delta must be greater than zero, not {}".format(
                        delta))
            return self.set_volume(self.status.volume_level + delta)

        def volume_down(self, delta=0.1):
            """ Decrement the volume by 0.1 (or delta) unless it is already 0.
            Returns the new volume.
            """
            if delta <= 0:
                raise ValueError(
                    "volume delta must be greater than zero, not {}".format(
                        delta))
            return self.set_volume(self.status.volume_level - delta)

        def mute(self, status=None):
            """ mute the sound.
                status is just a override.
            """
            if status is not None:
                st = status
            else:
                st = not status.volume_muted

            self._socket_client.receiver_controller.set_volume_muted(st)

        def show_media(self, media):
            """Show the media on the screen, but don't start it."""
            msg = media_to_chromecast_command(media,
                                              type=TYPE_DETAILS,
                                              requestid=self._inc_request())

            def cb():
                self._send_cmd(msg, inc_session_id=True, inc=False)

            self.launch(cb)

        def quit_app(self):
            """Quit the plex app"""
            self._socket_client.receiver_controller.stop_app()

        @property
        def status(self):
            # So to get this we could add a listener and update the data ourself
            # or get can just use socket_clients
            # status should get a own pr so we can grab the subtitle (episode title.)
            # Lets just patch this for now..
            def episode_title(self):
                return self.media_metadata.get('subtitle')

            mc = self._socket_client.media_controller.status
            mc.episode_title = property(episode_title)
            return self._socket_client.media_controller.status

        def disable_subtitle(self):  # Shit does not work.
            """Disable subtitle."""
            self._send_cmd(
                {
                    MESSAGE_TYPE: TYPE_EDIT_TRACKS_INFO,
                    "activeTrackIds": []
                },
                namespace='urn:x-cast:com.google.cast.media')

        def _send_start_play(self, media):
            msg = media_to_chromecast_command(media,
                                              requestid=self._inc_request())
            self._send_cmd(msg,
                           namespace='urn:x-cast:com.google.cast.media',
                           inc_session_id=True,
                           inc=False)

        def block_until_playing(self, item, timeout=None):
            """Helper just incase this is running as a script."""
            self.play_media_event.clear()
            self.play_media(item)
            self.play_media_event.wait(timeout)
            self.play_media_event.clear()

        def play_media(self, item):
            """Start playback in the chromecast using the
               selected media.
            """
            self.play_media_event.clear()

            def app_launched_callback():
                try:
                    self._send_start_play(item)
                finally:
                    self.play_media_event.set()

            self.launch(app_launched_callback)

        def join(self, timeout=None):
            self._socket_client.join(timeout=timeout)

        def disconnect(self, timeout=None, blocking=True):
            self._socket_client.disconnect()
            if blocking:
                self.join(timeout=timeout)

    cast = None

    try:
        cast = pychromecast.Chromecast(host=host)
    except pychromecast.ChromecastConnectionError:
        chromecasts = pychromecast.get_chromecasts()
        if len(chromecasts) == 1:
            cast = chromecasts[0]
        elif len(chromecasts) > 1:
            cast = next(cc for cc in chromecasts
                        if cc.device.friendly_name == name)
        else:
            LOG.warning("Could'nt find any chromecast on you network")
            return None, None

    pc = PlexController()
    cast.register_handler(pc)

    return pc, cast