Exemplo n.º 1
0
    def post(self, series_slug):
        """Rename list of episodes"
        ---
        tags: [Series]
        summary: Rename list of episodes
        description: Rename list of episodes
        parameters:
        - in: path
          schema:
            SeriesSlugPath
        responses:
          200:
            description: Success payload
            content:
              application/json:
                schema:
                  EpisodesRenameSuccessSchema
          400:
            description: Bad request; Check `errors` for any validation errors
            content:
              application/json:
                schema:
                  BadRequestSchema
          401:
            description: Returned if your JWT token is missing or expired
            content:
              application/json:
                schema:
                  NotAuthorizedSchema
        """
        data = json_decode(self.request.body)

        renamed_episodes = []

        series = find_show_by_slug(series_slug)
        if series is None:
            return self._not_found(
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        if not os.path.isdir(series.location):
            return self._bad_request(
                error=
                "Can't rename episodes when the show location does not exist")

        for episode_id in data.get('episodeIdList', []):
            episode = find_episode(episode_id, series.series_provider_id)
            if episode:
                episode.rename()
                renamed_episodes.append(episode.episode_id)

        if len(renamed_episodes) > 0:
            WebSocketMessage('SHOW_RENAMED', {
                'seriesSlug': series.slug
            }).push()

        return self.json_response(renamed_episodes)
Exemplo n.º 2
0
    def get(self, series_slug=None):
        """Get list of series or specific series information"
        ---
        tags: [Series]
        summary: Manually search for episodes on search providers
        description: Manually search for episodes on search providers
        parameters:
        - in: path
          schema:
            SeriesPath
        responses:
          200:
            description: Success payload
            content:
              application/json:
                schema:
                  SeriesSuccessSchema
          400:
            description: Bad request; Check `errors` for any validation errors
            content:
              application/json:
                schema:
                  BadRequestSchema
          401:
            description: Returned if your JWT token is missing or expired
            content:
              application/json:
                schema:
                  NotAuthorizedSchema
          404:
            description: Returned if the given series slug does not exist or no series results.
            content:
              application/json:
                schema:
                  NotFoundSchema
        """

        if not series_slug:
            all_series = {}

            for show in get_show_list():
                if sickrage.app.show_queue.is_being_removed(show.series_id):
                    continue

                all_series[show.slug] = show.to_json(progress=True)

            return self.write_json(all_series)

        series = find_show_by_slug(series_slug)
        if series is None:
            return self.send_error(
                404,
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        return self.write_json(series.to_json(episodes=True, details=True))
Exemplo n.º 3
0
    def get(self, series_slug, *args, **kwargs):
        series = find_show_by_slug(series_slug)
        if series is None:
            return self._not_found(
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        image = series_image(series.series_id, series.series_provider_id,
                             SeriesImageType.POSTER_THUMB)
        return self.json_response({'poster': image.url})
Exemplo n.º 4
0
    def get(self, series_slug, *args, **kwargs):
        series = find_show_by_slug(series_slug)
        if series is None:
            return self._not_found(
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        episodes = []
        for episode in series.episodes:
            episodes.append(episode.to_json())

        return self.json_response(episodes)
Exemplo n.º 5
0
    def get(self, series_slug, *args, **kwargs):
        series = find_show_by_slug(series_slug)
        if series is None:
            return self.send_error(
                404,
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        episodes = []
        for episode in series.episodes:
            episodes.append(episode.to_json())

        return self.write_json(episodes)
Exemplo n.º 6
0
    def get(self, series_slug, *args, **kwargs):
        series = find_show_by_slug(series_slug)
        if series is None:
            return self._not_found(
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        with sickrage.app.main_db.session() as session:
            imdb_info = session.query(MainDB.IMDbInfo).filter_by(
                imdb_id=series.imdb_id).one_or_none()
            json_data = IMDbInfoSchema().dump(imdb_info)

        return self.json_response(json_data)
Exemplo n.º 7
0
    def get(self, series_slug, *args, **kwargs):
        series = find_show_by_slug(series_slug)
        if series is None:
            return self._not_found(
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        with sickrage.app.main_db.session() as session:
            whitelist = session.query(MainDB.Whitelist).filter_by(
                series_id=series.series_id,
                series_provider_id=series.series_provider_id).one_or_none()
            json_data = WhitelistSchema().dump(whitelist)

        return self.json_response(json_data)
Exemplo n.º 8
0
    def delete(self, series_slug):
        data = json_decode(self.request.body)

        series = find_show_by_slug(series_slug)
        if series is None:
            return self._not_found(
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        sickrage.app.show_queue.remove_show(
            series.series_id, series.series_provider_id,
            checkbox_to_value(data.get('delete')))

        return self.json_response({'message': True})
Exemplo n.º 9
0
    def get(self, series_slug, *args, **kwargs):
        series = find_show_by_slug(series_slug)
        if series is None:
            return self.send_error(
                404,
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        with sickrage.app.main_db.session() as session:
            blacklist = session.query(MainDB.Blacklist).filter_by(
                series_id=series.series_id,
                series_provider_id=series.series_provider_id).one_or_none()
            json_data = BlacklistSchema().dump(blacklist)

        return self.write_json(json_data)
Exemplo n.º 10
0
    def get(self, series_slug):
        force = self.get_argument('force', None)

        series = find_show_by_slug(series_slug)
        if series is None:
            return self._not_found(
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        try:
            sickrage.app.show_queue.update_show(series.series_id,
                                                series.series_provider_id,
                                                force=bool(force))
        except CantUpdateShowException as e:
            return self._bad_request(
                error=_(f"Unable to update this show, error: {e}"))
Exemplo n.º 11
0
    def get(self, series_slug):
        force = self.get_argument('force', None)

        series = find_show_by_slug(series_slug)
        if series is None:
            return self.send_error(
                404,
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        try:
            sickrage.app.show_queue.refresh_show(series.series_id,
                                                 series.series_provider_id,
                                                 force=bool(force))
        except CantUpdateShowException as e:
            return self.send_error(
                400, error=_(f"Unable to refresh this show, error: {e}"))
Exemplo n.º 12
0
    def patch(self, series_slug):
        warnings, errors = [], []

        do_update = False
        do_update_exceptions = False

        data = json_decode(self.request.body)

        series = find_show_by_slug(series_slug)
        if series is None:
            return self.send_error(
                404,
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        # if we changed the language then kick off an update
        if data.get('lang') is not None and data['lang'] != series.lang:
            do_update = True

        if data.get('paused') is not None:
            series.paused = checkbox_to_value(data['paused'])

        if data.get('anime') is not None:
            series.anime = checkbox_to_value(data['anime'])

        if data.get('scene') is not None:
            series.scene = checkbox_to_value(data['scene'])

        if data.get('searchFormat') is not None:
            series.search_format = SearchFormat[data['searchFormat']]

        if data.get('subtitles') is not None:
            series.subtitles = checkbox_to_value(data['subtitles'])

        if data.get('subUseSrMetadata') is not None:
            series.sub_use_sr_metadata = checkbox_to_value(
                data['subUseSrMetadata'])

        if data.get('defaultEpStatus') is not None:
            series.default_ep_status = int(data['defaultEpStatus'])

        if data.get('skipDownloaded') is not None:
            series.skip_downloaded = checkbox_to_value(data['skipDownloaded'])

        if data.get('sceneExceptions') is not None and set(
                data['sceneExceptions']) != set(series.scene_exceptions):
            do_update_exceptions = True

        if data.get('whitelist') is not None:
            shortwhitelist = short_group_names(data['whitelist'])
            series.release_groups.set_white_keywords(shortwhitelist)

        if data.get('blacklist') is not None:
            shortblacklist = short_group_names(data['blacklist'])
            series.release_groups.set_black_keywords(shortblacklist)

        if data.get('qualityPreset') is not None:
            try:
                new_quality = Qualities[data['qualityPreset']]
            except KeyError:
                new_quality = Quality.combine_qualities(
                    [Qualities[x] for x in data['allowedQualities']],
                    [Qualities[x] for x in data['preferredQualities']])

            series.quality = new_quality

        if data.get('flattenFolders') is not None and bool(
                series.flatten_folders) != bool(data['flattenFolders']):
            series.flatten_folders = data['flattenFolders']
            try:
                sickrage.app.show_queue.refresh_show(series.series_id,
                                                     series.series_provider_id,
                                                     True)
            except CantRefreshShowException as e:
                errors.append(_(f"Unable to refresh this show: {e}"))

        if data.get('language') is not None:
            series.lang = data['language']

        if data.get('dvdOrder') is not None:
            series.dvd_order = checkbox_to_value(data['dvdOrder'])

        if data.get('rlsIgnoreWords') is not None:
            series.rls_ignore_words = data['rlsIgnoreWords']

        if data.get('rlsRequireWords') is not None:
            series.rls_require_words = data['rlsRequireWords']

        # series.search_delay = int(data['search_delay'])

        # if we change location clear the db of episodes, change it, write to db, and rescan
        if data.get('location') is not None and os.path.normpath(
                series.location) != os.path.normpath(data['location']):
            sickrage.app.log.debug(
                os.path.normpath(series.location) + " != " +
                os.path.normpath(data['location']))
            if not os.path.isdir(
                    data['location']
            ) and not sickrage.app.config.general.create_missing_show_dirs:
                warnings.append(
                    f"New location {data['location']} does not exist")

            # don't bother if we're going to update anyway
            elif not do_update:
                # change it
                try:
                    series.location = data['location']
                    try:
                        sickrage.app.show_queue.refresh_show(
                            series.series_id, series.series_provider_id, True)
                    except CantRefreshShowException as e:
                        errors.append(_(f"Unable to refresh this show: {e}"))
                        # grab updated info from TVDB
                        # showObj.loadEpisodesFromSeriesProvider()
                        # rescan the episodes in the new folder
                except NoNFOException:
                    warnings.append(
                        _(f"The folder at {data['location']} doesn't contain a tvshow.nfo - copy your files to that folder before you change the directory in SiCKRAGE."
                          ))

        # force the update
        if do_update:
            try:
                sickrage.app.show_queue.update_show(series.series_id,
                                                    series.series_provider_id,
                                                    force=True)
            except CantUpdateShowException as e:
                errors.append(_(f"Unable to update show: {e}"))

        if do_update_exceptions:
            try:
                series.scene_exceptions = set(
                    data['sceneExceptions'].split(','))
            except CantUpdateShowException:
                warnings.append(
                    _("Unable to force an update on scene exceptions of the show."
                      ))

        # if do_update_scene_numbering:
        #     try:
        #         xem_refresh(series.series_id, series.series_provider_id, True)
        #     except CantUpdateShowException:
        #         warnings.append(_("Unable to force an update on scene numbering of the show."))

        # commit changes to database
        series.save()

        return self.write_json(series.to_json(episodes=True, details=True))
Exemplo n.º 13
0
    def get(self):
        """Get list of episodes to rename"
        ---
        tags: [Episodes]
        summary: Get list of episodes to rename
        description: Get list of episodes to rename
        parameters:
        - in: query
          schema:
            EpisodesRenameSchema
        responses:
          200:
            description: Success payload
            content:
              application/json:
                schema:
                  EpisodesRenameSuccessSchema
          400:
            description: Bad request; Check `errors` for any validation errors
            content:
              application/json:
                schema:
                  BadRequestSchema
          401:
            description: Returned if your JWT token is missing or expired
            content:
              application/json:
                schema:
                  NotAuthorizedSchema
        """
        series_slug = self.get_argument('seriesSlug', None)

        validation_errors = self._validate_schema(EpisodesRenameSchema, self.request.arguments)
        if validation_errors:
            return self.send_error(400, error=validation_errors)

        if not series_slug:
            return self.send_error(400, error="Missing series slug")

        rename_data = []

        series = find_show_by_slug(series_slug)
        if series is None:
            return self.send_error(404, error=f"Unable to find the specified series using slug: {series_slug}")

        if not os.path.isdir(series.location):
            return self.send_error(400, error="Can't rename episodes when the show location does not exist")

        for episode in series.episodes:
            if not episode.location:
                continue

            current_location = episode.location[len(episode.show.location) + 1:]
            new_location = "{}.{}".format(episode.proper_path(), current_location.split('.')[-1])

            if current_location != new_location:
                rename_data.append({
                    'episodeId': episode.episode_id,
                    'season': episode.season,
                    'episode': episode.episode,
                    'currentLocation': current_location,
                    'newLocation': new_location,
                })

        return self.write_json(rename_data)
Exemplo n.º 14
0
    def get(self, series_slug, episode_slug):
        """Episode Manual Search"
        ---
        tags: [Series]
        summary: Manually search for episode on search providers
        description: Manually search for episode on search providers
        parameters:
        - in: path
          schema:
            SeriesSlugPath
        - in: path
          schema:
            EpisodeSlugPath
        responses:
          200:
            description: Success payload
            content:
              application/json:
                schema:
                  EpisodesManualSearchSuccessSchema
          400:
            description: Bad request; Check `errors` for any validation errors
            content:
              application/json:
                schema:
                  BadRequestSchema
          401:
            description: Returned if your JWT token is missing or expired
            content:
              application/json:
                schema:
                  NotAuthorizedSchema
          404:
            description: Returned if the given episode slug does not exist or the search returns no results.
            content:
              application/json:
                schema:
                  NotFoundSchema
        """
        use_existing_quality = self.get_argument('useExistingQuality',
                                                 None) or False

        # validation_errors = self._validate_schema(SeriesEpisodesManualSearchPath, self.request.path)
        # if validation_errors:
        #     return self._bad_request(error=validation_errors)
        #
        # validation_errors = self._validate_schema(SeriesEpisodesManualSearchSchema, self.request.arguments)
        # if validation_errors:
        #     return self._bad_request(error=validation_errors)
        #

        series = find_show_by_slug(series_slug)
        if series is None:
            return self._not_found(
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        match = re.match(r'^s(?P<season>\d+)e(?P<episode>\d+)$', episode_slug)
        season_num = match.group('season')
        episode_num = match.group('episode')

        episode = series.get_episode(int(season_num),
                                     int(episode_num),
                                     no_create=True)
        if episode is None:
            return self._bad_request(
                error=
                f"Unable to find the specified episode using slug: {episode_slug}"
            )

        # make a queue item for it and put it on the queue
        ep_queue_item = ManualSearchTask(int(episode.show.series_id),
                                         episode.show.series_provider_id,
                                         int(episode.season),
                                         int(episode.episode),
                                         bool(use_existing_quality))

        sickrage.app.search_queue.put(ep_queue_item)
        if not all([ep_queue_item.started, ep_queue_item.success]):
            return self.json_response({'success': True})

        return self._not_found(error=_(
            f"Unable to find season {season_num} episode {episode_num} for show {series.name} on search providers"
        ))