Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
SiCKRAGE
sickrage
Commits
3b1f1e3b
Commit
3b1f1e3b
authored
Aug 01, 2021
by
echel0n
Browse files
Refactored API v2 error handling and async functionality
Fixed issues with API v2 post-processing
parent
4a7fdbb6
Changes
11
Hide whitespace changes
Inline
Side-by-side
sickrage/core/webserver/handlers/api/__init__.py
View file @
3b1f1e3b
...
...
@@ -22,7 +22,9 @@ import functools
import
json
import
traceback
import
types
from
concurrent.futures.thread
import
ThreadPoolExecutor
import
bleach
import
sentry_sdk
from
apispec
import
APISpec
from
apispec.exceptions
import
APISpecError
...
...
@@ -31,14 +33,18 @@ from apispec_webframeworks.tornado import TornadoPlugin
from
tornado.escape
import
to_basestring
from
tornado.ioloop
import
IOLoop
from
tornado.web
import
HTTPError
from
tornado.web
import
RequestHandler
import
sickrage
from
sickrage.core.enums
import
UserPermission
from
sickrage.core.helpers
import
get_internal_ip
from
sickrage.core.webserver.handlers.base
import
BaseHandler
class
APIBaseHandler
(
BaseHandler
):
class
APIBaseHandler
(
RequestHandler
):
def
__init__
(
self
,
application
,
request
,
api_version
=
''
,
**
kwargs
):
super
(
APIBaseHandler
,
self
).
__init__
(
application
,
request
,
**
kwargs
)
self
.
executor
=
ThreadPoolExecutor
(
thread_name_prefix
=
f
'API
{
api_version
}
-Thread'
)
def
prepare
(
self
):
super
(
APIBaseHandler
,
self
).
prepare
()
...
...
@@ -84,7 +90,7 @@ class APIBaseHandler(BaseHandler):
})
if
sickrage
.
app
.
config
.
user
.
sub_id
!=
decoded_token
.
get
(
'sub'
):
return
self
.
send_error
(
401
,
error
=
'user is not authorized'
)
return
self
.
_unauthorized
(
error
=
'user is not authorized'
)
if
not
sickrage
.
app
.
api
.
token
:
exchanged_token
=
sickrage
.
app
.
auth_server
.
token_exchange
(
token
)
...
...
@@ -110,11 +116,11 @@ class APIBaseHandler(BaseHandler):
method
=
self
.
run_async
(
getattr
(
self
,
method_name
))
setattr
(
self
,
method_name
,
method
)
except
Exception
:
return
self
.
send_error
(
401
,
error
=
'failed to decode token'
)
return
self
.
_unauthorized
(
error
=
'failed to decode token'
)
else
:
return
self
.
send_error
(
401
,
error
=
'invalid authorization request'
)
return
self
.
_unauthorized
(
error
=
'invalid authorization request'
)
else
:
return
self
.
send_error
(
401
,
error
=
'authorization header missing'
)
return
self
.
_unauthorized
(
error
=
'authorization header missing'
)
def
run_async
(
self
,
method
):
@
functools
.
wraps
(
method
)
...
...
@@ -134,9 +140,6 @@ class APIBaseHandler(BaseHandler):
return
decoded_token
def
write_error
(
self
,
status_code
,
**
kwargs
):
self
.
set_header
(
'Content-Type'
,
'application/json'
)
self
.
set_status
(
status_code
)
if
status_code
==
500
:
excp
=
kwargs
[
'exc_info'
][
1
]
tb
=
kwargs
[
'exc_info'
][
2
]
...
...
@@ -148,14 +151,42 @@ class APIBaseHandler(BaseHandler):
sickrage
.
app
.
log
.
error
(
error_msg
)
return
self
.
finish
(
self
.
to_json
({
'
error
'
:
error_msg
}
))
return
self
.
finish
(
self
.
json_response
(
error
=
error_msg
,
status
=
status_code
))
def
set_default_headers
(
self
):
super
(
APIBaseHandler
,
self
).
set_default_headers
()
self
.
set_header
(
'X-SiCKRAGE-Server'
,
sickrage
.
version
())
self
.
set_header
(
"Access-Control-Allow-Origin"
,
"*"
)
self
.
set_header
(
"Access-Control-Allow-Headers"
,
"Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, X-SiCKRAGE-Server"
)
self
.
set_header
(
'Access-Control-Allow-Methods'
,
'POST, GET, PUT, PATCH, DELETE, OPTIONS'
)
self
.
set_header
(
'Cache-Control'
,
'no-store, no-cache, must-revalidate, max-age=0'
)
def
options
(
self
,
*
args
,
**
kwargs
):
self
.
finish
(
self
.
_no_content
())
def
json_response
(
self
,
data
=
None
,
error
=
None
,
status
=
200
):
self
.
set_header
(
'Content-Type'
,
'application/json'
)
def
to_json
(
self
,
response
):
return
json
.
dumps
(
response
)
self
.
set_status
(
status
)
if
error
is
not
None
:
return
json
.
dumps
({
'error'
:
error
})
if
data
is
not
None
:
return
json
.
dumps
(
data
)
return
None
def
_no_content
(
self
):
return
self
.
json_response
(
status
=
204
)
def
_unauthorized
(
self
,
error
):
return
self
.
json_response
(
error
=
error
,
status
=
401
)
def
_bad_request
(
self
,
error
):
return
self
.
json_response
(
error
=
error
,
status
=
400
)
def
_not_found
(
self
,
error
):
return
self
.
json_response
(
error
=
error
,
status
=
404
)
def
_validate_schema
(
self
,
schema
,
arguments
):
return
schema
().
validate
({
k
:
to_basestring
(
v
[
0
])
if
len
(
v
)
<=
1
else
to_basestring
(
v
)
for
k
,
v
in
arguments
.
items
()})
...
...
@@ -193,15 +224,23 @@ class APIBaseHandler(BaseHandler):
return
spec
.
to_dict
()
def
get_argument
(
self
,
*
args
,
**
kwargs
):
value
=
super
(
APIBaseHandler
,
self
).
get_argument
(
*
args
,
**
kwargs
)
try
:
return
bleach
.
clean
(
value
)
except
TypeError
:
return
value
class
ApiProfileHandler
(
APIBaseHandler
):
def
get
(
self
):
return
self
.
to_
json
(
self
.
current_user
)
return
self
.
json
_response
(
self
.
current_user
)
class
ApiPingHandler
(
APIBaseHandler
):
def
get
(
self
):
return
self
.
to_
json
({
'message'
:
'pong'
})
return
self
.
json
_response
({
'message'
:
'pong'
})
class
ApiSwaggerDotJsonHandler
(
APIBaseHandler
):
...
...
@@ -212,4 +251,4 @@ class ApiSwaggerDotJsonHandler(APIBaseHandler):
def
get
(
self
):
""" Get swagger.json """
return
self
.
to_
json
(
self
.
generate_swagger_json
(
self
.
api_handlers
,
self
.
api_version
))
return
self
.
json
_response
(
self
.
generate_swagger_json
(
self
.
api_handlers
,
self
.
api_version
))
sickrage/core/webserver/handlers/api/v1/__init__.py
View file @
3b1f1e3b
...
...
@@ -25,7 +25,6 @@ import os
import
re
import
time
import
traceback
import
types
from
concurrent.futures.thread
import
ThreadPoolExecutor
from
urllib.parse
import
unquote_plus
...
...
sickrage/core/webserver/handlers/api/v2/__init__.py
View file @
3b1f1e3b
...
...
@@ -19,7 +19,6 @@
# along with SiCKRAGE. If not, see <http://www.gnu.org/licenses/>.
# ##############################################################################
import
os
from
concurrent.futures.thread
import
ThreadPoolExecutor
import
sickrage
from
sickrage.core.webserver.handlers.api
import
APIBaseHandler
...
...
@@ -27,15 +26,14 @@ from sickrage.core.webserver.handlers.api import APIBaseHandler
class
ApiV2BaseHandler
(
APIBaseHandler
):
def
__init__
(
self
,
application
,
request
,
**
kwargs
):
super
(
ApiV2BaseHandler
,
self
).
__init__
(
application
,
request
,
**
kwargs
)
self
.
executor
=
ThreadPoolExecutor
(
thread_name_prefix
=
'APIv2-Thread'
)
super
(
ApiV2BaseHandler
,
self
).
__init__
(
application
,
request
,
api_version
=
'v2'
,
**
kwargs
)
class
ApiV2RetrieveSeriesMetadataHandler
(
ApiV2BaseHandler
):
def
get
(
self
):
series_directory
=
self
.
get_argument
(
'seriesDirectory'
,
None
)
if
not
series_directory
:
return
self
.
send_error
(
400
,
error
=
"Missing seriesDirectory parameter"
)
return
self
.
_bad_request
(
error
=
"Missing seriesDirectory parameter"
)
json_data
=
{
'rootDirectory'
:
os
.
path
.
dirname
(
series_directory
),
...
...
@@ -61,4 +59,4 @@ class ApiV2RetrieveSeriesMetadataHandler(ApiV2BaseHandler):
if
not
json_data
[
'seriesSlug'
]
and
series_id
and
series_provider_id
:
json_data
[
'seriesSlug'
]
=
f
'
{
series_id
}
-
{
series_provider_id
.
slug
}
'
return
self
.
to_
json
(
json_data
)
return
self
.
json
_response
(
json_data
)
sickrage/core/webserver/handlers/api/v2/config/__init__.py
View file @
3b1f1e3b
...
...
@@ -59,4 +59,4 @@ class ApiV2ConfigHandler(ApiV2BaseHandler):
}
}
return
self
.
to_
json
(
config_data
)
return
self
.
json
_response
(
config_data
)
sickrage/core/webserver/handlers/api/v2/file_browser/__init__.py
View file @
3b1f1e3b
...
...
@@ -28,7 +28,7 @@ class ApiV2FileBrowserHandler(ApiV2BaseHandler):
path
=
self
.
get_argument
(
'path'
,
None
)
include_files
=
self
.
get_argument
(
'includeFiles'
,
None
)
return
self
.
to_
json
(
self
.
get_path
(
path
,
bool
(
include_files
)))
return
self
.
json
_response
(
self
.
get_path
(
path
,
bool
(
include_files
)))
def
get_path
(
self
,
path
,
include_files
=
False
):
entries
=
{
...
...
sickrage/core/webserver/handlers/api/v2/history/__init__.py
View file @
3b1f1e3b
...
...
@@ -88,4 +88,4 @@ class ApiV2HistoryHandler(ApiV2BaseHandler):
results
.
append
(
row
)
return
self
.
to_
json
(
results
)
return
self
.
json
_response
(
results
)
sickrage/core/webserver/handlers/api/v2/postprocess/__init__.py
View file @
3b1f1e3b
...
...
@@ -70,15 +70,15 @@ class Apiv2PostProcessHandler(ApiV2BaseHandler):
validation_errors
=
self
.
_validate_schema
(
PostProcessSchema
,
self
.
request
.
arguments
)
if
validation_errors
:
return
self
.
send_error
(
400
,
error
s
=
validation_errors
)
return
self
.
_bad_request
(
error
=
validation_errors
)
if
not
path
and
not
sickrage
.
app
.
config
.
general
.
tv_download_dir
:
return
self
.
send_error
(
400
,
error
=
{
"path"
:
"You need to provide a path or set TV Download Dir"
})
return
self
.
_bad_request
(
error
=
{
"path"
:
"You need to provide a path or set TV Download Dir"
})
json_data
=
sickrage
.
app
.
postprocessor_queue
.
put
(
path
,
nzbName
=
nzb_name
,
process_method
=
ProcessMethod
[
process_method
.
upper
()],
force
=
force_replace
,
is_priority
=
is_priority
,
delete_on
=
delete
,
failed
=
failed
,
proc_type
=
proc_type
,
force_next
=
force_next
)
if
'Processing succeeded'
not
in
json_data
:
return
self
.
send_error
(
400
,
error
=
json_data
)
if
'Processing succeeded'
not
in
json_data
and
'Successfully processed'
not
in
json_data
:
return
self
.
_bad_request
(
error
=
json_data
)
return
self
.
to_
json
({
'data'
:
json_data
if
return_data
else
''
})
return
self
.
json
_response
({
'data'
:
json_data
if
return_data
else
''
})
sickrage/core/webserver/handlers/api/v2/schedule/__init__.py
View file @
3b1f1e3b
...
...
@@ -74,4 +74,4 @@ class ApiV2ScheduleHandler(ApiV2BaseHandler):
results
[
i
][
'localtime'
]
=
result
[
'localtime'
].
timestamp
()
results
[
i
]
=
convert_dict_keys_to_camelcase
(
results
[
i
])
return
self
.
to_
json
({
'episodes'
:
results
,
'today'
:
today
.
timestamp
(),
'nextWeek'
:
next_week
.
timestamp
()})
return
self
.
json
_response
({
'episodes'
:
results
,
'today'
:
today
.
timestamp
(),
'nextWeek'
:
next_week
.
timestamp
()})
sickrage/core/webserver/handlers/api/v2/series/__init__.py
View file @
3b1f1e3b
...
...
@@ -87,13 +87,13 @@ class ApiV2SeriesHandler(ApiV2BaseHandler):
all_series
.
append
(
show
.
to_json
(
progress
=
True
))
return
self
.
to_
json
(
all_series
)
return
self
.
json
_response
(
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
.
_not_found
(
error
=
f
"Unable to find the specified series using slug:
{
series_slug
}
"
)
return
self
.
to_
json
(
series
.
to_json
(
episodes
=
True
,
details
=
True
))
return
self
.
json
_response
(
series
.
to_json
(
episodes
=
True
,
details
=
True
))
def
post
(
self
):
data
=
json_decode
(
self
.
request
.
body
)
...
...
@@ -123,18 +123,18 @@ class ApiV2SeriesHandler(ApiV2BaseHandler):
add_show_year
=
self
.
_parse_boolean
(
data
.
get
(
'addShowYear'
,
'false'
))
if
not
series_id
:
return
self
.
send_error
(
400
,
error
=
f
"Missing seriesId parameter:
{
series_id
}
"
)
return
self
.
_bad_request
(
error
=
f
"Missing seriesId parameter:
{
series_id
}
"
)
series_provider_id
=
SeriesProviderID
.
by_slug
(
series_provider_slug
)
if
not
series_provider_id
:
return
self
.
send_error
(
404
,
error
=
"Unable to identify a series provider using provided slug"
)
return
self
.
_not_found
(
error
=
"Unable to identify a series provider using provided slug"
)
series
=
find_show
(
int
(
series_id
),
series_provider_id
)
if
series
:
return
self
.
send_error
(
400
,
error
=
f
"Already exists series:
{
series_id
}
"
)
return
self
.
_bad_request
(
error
=
f
"Already exists series:
{
series_id
}
"
)
if
is_existing
and
not
series_directory
:
return
self
.
send_error
(
400
,
error
=
"Missing seriesDirectory parameter"
)
return
self
.
_bad_request
(
error
=
"Missing seriesDirectory parameter"
)
if
not
is_existing
:
series_directory
=
os
.
path
.
join
(
root_directory
,
sanitize_file_name
(
series_name
))
...
...
@@ -146,12 +146,12 @@ class ApiV2SeriesHandler(ApiV2BaseHandler):
if
os
.
path
.
isdir
(
series_directory
):
sickrage
.
app
.
alerts
.
error
(
_
(
"Unable to add show"
),
_
(
"Folder "
)
+
series_directory
+
_
(
" exists already"
))
return
self
.
send_error
(
400
,
error
=
f
"Show directory
{
series_directory
}
already exists!"
)
return
self
.
_bad_request
(
error
=
f
"Show directory
{
series_directory
}
already exists!"
)
if
not
make_dir
(
series_directory
):
sickrage
.
app
.
log
.
warning
(
f
"Unable to create the folder
{
series_directory
}
, can't add the show"
)
sickrage
.
app
.
alerts
.
error
(
_
(
"Unable to add show"
),
_
(
f
"Unable to create the folder
{
series_directory
}
, can't add the show"
))
return
self
.
send_error
(
400
,
error
=
f
"Unable to create the show folder
{
series_directory
}
, can't add the show"
)
return
self
.
_bad_request
(
error
=
f
"Unable to create the show folder
{
series_directory
}
, can't add the show"
)
chmod_as_parent
(
series_directory
)
...
...
@@ -181,7 +181,7 @@ class ApiV2SeriesHandler(ApiV2BaseHandler):
sickrage
.
app
.
alerts
.
message
(
_
(
'Adding Show'
),
_
(
f
'Adding the specified show into
{
series_directory
}
'
))
return
self
.
to_
json
({
'message'
:
True
})
return
self
.
json
_response
({
'message'
:
True
})
def
patch
(
self
,
series_slug
):
warnings
,
errors
=
[],
[]
...
...
@@ -193,7 +193,7 @@ class ApiV2SeriesHandler(ApiV2BaseHandler):
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
.
_bad_request
(
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
:
...
...
@@ -307,80 +307,80 @@ class ApiV2SeriesHandler(ApiV2BaseHandler):
# commit changes to database
series
.
save
()
return
self
.
to_
json
(
series
.
to_json
(
episodes
=
True
,
details
=
True
))
return
self
.
json
_response
(
series
.
to_json
(
episodes
=
True
,
details
=
True
))
def
delete
(
self
,
series_slug
):
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
}
"
)
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
.
to_
json
({
'message'
:
True
})
return
self
.
json
_response
({
'message'
:
True
})
class
ApiV2SeriesEpisodesHandler
(
ApiV2BaseHandler
):
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
}
"
)
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
.
to_
json
(
episodes
)
return
self
.
json
_response
(
episodes
)
class
ApiV2SeriesImagesHandler
(
ApiV2BaseHandler
):
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
}
"
)
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
.
to_
json
({
'poster'
:
image
.
url
})
return
self
.
json
_response
({
'poster'
:
image
.
url
})
class
ApiV2SeriesImdbInfoHandler
(
ApiV2BaseHandler
):
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
}
"
)
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
.
to_
json
(
json_data
)
return
self
.
json
_response
(
json_data
)
class
ApiV2SeriesBlacklistHandler
(
ApiV2BaseHandler
):
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
}
"
)
return
self
.
_not_found
(
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
.
to_
json
(
json_data
)
return
self
.
json
_response
(
json_data
)
class
ApiV2SeriesWhitelistHandler
(
ApiV2BaseHandler
):
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
}
"
)
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
.
to_
json
(
json_data
)
return
self
.
json
_response
(
json_data
)
class
ApiV2SeriesRefreshHandler
(
ApiV2BaseHandler
):
...
...
@@ -389,12 +389,12 @@ class ApiV2SeriesRefreshHandler(ApiV2BaseHandler):
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
.
_not_found
(
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
}
"
))
return
self
.
_bad_request
(
error
=
_
(
f
"Unable to refresh this show, error:
{
e
}
"
))
class
ApiV2SeriesUpdateHandler
(
ApiV2BaseHandler
):
...
...
@@ -403,12 +403,12 @@ class ApiV2SeriesUpdateHandler(ApiV2BaseHandler):
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
.
_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
.
send_error
(
400
,
error
=
_
(
f
"Unable to update this show, error:
{
e
}
"
))
return
self
.
_bad_request
(
error
=
_
(
f
"Unable to update this show, error:
{
e
}
"
))
class
ApiV2SeriesEpisodesRenameHandler
(
ApiV2BaseHandler
):
...
...
@@ -443,16 +443,16 @@ class ApiV2SeriesEpisodesRenameHandler(ApiV2BaseHandler):
NotAuthorizedSchema
"""
if
not
series_slug
:
return
self
.
send_error
(
400
,
error
=
"Missing series slug"
)
return
self
.
_bad_request
(
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
}
"
)
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
.
send_error
(
400
,
error
=
"Can't rename episodes when the show location does not exist"
)
return
self
.
_bad_request
(
error
=
"Can't rename episodes when the show location does not exist"
)
for
episode
in
series
.
episodes
:
if
not
episode
.
location
:
...
...
@@ -470,7 +470,7 @@ class ApiV2SeriesEpisodesRenameHandler(ApiV2BaseHandler):
'newLocation'
:
new_location
,
})
return
self
.
to_
json
(
rename_data
)
return
self
.
json
_response
(
rename_data
)
def
post
(
self
,
series_slug
):
"""Rename list of episodes"
...
...
@@ -508,10 +508,10 @@ class ApiV2SeriesEpisodesRenameHandler(ApiV2BaseHandler):
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
.
_not_found
(
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"
)
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
)
...
...
@@ -522,7 +522,7 @@ class ApiV2SeriesEpisodesRenameHandler(ApiV2BaseHandler):
if
len
(
renamed_episodes
)
>
0
:
WebSocketMessage
(
'SHOW_RENAMED'
,
{
'seriesSlug'
:
series
.
slug
}).
push
()
return
self
.
to_
json
(
renamed_episodes
)
return
self
.
json
_response
(
renamed_episodes
)
class
ApiV2SeriesEpisodesManualSearchHandler
(
ApiV2BaseHandler
):
...
...
@@ -569,16 +569,16 @@ class ApiV2SeriesEpisodesManualSearchHandler(ApiV2BaseHandler):
# validation_errors = self._validate_schema(SeriesEpisodesManualSearchPath, self.request.path)
# if validation_errors:
# return self.
send_error(400,
error
s
=validation_errors)
# return self.
_bad_request(
error=validation_errors)
#
# validation_errors = self._validate_schema(SeriesEpisodesManualSearchSchema, self.request.arguments)
# if validation_errors:
# return self.
send_error(400,
error
s
=validation_errors)
# return self.
_bad_request(
error=validation_errors)
#
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
.
_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'
)
...
...
@@ -586,7 +586,7 @@ class ApiV2SeriesEpisodesManualSearchHandler(ApiV2BaseHandler):
episode
=
series
.
get_episode
(
int
(
season_num
),
int
(
episode_num
),
no_create
=
True
)
if
episode
is
None
:
return
self
.
send_error
(
404
,
error
=
f
"Unable to find the specified episode using slug:
{
episode_slug
}
"
)
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
),
...
...
@@ -597,9 +597,6 @@ class ApiV2SeriesEpisodesManualSearchHandler(ApiV2BaseHandler):
sickrage
.
app
.
search_queue
.
put
(
ep_queue_item
)
if
not
all
([
ep_queue_item
.
started
,
ep_queue_item
.
success
]):
return
self
.
to_
json
({
'success'
:
True
})
return
self
.
json
_response
({
'success'
:
True
})
return
self
.
send_error
(
status_code
=
404
,
error
=
_
(
f
"Unable to find season
{
season_num
}
episode
{
episode_num
}
for show
{
series
.
name
}
on search providers"
)
)
return
self
.
_not_found
(
error
=
_
(
f
"Unable to find season
{
season_num
}
episode
{
episode_num
}
for show
{
series
.
name
}
on search providers"
))
sickrage/core/webserver/handlers/api/v2/series_provider/__init__.py
View file @
3b1f1e3b
...
...
@@ -27,7 +27,7 @@ from sickrage.core.webserver.handlers.api.v2 import ApiV2BaseHandler
class
ApiV2SeriesProvidersHandler
(
ApiV2BaseHandler
):
def
get
(
self
):
return
self
.
to_
json
([{
'displayName'
:
x
.
display_name
,
'slug'
:
x
.
slug
}
for
x
in
SeriesProviderID
])
return
self
.
json
_response
([{
'displayName'
:
x
.
display_name
,
'slug'
:
x
.
slug
}
for
x
in
SeriesProviderID
])
class
ApiV2SeriesProvidersSearchHandler
(
ApiV2BaseHandler
):
...
...
@@ -37,22 +37,22 @@ class ApiV2SeriesProvidersSearchHandler(ApiV2BaseHandler):
series_provider_id
=
SeriesProviderID
.
by_slug
(
series_provider_slug
)
if
not
series_provider_id
:
return
self
.
send_error
(
400
,
reason
=
"Unable to identify a series provider using provided slug"
)
return
self
.
_bad_request
(
error
=
"Unable to identify a series provider using provided slug"
)
sickrage
.
app
.
log
.
debug
(
f
"Searching for show with term:
{
search_term
}
on series provider:
{
sickrage
.
app
.
series_providers
[
series_provider_id
].
name
}
"
)
# search via series name
results
=
sickrage
.
app
.
series_providers
[
series_provider_id
].
search
(
search_term
,
language
=
lang
)
if
not
results
:
return
self
.
send_error
(
404
,
reason
=
f
"Unable to find the series using the search term:
{
search_term
}
"
)
return
self
.
_not_found
(
error
=
f
"Unable to find the series using the search term:
{
search_term
}
"
)
return
self
.
to_
json
(
results
)
return
self
.
json
_response
(
results
)
class
ApiV2SeriesProvidersLanguagesHandler
(
ApiV2BaseHandler
):
def
get
(
self
,
series_provider_slug
):
series_provider_id
=
SeriesProviderID
.
by_slug
(
series_provider_slug
)
if
not
series_provider_id
:
return
self
.
send_error
(
404
,
reason
=
"Unable to identify a series provider using provided slug"
)
return
self
.
_not_found
(
error
=
"Unable to identify a series provider using provided slug"
)
return
self
.
to_
json
(
sickrage
.
app
.
series_providers
[
series_provider_id
].
languages
())
return
self
.
json
_response
(
sickrage
.
app
.
series_providers
[
series_provider_id
].
languages
())
sickrage/core/webserver/views/api_builder.mako
View file @
3b1f1e3b
...
...
@@ -6,7 +6,7 @@
%>
<%block name="metas">
<meta data-var="commands" data-content="${api_commands}">
##
<meta data-var="commands" data-content="${api_commands}">
<meta data-var="episodes" data-content="${episodes}">
</%block>
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment