Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/show sub original release #7955

Merged
merged 19 commits into from
Apr 19, 2020
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#### Improvements
- Add show names with dashes to guessit expected titles ([#7918](https://github.com/pymedusa/Medusa/pull/7918))
- Provider YggTorrents: Add 'saison' as a season pack search keyword ([#7920](https://github.com/pymedusa/Medusa/pull/7920))
- Show Snatched or Downloaded release name when manually picking a subtitle ([#7955](https://github.com/pymedusa/Medusa/pull/7955))

#### Fixes
- Fixed root dirs not always shown on Home page ([#7921](https://github.com/pymedusa/Medusa/pull/7921))
Expand Down
195 changes: 193 additions & 2 deletions dredd/api-description.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,6 @@ paths:
The Episode endpoint returns information about the Episodes from a given Series.
parameters:
- $ref: '#/parameters/series-id'
name: seriesid
- name: season
in: query
required: false
Expand Down Expand Up @@ -995,6 +994,91 @@ paths:
400:
$ref: '#/responses/error'
x-disabled: true
/history:
get:
summary: Return history entries to a specific show
description: |
The history endpoint returns logged activities stored in the history table, like episodes snatched and downloaded. Or downloaded subtitles for an episode.
parameters:
- $ref: '#/parameters/page'
- $ref: '#/parameters/limit'
- $ref: '#/parameters/sort'
responses:
200:
$ref: '#/responses/pagination_history'
x-disabled: true
400:
$ref: '#/responses/error'
description: Invalid series id or pagination parameters
x-request:
path-params:
seriesid: asdf
x-disabled: true
404:
$ref: '#/responses/error'
description: Series not found
x-request:
path-params:
seriesid: tvdb999999999
x-disabled: true
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@medariox @sharkykh yes i'm disabling these.
I'm not getting it to work. If some of you want to spend time on this, feel free.

/history/{seriesid}:
get:
summary: Return history entries to a specific show
description: |
The history endpoint returns logged activities stored in the history table, like episodes snatched and downloaded. Or downloaded subtitles for an episode.
parameters:
- $ref: '#/parameters/series-id'
- $ref: '#/parameters/page'
- $ref: '#/parameters/limit'
- $ref: '#/parameters/sort'
responses:
200:
$ref: '#/responses/pagination_history'
x-disabled: true
400:
$ref: '#/responses/error'
description: Invalid series id or pagination parameters
x-request:
path-params:
seriesid: asdf
x-disabled: true
404:
$ref: '#/responses/error'
description: Series not found
x-request:
path-params:
seriesid: tvdb999999999
x-disabled: true
/history/{seriesid}/episode/{episodeid}:
get:
summary: Return history entries for a specific episode
description: |
The histories episode endpoint returns history entries for a specific episode
parameters:
- $ref: '#/parameters/series-id'
- $ref: '#/parameters/episode-id'
responses:
200:
description: Array of History entries
schema:
type: array
items:
$ref: '#/definitions/History'
x-disabled: true
400:
$ref: '#/responses/error'
description: Invalid series id or pagination parameters
x-request:
path-params:
seriesid: asdf
x-disabled: true
404:
$ref: '#/responses/error'
description: Series not found
x-request:
path-params:
seriesid: tvdb999999999
x-disabled: true

definitions:
Series:
Expand Down Expand Up @@ -2721,6 +2805,60 @@ definitions:
overview:
type: string
description: Episode status/quality overview string

History:
description: History object
type: object
properties:
id:
type: integer
format: int32
description: Internal id for the history row
series:
type: string
description: Series slug (if available)
status:
type: integer
format: int32
description: Status (numberic)
statusName:
type: string
description: Status description
actionDate:
type: integer
format: int32
description: Date of when the history entrie was stored
resource:
type: string
description: Description of what was stored
example:
- The release name for a statusName of "Downloaded" or "Snatched"
- The language of a subitle downloaded fo ra statusName of "Subtitled"
size:
type: integer
description: Snatched or Downloaded filesize
season:
type: integer
description: Season number
episode:
type: integer
description: Episode number
manuallySearched:
type: boolean
description: Specifies if an episode was snatched or downloaded through a manual search
provider:
type: object
properties:
id:
type: string
description: Provider id
name:
type: string
description: Provider name
imagename:
type: string
description: Provider icon image name.

parameters:
detailed:
name: detailed
Expand Down Expand Up @@ -2762,7 +2900,7 @@ parameters:
x-example: tvdb301824
type: string
episode-id:
name: episode-id
name: episodeid
in: path
required: true
description: The episode id to retrieve. E.g. s02e03, e34 or 2016-12-31
Expand Down Expand Up @@ -2888,6 +3026,36 @@ parameters:
- 'episode'
- 'season'
example: 'episode'
history:
in: body
name: Search Config
description: Object with required information to search for a specific show's episode(s).
schema:
type: object
required:
- showSlug
- episodes
properties:
showSlug:
description: Show slug consisting of the indexer name + indexers id
type: string
example: tvdb301824
episodes:
description: An array of searched episode objects with information on the type of search used
type: array
items:
type: string
example: ["s01e01", "s03e03"]
options:
description: Type of the manual search. 'episode' or 'season' search.
type: object
properties:
type:
type: string
enum:
- 'episode'
- 'season'
example: 'episode'
responses:
pagination:
description: Pagination response
Expand Down Expand Up @@ -2925,3 +3093,26 @@ responses:
description: Unexpected error
schema:
$ref: '#/definitions/Error'
pagination_history:
description: A paged array of history records
headers:
X-Pagination-Page:
type: integer
format: int32
description: The page number
X-Pagination-Limit:
type: integer
format: int32
description: The pagination limit
X-Pagination-Count:
type: integer
format: int32
description: The total items count
Link:
type: string
description: "The pagination links: next, last, first and previous"
schema:
type: array
items:
$ref: '#/definitions/History'

108 changes: 108 additions & 0 deletions medusa/server/api/v2/episode_history.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# coding=utf-8
"""Request handler for series and episodes."""
from __future__ import unicode_literals

import logging

from medusa import db

from medusa.common import statusStrings
from medusa.logger.adapters.style import BraceAdapter
from medusa.providers.generic_provider import GenericProvider
from medusa.providers import get_provider_class
from medusa.server.api.v2.base import BaseRequestHandler
from medusa.server.api.v2.history import HistoryHandler
from medusa.tv.episode import Episode, EpisodeNumber
from medusa.tv.series import Series, SeriesIdentifier

from os.path import basename

log = BraceAdapter(logging.getLogger(__name__))
log.logger.addHandler(logging.NullHandler())


class EpisodeHistoryHandler(BaseRequestHandler):
"""Episode history request handler."""

#: parent resource handler
parent_handler = HistoryHandler
#: resource name
name = 'episode'
#: identifier
identifier = ('episode_slug', r'[\w-]+')
#: path param
path_param = ('path_param', r'\w+')
#: allowed HTTP methods
allowed_methods = ('GET',)

def get(self, series_slug, episode_slug, path_param):
"""Query episode's history information.

:param series_slug: series slug. E.g.: tvdb1234
:param episode_slug: episode slug. E.g.: s01e01
:param path_param:
"""
series_identifier = SeriesIdentifier.from_slug(series_slug)
if not series_identifier:
return self._bad_request('Invalid series slug')

series = Series.find_by_identifier(series_identifier)
if not series:
return self._not_found('Series not found')

if not episode_slug:
return self._bad_request('Invalid episode slug')

episode_number = EpisodeNumber.from_slug(episode_slug)
if not episode_number:
return self._not_found('Invalid episode number')

episode = Episode.find_by_series_and_episode(series, episode_number)
if not episode:
return self._not_found('Episode not found')

sql_base = '''
SELECT rowid, date, action, quality,
provider, version, resource, size, proper_tags,
indexer_id, showid, season, episode, manually_searched
FROM history
WHERE showid = ? AND indexer_id = ? AND season = ? AND episode = ?
'''

params = [series.series_id, series.indexer, episode.season, episode.episode]

sql_base += ' ORDER BY date DESC'
results = db.DBConnection().select(sql_base, params)

def data_generator():
"""Read history data and normalize key/value pairs."""
for item in results:
d = {}
d['id'] = item['rowid']
d['series'] = SeriesIdentifier.from_id(item['indexer_id'], item['showid']).slug
d['status'] = item['action']
d['actionDate'] = item['date']

d['resource'] = basename(item['resource'])
d['size'] = item['size']
d['properTags'] = item['proper_tags']
d['statusName'] = statusStrings.get(item['action'])
d['season'] = item['season']
d['episode'] = item['episode']
d['manuallySearched'] = bool(item['manually_searched'])

provider = get_provider_class(GenericProvider.make_id(item['provider']))
d['provider'] = {}
if provider:
d['provider']['id'] = provider.get_id()
d['provider']['name'] = provider.name
d['provider']['imageName'] = provider.image_name()

yield d

if not results:
return self._not_found('History data not found for show {show} and episode {episode}'.format(
show=series.identifier.slug, episode=episode.slug
))

return self._ok(data=list(data_generator()))
Loading