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 = '''hydrus
                         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 = ''' hydrus client

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 = ''' hydrus service

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 ]