import BaseHTTPServer import ClientConstants as CC import collections import Cookie import hashlib import httplib import HydrusAudioHandling import HydrusConstants as HC import HydrusDocumentHandling import HydrusExceptions import HydrusFileHandling import HydrusFlashHandling import HydrusImageHandling import HydrusServerAMP import HydrusServerResources import os import random import ServerConstants as SC import SocketServer import traceback import urllib import wx import yaml from twisted.internet import reactor, defer from twisted.internet.protocol import ServerFactory from twisted.internet.threads import deferToThread from twisted.protocols import amp from twisted.web.server import Request, Site, NOT_DONE_YET from twisted.web.resource import Resource from twisted.web.static import File as FileResource, NoRangeStaticProducer eris = '''
8888 8888888 888888888888888888888888 8888:::8888888888888888888888888 8888::::::8888888888888888888888888888 88::::::::888:::8888888888888888888888888 88888888::::8:::::::::::88888888888888888888 888 8::888888::::::::::::::::::88888888888 888 88::::88888888::::m::::::::::88888888888 8 888888888888888888:M:::::::::::8888888888888 88888888888888888888::::::::::::M88888888888888 8888888888888888888888:::::::::M8888888888888888 8888888888888888888888:::::::M888888888888888888 8888888888888888::88888::::::M88888888888888888888 88888888888888888:::88888:::::M888888888888888 8888 88888888888888888:::88888::::M::;o*M*o;888888888 88 88888888888888888:::8888:::::M:::::::::::88888888 8 88888888888888888::::88::::::M:;:::::::::::888888888 8888888888888888888:::8::::::M::aAa::::::::M8888888888 8 88 8888888888::88::::8::::M:::::::::::::888888888888888 8888 88 88888888888:::8:::::::::M::::::::::;::88:88888888888888888 8 8888888888888:::::::::::M::"@@@@@@@"::::8w8888888888888888 88888888888:888::::::::::M:::::"@a@":::::M8i888888888888888 8888888888::::88:::::::::M88:::::::::::::M88z88888888888888888 8888888888:::::8:::::::::M88888:::::::::MM888!888888888888888888 888888888:::::8:::::::::M8888888MAmmmAMVMM888*88888888 88888888 888888 M:::::::::::::::M888888888:::::::MM88888888888888 8888888 8888 M::::::::::::::M88888888888::::::MM888888888888888 88888 888 M:::::::::::::M8888888888888M:::::mM888888888888888 8888 888 M::::::::::::M8888:888888888888::::m::Mm88888 888888 8888 88 M::::::::::::8888:88888888888888888::::::Mm8 88888 888 88 M::::::::::8888M::88888::888888888888:::::::Mm88888 88 8 MM::::::::8888M:::8888:::::888888888888::::::::Mm8 4 8M:::::::8888M:::::888:::::::88:::8888888::::::::Mm 2 88MM:::::8888M:::::::88::::::::8:::::888888:::M:::::M 8888M:::::888MM::::::::8:::::::::::M::::8888::::M::::M 88888M:::::88:M::::::::::8:::::::::::M:::8888::::::M::M 88 888MM:::888:M:::::::::::::::::::::::M:8888:::::::::M: 8 88888M:::88::M:::::::::::::::::::::::MM:88::::::::::::M 88888M:::88::M::::::::::*88*::::::::::M:88::::::::::::::M 888888M:::88::M:::::::::88@@88:::::::::M::88::::::::::::::M 888888MM::88::MM::::::::88@@88:::::::::M:::8::::::::::::::*8 88888 M:::8::MM:::::::::*88*::::::::::M:::::::::::::::::88@@ 8888 MM::::::MM:::::::::::::::::::::MM:::::::::::::::::88@@ 888 M:::::::MM:::::::::::::::::::MM::M::::::::::::::::*8 888 MM:::::::MMM::::::::::::::::MM:::MM:::::::::::::::M 88 M::::::::MMMM:::::::::::MMMM:::::MM::::::::::::MM 88 MM:::::::::MMMMMMMMMMMMMMM::::::::MMM::::::::MMM 88 MM::::::::::::MMMMMMM::::::::::::::MMMMMMMMMM 88 8MM::::::::::::::::::::::::::::::::::MMMMMM 8 88MM::::::::::::::::::::::M:::M::::::::MM 888MM::::::::::::::::::MM::::::MM::::::MM 88888MM:::::::::::::::MMM:::::::mM:::::MM 888888MM:::::::::::::MMM:::::::::MMM:::M 88888888MM:::::::::::MMM:::::::::::MM:::M 88 8888888M:::::::::MMM::::::::::::::M:::M 8 888888 M:::::::MM:::::::::::::::::M:::M: 888888 M::::::M:::::::::::::::::::M:::MM 888888 M:::::M::::::::::::::::::::::::M:M 888888 M:::::M:::::::::@::::::::::::::M::M 88888 M::::::::::::::@@:::::::::::::::M::M 88888 M::::::::::::::@@@::::::::::::::::M::M 88888 M:::::::::::::::@@::::::::::::::::::M::M 88888 M:::::m::::::::::@::::::::::Mm:::::::M:::M 8888 M:::::M:::::::::::::::::::::::MM:::::::M:::M 8888 M:::::M:::::::::::::::::::::::MMM::::::::M:::M 888 M:::::Mm::::::::::::::::::::::MMM:::::::::M::::M 8888 MM::::Mm:::::::::::::::::::::MMMM:::::::::m::m:::M 888 M:::::M::::::::::::::::::::MMM::::::::::::M::mm:::M 8888 MM:::::::::::::::::::::::::MM:::::::::::::mM::MM:::M: M:::::::::::::::::::::::::M:::::::::::::::mM::MM:::Mm MM::::::m:::::::::::::::::::::::::::::::::::M::MM:::MM M::::::::M:::::::::::::::::::::::::::::::::::M::M:::MM MM:::::::::M:::::::::::::M:::::::::::::::::::::M:M:::MM M:::::::::::M88:::::::::M:::::::::::::::::::::::MM::MMM M::::::::::::8888888888M::::::::::::::::::::::::MM::MM M:::::::::::::88888888M:::::::::::::::::::::::::M::MM M::::::::::::::888888M:::::::::::::::::::::::::M::MM M:::::::::::::::88888M:::::::::::::::::::::::::M:MM M:::::::::::::::::88M::::::::::::::::::::::::::MMM M:::::::::::::::::::M::::::::::::::::::::::::::MMM MM:::::::::::::::::M::::::::::::::::::::::::::MMM M:::::::::::::::::M::::::::::::::::::::::::::MMM MM:::::::::::::::M::::::::::::::::::::::::::MMM M:::::::::::::::M:::::::::::::::::::::::::MMM MM:::::::::::::M:::::::::::::::::::::::::MMM M:::::::::::::M::::::::::::::::::::::::MMM MM:::::::::::M::::::::::::::::::::::::MMM M:::::::::::M:::::::::::::::::::::::MMM MM:::::::::M:::::::::::::::::::::::MMM M:::::::::M::::::::::::::::::::::MMM MM:::::::M::::::::::::::::::::::MMM MM::::::M:::::::::::::::::::::MMM MM:::::M:::::::::::::::::::::MMM MM::::M::::::::::::::::::::MMM MM:::M::::::::::::::::::::MMM MM::M:::::::::::::::::::MMM THIS IS THE HYDRUS SERVER ADMIN SERVICE, VERSION ''' + HC.u( HC.SOFTWARE_VERSION ) + ''' MM:M:::::::::::::::::::MMM MMM::::::::::::::::::MMM MM::::::::::::::::::MMM M:::::::::::::::::MMM MM::::::::::::::::MMM MM:::::::::::::::MMM MM::::M:::::::::MMM: mMM::::MM:::::::MMMM MMM:::::::::::MMM:M mMM:::M:::::::M:M:M MM::MMMM:::::::M:M MM::MMM::::::::M:M mMM::MM::::::::M:M MM::MM:::::::::M:M MM::MM::::::::::M:m MM:::M:::::::::::MM MMM:::::::::::::::M: MMM:::::::::::::::M: MMM::::::::::::::::M MMM::::::::::::::::M MMM::::::::::::::::Mm MM::::::::::::::::MM MMM:::::::::::::::MM MMM:::::::::::::::MM MMM:::::::::::::::MM MMM:::::::::::::::MM MM::::::::::::::MMM MMM:::::::::::::MM MMM:::::::::::::MM MMM::::::::::::MM MM::::::::::::MM MM::::::::::::MM MM:::::::::::MM MMM::::::::::MM MMM::::::::::MM MM:::::::::MM MMM::::::::MM MMM::::::::MM MM::::::::MM MMM::::::MM MMM::::::MM MM::::::MM MM::::::MM MM:::::MM MM:::::MM: MM:::::M:M MM:::::M:M :M::::::M: M:M:::::::M M:::M::::::M M::::M::::::M M:::::M:::::::M M::::::MM:::::::M M:::::::M::::::::M M;:;::::M:::::::::M M:m:;:::M::::::::::M MM:m:m::M::::::::;:M MM:m::MM:::::::;:;M MM::MMM::::::;:m:M MMMM MM::::m:m:MM MM::::m:MM MM::::MM MM::MM MMMM''' CLIENT_ROOT_MESSAGE = '''
This hydrus client uses software version ''' + HC.u( HC.SOFTWARE_VERSION ) + ''' and network version ''' + HC.u( HC.NETWORK_VERSION ) + '''.
It only serves requests from 127.0.0.1.
''' ROOT_MESSAGE_BEGIN = '''This hydrus service uses software version ''' + HC.u( HC.SOFTWARE_VERSION ) + ''' and network version ''' + HC.u( HC.NETWORK_VERSION ) + '''.
''' ROOT_MESSAGE_END = '''
''' LOCAL_DOMAIN = HydrusServerResources.HydrusDomain( True ) REMOTE_DOMAIN = HydrusServerResources.HydrusDomain( False ) class HydrusRequest( Request ): def __init__( self, *args, **kwargs ): Request.__init__( self, *args, **kwargs ) self.is_hydrus_client = True self.hydrus_args = None self.hydrus_response_context = None self.hydrus_request_data_usage = 0 class HydrusRequestRestricted( HydrusRequest ): def __init__( self, *args, **kwargs ): HydrusRequest.__init__( self, *args, **kwargs ) self.hydrus_account = None class HydrusService( Site ): def __init__( self, service_key, service_type, message ): self._service_key = service_key self._service_type = service_type self._message = message root = self._InitRoot() Site.__init__( self, root ) self.requestFactory = HydrusRequest def _InitRoot( self ): root = Resource() root.putChild( '', HydrusServerResources.HydrusResourceWelcome( self._service_key, self._service_type, self._message ) ) root.putChild( 'favicon.ico', HydrusServerResources.hydrus_favicon ) return root class HydrusServiceBooru( HydrusService ): def _InitRoot( self ): root = HydrusService._InitRoot( self ) root.putChild( 'gallery', HydrusServerResources.HydrusResourceCommandBooruGallery( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'page', HydrusServerResources.HydrusResourceCommandBooruPage( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'file', HydrusServerResources.HydrusResourceCommandBooruFile( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'thumbnail', HydrusServerResources.HydrusResourceCommandBooruThumbnail( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'style.css', HydrusServerResources.local_booru_css ) return root class HydrusServiceLocal( HydrusService ): def _InitRoot( self ): root = HydrusService._InitRoot( self ) root.putChild( 'file', HydrusServerResources.HydrusResourceCommandLocalFile( self._service_key, self._service_type, LOCAL_DOMAIN ) ) root.putChild( 'thumbnail', HydrusServerResources.HydrusResourceCommandLocalThumbnail( self._service_key, self._service_type, LOCAL_DOMAIN ) ) return root class HydrusServiceRestricted( HydrusService ): def __init__( self, service_key, service_type, message ): HydrusService.__init__( self, service_key, service_type, message ) self.requestFactory = HydrusRequestRestricted def _InitRoot( self ): root = HydrusService._InitRoot( self ) root.putChild( 'access_key', HydrusServerResources.HydrusResourceCommandAccessKey( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'access_key_verification', HydrusServerResources.HydrusResourceCommandAccessKeyVerification( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'session_key', HydrusServerResources.HydrusResourceCommandSessionKey( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'account', HydrusServerResources.HydrusResourceCommandRestrictedAccount( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'account_info', HydrusServerResources.HydrusResourceCommandRestrictedAccountInfo( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'account_types', HydrusServerResources.HydrusResourceCommandRestrictedAccountTypes( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'registration_keys', HydrusServerResources.HydrusResourceCommandRestrictedRegistrationKeys( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'stats', HydrusServerResources.HydrusResourceCommandRestrictedStats( self._service_key, self._service_type, REMOTE_DOMAIN ) ) return root class HydrusServiceAdmin( HydrusServiceRestricted ): def _InitRoot( self ): root = HydrusServiceRestricted._InitRoot( self ) root.putChild( 'backup', HydrusServerResources.HydrusResourceCommandRestrictedBackup( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'init', HydrusServerResources.HydrusResourceCommandInit( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'services', HydrusServerResources.HydrusResourceCommandRestrictedServices( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'services_info', HydrusServerResources.HydrusResourceCommandRestrictedServicesInfo( self._service_key, self._service_type, REMOTE_DOMAIN ) ) return root class HydrusServiceRepository( HydrusServiceRestricted ): def _InitRoot( self ): root = HydrusServiceRestricted._InitRoot( self ) root.putChild( 'news', HydrusServerResources.HydrusResourceCommandRestrictedNews( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'num_petitions', HydrusServerResources.HydrusResourceCommandRestrictedNumPetitions( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'petition', HydrusServerResources.HydrusResourceCommandRestrictedPetition( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'update', HydrusServerResources.HydrusResourceCommandRestrictedUpdate( self._service_key, self._service_type, REMOTE_DOMAIN ) ) return root class HydrusServiceRepositoryFile( HydrusServiceRepository ): def _InitRoot( self ): root = HydrusServiceRepository._InitRoot( self ) root.putChild( 'file', HydrusServerResources.HydrusResourceCommandRestrictedRepositoryFile( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'ip', HydrusServerResources.HydrusResourceCommandRestrictedIP( self._service_key, self._service_type, REMOTE_DOMAIN ) ) root.putChild( 'thumbnail', HydrusServerResources.HydrusResourceCommandRestrictedRepositoryThumbnail( self._service_key, self._service_type, REMOTE_DOMAIN ) ) return root class HydrusServiceRepositoryTag( HydrusServiceRepository ): pass class MessagingServiceFactory( ServerFactory ): protocol = HydrusServerAMP.MessagingServiceProtocol def __init__( self, service_key ): self.service_key = service_key self._persistent_connections = collections.defaultdict( dict ) self._temporary_connections = collections.defaultdict( dict ) def AddConnection( self, persistent, identifier, name, connection ): if persistent: self._persistent_connections[ identifier ][ name ] = connection else: self._temporary_connections[ identifier ][ name ] = connection def GetConnection( self, identifier, name ): if name in self._persistent_connections[ identifier ]: return self._persistent_connections[ identifier ][ name ] elif name in self._temporary_connections[ identifier ]: return self._temporary_connections[ identifier ][ name ] else: raise Exception() # make this better, obviously def GetOnlineNames( self, identifier ): return self._persistent_connections[ identifier ].keys() def RemoveConnection( self, identifier, name ): if name in self._temporary_connections[ identifier ]: del self._temporary_connections[ identifier ][ name ] elif name in self._persistent_connections[ identifier ]: del self._persistent_connections[ identifier ][ name ]