Exemplo n.º 1
0
def getShowImage(url, imgNum=None):
    if not url:
        return None

    # if they provided a fanart number try to use it instead
    if imgNum is not None:
        temp_url = url.split("-")[0] + "-" + str(imgNum) + ".jpg"
    else:
        temp_url = url

    logger.debug("Fetching image from " + temp_url)

    try:
        image_data = helpers.getURL(temp_url,
                                    session=meta_session,
                                    returns="content",
                                    allow_proxy=settings.PROXY_INDEXERS)
    except requests.exceptions.RequestException:
        image_data = None

    if not image_data:
        logger.warning(
            "There was an error trying to retrieve the image, aborting")
        return

    return image_data
Exemplo n.º 2
0
    def _sendBoxcar2(self, msg, title, accesstoken):
        '''
        Sends a boxcar2 notification to the address provided

        msg: The message to send
        title: The title of the message
        accesstoken: to send to this device

        returns: True if the message succeeded, False otherwise
        '''
        # http://blog.boxcar.io/post/93211745502/boxcar-api-update-boxcar-api-update-icon-and

        post_data = {
            'user_credentials': accesstoken,
            'notification[title]': 'SickChill : {0}: {1}'.format(title, msg),
            'notification[long_message]': msg,
            'notification[sound]': 'notifier-2',
            'notification[source_name]': 'SickChill',
            'notification[icon_url]': settings.LOGO_URL
        }

        response = helpers.getURL(self.url, post_data=post_data, session=self.session, timeout=60, returns='json')
        if not response:
            logger.exception('Boxcar2 notification failed.')
            return False

        logger.debug('Boxcar2 notification successful.')
        return True
Exemplo n.º 3
0
    def _send_telegram_msg(self, title, msg, id=None, api_key=None):
        """
        Sends a Telegram notification

        :param title: The title of the notification to send
        :param msg: The message string to send
        :param id: The Telegram user/group id to send the message to
        :param api_key: Your Telegram bot API token

        :returns: True if the message succeeded, False otherwise
        """
        logger.debug('Telegram in use with API KEY: {0}'.format(api_key))
        params = {
            'chat_id': id or settings.TELEGRAM_ID,
            'text': f'{title} : {msg}'
        }
        response = getURL(
            f'https://api.telegram.org/bot{api_key or settings.TELEGRAM_APIKEY}/sendMessage',
            params=params,
            session=self.session,
            returns='json')
        message = (
            'Telegram message sent successfully.',
            'Sending Telegram message failed, check the log')[response is None]
        logger.info(message)
        return response is not None, message
Exemplo n.º 4
0
    def _sendBoxcar2(self, msg, title, accesstoken):
        """
        Sends a boxcar2 notification to the address provided

        msg: The message to send
        title: The title of the message
        accesstoken: to send to this device

        returns: True if the message succeeded, False otherwise
        """
        # http://blog.boxcar.io/post/93211745502/boxcar-api-update-boxcar-api-update-icon-and

        post_data = {
            "user_credentials": accesstoken,
            "notification[title]": "SickChill : {0}: {1}".format(title, msg),
            "notification[long_message]": msg,
            "notification[sound]": "notifier-2",
            "notification[source_name]": "SickChill",
            "notification[icon_url]": settings.LOGO_URL,
        }

        response = helpers.getURL(self.url,
                                  post_data=post_data,
                                  session=self.session,
                                  timeout=60,
                                  returns="json")
        if not response:
            logger.exception("Boxcar2 notification failed.")
            return False

        logger.debug("Boxcar2 notification successful.")
        return True
Exemplo n.º 5
0
    def compare_db_version(self):
        try:
            self.need_update()
            cur_hash = self.get_newest_commit_hash()
            assert len(
                cur_hash
            ) == 40, "Commit hash wrong length: {0} hash: {1}".format(
                len(cur_hash), cur_hash)

            check_url = "https://raw.githubusercontent.com/{0}/{1}/{2}/sickchill/oldbeard/databases/main.py"
            for attempt in (cur_hash, "master"):
                response = helpers.getURL(check_url.format(
                    settings.GIT_ORG, settings.GIT_REPO, attempt),
                                          session=self.session,
                                          returns='text')
                if response:
                    break

            assert response, "Empty response from {0}".format(check_url)

            match = re.search(r"MAX_DB_VERSION\s=\s(?P<version>\d{2,3})",
                              response)
            destination_db_version = int(match.group('version'))
            main_db_con = db.DBConnection()
            current_db_version = main_db_con.get_db_version()
            if destination_db_version > current_db_version:
                return 'upgrade'
            elif destination_db_version == current_db_version:
                return 'equal'
            else:
                return 'downgrade'
        except Exception as e:
            return repr(e)
Exemplo n.º 6
0
    def fetch_popular_shows(self):
        """Get popular show information from IMDB"""

        popular_shows = []

        data = helpers.getURL(self.url,
                              session=self.session,
                              params=self.params,
                              headers={'Referer': self.base_url},
                              returns='text')
        if not data:
            return None

        soup = BeautifulSoup(data, 'html5lib')
        results = soup.find_all("div", {"class": "lister-item"})

        for row in results:
            show = {}
            image_div = row.find("div", {"class": "lister-item-image"})
            if image_div:
                image = image_div.find("img")
                show['image_url_large'] = self.change_size(
                    image['loadlate'], 3)
                show['imdb_tt'] = image['data-tconst']
                show['image_path'] = posixpath.join(
                    'images', 'imdb_popular',
                    os.path.basename(show['image_url_large']))
                self.cache_image(show['image_url_large'])

            content = row.find("div", {"class": "lister-item-content"})
            if content:
                header = row.find("h3", {"class": "lister-item-header"})
                if header:
                    a_tag = header.find("a")
                    if a_tag:
                        show['name'] = a_tag.get_text(strip=True)
                        show[
                            'imdb_url'] = "http://www.imdb.com" + a_tag["href"]
                        show['year'] = header.find("span", {
                            "class": "lister-item-year"
                        }).contents[0].split(" ")[0][1:].strip("-")

                imdb_rating = row.find("div", {"class": "ratings-imdb-rating"})
                show['rating'] = imdb_rating[
                    'data-value'] if imdb_rating else None

                votes = row.find("span", {"name": "nv"})
                show['votes'] = votes['data-value'] if votes else None

                outline = content.find_all("p", {"class": "text-muted"})
                if outline and len(outline) >= 2:
                    show['outline'] = outline[1].contents[0].strip("\"")
                else:
                    show['outline'] = ''

                popular_shows.append(show)

        return popular_shows
Exemplo n.º 7
0
 def get_devices(self, pushbullet_api):
     logger.debug(
         "Testing Pushbullet authentication and retrieving the device list."
     )
     headers = {"Access-Token": pushbullet_api}
     return helpers.getURL(urljoin(self.url, "devices"),
                           session=self.session,
                           headers=headers,
                           returns="text") or {}
Exemplo n.º 8
0
 def get_channels(self, pushbullet_api):
     """Fetches the list of channels a given access key has permissions to push to"""
     logger.debug(
         "Testing Pushbullet authentication and retrieving the device list."
     )
     headers = {"Access-Token": pushbullet_api}
     return helpers.getURL(urljoin(self.url, "channels"),
                           session=self.session,
                           headers=headers,
                           returns="text") or {}
Exemplo n.º 9
0
    def compare_db_version(self):
        try:
            self.need_update()
            newest_version = self.get_newest_commit_hash()
            if isinstance(newest_version, str):
                if len(newest_version) != 40:
                    raise UpdaterException(
                        f"Commit hash wrong length: {len(newest_version)} hash: {newest_version}"
                    )
            else:
                newest_version = f"v{newest_version.major}.{newest_version.minor:02d}.{newest_version.micro:02d}-{newest_version.post}"

            response = helpers.getURL(
                f"https://raw.githubusercontent.com/{settings.GIT_ORG}/{settings.GIT_REPO}/{newest_version}/sickchill/oldbeard/databases/main.py",
                session=self.session,
                returns="text",
            )
            if not response:
                response = helpers.getURL(
                    f"https://raw.githubusercontent.com/{settings.GIT_ORG}/{settings.GIT_REPO}/master/sickchill/oldbeard/databases/main.py",
                    session=self.session,
                    returns="text",
                )

            if not response:
                raise UpdaterException(
                    f"Empty response from GitHub for {newest_version}")

            match = re.search(r"MAX_DB_VERSION\s=\s(?P<version>\d{2,3})",
                              response)
            destination_db_version = int(match.group("version"))
            main_db_con = db.DBConnection()
            current_db_version = main_db_con.get_db_version()
            if destination_db_version > current_db_version:
                return "upgrade"
            elif destination_db_version == current_db_version:
                return "equal"
            else:
                return "downgrade"
        except Exception as e:
            return repr(e)
Exemplo n.º 10
0
    def _sendPushbullet(self,
                        pushbullet_api=None,
                        pushbullet_device=None,
                        pushbullet_channel=None,
                        event=None,
                        message=None,
                        link=None,
                        force=False):

        if not (settings.USE_PUSHBULLET or force):
            return False

        pushbullet_api = pushbullet_api or settings.PUSHBULLET_API
        pushbullet_device = pushbullet_device or settings.PUSHBULLET_DEVICE
        pushbullet_channel = pushbullet_channel or settings.PUSHBULLET_CHANNEL

        logger.debug("Pushbullet event: {0!r}".format(event))
        logger.debug("Pushbullet message: {0!r}".format(message))
        logger.debug("Pushbullet api: {0!r}".format(pushbullet_api))
        logger.debug("Pushbullet devices: {0!r}".format(pushbullet_device))

        post_data = {
            "title": event,
            "body": message,
            "type": "link" if link else "note"
        }
        if link:
            post_data["url"] = link

        headers = {"Access-Token": pushbullet_api}

        if pushbullet_device:
            post_data["device_iden"] = pushbullet_device
        elif pushbullet_channel:
            post_data["channel_tag"] = pushbullet_channel

        response = helpers.getURL(urljoin(self.url, "pushes"),
                                  session=self.session,
                                  post_data=post_data,
                                  headers=headers,
                                  returns="json") or {}

        failed = response.pop("error", {})
        if failed:
            logger.warning("Pushbullet notification failed: {0}".format(
                failed.pop("message")))
        else:
            logger.debug("Pushbullet notification sent.")

        return False if failed else True
Exemplo n.º 11
0
    def check_for_new_news(self):
        """
        Checks GitHub for the latest news.

        returns: str, a copy of the news

        force: ignored
        """

        # Grab a copy of the news
        logger.debug('check_for_new_news: Checking GitHub for latest news.')
        try:
            news = helpers.getURL(settings.NEWS_URL,
                                  session=self.session,
                                  returns='text')
        except Exception:
            logger.warning(
                'check_for_new_news: Could not load news from repo.')
            news = ''

        if not news:
            return ''

        try:
            last_read = datetime.datetime.strptime(settings.NEWS_LAST_READ,
                                                   '%Y-%m-%d')
        except Exception:
            last_read = 0

        settings.NEWS_UNREAD = 0
        found_news = False
        for match in re.finditer(r'^####\s*(\d{4}-\d{2}-\d{2})\s*####', news,
                                 re.M):
            if not found_news:
                found_news = True
                settings.NEWS_LATEST = match.group(1)

            try:
                if datetime.datetime.strptime(match.group(1),
                                              '%Y-%m-%d') > last_read:
                    settings.NEWS_UNREAD += 1
            except Exception:
                pass

        return news
Exemplo n.º 12
0
    def _sendPushbullet(
            self, pushbullet_api=None, pushbullet_device=None, pushbullet_channel=None, event=None, message=None, link=None, force=False):

        if not (settings.USE_PUSHBULLET or force):
            return False

        pushbullet_api = pushbullet_api or settings.PUSHBULLET_API
        pushbullet_device = pushbullet_device or settings.PUSHBULLET_DEVICE
        pushbullet_channel = pushbullet_channel or settings.PUSHBULLET_CHANNEL

        logger.debug('Pushbullet event: {0!r}'.format(event))
        logger.debug('Pushbullet message: {0!r}'.format(message))
        logger.debug('Pushbullet api: {0!r}'.format(pushbullet_api))
        logger.debug('Pushbullet devices: {0!r}'.format(pushbullet_device))

        post_data = {
            'title': event,
            'body': message,
            'type': 'link' if link else 'note'
        }
        if link:
            post_data['url'] = link

        headers = {'Access-Token': pushbullet_api}

        if pushbullet_device:
            post_data['device_iden'] = pushbullet_device
        elif pushbullet_channel:
            post_data['channel_tag'] = pushbullet_channel

        response = helpers.getURL(urljoin(self.url, 'pushes'), session=self.session, post_data=post_data, headers=headers, returns='json') or {}

        failed = response.pop('error', {})
        if failed:
            logger.warning('Pushbullet notification failed: {0}'.format(failed.pop('message')))
        else:
            logger.debug('Pushbullet notification sent.')

        return False if failed else True
Exemplo n.º 13
0
    def get_token(self, username=None, password=None, plex_server_token=None):
        username = username or settings.PLEX_SERVER_USERNAME
        password = password or settings.PLEX_SERVER_PASSWORD
        plex_server_token = plex_server_token or settings.PLEX_SERVER_TOKEN

        if plex_server_token:
            self.headers['X-Plex-Token'] = plex_server_token

        if 'X-Plex-Token' in self.headers:
            return True

        if not (username and password):
            return True

        logger.debug('PLEX: fetching plex.tv credentials for user: '******'user[login]': username, 'user[password]': password}

        try:
            response = getURL('https://plex.tv/users/sign_in.json',
                              post_data=params,
                              headers=self.headers,
                              session=self.session,
                              returns='json',
                              allow_proxy=False)

            self.headers['X-Plex-Token'] = response['user'][
                'authentication_token']

        except Exception as error:
            self.headers.pop('X-Plex-Token', '')
            logger.debug(
                'PLEX: Error fetching credentials from from plex.tv for user {0}: {1}'
                .format(username, error))

        return 'X-Plex-Token' in self.headers
Exemplo n.º 14
0
    def get_token(self, username=None, password=None, plex_server_token=None):
        username = username or settings.PLEX_SERVER_USERNAME
        password = password or settings.PLEX_SERVER_PASSWORD
        plex_server_token = plex_server_token or settings.PLEX_SERVER_TOKEN

        if plex_server_token:
            self.headers["X-Plex-Token"] = plex_server_token

        if "X-Plex-Token" in self.headers:
            return True

        if not (username and password):
            return True

        logger.debug("PLEX: fetching plex.tv credentials for user: "******"user[login]": username, "user[password]": password}

        try:
            response = getURL("https://plex.tv/users/sign_in.json",
                              post_data=params,
                              headers=self.headers,
                              session=self.session,
                              returns="json",
                              allow_proxy=False)

            self.headers["X-Plex-Token"] = response["user"][
                "authentication_token"]

        except Exception as error:
            self.headers.pop("X-Plex-Token", "")
            logger.debug(
                "PLEX: Error fetching credentials from from plex.tv for user {0}: {1}"
                .format(username, error))

        return "X-Plex-Token" in self.headers
Exemplo n.º 15
0
 def get_url(self, url, post_data=None, params=None, timeout=30, **kwargs):
     kwargs['hooks'] = {'response': self.get_url_hook}
     return getURL(url, post_data, params, self.headers, timeout,
                   self.session, **kwargs)
Exemplo n.º 16
0
    def update_library(self,
                       ep_obj=None,
                       host=None,
                       username=None,
                       password=None,
                       plex_server_token=None,
                       force=False):
        """Handles updating the Plex Media Server host via HTTP API

        Plex Media Server currently only supports updating the whole video library and not a specific path.

        Returns:
            Returns None for no issue, else a string of host with connection issues

        """

        if not (settings.USE_PLEX_SERVER
                and settings.PLEX_UPDATE_LIBRARY) and not force:
            return None

        host = host or settings.PLEX_SERVER_HOST
        if not host:
            logger.debug(
                'PLEX: No Plex Media Server host specified, check your settings'
            )
            return False

        if not self.get_token(username, password, plex_server_token):
            logger.warning(
                'PLEX: Error getting auth token for Plex Media Server, check your settings'
            )
            return False

        file_location = '' if not ep_obj else ep_obj.location
        host_list = {x.strip() for x in host.split(',') if x.strip()}
        hosts_all = hosts_match = {}
        hosts_failed = set()

        for cur_host in host_list:

            url = 'http{0}://{1}/library/sections'.format(
                ('', 's')[settings.PLEX_SERVER_HTTPS], cur_host)
            try:
                xml_response = getURL(url,
                                      headers=self.headers,
                                      session=self.session,
                                      returns='text',
                                      verify=False,
                                      allow_proxy=False)
                if not xml_response:
                    logger.warning(
                        'PLEX: Error while trying to contact Plex Media Server: {0}'
                        .format(cur_host))
                    hosts_failed.add(cur_host)
                    continue

                media_container = ElementTree.fromstring(xml_response)
            except IOError as error:
                logger.warning(
                    'PLEX: Error while trying to contact Plex Media Server: {0}'
                    .format(str(error)))
                hosts_failed.add(cur_host)
                continue
            except Exception as error:
                if 'invalid token' in str(error):
                    logger.warning('PLEX: Please set TOKEN in Plex settings: ')
                else:
                    logger.warning(
                        'PLEX: Error while trying to contact Plex Media Server: {0}'
                        .format(str(error)))
                hosts_failed.add(cur_host)
                continue

            sections = media_container.findall('.//Directory')
            if not sections:
                logger.debug(
                    'PLEX: Plex Media Server not running on: {0}'.format(
                        cur_host))
                hosts_failed.add(cur_host)
                continue

            for section in sections:
                if 'show' == section.attrib['type']:

                    keyed_host = [(str(section.attrib['key']), cur_host)]
                    hosts_all.update(keyed_host)
                    if not file_location:
                        continue

                    for section_location in section.findall('.//Location'):
                        section_path = re.sub(
                            r'[/\\]+', '/',
                            section_location.attrib['path'].lower())
                        section_path = re.sub(r'^(.{,2})[/\\]', '',
                                              section_path)
                        location_path = re.sub(r'[/\\]+', '/',
                                               file_location.lower())
                        location_path = re.sub(r'^(.{,2})[/\\]', '',
                                               location_path)

                        if section_path in location_path:
                            hosts_match.update(keyed_host)

        if force:
            return (', '.join(set(hosts_failed)), None)[not len(hosts_failed)]

        if hosts_match:
            logger.debug(
                'PLEX: Updating hosts where TV section paths match the downloaded show: '
                + ', '.join(set(hosts_match)))
        else:
            logger.debug('PLEX: Updating all hosts with TV sections: ' +
                         ', '.join(set(hosts_all)))

        hosts_try = (hosts_match.copy(),
                     hosts_all.copy())[not len(hosts_match)]
        for section_key, cur_host in hosts_try.items():

            url = 'http{0}://{1}/library/sections/{2}/refresh'.format(
                ('', 's')[settings.PLEX_SERVER_HTTPS], cur_host, section_key)
            try:
                getURL(url,
                       headers=self.headers,
                       session=self.session,
                       returns='text',
                       verify=False,
                       allow_proxy=False)
            except Exception as error:
                logger.warning(
                    'PLEX: Error updating library section for Plex Media Server: {0}'
                    .format(str(error)))
                hosts_failed.add(cur_host)

        return (', '.join(set(hosts_failed)), None)[not len(hosts_failed)]
Exemplo n.º 17
0
 def get_devices(self, pushbullet_api):
     logger.debug('Testing Pushbullet authentication and retrieving the device list.')
     headers = {'Access-Token': pushbullet_api}
     return helpers.getURL(urljoin(self.url, 'devices'), session=self.session, headers=headers, returns='text') or {}