-
Notifications
You must be signed in to change notification settings - Fork 278
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature/show sub original release (#7955)
* Add history api route. (python apiv2 changes) This was already prepared for another PR, where it will be used by the snatch-selection (vue) component and the history (vue) component. For this addition to the subtitle-search.vue component. Only one of the actions in history.js is used. * Add the last release name from the history table, to the subtitle-search.vue manual search table (if available) * Fix a small front end (racing condition) bug. * Only show release names when status in Snatched or Downloaded * Fix lint errors * Update api-description * Added "provider" to api-description.yml * Updated changelog * Review comments. * Re-arange subtitle-search.vue to make it more test friendly * Fixed jest tests * Updated jest snapshot * Fix getting proper_tags & manually_searched * make sure the pagination response is valid. * Disabling the history tests. * Use the provider field, as a generic string field. * Fix flake warnings * flake Co-authored-by: Dario <medariox@users.noreply.github.com>
- Loading branch information
Showing
18 changed files
with
2,361 additions
and
1,707 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
# coding=utf-8 | ||
"""Request handler for series and episodes.""" | ||
from __future__ import unicode_literals | ||
|
||
import logging | ||
from os.path import basename | ||
|
||
from medusa import db | ||
from medusa.common import statusStrings | ||
from medusa.logger.adapters.style import BraceAdapter | ||
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 | ||
|
||
|
||
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']) | ||
d['provider'] = item['provider'] | ||
|
||
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())) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# coding=utf-8 | ||
"""Request handler for alias (scene exceptions).""" | ||
from __future__ import unicode_literals | ||
|
||
from os.path import basename | ||
|
||
from medusa import db | ||
from medusa.common import statusStrings | ||
from medusa.server.api.v2.base import BaseRequestHandler | ||
from medusa.tv.series import SeriesIdentifier | ||
|
||
|
||
class HistoryHandler(BaseRequestHandler): | ||
"""History request handler.""" | ||
|
||
#: resource name | ||
name = 'history' | ||
#: identifier | ||
identifier = ('series_slug', r'\w+') | ||
#: path param | ||
path_param = ('path_param', r'\w+') | ||
#: allowed HTTP methods | ||
allowed_methods = ('GET', 'POST', 'PUT', 'DELETE') | ||
|
||
def get(self, series_slug, path_param): | ||
""" | ||
Get history records. | ||
History records can be specified using a show slug. | ||
""" | ||
sql_base = """ | ||
SELECT rowid, date, action, quality, | ||
provider, version, proper_tags, manually_searched, | ||
resource, size, indexer_id, showid, season, episode | ||
FROM history | ||
""" | ||
params = [] | ||
|
||
arg_page = self._get_page() | ||
arg_limit = self._get_limit(default=50) | ||
|
||
if series_slug is not None: | ||
series_identifier = SeriesIdentifier.from_slug(series_slug) | ||
if not series_identifier: | ||
return self._bad_request('Invalid series') | ||
|
||
sql_base += ' WHERE indexer_id = ? AND showid = ?' | ||
params += [series_identifier.indexer.id, series_identifier.id] | ||
|
||
sql_base += ' ORDER BY date DESC' | ||
results = db.DBConnection().select(sql_base, params) | ||
|
||
def data_generator(): | ||
"""Read and paginate history records.""" | ||
start = arg_limit * (arg_page - 1) | ||
|
||
for item in results[start:start + arg_limit]: | ||
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']) | ||
d['provider'] = item['provider'] | ||
|
||
yield d | ||
|
||
if not results: | ||
return self._not_found('History data not found') | ||
|
||
return self._paginate(data_generator=data_generator) | ||
|
||
def delete(self, identifier, **kwargs): | ||
"""Delete a history record.""" | ||
identifier = self._parse(identifier) | ||
if not identifier: | ||
return self._bad_request('Invalid history id') | ||
|
||
main_db_con = db.DBConnection() | ||
last_changes = main_db_con.connection.total_changes | ||
main_db_con.action('DELETE FROM history WHERE row_id = ?', [identifier]) | ||
if main_db_con.connection.total_changes - last_changes <= 0: | ||
return self._not_found('History row not found') | ||
|
||
return self._no_content() |
Oops, something went wrong.