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
from . import ClientFiles
2019-02-13 22:26:43 +00:00
from . import ClientImportFileSeeds
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-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 ( )
CLIENT_API_INT_PARAMS = set ( )
CLIENT_API_BYTE_PARAMS = set ( )
CLIENT_API_STRING_PARAMS = { ' name ' , ' url ' }
2019-03-06 23:06:22 +00:00
CLIENT_API_JSON_PARAMS = { ' basic_permissions ' , ' system_inbox ' , ' system_archive ' , ' tags ' }
2019-02-06 22:41:35 +00:00
def ParseLocalBooruGETArgs ( requests_args ) :
args = HydrusNetworking . ParseTwistedRequestGETArgs ( requests_args , LOCAL_BOORU_INT_PARAMS , LOCAL_BOORU_BYTE_PARAMS , LOCAL_BOORU_STRING_PARAMS , LOCAL_BOORU_JSON_PARAMS )
return args
def ParseClientAPIGETArgs ( requests_args ) :
args = HydrusNetworking . ParseTwistedRequestGETArgs ( requests_args , CLIENT_API_INT_PARAMS , CLIENT_API_BYTE_PARAMS , CLIENT_API_STRING_PARAMS , CLIENT_API_JSON_PARAMS )
return args
2019-02-27 23:03:30 +00:00
def ParseClientAPIPOSTHashesArgs ( args ) :
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 )
if ' hash ' in parsed_request_args :
try :
hash = bytes . fromhex ( parsed_request_args [ ' hash ' ] )
if len ( hash ) == 0 :
del parsed_request_args [ ' hash ' ]
else :
parsed_request_args [ ' hash ' ] = hash
except :
raise HydrusExceptions . BadRequestException ( ' I was expecting to parse \' ' + ' hash ' + ' \' as a hex-encoded bytestring, but it failed. ' )
if ' hashes ' in parsed_request_args :
try :
hashes = [ bytes . fromhex ( hash_hex ) for hash_hex in parsed_request_args [ ' hashes ' ] ]
hashes = [ hash for hash in hashes if len ( hash ) > 0 ]
if len ( hashes ) == 0 :
del parsed_request_args [ ' hashes ' ]
else :
parsed_request_args [ ' hashes ' ] = hashes
except :
raise HydrusExceptions . BadRequestException ( ' I was expecting to parse \' ' + ' hashes ' + ' \' as a list of hex-encoded bytestrings, but it failed. ' )
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 )
parsed_request_args = ParseClientAPIPOSTHashesArgs ( 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 :
predicates . append ( ClientSearch . Predicate ( predicate_type = HC . PREDICATE_TYPE_TAG , value = tag , inclusive = False ) )
for tag in tags :
predicates . append ( ClientSearch . Predicate ( predicate_type = HC . PREDICATE_TYPE_TAG , value = tag ) )
if system_inbox :
predicates . append ( ClientSearch . Predicate ( predicate_type = HC . PREDICATE_TYPE_SYSTEM_INBOX ) )
elif system_archive :
predicates . append ( ClientSearch . Predicate ( predicate_type = HC . PREDICATE_TYPE_SYSTEM_ARCHIVE ) )
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-02-27 23:03:30 +00:00
share_key = request . parsed_request_args [ ' share_key ' ]
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-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
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 ( )
if mime in HC . IMAGES :
( 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-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
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
2016-07-27 21:53:34 +00:00
path = client_files_manager . GetFullSizeThumbnailPath ( hash )
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 ' )
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 _ParseClientAPIAccessKey ( self , request ) :
if not request . requestHeaders . hasHeader ( ' Hydrus-Client-API-Access-Key ' ) :
raise HydrusExceptions . MissingCredentialsException ( ' No Hydrus-Client-API-Access-Key header! ' )
access_key_texts = request . requestHeaders . getRawHeaders ( ' Hydrus-Client-API-Access-Key ' )
access_key_text = access_key_texts [ 0 ]
try :
access_key = bytes . fromhex ( access_key_text )
except :
raise Exception ( ' Problem parsing api access key! ' )
return access_key
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-02-27 23:03:30 +00:00
name = request . parsed_request_args [ ' name ' ]
basic_permissions = request . parsed_request_args [ ' basic_permissions ' ]
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 HydrusResourceClientAPIVerify ( HydrusResourceClientAPI ) :
def _threadDoGETJob ( self , request ) :
access_key = self . _ParseClientAPIAccessKey ( request )
client_api_manager = HG . client_controller . client_api_manager
try :
api_permissions = client_api_manager . GetPermissions ( access_key )
basic_permissions = api_permissions . GetBasicPermissions ( )
human_description = api_permissions . ToHumanString ( )
body_dict = { }
2019-02-13 22:26:43 +00:00
body_dict [ ' basic_permissions ' ] = list ( basic_permissions ) # set->list for json
2019-02-06 22:41:35 +00:00
body_dict [ ' human_description ' ] = human_description
body = json . dumps ( body_dict )
response_context = HydrusServerResources . ResponseContext ( 200 , mime = HC . APPLICATION_JSON , body = body )
except HydrusExceptions . DataMissing :
raise HydrusExceptions . InsufficientCredentialsException ( ' Could not find that access key! ' )
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 ) :
def _callbackCheckRestrictions ( self , request ) :
HydrusResourceClientAPI . _callbackCheckRestrictions ( self , request )
self . _EstablishAPIPermissions ( request )
self . _CheckAPIPermissions ( request )
return request
def _CheckAPIPermissions ( self , request ) :
raise NotImplementedError ( )
def _EstablishAPIPermissions ( self , request ) :
access_key = self . _ParseClientAPIAccessKey ( request )
try :
api_permissions = HG . client_controller . client_api_manager . GetPermissions ( access_key )
except HydrusExceptions . DataMissing :
raise HydrusExceptions . InsufficientCredentialsException ( ' Could not find that access key in the list of permissions! ' )
request . client_api_permissions = api_permissions
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-02-27 23:03:30 +00:00
path = request . parsed_request_args [ ' path ' ]
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 :
( status , hash , note ) = HG . client_controller . client_files_manager . ImportFile ( file_import_job )
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 :
hash = request . parsed_request_args [ ' hash ' ]
hashes . add ( hash )
if ' hashes ' in request . parsed_request_args :
more_hashes = request . parsed_request_args [ ' hashes ' ]
hashes . update ( hashes )
if len ( hashes ) == 0 :
raise HydrusExceptions . BadRequestException ( ' There were no hashes given! ' )
#
service_keys_to_content_updates = collections . defaultdict ( list )
if ' service_names_to_tags ' in request . parsed_request_args :
service_names_to_tags = request . parsed_request_args [ ' service_names_to_tags ' ]
for ( service_name , tags ) in service_names_to_tags . items ( ) :
try :
service_key = HG . client_controller . services_manager . GetServiceKeyFromName ( HC . TAG_SERVICES , service_name )
except :
raise HydrusExceptions . BadRequestException ( ' Could not find the service " {} " ! ' . format ( service_name ) )
tags = HydrusTags . CleanTags ( tags )
if len ( tags ) == 0 :
continue
if service_key == CC . LOCAL_TAG_SERVICE_KEY :
content_action = HC . CONTENT_UPDATE_ADD
else :
content_action = HC . CONTENT_UPDATE_PEND
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 :
service_names_to_actions_to_tags = request . parsed_request_args [ ' service_names_to_actions_to_tags ' ]
for ( service_name , actions_to_tags ) in service_names_to_actions_to_tags . items ( ) :
try :
service_key = HG . client_controller . services_manager . GetServiceKeyFromName ( HC . TAG_SERVICES , service_name )
except :
raise HydrusExceptions . BadRequestException ( ' Could not find the service " {} " ! ' . format ( service_name ) )
for ( content_action , tags ) in actions_to_tags . items ( ) :
tags = HydrusTags . CleanTags ( tags )
if len ( tags ) == 0 :
continue
if service_key == CC . LOCAL_TAG_SERVICE_KEY :
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
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
content_updates = [ HydrusData . ContentUpdate ( HC . CONTENT_TYPE_MAPPINGS , content_action , ( tag , hashes , reason ) ) for ( tag , reason ) in tags_and_reasons ]
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 ) :
tags = request . parsed_request_args [ ' tags ' ]
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 :
url = request . parsed_request_args [ ' url_to_add ' ]
if not isinstance ( url , str ) :
raise HydrusExceptions . BadRequestException ( ' Did not understand the given URL " {} " ! ' . format ( url ) )
urls_to_add . append ( url )
if ' urls_to_add ' in request . parsed_request_args :
urls = request . parsed_request_args [ ' urls_to_add ' ]
if not isinstance ( urls , list ) :
raise HydrusExceptions . BadRequestException ( ' Did not understand the given URLs! ' )
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 :
url = request . parsed_request_args [ ' url_to_delete ' ]
if not isinstance ( url , str ) :
raise HydrusExceptions . BadRequestException ( ' Did not understand the given URL " {} " ! ' . format ( url ) )
urls_to_delete . append ( url )
if ' urls_to_delete ' in request . parsed_request_args :
urls = request . parsed_request_args [ ' urls_to_delete ' ]
if not isinstance ( urls , list ) :
raise HydrusExceptions . BadRequestException ( ' Did not understand the given URLs! ' )
for url in urls :
if not isinstance ( url , str ) :
continue
urls_to_delete . append ( url )
applicable_hashes = [ ]
if ' hash ' in request . parsed_request_args :
applicable_hashes . append ( request . parsed_request_args [ ' hash ' ] )
if ' hashes ' in request . parsed_request_args :
applicable_hashes . extend ( request . parsed_request_args [ ' hashes ' ] )
if len ( urls_to_add ) == 0 and len ( urls_to_delete ) == 0 :
raise HydrusExceptions . BadRequestException ( ' Did not find any URLs to add! ' )
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-02-27 23:03:30 +00:00
url = request . parsed_request_args [ ' url ' ]
2019-02-06 22:41:35 +00:00
2019-02-13 22:26:43 +00:00
normalised_url = HG . client_controller . network_engine . domain_manager . NormaliseURL ( url )
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-02-27 23:03:30 +00:00
url = request . parsed_request_args [ ' url ' ]
2019-02-13 22:26:43 +00:00
normalised_url = HG . client_controller . network_engine . domain_manager . NormaliseURL ( url )
( 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-02-27 23:03:30 +00:00
url = request . parsed_request_args [ ' url ' ]
2019-02-06 22:41:35 +00:00
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-02-27 23:03:30 +00:00
service_names_to_tags = request . parsed_request_args [ ' service_names_to_tags ' ]
2019-02-13 22:26:43 +00:00
for ( service_name , tags ) in service_names_to_tags . items ( ) :
try :
2019-02-27 23:03:30 +00:00
service_key = HG . client_controller . services_manager . GetServiceKeyFromName ( HC . 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 :
destination_page_name = request . parsed_request_args [ ' destination_page_name ' ]
if not isinstance ( destination_page_name , str ) :
raise HydrusExceptions . BadRequestException ( ' " destination_page_name " did not seem to be a string! ' )
2019-02-13 22:26:43 +00:00
gui = HG . client_controller . gui
2019-02-06 22:41:35 +00:00
2019-02-27 23:03:30 +00:00
( normalised_url , result_text ) = HG . client_controller . CallBlockingToWX ( gui , gui . ImportURLFromAPI , url , service_keys_to_tags , destination_page_name )
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 ) :
2019-03-06 23:06:22 +00:00
predicates = ParseClientAPISearchPredicates ( request )
2019-02-06 22:41:35 +00:00
2019-03-06 23:06:22 +00:00
file_search_context = ClientSearch . FileSearchContext ( file_service_key = CC . LOCAL_FILE_SERVICE_KEY , tag_service_key = CC . COMBINED_TAG_SERVICE_KEY , predicates = predicates )
2019-02-06 22:41:35 +00:00
2019-03-06 23:06:22 +00:00
hash_ids = HG . client_controller . Read ( ' file_query_ids ' , file_search_context )
2019-02-06 22:41:35 +00:00
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-02-27 23:03:30 +00:00
file_id = request . parsed_request_args [ ' file_id ' ]
2019-02-06 22:41:35 +00:00
request . client_api_permissions . CheckPermissionToSeeFiles ( ( file_id , ) )
media_result = ' blah ' # get it from controller
mime = media_result . GetMime ( )
2015-08-05 18:42:35 +00:00
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
2019-02-06 22:41:35 +00:00
path = client_files_manager . GetFilePath ( hash , mime )
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-06 23:06:22 +00:00
class HydrusResourceClientAPIRestrictedGetFilesGetMetadata ( HydrusResourceClientAPIRestrictedGetFiles ) :
2015-08-05 18:42:35 +00:00
def _threadDoGETJob ( self , request ) :
2019-02-27 23:03:30 +00:00
file_ids = request . parsed_request_args [ ' file_ids ' ]
2019-02-06 22:41:35 +00:00
request . client_api_permissions . CheckPermissionToSeeFiles ( file_ids )
media_results = ' blah ' # get it from controller
# turn media results into json/xml result. maybe start with json to keep it simple
mime = HC . APPLICATION_JSON
body = ' blah '
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-02-27 23:03:30 +00:00
file_id = request . parsed_request_args [ ' file_id ' ]
2019-02-06 22:41:35 +00:00
request . client_api_permissions . CheckPermissionToSeeFiles ( ( file_id , ) )
media_result = ' blah ' # get it from controller
mime = media_result . GetMime ( ) # jpg or png
2015-08-05 18:42:35 +00:00
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-02-06 22:41:35 +00:00
path = client_files_manager . GetFilePath ( hash , mime )
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
2017-03-02 02:14:56 +00:00