2019-02-27 23:03:30 +00:00
import collections
2019-02-06 22:41:35 +00:00
from . import ClientAPI
2019-01-09 22:59:03 +00:00
from . import ClientConstants as CC
2019-02-13 22:26:43 +00:00
from . import ClientImportFileSeeds
2019-08-21 21:34:01 +00:00
from . import ClientMedia
2019-08-07 22:59:53 +00:00
from . import ClientNetworkingContexts
2019-03-06 23:06:22 +00:00
from . import ClientSearch
2019-02-27 23:03:30 +00:00
from . import ClientTags
2019-01-09 22:59:03 +00:00
from . import HydrusConstants as HC
from . import HydrusData
from . import HydrusExceptions
from . import HydrusGlobals as HG
2019-02-06 22:41:35 +00:00
from . import HydrusNetworking
from . import HydrusPaths
2019-01-09 22:59:03 +00:00
from . import HydrusServerResources
2019-02-27 23:03:30 +00:00
from . import HydrusTags
2019-08-07 22:59:53 +00:00
import http . cookiejar
2019-02-06 22:41:35 +00:00
import json
2015-08-05 18:42:35 +00:00
import os
2019-03-06 23:06:22 +00:00
import time
2019-02-13 22:26:43 +00:00
import traceback
2015-12-02 22:32:18 +00:00
from twisted . web . static import File as FileResource
local_booru_css = FileResource ( os . path . join ( HC . STATIC_DIR , ' local_booru_style.css ' ) , defaultType = ' text/css ' )
2015-08-05 18:42:35 +00:00
2019-02-06 22:41:35 +00:00
LOCAL_BOORU_INT_PARAMS = set ( )
LOCAL_BOORU_BYTE_PARAMS = { ' share_key ' , ' hash ' }
LOCAL_BOORU_STRING_PARAMS = set ( )
LOCAL_BOORU_JSON_PARAMS = set ( )
2019-06-26 21:27:18 +00:00
LOCAL_BOORU_JSON_BYTE_LIST_PARAMS = set ( )
2019-02-06 22:41:35 +00:00
2019-03-13 21:04:21 +00:00
CLIENT_API_INT_PARAMS = { ' file_id ' }
2019-07-17 22:10:19 +00:00
CLIENT_API_BYTE_PARAMS = { ' hash ' , ' destination_page_key ' , ' page_key ' , ' Hydrus-Client-API-Access-Key ' , ' Hydrus-Client-API-Session-Key ' }
2019-08-07 22:59:53 +00:00
CLIENT_API_STRING_PARAMS = { ' name ' , ' url ' , ' domain ' }
2019-08-21 21:34:01 +00:00
CLIENT_API_JSON_PARAMS = { ' basic_permissions ' , ' system_inbox ' , ' system_archive ' , ' tags ' , ' file_ids ' , ' only_return_identifiers ' , ' simple ' }
2019-06-26 21:27:18 +00:00
CLIENT_API_JSON_BYTE_LIST_PARAMS = { ' hashes ' }
2019-02-06 22:41:35 +00:00
def ParseLocalBooruGETArgs ( requests_args ) :
2019-06-26 21:27:18 +00:00
args = HydrusNetworking . ParseTwistedRequestGETArgs ( requests_args , LOCAL_BOORU_INT_PARAMS , LOCAL_BOORU_BYTE_PARAMS , LOCAL_BOORU_STRING_PARAMS , LOCAL_BOORU_JSON_PARAMS , LOCAL_BOORU_JSON_BYTE_LIST_PARAMS )
2019-02-06 22:41:35 +00:00
return args
def ParseClientAPIGETArgs ( requests_args ) :
2019-06-26 21:27:18 +00:00
args = HydrusNetworking . ParseTwistedRequestGETArgs ( requests_args , CLIENT_API_INT_PARAMS , CLIENT_API_BYTE_PARAMS , CLIENT_API_STRING_PARAMS , CLIENT_API_JSON_PARAMS , CLIENT_API_JSON_BYTE_LIST_PARAMS )
2019-02-06 22:41:35 +00:00
return args
2019-06-26 21:27:18 +00:00
def ParseClientAPIPOSTByteArgs ( args ) :
2019-02-27 23:03:30 +00:00
if not isinstance ( args , dict ) :
raise HydrusExceptions . BadRequestException ( ' The given parameter did not seem to be a JSON Object! ' )
parsed_request_args = HydrusNetworking . ParsedRequestArguments ( args )
2019-06-26 21:27:18 +00:00
for var_name in CLIENT_API_BYTE_PARAMS :
2019-02-27 23:03:30 +00:00
2019-06-26 21:27:18 +00:00
if var_name in parsed_request_args :
2019-02-27 23:03:30 +00:00
2019-06-26 21:27:18 +00:00
try :
2019-02-27 23:03:30 +00:00
2019-06-26 21:27:18 +00:00
v = bytes . fromhex ( parsed_request_args [ var_name ] )
2019-02-27 23:03:30 +00:00
2019-06-26 21:27:18 +00:00
if len ( v ) == 0 :
del parsed_request_args [ var_name ]
else :
parsed_request_args [ var_name ] = v
2019-02-27 23:03:30 +00:00
2019-06-26 21:27:18 +00:00
except :
raise HydrusExceptions . BadRequestException ( ' I was expecting to parse \' {} \' as a hex string, but it failed. ' . format ( var_name ) )
2019-02-27 23:03:30 +00:00
2019-06-26 21:27:18 +00:00
for var_name in CLIENT_API_JSON_BYTE_LIST_PARAMS :
2019-02-27 23:03:30 +00:00
2019-06-26 21:27:18 +00:00
if var_name in parsed_request_args :
2019-02-27 23:03:30 +00:00
2019-06-26 21:27:18 +00:00
try :
2019-02-27 23:03:30 +00:00
2019-06-26 21:27:18 +00:00
v_list = [ bytes . fromhex ( hash_hex ) for hash_hex in parsed_request_args [ var_name ] ]
2019-02-27 23:03:30 +00:00
2019-06-26 21:27:18 +00:00
v_list = [ v for v in v_list if len ( v ) > 0 ]
2019-02-27 23:03:30 +00:00
2019-06-26 21:27:18 +00:00
if len ( v_list ) == 0 :
del parsed_request_args [ var_name ]
else :
parsed_request_args [ var_name ] = v_list
except :
raise HydrusExceptions . BadRequestException ( ' I was expecting to parse \' {} \' as a list of hex strings, but it failed. ' . format ( var_name ) )
2019-02-27 23:03:30 +00:00
return parsed_request_args
2019-02-06 22:41:35 +00:00
2019-02-27 23:03:30 +00:00
def ParseClientAPIPOSTArgs ( request ) :
2019-02-06 22:41:35 +00:00
request . content . seek ( 0 )
if not request . requestHeaders . hasHeader ( ' Content-Type ' ) :
2019-02-27 23:03:30 +00:00
parsed_request_args = HydrusNetworking . ParsedRequestArguments ( )
2019-02-06 22:41:35 +00:00
total_bytes_read = 0
else :
content_types = request . requestHeaders . getRawHeaders ( ' Content-Type ' )
content_type = content_types [ 0 ]
try :
mime = HC . mime_enum_lookup [ content_type ]
except :
2019-02-27 23:03:30 +00:00
raise HydrusExceptions . BadRequestException ( ' Did not recognise Content-Type header! ' )
2019-02-06 22:41:35 +00:00
total_bytes_read = 0
if mime == HC . APPLICATION_JSON :
json_bytes = request . content . read ( )
total_bytes_read + = len ( json_bytes )
json_string = str ( json_bytes , ' utf-8 ' )
2019-02-27 23:03:30 +00:00
args = json . loads ( json_string )
2019-06-26 21:27:18 +00:00
parsed_request_args = ParseClientAPIPOSTByteArgs ( args )
2019-02-06 22:41:35 +00:00
else :
2019-02-27 23:03:30 +00:00
parsed_request_args = HydrusNetworking . ParsedRequestArguments ( )
2019-02-06 22:41:35 +00:00
( os_file_handle , temp_path ) = HydrusPaths . GetTempPath ( )
request . temp_file_info = ( os_file_handle , temp_path )
with open ( temp_path , ' wb ' ) as f :
for block in HydrusPaths . ReadFileLikeAsBlocks ( request . content ) :
f . write ( block )
total_bytes_read + = len ( block )
2019-02-27 23:03:30 +00:00
return ( parsed_request_args , total_bytes_read )
2019-02-06 22:41:35 +00:00
2019-03-06 23:06:22 +00:00
def ParseClientAPISearchPredicates ( request ) :
default_search_values = { }
default_search_values [ ' tags ' ] = [ ]
default_search_values [ ' system_inbox ' ] = False
default_search_values [ ' system_archive ' ] = False
for ( key , value ) in default_search_values . items ( ) :
if key not in request . parsed_request_args :
request . parsed_request_args [ key ] = value
tags = request . parsed_request_args [ ' tags ' ]
system_inbox = request . parsed_request_args [ ' system_inbox ' ]
system_archive = request . parsed_request_args [ ' system_archive ' ]
negated_tags = [ tag for tag in tags if tag . startswith ( ' - ' ) ]
tags = [ tag for tag in tags if not tag . startswith ( ' - ' ) ]
negated_tags = HydrusTags . CleanTags ( negated_tags )
tags = HydrusTags . CleanTags ( tags )
request . client_api_permissions . CheckCanSearchTags ( tags )
predicates = [ ]
for tag in negated_tags :
2020-03-11 21:52:11 +00:00
predicates . append ( ClientSearch . Predicate ( predicate_type = ClientSearch . PREDICATE_TYPE_TAG , value = tag , inclusive = False ) )
2019-03-06 23:06:22 +00:00
for tag in tags :
2020-03-11 21:52:11 +00:00
predicates . append ( ClientSearch . Predicate ( predicate_type = ClientSearch . PREDICATE_TYPE_TAG , value = tag ) )
2019-03-06 23:06:22 +00:00
if system_inbox :
2020-03-11 21:52:11 +00:00
predicates . append ( ClientSearch . Predicate ( predicate_type = ClientSearch . PREDICATE_TYPE_SYSTEM_INBOX ) )
2019-03-06 23:06:22 +00:00
elif system_archive :
2020-03-11 21:52:11 +00:00
predicates . append ( ClientSearch . Predicate ( predicate_type = ClientSearch . PREDICATE_TYPE_SYSTEM_ARCHIVE ) )
2019-03-06 23:06:22 +00:00
return predicates
2017-03-02 02:14:56 +00:00
class HydrusResourceBooru ( HydrusServerResources . HydrusResource ) :
2015-08-05 18:42:35 +00:00
2019-02-06 22:41:35 +00:00
def _callbackParseGETArgs ( self , request ) :
2019-02-27 23:03:30 +00:00
parsed_request_args = ParseLocalBooruGETArgs ( request . args )
2019-02-06 22:41:35 +00:00
2019-02-27 23:03:30 +00:00
request . parsed_request_args = parsed_request_args
2019-02-06 22:41:35 +00:00
return request
def _callbackParsePOSTArgs ( self , request ) :
return request
2017-06-21 21:15:59 +00:00
def _reportDataUsed ( self , request , num_bytes ) :
2015-08-05 18:42:35 +00:00
2017-06-21 21:15:59 +00:00
self . _service . ReportDataUsed ( num_bytes )
2015-08-05 18:42:35 +00:00
2017-06-21 21:15:59 +00:00
def _reportRequestUsed ( self , request ) :
2015-08-05 18:42:35 +00:00
2017-06-21 21:15:59 +00:00
self . _service . ReportRequestUsed ( )
2015-08-05 18:42:35 +00:00
2017-03-02 02:14:56 +00:00
def _checkService ( self , request ) :
2015-08-05 18:42:35 +00:00
2017-03-02 02:14:56 +00:00
HydrusServerResources . HydrusResource . _checkService ( self , request )
2015-08-05 18:42:35 +00:00
2017-06-07 22:05:15 +00:00
if not self . _service . BandwidthOK ( ) :
2017-03-02 02:14:56 +00:00
raise HydrusExceptions . BandwidthException ( ' This service has run out of bandwidth. Please try again later. ' )
2015-08-05 18:42:35 +00:00
2017-03-02 02:14:56 +00:00
class HydrusResourceBooruFile ( HydrusResourceBooru ) :
2015-08-05 18:42:35 +00:00
def _threadDoGETJob ( self , request ) :
2019-02-27 23:03:30 +00:00
share_key = request . parsed_request_args [ ' share_key ' ]
hash = request . parsed_request_args [ ' hash ' ]
2015-08-05 18:42:35 +00:00
2017-12-06 22:06:56 +00:00
HG . client_controller . local_booru_manager . CheckFileAuthorised ( share_key , hash )
2015-08-05 18:42:35 +00:00
2018-03-07 22:48:29 +00:00
media_result = HG . client_controller . local_booru_manager . GetMediaResult ( share_key , hash )
mime = media_result . GetMime ( )
2017-06-28 20:23:21 +00:00
client_files_manager = HG . client_controller . client_files_manager
2015-12-02 22:32:18 +00:00
2018-03-07 22:48:29 +00:00
path = client_files_manager . GetFilePath ( hash , mime )
2015-08-05 18:42:35 +00:00
2018-03-07 22:48:29 +00:00
response_context = HydrusServerResources . ResponseContext ( 200 , mime = mime , path = path )
2015-08-05 18:42:35 +00:00
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceBooruGallery ( HydrusResourceBooru ) :
2015-08-05 18:42:35 +00:00
def _threadDoGETJob ( self , request ) :
# in future, make this a standard frame with a search key that'll load xml or yaml AJAX stuff
# with file info included, so the page can sort and whatever
2019-08-21 21:34:01 +00:00
share_key = request . parsed_request_args . GetValue ( ' share_key ' , bytes )
2015-08-05 18:42:35 +00:00
2017-12-06 22:06:56 +00:00
local_booru_manager = HG . client_controller . local_booru_manager
2015-08-05 18:42:35 +00:00
local_booru_manager . CheckShareAuthorised ( share_key )
( name , text , timeout , media_results ) = local_booru_manager . GetGalleryInfo ( share_key )
body = ''' <html>
< head > '''
if name == ' ' : body + = '''
< title > hydrus network local booru share < / title > '''
else : body + = '''
< title > ''' + name + ''' < / title > '''
body + = '''
< link href = " hydrus.ico " rel = " shortcut icon " / >
< link href = " style.css " rel = " stylesheet " type = " text/css " / > '''
( thumbnail_width , thumbnail_height ) = HC . options [ ' thumbnail_dimensions ' ]
body + = '''
< style >
. thumbnail_container { width : ''' + str( thumbnail_width ) + ''' px ; height : ''' + str( thumbnail_height ) + ''' px ; }
< / style > '''
body + = '''
< / head >
< body > '''
body + = '''
< div class = " timeout " > This share ''' + HydrusData.ConvertTimestampToPrettyExpires( timeout ) + ''' . < / div > '''
if name != ' ' : body + = '''
< h3 > ''' + name + ''' < / h3 > '''
if text != ' ' :
newline = ''' </p>
< p > '''
body + = '''
< p > ''' + text.replace( os.linesep, newline ).replace( ' \n ' , newline ) + ''' < / p > '''
body + = '''
< div class = " media " > '''
for media_result in media_results :
hash = media_result . GetHash ( )
mime = media_result . GetMime ( )
# if mime in flash or pdf or whatever, get other thumbnail
body + = '''
< span class = " thumbnail " >
< span class = " thumbnail_container " >
2019-01-09 22:59:03 +00:00
< a href = " page?share_key= ' ' ' + share_key.hex() + ' ' ' &hash= ' ' ' + hash.hex() + ' ' ' " >
< img src = " thumbnail?share_key= ' ' ' + share_key.hex() + ' ' ' &hash= ' ' ' + hash.hex() + ' ' ' " / >
2015-08-05 18:42:35 +00:00
< / a >
< / span >
< / span > '''
body + = '''
< / div >
2015-10-21 21:53:10 +00:00
< div class = " footer " > < a href = " https://hydrusnetwork.github.io/hydrus/ " > hydrus network < / a > < / div >
2015-08-05 18:42:35 +00:00
< / body >
< / html > '''
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . TEXT_HTML , body = body )
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceBooruPage ( HydrusResourceBooru ) :
2015-08-05 18:42:35 +00:00
def _threadDoGETJob ( self , request ) :
2019-08-21 21:34:01 +00:00
share_key = request . parsed_request_args . GetValue ( ' share_key ' , bytes )
hash = request . parsed_request_args . GetValue ( ' hash ' , bytes )
2015-08-05 18:42:35 +00:00
2017-12-06 22:06:56 +00:00
local_booru_manager = HG . client_controller . local_booru_manager
2015-08-05 18:42:35 +00:00
local_booru_manager . CheckFileAuthorised ( share_key , hash )
( name , text , timeout , media_result ) = local_booru_manager . GetPageInfo ( share_key , hash )
body = ''' <html>
< head > '''
if name == ' ' : body + = '''
< title > hydrus network local booru share < / title > '''
else : body + = '''
< title > ''' + name + ''' < / title > '''
body + = '''
< link href = " hydrus.ico " rel = " shortcut icon " / >
< link href = " style.css " rel = " stylesheet " type = " text/css " / > '''
body + = '''
< / head >
< body > '''
body + = '''
< div class = " timeout " > This share ''' + HydrusData.ConvertTimestampToPrettyExpires( timeout ) + ''' . < / div > '''
if name != ' ' : body + = '''
< h3 > ''' + name + ''' < / h3 > '''
if text != ' ' :
newline = ''' </p>
< p > '''
body + = '''
< p > ''' + text.replace( os.linesep, newline ).replace( ' \n ' , newline ) + ''' < / p > '''
body + = '''
< div class = " media " > '''
mime = media_result . GetMime ( )
2020-01-22 21:04:43 +00:00
if mime in HC . IMAGES or mime in HC . ANIMATIONS :
2015-08-05 18:42:35 +00:00
( width , height ) = media_result . GetResolution ( )
body + = '''
2019-01-09 22:59:03 +00:00
< img width = " ' ' ' + str( width ) + ' ' ' " height = " ' ' ' + str( height ) + ' ' ' " src = " file?share_key= ' ' ' + share_key.hex() + ' ' ' &hash= ' ' ' + hash.hex() + ' ' ' " / > '''
2015-08-05 18:42:35 +00:00
elif mime in HC . VIDEO :
( width , height ) = media_result . GetResolution ( )
body + = '''
2019-01-09 22:59:03 +00:00
< video width = " ' ' ' + str( width ) + ' ' ' " height = " ' ' ' + str( height ) + ' ' ' " controls = " " loop = " " autoplay = " " src = " file?share_key= ' ' ' + share_key.hex() + ' ' ' &hash= ' ' ' + hash.hex() + ' ' ' " / >
< p > < a href = " file?share_key= ' ' ' + share_key.hex() + ' ' ' &hash= ' ' ' + hash.hex() + ' ' ' " > link to ''' + HC.mime_string_lookup[ mime ] + ''' file < / a > < / p > '''
2015-08-05 18:42:35 +00:00
elif mime == HC . APPLICATION_FLASH :
( width , height ) = media_result . GetResolution ( )
body + = '''
2019-01-09 22:59:03 +00:00
< embed width = " ' ' ' + str( width ) + ' ' ' " height = " ' ' ' + str( height ) + ' ' ' " src = " file?share_key= ' ' ' + share_key.hex() + ' ' ' &hash= ' ' ' + hash.hex() + ' ' ' " / >
< p > < a href = " file?share_key= ' ' ' + share_key.hex() + ' ' ' &hash= ' ' ' + hash.hex() + ' ' ' " > link to ''' + HC.mime_string_lookup[ mime ] + ''' file < / a > < / p > '''
2015-08-05 18:42:35 +00:00
else :
body + = '''
2019-01-09 22:59:03 +00:00
< p > < a href = " file?share_key= ' ' ' + share_key.hex() + ' ' ' &hash= ' ' ' + hash.hex() + ' ' ' " > link to ''' + HC.mime_string_lookup[ mime ] + ''' file < / a > < / p > '''
2015-08-05 18:42:35 +00:00
body + = '''
< / div >
2015-10-21 21:53:10 +00:00
< div class = " footer " > < a href = " https://hydrusnetwork.github.io/hydrus/ " > hydrus network < / a > < / div >
2015-08-05 18:42:35 +00:00
< / body >
< / html > '''
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . TEXT_HTML , body = body )
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceBooruThumbnail ( HydrusResourceBooru ) :
2015-08-05 18:42:35 +00:00
def _threadDoGETJob ( self , request ) :
2019-08-21 21:34:01 +00:00
share_key = request . parsed_request_args . GetValue ( ' share_key ' , bytes )
hash = request . parsed_request_args . GetValue ( ' hash ' , bytes )
2015-08-05 18:42:35 +00:00
2017-12-06 22:06:56 +00:00
local_booru_manager = HG . client_controller . local_booru_manager
2015-08-05 18:42:35 +00:00
local_booru_manager . CheckFileAuthorised ( share_key , hash )
media_result = local_booru_manager . GetMediaResult ( share_key , hash )
mime = media_result . GetMime ( )
2017-03-02 02:14:56 +00:00
response_context_mime = HC . IMAGE_PNG
2016-06-08 20:27:22 +00:00
if mime in HC . MIMES_WITH_THUMBNAILS :
2017-06-28 20:23:21 +00:00
client_files_manager = HG . client_controller . client_files_manager
2016-06-08 20:27:22 +00:00
2019-04-24 22:18:50 +00:00
path = client_files_manager . GetThumbnailPath ( media_result )
2016-06-08 20:27:22 +00:00
2017-03-02 02:14:56 +00:00
response_context_mime = HC . APPLICATION_UNKNOWN
2018-03-07 22:48:29 +00:00
elif mime in HC . AUDIO :
path = os . path . join ( HC . STATIC_DIR , ' audio.png ' )
elif mime == HC . APPLICATION_PDF :
path = os . path . join ( HC . STATIC_DIR , ' pdf.png ' )
2019-03-20 21:22:10 +00:00
elif mime == HC . APPLICATION_PSD :
path = os . path . join ( HC . STATIC_DIR , ' psd.png ' )
2018-03-07 22:48:29 +00:00
else :
path = os . path . join ( HC . STATIC_DIR , ' hydrus.png ' )
2015-08-05 18:42:35 +00:00
2017-03-02 02:14:56 +00:00
response_context = HydrusServerResources . ResponseContext ( 200 , mime = response_context_mime , path = path )
2015-08-05 18:42:35 +00:00
return response_context
2019-02-06 22:41:35 +00:00
class HydrusResourceClientAPI ( HydrusServerResources . HydrusResource ) :
def _callbackParseGETArgs ( self , request ) :
2019-02-27 23:03:30 +00:00
parsed_request_args = ParseClientAPIGETArgs ( request . args )
2019-02-06 22:41:35 +00:00
2019-02-27 23:03:30 +00:00
request . parsed_request_args = parsed_request_args
2019-02-06 22:41:35 +00:00
return request
def _callbackParsePOSTArgs ( self , request ) :
2019-02-27 23:03:30 +00:00
( parsed_request_args , total_bytes_read ) = ParseClientAPIPOSTArgs ( request )
2019-02-06 22:41:35 +00:00
self . _reportDataUsed ( request , total_bytes_read )
2019-02-27 23:03:30 +00:00
request . parsed_request_args = parsed_request_args
2019-02-06 22:41:35 +00:00
return request
def _reportDataUsed ( self , request , num_bytes ) :
self . _service . ReportDataUsed ( num_bytes )
def _reportRequestUsed ( self , request ) :
self . _service . ReportRequestUsed ( )
def _checkService ( self , request ) :
HydrusServerResources . HydrusResource . _checkService ( self , request )
if not self . _service . BandwidthOK ( ) :
raise HydrusExceptions . BandwidthException ( ' This service has run out of bandwidth. Please try again later. ' )
class HydrusResourceClientAPIPermissionsRequest ( HydrusResourceClientAPI ) :
2015-08-05 18:42:35 +00:00
def _threadDoGETJob ( self , request ) :
2019-02-06 22:41:35 +00:00
if not ClientAPI . api_request_dialog_open :
raise HydrusExceptions . InsufficientCredentialsException ( ' The permission registration dialog is not open. Please open it under " review services " in the hydrus client. ' )
2019-08-21 21:34:01 +00:00
name = request . parsed_request_args . GetValue ( ' name ' , str )
basic_permissions = request . parsed_request_args . GetValue ( ' basic_permissions ' , list )
2019-02-06 22:41:35 +00:00
basic_permissions = [ int ( value ) for value in basic_permissions ]
api_permissions = ClientAPI . APIPermissions ( name = name , basic_permissions = basic_permissions )
ClientAPI . last_api_permissions_request = api_permissions
access_key = api_permissions . GetAccessKey ( )
2019-02-13 22:26:43 +00:00
body_dict = { }
body_dict [ ' access_key ' ] = access_key . hex ( )
body = json . dumps ( body_dict )
2019-02-06 22:41:35 +00:00
2019-02-13 22:26:43 +00:00
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
2019-02-06 22:41:35 +00:00
return response_context
class HydrusResourceClientAPIVersion ( HydrusResourceClientAPI ) :
def _threadDoGETJob ( self , request ) :
2019-02-13 22:26:43 +00:00
body_dict = { }
body_dict [ ' version ' ] = HC . CLIENT_API_VERSION
body = json . dumps ( body_dict )
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
2019-02-06 22:41:35 +00:00
return response_context
class HydrusResourceClientAPIRestricted ( HydrusResourceClientAPI ) :
2019-06-26 21:27:18 +00:00
def _callbackCheckAccountRestrictions ( self , request ) :
2019-02-06 22:41:35 +00:00
2019-06-26 21:27:18 +00:00
HydrusResourceClientAPI . _callbackCheckAccountRestrictions ( self , request )
2019-02-06 22:41:35 +00:00
2019-06-26 21:27:18 +00:00
self . _CheckAPIPermissions ( request )
2019-02-06 22:41:35 +00:00
return request
2019-07-03 22:49:27 +00:00
def _callbackEstablishAccountFromHeader ( self , request ) :
2019-02-06 22:41:35 +00:00
2019-07-03 22:49:27 +00:00
access_key = self . _ParseClientAPIAccessKey ( request , ' header ' )
if access_key is not None :
self . _EstablishAPIPermissions ( request , access_key )
return request
2019-02-06 22:41:35 +00:00
2019-07-03 22:49:27 +00:00
def _callbackEstablishAccountFromArgs ( self , request ) :
2019-02-06 22:41:35 +00:00
2019-07-03 22:49:27 +00:00
if request . client_api_permissions is None :
access_key = self . _ParseClientAPIAccessKey ( request , ' args ' )
if access_key is not None :
self . _EstablishAPIPermissions ( request , access_key )
if request . client_api_permissions is None :
raise HydrusExceptions . MissingCredentialsException ( ' No access key or session key provided! ' )
return request
def _CheckAPIPermissions ( self , request ) :
2019-06-26 21:27:18 +00:00
2019-07-03 22:49:27 +00:00
raise NotImplementedError ( )
def _EstablishAPIPermissions ( self , request , access_key ) :
2019-02-06 22:41:35 +00:00
try :
2019-07-03 22:49:27 +00:00
api_permissions = HG . client_controller . client_api_manager . GetPermissions ( access_key )
2019-02-06 22:41:35 +00:00
2019-06-26 21:27:18 +00:00
except HydrusExceptions . DataMissing as e :
2019-02-06 22:41:35 +00:00
2019-06-26 21:27:18 +00:00
raise HydrusExceptions . InsufficientCredentialsException ( str ( e ) )
2019-02-06 22:41:35 +00:00
request . client_api_permissions = api_permissions
2019-07-03 22:49:27 +00:00
def _ParseClientAPIKey ( self , request , source , name_of_key ) :
key = None
if source == ' header ' :
if request . requestHeaders . hasHeader ( name_of_key ) :
key_texts = request . requestHeaders . getRawHeaders ( name_of_key )
key_text = key_texts [ 0 ]
try :
key = bytes . fromhex ( key_text )
except :
raise Exception ( ' Problem parsing {} ! ' . format ( name_of_key ) )
elif source == ' args ' :
if name_of_key in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
key = request . parsed_request_args . GetValue ( name_of_key , bytes )
2019-07-03 22:49:27 +00:00
return key
def _ParseClientAPIAccessKey ( self , request , source ) :
access_key = self . _ParseClientAPIKey ( request , source , ' Hydrus-Client-API-Access-Key ' )
if access_key is None :
session_key = self . _ParseClientAPIKey ( request , source , ' Hydrus-Client-API-Session-Key ' )
if session_key is None :
return None
try :
access_key = HG . client_controller . client_api_manager . GetAccessKey ( session_key )
except HydrusExceptions . DataMissing as e :
raise HydrusExceptions . SessionException ( str ( e ) )
return access_key
2019-06-26 21:27:18 +00:00
class HydrusResourceClientAPIRestrictedAccount ( HydrusResourceClientAPIRestricted ) :
def _CheckAPIPermissions ( self , request ) :
pass
class HydrusResourceClientAPIRestrictedAccountSessionKey ( HydrusResourceClientAPIRestrictedAccount ) :
def _threadDoGETJob ( self , request ) :
new_session_key = HG . client_controller . client_api_manager . GenerateSessionKey ( request . client_api_permissions . GetAccessKey ( ) )
body_dict = { }
body_dict [ ' session_key ' ] = new_session_key . hex ( )
body = json . dumps ( body_dict )
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
return response_context
class HydrusResourceClientAPIRestrictedAccountVerify ( HydrusResourceClientAPIRestrictedAccount ) :
def _threadDoGETJob ( self , request ) :
api_permissions = request . client_api_permissions
basic_permissions = api_permissions . GetBasicPermissions ( )
human_description = api_permissions . ToHumanString ( )
body_dict = { }
body_dict [ ' basic_permissions ' ] = list ( basic_permissions ) # set->list for json
body_dict [ ' human_description ' ] = human_description
body = json . dumps ( body_dict )
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
return response_context
2019-02-13 22:26:43 +00:00
class HydrusResourceClientAPIRestrictedAddFile ( HydrusResourceClientAPIRestricted ) :
2019-02-06 22:41:35 +00:00
def _CheckAPIPermissions ( self , request ) :
request . client_api_permissions . CheckPermission ( ClientAPI . CLIENT_API_PERMISSION_ADD_FILES )
def _threadDoPOSTJob ( self , request ) :
2019-02-13 22:26:43 +00:00
if not hasattr ( request , ' temp_file_info ' ) :
2019-08-21 21:34:01 +00:00
path = request . parsed_request_args . GetValue ( ' path ' , str )
2019-02-13 22:26:43 +00:00
if not os . path . exists ( path ) :
2019-02-27 23:03:30 +00:00
raise HydrusExceptions . BadRequestException ( ' Path " {} " does not exist! ' . format ( path ) )
2019-02-13 22:26:43 +00:00
( os_file_handle , temp_path ) = HydrusPaths . GetTempPath ( )
request . temp_file_info = ( os_file_handle , temp_path )
HydrusPaths . MirrorFile ( path , temp_path )
( os_file_handle , temp_path ) = request . temp_file_info
2019-02-06 22:41:35 +00:00
2019-02-13 22:26:43 +00:00
file_import_options = HG . client_controller . new_options . GetDefaultFileImportOptions ( ' quiet ' )
2019-02-06 22:41:35 +00:00
2019-02-13 22:26:43 +00:00
file_import_job = ClientImportFileSeeds . FileImportJob ( temp_path , file_import_options )
2019-02-06 22:41:35 +00:00
2019-02-13 22:26:43 +00:00
try :
2019-05-08 21:06:42 +00:00
( status , hash , note ) = file_import_job . DoWork ( )
2019-02-13 22:26:43 +00:00
except :
status = CC . STATUS_ERROR
hash = file_import_job . GetHash ( )
note = traceback . format_exc ( )
body_dict = { }
body_dict [ ' status ' ] = status
body_dict [ ' hash ' ] = hash . hex ( )
body_dict [ ' note ' ] = note
2019-02-06 22:41:35 +00:00
body = json . dumps ( body_dict )
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
return response_context
class HydrusResourceClientAPIRestrictedAddTags ( HydrusResourceClientAPIRestricted ) :
def _CheckAPIPermissions ( self , request ) :
request . client_api_permissions . CheckPermission ( ClientAPI . CLIENT_API_PERMISSION_ADD_TAGS )
2019-02-13 22:26:43 +00:00
class HydrusResourceClientAPIRestrictedAddTagsAddTags ( HydrusResourceClientAPIRestrictedAddTags ) :
2019-02-06 22:41:35 +00:00
def _threadDoPOSTJob ( self , request ) :
2019-02-27 23:03:30 +00:00
hashes = set ( )
if ' hash ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
hash = request . parsed_request_args . GetValue ( ' hash ' , bytes )
2019-02-27 23:03:30 +00:00
hashes . add ( hash )
if ' hashes ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
more_hashes = request . parsed_request_args . GetValue ( ' hashes ' , list )
2019-02-27 23:03:30 +00:00
2019-04-17 21:51:50 +00:00
hashes . update ( more_hashes )
2019-02-27 23:03:30 +00:00
if len ( hashes ) == 0 :
raise HydrusExceptions . BadRequestException ( ' There were no hashes given! ' )
#
2019-08-21 21:34:01 +00:00
add_siblings_and_parents = request . parsed_request_args . GetValue ( ' add_siblings_and_parents ' , bool , default_value = True )
2019-04-17 21:51:50 +00:00
2019-02-27 23:03:30 +00:00
service_keys_to_content_updates = collections . defaultdict ( list )
if ' service_names_to_tags ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
service_names_to_tags = request . parsed_request_args . GetValue ( ' service_names_to_tags ' , dict )
2019-02-27 23:03:30 +00:00
for ( service_name , tags ) in service_names_to_tags . items ( ) :
try :
2020-03-11 21:52:11 +00:00
service_key = HG . client_controller . services_manager . GetServiceKeyFromName ( HC . REAL_TAG_SERVICES , service_name )
2019-02-27 23:03:30 +00:00
except :
raise HydrusExceptions . BadRequestException ( ' Could not find the service " {} " ! ' . format ( service_name ) )
2019-09-18 22:40:39 +00:00
service = HG . client_controller . services_manager . GetService ( service_key )
2019-02-27 23:03:30 +00:00
tags = HydrusTags . CleanTags ( tags )
if len ( tags ) == 0 :
continue
2019-09-18 22:40:39 +00:00
if service . GetServiceType ( ) == HC . LOCAL_TAG :
2019-02-27 23:03:30 +00:00
content_action = HC . CONTENT_UPDATE_ADD
else :
content_action = HC . CONTENT_UPDATE_PEND
2019-04-17 21:51:50 +00:00
if add_siblings_and_parents :
siblings_manager = HG . client_controller . tag_siblings_manager
tags = siblings_manager . CollapseTags ( service_key , tags )
parents_manager = HG . client_controller . tag_parents_manager
tags = parents_manager . ExpandTags ( service_key , tags )
2019-02-27 23:03:30 +00:00
content_updates = [ HydrusData . ContentUpdate ( HC . CONTENT_TYPE_MAPPINGS , content_action , ( tag , hashes ) ) for tag in tags ]
service_keys_to_content_updates [ service_key ] . extend ( content_updates )
if ' service_names_to_actions_to_tags ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
service_names_to_actions_to_tags = request . parsed_request_args . GetValue ( ' service_names_to_actions_to_tags ' , dict )
2019-02-27 23:03:30 +00:00
for ( service_name , actions_to_tags ) in service_names_to_actions_to_tags . items ( ) :
try :
2020-03-11 21:52:11 +00:00
service_key = HG . client_controller . services_manager . GetServiceKeyFromName ( HC . REAL_TAG_SERVICES , service_name )
2019-02-27 23:03:30 +00:00
except :
raise HydrusExceptions . BadRequestException ( ' Could not find the service " {} " ! ' . format ( service_name ) )
2019-09-18 22:40:39 +00:00
service = HG . client_controller . services_manager . GetService ( service_key )
2019-02-27 23:03:30 +00:00
for ( content_action , tags ) in actions_to_tags . items ( ) :
2019-03-13 21:04:21 +00:00
content_action = int ( content_action )
2019-02-27 23:03:30 +00:00
tags = HydrusTags . CleanTags ( tags )
if len ( tags ) == 0 :
continue
2019-09-18 22:40:39 +00:00
if service . GetServiceType ( ) == HC . LOCAL_TAG :
2019-02-27 23:03:30 +00:00
if content_action not in ( HC . CONTENT_UPDATE_ADD , HC . CONTENT_UPDATE_DELETE ) :
continue
else :
if content_action in ( HC . CONTENT_UPDATE_ADD , HC . CONTENT_UPDATE_DELETE ) :
continue
2019-04-17 21:51:50 +00:00
if content_action in ( HC . CONTENT_UPDATE_ADD , HC . CONTENT_UPDATE_PEND ) and add_siblings_and_parents :
siblings_manager = HG . client_controller . tag_siblings_manager
tags = siblings_manager . CollapseTags ( service_key , tags )
parents_manager = HG . client_controller . tag_parents_manager
tags = parents_manager . ExpandTags ( service_key , tags )
2019-02-27 23:03:30 +00:00
if content_action == HC . CONTENT_UPDATE_PETITION :
if isinstance ( tags [ 0 ] , str ) :
tags_and_reasons = [ ( tag , ' Petitioned from API ' ) for tag in tags ]
else :
tags_and_reasons = tags
2019-04-10 22:50:53 +00:00
content_updates = [ HydrusData . ContentUpdate ( HC . CONTENT_TYPE_MAPPINGS , content_action , ( tag , hashes ) , reason = reason ) for ( tag , reason ) in tags_and_reasons ]
2019-02-27 23:03:30 +00:00
else :
content_updates = [ HydrusData . ContentUpdate ( HC . CONTENT_TYPE_MAPPINGS , content_action , ( tag , hashes ) ) for tag in tags ]
service_keys_to_content_updates [ service_key ] . extend ( content_updates )
2019-02-06 22:41:35 +00:00
2019-02-27 23:03:30 +00:00
if len ( service_keys_to_content_updates ) > 0 :
HG . client_controller . WriteSynchronous ( ' content_updates ' , service_keys_to_content_updates )
2019-02-06 22:41:35 +00:00
response_context = HydrusServerResources . ResponseContext ( 200 )
return response_context
2019-02-13 22:26:43 +00:00
class HydrusResourceClientAPIRestrictedAddTagsGetTagServices ( HydrusResourceClientAPIRestrictedAddTags ) :
def _threadDoGETJob ( self , request ) :
local_tags = HG . client_controller . services_manager . GetServices ( ( HC . LOCAL_TAG , ) )
tag_repos = HG . client_controller . services_manager . GetServices ( ( HC . TAG_REPOSITORY , ) )
body_dict = { }
body_dict [ ' local_tags ' ] = [ service . GetName ( ) for service in local_tags ]
body_dict [ ' tag_repositories ' ] = [ service . GetName ( ) for service in tag_repos ]
body = json . dumps ( body_dict )
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
return response_context
2019-02-27 23:03:30 +00:00
class HydrusResourceClientAPIRestrictedAddTagsCleanTags ( HydrusResourceClientAPIRestrictedAddTags ) :
def _threadDoGETJob ( self , request ) :
2019-08-21 21:34:01 +00:00
tags = request . parsed_request_args . GetValue ( ' tags ' , list )
2019-02-27 23:03:30 +00:00
tags = list ( HydrusTags . CleanTags ( tags ) )
tags = HydrusTags . SortNumericTags ( tags )
body_dict = { }
body_dict [ ' tags ' ] = tags
body = json . dumps ( body_dict )
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
return response_context
2019-02-06 22:41:35 +00:00
class HydrusResourceClientAPIRestrictedAddURLs ( HydrusResourceClientAPIRestricted ) :
def _CheckAPIPermissions ( self , request ) :
request . client_api_permissions . CheckPermission ( ClientAPI . CLIENT_API_PERMISSION_ADD_URLS )
2019-02-27 23:03:30 +00:00
class HydrusResourceClientAPIRestrictedAddURLsAssociateURL ( HydrusResourceClientAPIRestrictedAddURLs ) :
def _threadDoPOSTJob ( self , request ) :
urls_to_add = [ ]
if ' url_to_add ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
url = request . parsed_request_args . GetValue ( ' url_to_add ' , str )
2019-02-27 23:03:30 +00:00
urls_to_add . append ( url )
if ' urls_to_add ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
urls = request . parsed_request_args . GetValue ( ' urls_to_add ' , list )
2019-02-27 23:03:30 +00:00
for url in urls :
if not isinstance ( url , str ) :
continue
urls_to_add . append ( url )
urls_to_delete = [ ]
if ' url_to_delete ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
url = request . parsed_request_args . GetValue ( ' url_to_delete ' , str )
2019-02-27 23:03:30 +00:00
urls_to_delete . append ( url )
if ' urls_to_delete ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
urls = request . parsed_request_args . GetValue ( ' urls_to_delete ' , list )
2019-02-27 23:03:30 +00:00
for url in urls :
if not isinstance ( url , str ) :
continue
urls_to_delete . append ( url )
2019-08-21 21:34:01 +00:00
if len ( urls_to_add ) == 0 and len ( urls_to_delete ) == 0 :
raise HydrusExceptions . BadRequestException ( ' Did not find any URLs to add or delete! ' )
2019-02-27 23:03:30 +00:00
applicable_hashes = [ ]
if ' hash ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
hash = request . parsed_request_args . GetValue ( ' hash ' , bytes )
applicable_hashes . append ( hash )
2019-02-27 23:03:30 +00:00
if ' hashes ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
hashes = request . parsed_request_args . GetValue ( ' hashes ' , list )
applicable_hashes . extend ( hashes )
2019-02-27 23:03:30 +00:00
2019-08-21 21:34:01 +00:00
if len ( applicable_hashes ) == 0 :
2019-02-27 23:03:30 +00:00
2019-08-21 21:34:01 +00:00
raise HydrusExceptions . BadRequestException ( ' Did not find any hashes to apply the urls to! ' )
2019-02-27 23:03:30 +00:00
service_keys_to_content_updates = collections . defaultdict ( list )
if len ( urls_to_add ) > 0 :
content_update = HydrusData . ContentUpdate ( HC . CONTENT_TYPE_URLS , HC . CONTENT_UPDATE_ADD , ( urls_to_add , applicable_hashes ) )
service_keys_to_content_updates [ CC . COMBINED_LOCAL_FILE_SERVICE_KEY ] . append ( content_update )
if len ( urls_to_delete ) > 0 :
content_update = HydrusData . ContentUpdate ( HC . CONTENT_TYPE_URLS , HC . CONTENT_UPDATE_DELETE , ( urls_to_delete , applicable_hashes ) )
service_keys_to_content_updates [ CC . COMBINED_LOCAL_FILE_SERVICE_KEY ] . append ( content_update )
HG . client_controller . WriteSynchronous ( ' content_updates ' , service_keys_to_content_updates )
response_context = HydrusServerResources . ResponseContext ( 200 )
return response_context
2019-02-13 22:26:43 +00:00
class HydrusResourceClientAPIRestrictedAddURLsGetURLFiles ( HydrusResourceClientAPIRestrictedAddURLs ) :
2019-02-06 22:41:35 +00:00
def _threadDoGETJob ( self , request ) :
2019-08-21 21:34:01 +00:00
url = request . parsed_request_args . GetValue ( ' url ' , str )
2019-02-06 22:41:35 +00:00
2019-07-03 22:49:27 +00:00
if url == ' ' :
raise HydrusExceptions . BadRequestException ( ' Given URL was empty! ' )
try :
normalised_url = HG . client_controller . network_engine . domain_manager . NormaliseURL ( url )
except HydrusExceptions . URLClassException as e :
raise HydrusExceptions . BadRequestException ( e )
2019-02-13 22:26:43 +00:00
url_statuses = HG . client_controller . Read ( ' url_statuses ' , normalised_url )
2019-02-06 22:41:35 +00:00
2019-02-13 22:26:43 +00:00
json_happy_url_statuses = [ ]
for ( status , hash , note ) in url_statuses :
d = { }
d [ ' status ' ] = status
d [ ' hash ' ] = hash . hex ( )
d [ ' note ' ] = note
json_happy_url_statuses . append ( d )
body_dict = { ' normalised_url ' : normalised_url , ' url_file_statuses ' : json_happy_url_statuses }
body = json . dumps ( body_dict )
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
return response_context
class HydrusResourceClientAPIRestrictedAddURLsGetURLInfo ( HydrusResourceClientAPIRestrictedAddURLs ) :
def _threadDoGETJob ( self , request ) :
2019-08-21 21:34:01 +00:00
url = request . parsed_request_args . GetValue ( ' url ' , str )
2019-02-13 22:26:43 +00:00
2019-07-03 22:49:27 +00:00
if url == ' ' :
raise HydrusExceptions . BadRequestException ( ' Given URL was empty! ' )
try :
normalised_url = HG . client_controller . network_engine . domain_manager . NormaliseURL ( url )
except HydrusExceptions . URLClassException as e :
raise HydrusExceptions . BadRequestException ( e )
2019-02-13 22:26:43 +00:00
( url_type , match_name , can_parse ) = HG . client_controller . network_engine . domain_manager . GetURLParseCapability ( normalised_url )
body_dict = { ' normalised_url ' : normalised_url , ' url_type ' : url_type , ' url_type_string ' : HC . url_type_string_lookup [ url_type ] , ' match_name ' : match_name , ' can_parse ' : can_parse }
2019-02-06 22:41:35 +00:00
body = json . dumps ( body_dict )
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
return response_context
class HydrusResourceClientAPIRestrictedAddURLsImportURL ( HydrusResourceClientAPIRestrictedAddURLs ) :
def _threadDoPOSTJob ( self , request ) :
2019-08-21 21:34:01 +00:00
url = request . parsed_request_args . GetValue ( ' url ' , str )
2019-02-06 22:41:35 +00:00
2019-07-03 22:49:27 +00:00
if url == ' ' :
raise HydrusExceptions . BadRequestException ( ' Given URL was empty! ' )
2019-02-27 23:03:30 +00:00
service_keys_to_tags = None
2019-02-13 22:26:43 +00:00
2019-02-27 23:03:30 +00:00
if ' service_names_to_tags ' in request . parsed_request_args :
service_keys_to_tags = ClientTags . ServiceKeysToTags ( )
2019-02-13 22:26:43 +00:00
request . client_api_permissions . CheckPermission ( ClientAPI . CLIENT_API_PERMISSION_ADD_TAGS )
2019-08-21 21:34:01 +00:00
service_names_to_tags = request . parsed_request_args . GetValue ( ' service_names_to_tags ' , dict )
2019-02-13 22:26:43 +00:00
for ( service_name , tags ) in service_names_to_tags . items ( ) :
try :
2020-03-11 21:52:11 +00:00
service_key = HG . client_controller . services_manager . GetServiceKeyFromName ( HC . REAL_TAG_SERVICES , service_name )
2019-02-13 22:26:43 +00:00
except :
2019-02-27 23:03:30 +00:00
raise HydrusExceptions . BadRequestException ( ' Could not find the service " {} " ! ' . format ( service_name ) )
tags = HydrusTags . CleanTags ( tags )
if len ( tags ) == 0 :
continue
2019-02-13 22:26:43 +00:00
service_keys_to_tags [ service_key ] = tags
2019-02-27 23:03:30 +00:00
destination_page_name = None
if ' destination_page_name ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
destination_page_name = request . parsed_request_args . GetValue ( ' destination_page_name ' , str )
2019-02-27 23:03:30 +00:00
2019-06-26 21:27:18 +00:00
destination_page_key = None
if ' destination_page_key ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
destination_page_key = request . parsed_request_args . GetValue ( ' destination_page_key ' , bytes )
2019-06-26 21:27:18 +00:00
2019-08-21 21:34:01 +00:00
show_destination_page = request . parsed_request_args . GetValue ( ' show_destination_page ' , bool , default_value = False )
2019-03-20 21:22:10 +00:00
2019-06-05 19:42:39 +00:00
def do_it ( ) :
2019-06-26 21:27:18 +00:00
return HG . client_controller . gui . ImportURLFromAPI ( url , service_keys_to_tags , destination_page_name , destination_page_key , show_destination_page )
2019-06-05 19:42:39 +00:00
2019-02-06 22:41:35 +00:00
2019-07-03 22:49:27 +00:00
try :
2019-11-14 03:56:30 +00:00
( normalised_url , result_text ) = HG . client_controller . CallBlockingToQt ( HG . client_controller . gui , do_it )
2019-07-03 22:49:27 +00:00
except HydrusExceptions . URLClassException as e :
raise HydrusExceptions . BadRequestException ( e )
2019-02-13 22:26:43 +00:00
2019-03-06 23:06:22 +00:00
time . sleep ( 0.05 ) # yield and give the ui time to catch up with new URL pubsubs in case this is being spammed
2019-02-13 22:26:43 +00:00
body_dict = { ' human_result_text ' : result_text , ' normalised_url ' : normalised_url }
body = json . dumps ( body_dict )
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
2019-02-06 22:41:35 +00:00
return response_context
2019-03-06 23:06:22 +00:00
class HydrusResourceClientAPIRestrictedGetFiles ( HydrusResourceClientAPIRestricted ) :
2019-02-06 22:41:35 +00:00
def _CheckAPIPermissions ( self , request ) :
request . client_api_permissions . CheckPermission ( ClientAPI . CLIENT_API_PERMISSION_SEARCH_FILES )
2019-03-06 23:06:22 +00:00
class HydrusResourceClientAPIRestrictedGetFilesSearchFiles ( HydrusResourceClientAPIRestrictedGetFiles ) :
2019-02-06 22:41:35 +00:00
def _threadDoGETJob ( self , request ) :
2020-03-11 21:52:11 +00:00
tag_search_context = ClientSearch . TagSearchContext ( service_key = CC . COMBINED_TAG_SERVICE_KEY )
2019-03-06 23:06:22 +00:00
predicates = ParseClientAPISearchPredicates ( request )
2019-02-06 22:41:35 +00:00
2020-03-11 21:52:11 +00:00
file_search_context = ClientSearch . FileSearchContext ( file_service_key = CC . LOCAL_FILE_SERVICE_KEY , tag_search_context = tag_search_context , predicates = predicates )
2019-02-06 22:41:35 +00:00
2019-08-21 21:34:01 +00:00
# newest first
sort_by = ClientMedia . MediaSort ( sort_type = ( ' system ' , CC . SORT_FILES_BY_IMPORT_TIME ) , sort_asc = CC . SORT_DESC )
hash_ids = HG . client_controller . Read ( ' file_query_ids ' , file_search_context , sort_by = sort_by )
2019-02-06 22:41:35 +00:00
2019-03-13 21:04:21 +00:00
request . client_api_permissions . SetLastSearchResults ( hash_ids )
2019-03-06 23:06:22 +00:00
body_dict = { ' file_ids ' : list ( hash_ids ) }
2019-02-06 22:41:35 +00:00
2019-03-06 23:06:22 +00:00
body = json . dumps ( body_dict )
2019-02-06 22:41:35 +00:00
2019-03-06 23:06:22 +00:00
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
2019-02-06 22:41:35 +00:00
return response_context
2019-03-06 23:06:22 +00:00
class HydrusResourceClientAPIRestrictedGetFilesGetFile ( HydrusResourceClientAPIRestrictedGetFiles ) :
2019-02-06 22:41:35 +00:00
def _threadDoGETJob ( self , request ) :
2019-03-13 21:04:21 +00:00
try :
if ' file_id ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
file_id = request . parsed_request_args . GetValue ( ' file_id ' , int )
2019-03-13 21:04:21 +00:00
request . client_api_permissions . CheckPermissionToSeeFiles ( ( file_id , ) )
( media_result , ) = HG . client_controller . Read ( ' media_results_from_ids ' , ( file_id , ) )
elif ' hash ' in request . parsed_request_args :
request . client_api_permissions . CheckCanSeeAllFiles ( )
2019-08-21 21:34:01 +00:00
hash = request . parsed_request_args . GetValue ( ' hash ' , bytes )
2019-03-13 21:04:21 +00:00
( media_result , ) = HG . client_controller . Read ( ' media_results ' , ( hash , ) )
else :
raise HydrusExceptions . BadRequestException ( ' Please include a file_id or hash parameter! ' )
except HydrusExceptions . DataMissing as e :
raise HydrusExceptions . NotFoundException ( ' One or more of those file identifiers was missing! ' )
2015-12-02 22:32:18 +00:00
2019-03-13 21:04:21 +00:00
try :
hash = media_result . GetHash ( )
mime = media_result . GetMime ( )
path = HG . client_controller . client_files_manager . GetFilePath ( hash , mime )
except HydrusExceptions . FileMissingException :
raise HydrusExceptions . NotFoundException ( ' Could not find that file! ' )
2015-08-05 18:42:35 +00:00
2019-02-06 22:41:35 +00:00
response_context = HydrusServerResources . ResponseContext ( 200 , mime = mime , path = path )
2015-08-05 18:42:35 +00:00
return response_context
2019-03-13 21:04:21 +00:00
class HydrusResourceClientAPIRestrictedGetFilesFileMetadata ( HydrusResourceClientAPIRestrictedGetFiles ) :
2015-08-05 18:42:35 +00:00
def _threadDoGETJob ( self , request ) :
2019-08-21 21:34:01 +00:00
only_return_identifiers = request . parsed_request_args . GetValue ( ' only_return_identifiers ' , bool , default_value = False )
2019-03-13 21:04:21 +00:00
try :
if ' file_ids ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
file_ids = request . parsed_request_args . GetValue ( ' file_ids ' , list )
2019-03-13 21:04:21 +00:00
request . client_api_permissions . CheckPermissionToSeeFiles ( file_ids )
if only_return_identifiers :
2019-03-27 22:01:02 +00:00
file_ids_to_hashes = HG . client_controller . Read ( ' hash_ids_to_hashes ' , hash_ids = file_ids )
2019-03-13 21:04:21 +00:00
else :
media_results = HG . client_controller . Read ( ' media_results_from_ids ' , file_ids )
elif ' hashes ' in request . parsed_request_args :
request . client_api_permissions . CheckCanSeeAllFiles ( )
2019-08-21 21:34:01 +00:00
hashes = request . parsed_request_args . GetValue ( ' hashes ' , list )
2019-03-13 21:04:21 +00:00
if only_return_identifiers :
file_ids_to_hashes = HG . client_controller . Read ( ' hash_ids_to_hashes ' , hashes = hashes )
else :
media_results = HG . client_controller . Read ( ' media_results ' , hashes )
else :
raise HydrusExceptions . BadRequestException ( ' Please include a file_ids or hashes parameter! ' )
except HydrusExceptions . DataMissing as e :
raise HydrusExceptions . NotFoundException ( ' One or more of those file identifiers was missing! ' )
body_dict = { }
2019-02-06 22:41:35 +00:00
2019-03-13 21:04:21 +00:00
metadata = [ ]
2019-02-06 22:41:35 +00:00
2019-03-13 21:04:21 +00:00
if only_return_identifiers :
for ( file_id , hash ) in file_ids_to_hashes . items ( ) :
metadata_row = { }
metadata_row [ ' file_id ' ] = file_id
metadata_row [ ' hash ' ] = hash . hex ( )
metadata . append ( metadata_row )
else :
services_manager = HG . client_controller . services_manager
service_keys_to_names = { }
for media_result in media_results :
metadata_row = { }
file_info_manager = media_result . GetFileInfoManager ( )
metadata_row [ ' file_id ' ] = file_info_manager . hash_id
metadata_row [ ' hash ' ] = file_info_manager . hash . hex ( )
metadata_row [ ' size ' ] = file_info_manager . size
2020-01-16 02:08:23 +00:00
metadata_row [ ' mime ' ] = HC . mime_mimetype_string_lookup [ file_info_manager . mime ]
2019-03-13 21:04:21 +00:00
metadata_row [ ' width ' ] = file_info_manager . width
metadata_row [ ' height ' ] = file_info_manager . height
metadata_row [ ' duration ' ] = file_info_manager . duration
metadata_row [ ' num_frames ' ] = file_info_manager . num_frames
metadata_row [ ' num_words ' ] = file_info_manager . num_words
2019-08-07 22:59:53 +00:00
metadata_row [ ' has_audio ' ] = file_info_manager . has_audio
known_urls = list ( media_result . GetLocationsManager ( ) . GetURLs ( ) )
known_urls . sort ( )
metadata_row [ ' known_urls ' ] = known_urls
2019-03-13 21:04:21 +00:00
tags_manager = media_result . GetTagsManager ( )
service_names_to_statuses_to_tags = { }
2019-10-02 23:38:59 +00:00
service_keys_to_statuses_to_tags = tags_manager . GetServiceKeysToStatusesToTags ( ClientTags . TAG_DISPLAY_STORAGE )
2019-03-13 21:04:21 +00:00
for ( service_key , statuses_to_tags ) in service_keys_to_statuses_to_tags . items ( ) :
if service_key not in service_keys_to_names :
service_keys_to_names [ service_key ] = services_manager . GetName ( service_key )
service_name = service_keys_to_names [ service_key ]
service_names_to_statuses_to_tags [ service_name ] = { str ( status ) : list ( tags ) for ( status , tags ) in statuses_to_tags . items ( ) }
metadata_row [ ' service_names_to_statuses_to_tags ' ] = service_names_to_statuses_to_tags
metadata . append ( metadata_row )
2019-02-06 22:41:35 +00:00
2019-03-13 21:04:21 +00:00
body_dict [ ' metadata ' ] = metadata
2019-02-06 22:41:35 +00:00
mime = HC . APPLICATION_JSON
2019-03-13 21:04:21 +00:00
body = json . dumps ( body_dict )
2019-02-06 22:41:35 +00:00
response_context = HydrusServerResources . ResponseContext ( 200 , mime = mime , body = body )
return response_context
2019-03-06 23:06:22 +00:00
class HydrusResourceClientAPIRestrictedGetFilesGetThumbnail ( HydrusResourceClientAPIRestrictedGetFiles ) :
2019-02-06 22:41:35 +00:00
def _threadDoGETJob ( self , request ) :
2019-03-13 21:04:21 +00:00
try :
if ' file_id ' in request . parsed_request_args :
2019-08-21 21:34:01 +00:00
file_id = request . parsed_request_args . GetValue ( ' file_id ' , int )
2019-03-13 21:04:21 +00:00
request . client_api_permissions . CheckPermissionToSeeFiles ( ( file_id , ) )
( media_result , ) = HG . client_controller . Read ( ' media_results_from_ids ' , ( file_id , ) )
elif ' hash ' in request . parsed_request_args :
request . client_api_permissions . CheckCanSeeAllFiles ( )
2019-08-21 21:34:01 +00:00
hash = request . parsed_request_args . GetValue ( ' hash ' , bytes )
2019-03-13 21:04:21 +00:00
( media_result , ) = HG . client_controller . Read ( ' media_results ' , ( hash , ) )
else :
raise HydrusExceptions . BadRequestException ( ' Please include a file_id or hash parameter! ' )
except HydrusExceptions . DataMissing as e :
raise HydrusExceptions . NotFoundException ( ' One or more of those file identifiers was missing! ' )
2016-06-08 20:27:22 +00:00
2019-03-13 21:04:21 +00:00
try :
2019-04-24 22:18:50 +00:00
path = HG . client_controller . client_files_manager . GetThumbnailPath ( media_result )
2019-03-13 21:04:21 +00:00
except HydrusExceptions . FileMissingException :
raise HydrusExceptions . NotFoundException ( ' Could not find that file! ' )
2015-08-05 18:42:35 +00:00
2019-03-13 21:04:21 +00:00
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_OCTET_STREAM , path = path )
2015-08-05 18:42:35 +00:00
return response_context
2017-03-02 02:14:56 +00:00
2019-08-07 22:59:53 +00:00
class HydrusResourceClientAPIRestrictedManageCookies ( HydrusResourceClientAPIRestricted ) :
def _CheckAPIPermissions ( self , request ) :
request . client_api_permissions . CheckPermission ( ClientAPI . CLIENT_API_PERMISSION_MANAGE_COOKIES )
class HydrusResourceClientAPIRestrictedManageCookiesGetCookies ( HydrusResourceClientAPIRestrictedManageCookies ) :
def _threadDoGETJob ( self , request ) :
2019-08-21 21:34:01 +00:00
domain = request . parsed_request_args . GetValue ( ' domain ' , str )
2019-08-07 22:59:53 +00:00
if ' . ' not in domain :
raise HydrusExceptions . BadRequestException ( ' The value " {} " does not seem to be a domain! ' . format ( domain ) )
network_context = ClientNetworkingContexts . NetworkContext ( CC . NETWORK_CONTEXT_DOMAIN , domain )
session = HG . client_controller . network_engine . session_manager . GetSession ( network_context )
body_cookies_list = [ ]
for cookie in session . cookies :
name = cookie . name
value = cookie . value
domain = cookie . domain
path = cookie . path
expires = cookie . expires
body_cookies_list . append ( [ name , value , domain , path , expires ] )
body_dict = { }
body_dict = { ' cookies ' : body_cookies_list }
body = json . dumps ( body_dict )
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
return response_context
class HydrusResourceClientAPIRestrictedManageCookiesSetCookies ( HydrusResourceClientAPIRestrictedManageCookies ) :
def _threadDoPOSTJob ( self , request ) :
2019-08-21 21:34:01 +00:00
cookie_rows = request . parsed_request_args . GetValue ( ' cookies ' , list )
2019-08-07 22:59:53 +00:00
for cookie_row in cookie_rows :
if len ( cookie_row ) != 5 :
raise HydrusExceptions . BadRequestException ( ' The cookie " {} " did not come in the format [ name, value, domain, path, expires ]! ' . format ( cookie_row ) )
( name , value , domain , path , expires ) = cookie_row
ndp_bad = True in ( not isinstance ( var , str ) for var in ( name , domain , path ) )
v_bad = value is not None and not isinstance ( value , str )
e_bad = expires is not None and not isinstance ( expires , int )
if ndp_bad or v_bad or e_bad :
raise HydrusExceptions . BadRequestException ( ' In the row [ name, value, domain, path, expires ], which I received as " {} " , name, domain, and path need to be strings, value needs to be null or a string, and expires needs to be null or an integer! ' . format ( cookie_row ) )
network_context = ClientNetworkingContexts . NetworkContext ( CC . NETWORK_CONTEXT_DOMAIN , domain )
session = HG . client_controller . network_engine . session_manager . GetSession ( network_context )
if value is None :
session . cookies . clear ( domain , path , name )
else :
version = 0
port = None
port_specified = False
domain_specified = True
domain_initial_dot = domain . startswith ( ' . ' )
path_specified = True
secure = False
discard = False
comment = None
comment_url = None
rest = { }
cookie = http . cookiejar . Cookie ( version , name , value , port , port_specified , domain , domain_specified , domain_initial_dot , path , path_specified , secure , expires , discard , comment , comment_url , rest )
session . cookies . set_cookie ( cookie )
HG . client_controller . network_engine . session_manager . SetDirty ( )
response_context = HydrusServerResources . ResponseContext ( 200 )
return response_context
2019-06-05 19:42:39 +00:00
class HydrusResourceClientAPIRestrictedManagePages ( HydrusResourceClientAPIRestricted ) :
def _CheckAPIPermissions ( self , request ) :
request . client_api_permissions . CheckPermission ( ClientAPI . CLIENT_API_PERMISSION_MANAGE_PAGES )
2019-07-17 22:10:19 +00:00
class HydrusResourceClientAPIRestrictedManagePagesFocusPage ( HydrusResourceClientAPIRestrictedManagePages ) :
def _threadDoPOSTJob ( self , request ) :
def do_it ( page_key ) :
return HG . client_controller . gui . ShowPage ( page_key )
2019-08-21 21:34:01 +00:00
page_key = request . parsed_request_args . GetValue ( ' page_key ' , bytes )
2019-07-17 22:10:19 +00:00
try :
2019-11-14 03:56:30 +00:00
HG . client_controller . CallBlockingToQt ( HG . client_controller . gui , do_it , page_key )
2019-07-17 22:10:19 +00:00
except HydrusExceptions . DataMissing as e :
raise HydrusExceptions . NotFoundException ( ' Could not find that page! ' )
response_context = HydrusServerResources . ResponseContext ( 200 )
return response_context
2019-06-05 19:42:39 +00:00
class HydrusResourceClientAPIRestrictedManagePagesGetPages ( HydrusResourceClientAPIRestrictedManagePages ) :
def _threadDoGETJob ( self , request ) :
def do_it ( ) :
2019-08-21 21:34:01 +00:00
return HG . client_controller . gui . GetCurrentSessionPageAPIInfoDict ( )
2019-06-05 19:42:39 +00:00
2019-11-14 03:56:30 +00:00
page_info_dict = HG . client_controller . CallBlockingToQt ( HG . client_controller . gui , do_it )
2019-06-05 19:42:39 +00:00
body_dict = { ' pages ' : page_info_dict }
body = json . dumps ( body_dict )
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
return response_context
2019-08-21 21:34:01 +00:00
class HydrusResourceClientAPIRestrictedManagePagesGetPageInfo ( HydrusResourceClientAPIRestrictedManagePages ) :
def _threadDoGETJob ( self , request ) :
def do_it ( page_key , simple ) :
return HG . client_controller . gui . GetPageAPIInfoDict ( page_key , simple )
page_key = request . parsed_request_args . GetValue ( ' page_key ' , bytes )
simple = request . parsed_request_args . GetValue ( ' simple ' , bool , default_value = True )
2019-11-14 03:56:30 +00:00
page_info_dict = HG . client_controller . CallBlockingToQt ( HG . client_controller . gui , do_it , page_key , simple )
2019-08-21 21:34:01 +00:00
if page_info_dict is None :
raise HydrusExceptions . NotFoundException ( ' Did not find a page for " {} " ! ' . format ( page_key . hex ( ) ) )
body_dict = { ' page_info ' : page_info_dict }
body = json . dumps ( body_dict )
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
return response_context