hydrus/hydrus/server/ServerServerResources.py

720 lines
24 KiB
Python
Raw Normal View History

2019-01-09 22:59:03 +00:00
import http.cookies
2020-04-22 21:00:35 +00:00
from hydrus.core import HydrusConstants as HC
from hydrus.core import HydrusData
from hydrus.core import HydrusExceptions
from hydrus.core import HydrusGlobals as HG
from hydrus.core import HydrusNetwork
from hydrus.core import HydrusNetworking
from hydrus.core import HydrusPaths
from hydrus.core import HydrusSerialisable
from hydrus.core import HydrusServerResources
from hydrus.server import ServerFiles
2019-10-09 22:03:03 +00:00
import threading
2015-12-02 22:32:18 +00:00
class HydrusResourceBusyCheck( HydrusServerResources.Resource ):
def __init__( self ):
HydrusServerResources.Resource.__init__( self )
self._server_version_string = HC.service_string_lookup[ HC.SERVER_ADMIN ] + '/' + str( HC.NETWORK_VERSION )
def render_GET( self, request ):
request.setResponseCode( 200 )
request.setHeader( 'Server', self._server_version_string )
2019-10-09 22:03:03 +00:00
if HG.server_busy.locked():
2019-02-06 22:41:35 +00:00
return b'1'
else:
return b'0'
class HydrusResourceHydrusNetwork( HydrusServerResources.HydrusResource ):
2019-10-09 22:03:03 +00:00
BLOCKED_WHEN_BUSY = True
2019-02-06 22:41:35 +00:00
def _callbackParseGETArgs( self, request ):
2019-02-27 23:03:30 +00:00
parsed_request_args = HydrusNetwork.ParseHydrusNetworkGETArgs( 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 ):
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
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_string = request.content.read()
total_bytes_read += len( json_string )
2019-02-27 23:03:30 +00:00
parsed_request_args = HydrusNetwork.ParseNetworkBytesToParsedHydrusArgs( json_string )
2019-02-06 22:41:35 +00:00
else:
( 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 )
decompression_bombs_ok = self._DecompressionBombsOK( request )
2019-02-27 23:03:30 +00:00
parsed_request_args = HydrusServerResources.ParseFileArguments( temp_path, decompression_bombs_ok )
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
2015-12-02 22:32:18 +00:00
2019-10-09 22:03:03 +00:00
def _checkService( self, request ):
if self.BLOCKED_WHEN_BUSY and HG.server_busy.locked():
raise HydrusExceptions.ServerBusyException( 'This server is busy, please try again later.' )
return request
2019-02-06 22:41:35 +00:00
class HydrusResourceAccessKey( HydrusResourceHydrusNetwork ):
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2019-02-27 23:03:30 +00:00
registration_key = request.parsed_request_args[ 'registration_key' ]
2015-12-02 22:32:18 +00:00
2017-05-10 21:33:58 +00:00
access_key = HG.server_controller.Read( 'access_key', self._service_key, registration_key )
2015-12-02 22:32:18 +00:00
2019-01-09 22:59:03 +00:00
body = HydrusNetwork.DumpHydrusArgsToNetworkBytes( { 'access_key' : access_key } )
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200, body = body )
return response_context
2019-02-06 22:41:35 +00:00
class HydrusResourceShutdown( HydrusResourceHydrusNetwork ):
2015-12-02 22:32:18 +00:00
def _threadDoPOSTJob( self, request ):
2017-05-10 21:33:58 +00:00
HG.server_controller.ShutdownFromServer()
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200 )
return response_context
2019-02-06 22:41:35 +00:00
class HydrusResourceAccessKeyVerification( HydrusResourceHydrusNetwork ):
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2019-02-06 22:41:35 +00:00
access_key = self._parseHydrusNetworkAccessKey( request )
2015-12-02 22:32:18 +00:00
2017-05-10 21:33:58 +00:00
verified = HG.server_controller.Read( 'verify_access_key', self._service_key, access_key )
2015-12-02 22:32:18 +00:00
2019-01-09 22:59:03 +00:00
body = HydrusNetwork.DumpHydrusArgsToNetworkBytes( { 'verified' : verified } )
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200, body = body )
return response_context
2019-02-06 22:41:35 +00:00
class HydrusResourceSessionKey( HydrusResourceHydrusNetwork ):
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2019-02-06 22:41:35 +00:00
access_key = self._parseHydrusNetworkAccessKey( request )
2015-12-02 22:32:18 +00:00
2017-12-06 22:06:56 +00:00
( session_key, expires ) = HG.server_controller.server_session_manager.AddSession( self._service_key, access_key )
2015-12-02 22:32:18 +00:00
now = HydrusData.GetNow()
2017-10-25 21:45:15 +00:00
max_age = expires - now
2015-12-02 22:32:18 +00:00
2019-04-24 22:18:50 +00:00
cookies = [ ( 'session_key', session_key.hex(), { 'max_age' : str( max_age ), 'path' : '/' } ) ]
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200, cookies = cookies )
return response_context
2019-02-06 22:41:35 +00:00
class HydrusResourceRestricted( HydrusResourceHydrusNetwork ):
2015-12-02 22:32:18 +00:00
2019-06-26 21:27:18 +00:00
def _callbackCheckAccountRestrictions( self, request ):
2015-12-02 22:32:18 +00:00
2019-06-26 21:27:18 +00:00
HydrusResourceHydrusNetwork._callbackCheckAccountRestrictions( self, request )
2015-12-02 22:32:18 +00:00
2019-06-26 21:27:18 +00:00
self._checkAccount( request )
2015-12-02 22:32:18 +00:00
return request
2019-07-03 22:49:27 +00:00
def _callbackEstablishAccountFromHeader( self, request ):
2015-12-02 22:32:18 +00:00
2019-09-25 21:34:18 +00:00
session_key = None
if request.requestHeaders.hasHeader( 'Cookie' ):
2017-03-02 02:14:56 +00:00
2019-09-25 21:34:18 +00:00
cookie_texts = request.requestHeaders.getRawHeaders( 'Cookie' )
cookie_text = cookie_texts[0]
try:
cookies = http.cookies.SimpleCookie( cookie_text )
if 'session_key' in cookies:
# Morsel, for real, ha ha ha
morsel = cookies[ 'session_key' ]
session_key_hex = morsel.value
session_key = bytes.fromhex( session_key_hex )
except:
raise HydrusExceptions.InsufficientCredentialsException( 'Problem parsing cookies for Session Cookie!' )
2017-03-02 02:14:56 +00:00
2015-12-02 22:32:18 +00:00
2019-09-25 21:34:18 +00:00
if session_key is None:
2015-12-02 22:32:18 +00:00
2019-09-25 21:34:18 +00:00
access_key = self._parseHydrusNetworkAccessKey( request, key_required = False )
2015-12-02 22:32:18 +00:00
2019-09-25 21:34:18 +00:00
if access_key is None:
2017-03-02 02:14:56 +00:00
2019-09-25 21:34:18 +00:00
raise HydrusExceptions.MissingCredentialsException( 'No credentials found in request!' )
2017-03-02 02:14:56 +00:00
else:
2019-09-25 21:34:18 +00:00
account = HG.server_controller.server_session_manager.GetAccountFromAccessKey( self._service_key, access_key )
2017-03-02 02:14:56 +00:00
2019-09-25 21:34:18 +00:00
else:
2017-03-02 02:14:56 +00:00
2019-09-25 21:34:18 +00:00
account = HG.server_controller.server_session_manager.GetAccount( self._service_key, session_key )
2015-12-02 22:32:18 +00:00
request.hydrus_account = account
return request
2019-07-03 22:49:27 +00:00
def _checkAccount( self, request ):
request.hydrus_account.CheckFunctional()
return request
def _checkBandwidth( self, request ):
if not self._service.BandwidthOK():
raise HydrusExceptions.BandwidthException( 'This service has run out of bandwidth. Please try again later.' )
if not HG.server_controller.ServerBandwidthOK():
raise HydrusExceptions.BandwidthException( 'This server has run out of bandwidth. Please try again later.' )
2017-06-21 21:15:59 +00:00
def _reportDataUsed( self, request, num_bytes ):
2015-12-02 22:32:18 +00:00
2019-02-06 22:41:35 +00:00
HydrusResourceHydrusNetwork._reportDataUsed( self, request, num_bytes )
2015-12-02 22:32:18 +00:00
2017-06-21 21:15:59 +00:00
account = request.hydrus_account
if account is not None:
account.ReportDataUsed( num_bytes )
def _reportRequestUsed( self, request ):
2019-02-06 22:41:35 +00:00
HydrusResourceHydrusNetwork._reportRequestUsed( self, request )
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
account = request.hydrus_account
if account is not None:
2015-12-02 22:32:18 +00:00
2017-06-21 21:15:59 +00:00
account.ReportRequestUsed()
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedAccount( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
def _checkAccount( self, request ):
# you can always fetch your account (e.g. to be notified that you are banned!)
return request
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
account = request.hydrus_account
2019-01-09 22:59:03 +00:00
body = HydrusNetwork.DumpHydrusArgsToNetworkBytes( { 'account' : account } )
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200, body = body )
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedAccountInfo( HydrusResourceRestricted ):
def _threadDoGETJob( self, request ):
2015-12-02 22:32:18 +00:00
2019-02-27 23:03:30 +00:00
subject_identifier = request.parsed_request_args[ 'subject_identifier' ]
2015-12-02 22:32:18 +00:00
2018-12-05 22:35:30 +00:00
if subject_identifier.HasAccountKey():
subject_account_key = subject_identifier.GetData()
else:
2019-02-06 22:41:35 +00:00
raise HydrusExceptions.MissingCredentialsException( 'I was expecting an account key, but did not get one!' )
2018-12-05 22:35:30 +00:00
subject_account = HG.server_controller.Read( 'account', self._service_key, subject_account_key )
account_info = HG.server_controller.Read( 'account_info', self._service_key, request.hydrus_account, subject_account )
2015-12-02 22:32:18 +00:00
2019-01-09 22:59:03 +00:00
body = HydrusNetwork.DumpHydrusArgsToNetworkBytes( { 'account_info' : account_info } )
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
response_context = HydrusServerResources.ResponseContext( 200, body = body )
2015-12-02 22:32:18 +00:00
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedAccountModification( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
def _threadDoPOSTJob( self, request ):
2015-12-02 22:32:18 +00:00
2019-02-27 23:03:30 +00:00
action = request.parsed_request_args[ 'action' ]
2015-12-02 22:32:18 +00:00
2019-02-27 23:03:30 +00:00
subject_accounts = request.parsed_request_args[ 'accounts' ]
2015-12-02 22:32:18 +00:00
2019-02-27 23:03:30 +00:00
kwargs = request.parsed_request_args # for things like expires, title, and so on
2015-12-02 22:32:18 +00:00
2017-05-10 21:33:58 +00:00
with HG.dirty_object_lock:
2017-03-02 02:14:56 +00:00
2017-05-10 21:33:58 +00:00
HG.server_controller.WriteSynchronous( 'account_modification', self._service_key, request.hydrus_account, action, subject_accounts, **kwargs )
2017-03-02 02:14:56 +00:00
2017-12-06 22:06:56 +00:00
HG.server_controller.server_session_manager.UpdateAccounts( self._service_key, subject_accounts )
2017-03-02 02:14:56 +00:00
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
response_context = HydrusServerResources.ResponseContext( 200 )
2015-12-02 22:32:18 +00:00
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedAccountTypes( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2017-05-10 21:33:58 +00:00
account_types = HG.server_controller.Read( 'account_types', self._service_key, request.hydrus_account )
2015-12-02 22:32:18 +00:00
2019-01-09 22:59:03 +00:00
body = HydrusNetwork.DumpHydrusArgsToNetworkBytes( { 'account_types' : account_types } )
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200, body = body )
return response_context
def _threadDoPOSTJob( self, request ):
2019-02-27 23:03:30 +00:00
account_types = request.parsed_request_args[ 'account_types' ]
deletee_account_type_keys_to_new_account_type_keys = request.parsed_request_args[ 'deletee_account_type_keys_to_new_account_type_keys' ]
2015-12-02 22:32:18 +00:00
2017-05-10 21:33:58 +00:00
HG.server_controller.WriteSynchronous( 'account_types', self._service_key, request.hydrus_account, account_types, deletee_account_type_keys_to_new_account_type_keys )
2015-12-02 22:32:18 +00:00
2017-12-06 22:06:56 +00:00
HG.server_controller.server_session_manager.RefreshAccounts( self._service_key )
2016-07-27 21:53:34 +00:00
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200 )
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedBackup( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
def _threadDoPOSTJob( self, request ):
2017-03-02 02:14:56 +00:00
# check permission here since this is an asynchronous job
request.hydrus_account.CheckPermission( HC.CONTENT_TYPE_SERVICES, HC.PERMISSION_ACTION_OVERRULE )
2015-12-02 22:32:18 +00:00
2019-10-09 22:03:03 +00:00
HG.server_controller.Write( 'backup' )
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200 )
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedIP( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2019-02-27 23:03:30 +00:00
hash = request.parsed_request_args[ 'hash' ]
2015-12-02 22:32:18 +00:00
2017-05-10 21:33:58 +00:00
( ip, timestamp ) = HG.server_controller.Read( 'ip', self._service_key, request.hydrus_account, hash )
2015-12-02 22:32:18 +00:00
2019-01-09 22:59:03 +00:00
body = HydrusNetwork.DumpHydrusArgsToNetworkBytes( { 'ip' : ip, 'timestamp' : timestamp } )
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200, body = body )
return response_context
2019-10-09 22:03:03 +00:00
class HydrusResourceRestrictedLockOn( HydrusResourceRestricted ):
def _threadDoPOSTJob( self, request ):
# check permission here since no db work
request.hydrus_account.CheckPermission( HC.CONTENT_TYPE_SERVICES, HC.PERMISSION_ACTION_OVERRULE )
2020-04-01 21:51:42 +00:00
locked = HG.server_busy.acquire( False ) # pylint: disable=E1111
2019-10-09 22:03:03 +00:00
if not locked:
raise HydrusExceptions.BadRequestException( 'The server was already locked!' )
HG.server_controller.db.PauseAndDisconnect( True )
# shut down db, wait until it is done?
response_context = HydrusServerResources.ResponseContext( 200 )
return response_context
class HydrusResourceRestrictedLockOff( HydrusResourceRestricted ):
BLOCKED_WHEN_BUSY = False
def _threadDoPOSTJob( self, request ):
# check permission here since no db work
request.hydrus_account.CheckPermission( HC.CONTENT_TYPE_SERVICES, HC.PERMISSION_ACTION_OVERRULE )
try:
HG.server_busy.release()
except threading.ThreadError:
raise HydrusExceptions.BadRequestException( 'The server is not busy!' )
HG.server_controller.db.PauseAndDisconnect( False )
response_context = HydrusServerResources.ResponseContext( 200 )
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedNumPetitions( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2017-05-10 21:33:58 +00:00
petition_count_info = HG.server_controller.Read( 'num_petitions', self._service_key, request.hydrus_account )
2015-12-02 22:32:18 +00:00
2019-01-09 22:59:03 +00:00
body = HydrusNetwork.DumpHydrusArgsToNetworkBytes( { 'num_petitions' : petition_count_info } )
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200, body = body )
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedPetition( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2019-02-27 23:03:30 +00:00
content_type = request.parsed_request_args[ 'content_type' ]
status = request.parsed_request_args[ 'status' ]
2015-12-02 22:32:18 +00:00
2017-05-10 21:33:58 +00:00
petition = HG.server_controller.Read( 'petition', self._service_key, request.hydrus_account, content_type, status )
2015-12-02 22:32:18 +00:00
2019-01-09 22:59:03 +00:00
body = HydrusNetwork.DumpHydrusArgsToNetworkBytes( { 'petition' : petition } )
2017-03-02 02:14:56 +00:00
response_context = HydrusServerResources.ResponseContext( 200, body = body )
2015-12-02 22:32:18 +00:00
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedRegistrationKeys( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2019-02-27 23:03:30 +00:00
num = request.parsed_request_args[ 'num' ]
account_type_key = request.parsed_request_args[ 'account_type_key' ]
2017-03-15 20:13:04 +00:00
2019-02-27 23:03:30 +00:00
if 'expires' in request.parsed_request_args:
2017-03-15 20:13:04 +00:00
2019-02-27 23:03:30 +00:00
expires = request.parsed_request_args[ 'expires' ]
2017-03-15 20:13:04 +00:00
else:
expires = None
2015-12-02 22:32:18 +00:00
2017-05-10 21:33:58 +00:00
registration_keys = HG.server_controller.Read( 'registration_keys', self._service_key, request.hydrus_account, num, account_type_key, expires )
2015-12-02 22:32:18 +00:00
2019-01-09 22:59:03 +00:00
body = HydrusNetwork.DumpHydrusArgsToNetworkBytes( { 'registration_keys' : registration_keys } )
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200, body = body )
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedRepositoryFile( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
2018-06-20 20:20:22 +00:00
def _DecompressionBombsOK( self, request ):
2019-07-03 22:49:27 +00:00
if request.hydrus_account is None:
return False
else:
return request.hydrus_account.HasPermission( HC.CONTENT_TYPE_ACCOUNTS, HC.PERMISSION_ACTION_CREATE )
2018-06-20 20:20:22 +00:00
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2017-03-02 02:14:56 +00:00
self._checkBandwidth( request )
# no permission check as any functional account can get files
2019-02-27 23:03:30 +00:00
hash = request.parsed_request_args[ 'hash' ]
2015-12-02 22:32:18 +00:00
2017-05-10 21:33:58 +00:00
( valid, mime ) = HG.server_controller.Read( 'service_has_file', self._service_key, hash )
2017-03-02 02:14:56 +00:00
if not valid:
raise HydrusExceptions.NotFoundException( 'File not found on this service!' )
2015-12-02 22:32:18 +00:00
2016-06-08 20:27:22 +00:00
path = ServerFiles.GetFilePath( hash )
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
response_context = HydrusServerResources.ResponseContext( 200, mime = mime, path = path )
2015-12-02 22:32:18 +00:00
return response_context
def _threadDoPOSTJob( self, request ):
2019-02-27 23:03:30 +00:00
file_dict = request.parsed_request_args
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
if self._service.LogUploaderIPs():
file_dict[ 'ip' ] = request.getClientIP()
2015-12-02 22:32:18 +00:00
2019-09-18 22:40:39 +00:00
timestamp = self._service.GetMetadata().GetNextUpdateBegin() + 1
HG.server_controller.WriteSynchronous( 'file', self._service, request.hydrus_account, file_dict, timestamp )
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200 )
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedRepositoryThumbnail( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2017-03-02 02:14:56 +00:00
self._checkBandwidth( request )
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
# no permission check as any functional account can get thumbnails
2015-12-02 22:32:18 +00:00
2019-02-27 23:03:30 +00:00
hash = request.parsed_request_args[ 'hash' ]
2015-12-02 22:32:18 +00:00
2017-05-10 21:33:58 +00:00
( valid, mime ) = HG.server_controller.Read( 'service_has_file', self._service_key, hash )
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
if not valid:
raise HydrusExceptions.NotFoundException( 'Thumbnail not found on this service!' )
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
if mime not in HC.MIMES_WITH_THUMBNAILS:
raise HydrusExceptions.NotFoundException( 'That mime should not have a thumbnail!' )
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
path = ServerFiles.GetThumbnailPath( hash )
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
response_context = HydrusServerResources.ResponseContext( 200, mime = HC.APPLICATION_OCTET_STREAM, path = path )
2015-12-02 22:32:18 +00:00
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedServices( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2017-05-10 21:33:58 +00:00
services = HG.server_controller.Read( 'services_from_account', request.hydrus_account )
2015-12-02 22:32:18 +00:00
2019-01-09 22:59:03 +00:00
body = HydrusNetwork.DumpHydrusArgsToNetworkBytes( { 'services' : services } )
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200, body = body )
return response_context
2017-03-02 02:14:56 +00:00
def _threadDoPOSTJob( self, request ):
2015-12-02 22:32:18 +00:00
2019-02-27 23:03:30 +00:00
services = request.parsed_request_args[ 'services' ]
2017-03-02 02:14:56 +00:00
2018-03-28 21:55:58 +00:00
unique_ports = { service.GetPort() for service in services }
if len( unique_ports ) < len( services ):
2019-02-27 23:03:30 +00:00
raise HydrusExceptions.BadRequestException( 'It looks like some of those services share ports! Please give them unique ports!' )
2018-03-28 21:55:58 +00:00
2017-05-10 21:33:58 +00:00
with HG.dirty_object_lock:
2017-03-02 02:14:56 +00:00
2017-05-10 21:33:58 +00:00
HG.server_controller.SetServices( services )
2017-03-02 02:14:56 +00:00
2019-07-24 21:39:02 +00:00
service_keys_to_access_keys = HG.server_controller.WriteSynchronous( 'services', request.hydrus_account, services )
2015-12-02 22:32:18 +00:00
2019-01-09 22:59:03 +00:00
body = HydrusNetwork.DumpHydrusArgsToNetworkBytes( { 'service_keys_to_access_keys' : service_keys_to_access_keys } )
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200, body = body )
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedUpdate( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2017-03-02 02:14:56 +00:00
self._checkBandwidth( request )
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
# no permissions check as any functional account can get updates
2015-12-02 22:32:18 +00:00
2019-02-27 23:03:30 +00:00
update_hash = request.parsed_request_args[ 'update_hash' ]
2017-03-02 02:14:56 +00:00
if not self._service.HasUpdateHash( update_hash ):
raise HydrusExceptions.NotFoundException( 'This update hash does not exist on this service!' )
path = ServerFiles.GetFilePath( update_hash )
response_context = HydrusServerResources.ResponseContext( 200, mime = HC.APPLICATION_OCTET_STREAM, path = path )
2015-12-02 22:32:18 +00:00
return response_context
def _threadDoPOSTJob( self, request ):
2019-02-27 23:03:30 +00:00
client_to_server_update = request.parsed_request_args[ 'client_to_server_update' ]
2015-12-02 22:32:18 +00:00
2019-09-18 22:40:39 +00:00
timestamp = self._service.GetMetadata().GetNextUpdateBegin() + 1
HG.server_controller.WriteSynchronous( 'update', self._service_key, request.hydrus_account, client_to_server_update, timestamp )
2015-12-02 22:32:18 +00:00
response_context = HydrusServerResources.ResponseContext( 200 )
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedImmediateUpdate( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2017-05-10 21:33:58 +00:00
updates = HG.server_controller.Read( 'immediate_update', self._service_key, request.hydrus_account )
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
updates = HydrusSerialisable.SerialisableList( updates )
2015-12-02 22:32:18 +00:00
2019-01-09 22:59:03 +00:00
body = HydrusNetwork.DumpHydrusArgsToNetworkBytes( { 'updates' : updates } )
2017-03-02 02:14:56 +00:00
response_context = HydrusServerResources.ResponseContext( 200, body = body )
2015-12-02 22:32:18 +00:00
return response_context
2017-03-02 02:14:56 +00:00
class HydrusResourceRestrictedMetadataUpdate( HydrusResourceRestricted ):
2015-12-02 22:32:18 +00:00
def _threadDoGETJob( self, request ):
2017-03-02 02:14:56 +00:00
# no permissions check as any functional account can get metadata slices
2019-02-27 23:03:30 +00:00
since = request.parsed_request_args[ 'since' ]
2015-12-02 22:32:18 +00:00
2017-03-02 02:14:56 +00:00
metadata_slice = self._service.GetMetadataSlice( since )
2015-12-02 22:32:18 +00:00
2019-01-09 22:59:03 +00:00
body = HydrusNetwork.DumpHydrusArgsToNetworkBytes( { 'metadata_slice' : metadata_slice } )
2017-03-02 02:14:56 +00:00
response_context = HydrusServerResources.ResponseContext( 200, body = body )
2015-12-02 22:32:18 +00:00
return response_context
2017-01-25 22:56:55 +00:00
2019-10-09 22:03:03 +00:00
class HydrusResourceRestrictedVacuum( HydrusResourceRestricted ):
def _threadDoPOSTJob( self, request ):
# check permission here since this is an asynchronous job
request.hydrus_account.CheckPermission( HC.CONTENT_TYPE_SERVICES, HC.PERMISSION_ACTION_OVERRULE )
HG.server_controller.Write( 'vacuum' )
response_context = HydrusServerResources.ResponseContext( 200 )
return response_context