Пример #1
0
 def CheckPermission( self, permission ):
     
     if self._IsBanned(): raise HydrusExceptions.PermissionException( 'This account is banned!' )
     
     if self._IsExpired(): raise HydrusExceptions.PermissionException( 'This account is expired.' )
     
     if self._IsBytesExceeded(): raise HydrusExceptions.PermissionException( 'You have hit your data transfer limit, and cannot make any more requests for the month.' )
     
     if self._IsRequestsExceeded(): raise HydrusExceptions.PermissionException( 'You have hit your requests limit, and cannot make any more requests for the month.' )
     
     if not self._info[ 'account_type' ].HasPermission( permission ): raise HydrusExceptions.PermissionException( 'You do not have permission to do that.' )
Пример #2
0
def ProcessStartingAction( db_dir, action ):
    
    already_running = HydrusData.IsAlreadyRunning( db_dir, 'server' )
    
    if action == 'start':
        
        if already_running:
            
            HydrusData.Print( 'The server is already running. Would you like to [s]top it, [r]estart it, or e[x]it?' )
            
            answer = raw_input()
            
            if len( answer ) > 0:
                
                answer = answer[0]
                
                if answer == 's':
                    
                    return 'stop'
                    
                elif answer == 'r':
                    
                    return 'restart'
                    
                
            
            raise HydrusExceptions.PermissionException( 'Exiting!' )
            
        else:
            
            return action
            
        
    elif action == 'stop':
        
        if already_running:
            
            return action
            
        else:
            
            raise HydrusExceptions.PermissionException( 'The server is not running, so it cannot be stopped!' )
            
        
    elif action == 'restart':
        
        if already_running:
            
            return action
            
        else:
            
            return 'start'
Пример #3
0
    def InitDB(self):

        try:

            def make_temp_files_deletable(function_called, path,
                                          traceback_gumpf):

                os.chmod(path, stat.S_IWRITE)

                try:
                    function_called(path)  # try again
                except:
                    pass

            if os.path.exists(HC.TEMP_DIR):
                shutil.rmtree(HC.TEMP_DIR, onerror=make_temp_files_deletable)

        except:
            pass

        try:

            if not os.path.exists(HC.TEMP_DIR): os.mkdir(HC.TEMP_DIR)

        except:
            pass

        db_initialised = False

        while not db_initialised:

            try:

                self._db = ClientDB.DB()

                db_initialised = True

            except HydrusExceptions.DBAccessException as e:

                try:
                    print(HC.u(e))
                except:
                    print(repr(HC.u(e)))

                message = 'This instance of the client had a problem connecting to the database, which probably means an old instance is still closing.'
                message += os.linesep * 2
                message += 'If the old instance does not close for a _very_ long time, you can usually safely force-close it from task manager.'

                with ClientGUIDialogs.DialogYesNo(
                        None,
                        message,
                        'There was a problem connecting to the database.',
                        yes_label='wait a bit, then try again',
                        no_label='forget it') as dlg:

                    if dlg.ShowModal() == wx.ID_YES: time.sleep(3)
                    else: raise HydrusExceptions.PermissionException()

        threading.Thread(target=self._db.MainLoop,
                         name='Database Main Loop').start()
Пример #4
0
    def InitClientFilesManager(self):

        self.client_files_manager = ClientCaches.ClientFilesManager(self)

        missing_locations = self.client_files_manager.GetMissing()

        while len(missing_locations) > 0:

            with ClientGUITopLevelWindows.DialogManage(
                    None, 'repair file system') as dlg:

                panel = ClientGUIScrolledPanelsManagement.RepairFileSystemPanel(
                    dlg, missing_locations)

                dlg.SetPanel(panel)

                if dlg.ShowModal() == wx.ID_OK:

                    self.client_files_manager = ClientCaches.ClientFilesManager(
                        self)

                    missing_locations = self.client_files_manager.GetMissing()

                else:

                    raise HydrusExceptions.PermissionException(
                        'File system failed, user chose to quit.')
Пример #5
0
 def _checkSession( self, request ):
     
     if not request.requestHeaders.hasHeader( 'Cookie' ):
         
         raise HydrusExceptions.PermissionException( 'No cookies found!' )
         
     
     cookie_texts = request.requestHeaders.getRawHeaders( 'Cookie' )
     
     cookie_text = cookie_texts[0]
     
     try:
         
         cookies = Cookie.SimpleCookie( cookie_text )
         
         if 'session_key' not in cookies:
             
             session_key = None
             
         else:
             
             session_key = cookies[ 'session_key' ].value.decode( 'hex' )
             
         
     except:
         
         raise Exception( 'Problem parsing cookies!' )
         
     
     account = HG.server_controller.server_session_manager.GetAccount( self._service_key, session_key )
     
     request.hydrus_account = account
     
     return request
Пример #6
0
    def _threadDoPOSTJob(self, request):

        services = request.hydrus_args['services']

        unique_ports = {service.GetPort() for service in services}

        if len(unique_ports) < len(services):

            raise HydrusExceptions.PermissionException(
                'It looks like some of those services share ports! Please give them unique ports!'
            )

        if len(unique_ports) < services:

            pass

        with HG.dirty_object_lock:

            service_keys_to_access_keys = HG.server_controller.WriteSynchronous(
                'services', request.hydrus_account, services)

            HG.server_controller.SetServices(services)

        body = HydrusNetwork.DumpToBodyString(
            {'service_keys_to_access_keys': service_keys_to_access_keys})

        response_context = HydrusServerResources.ResponseContext(200,
                                                                 body=body)

        return response_context
Пример #7
0
 def wx_code():
     
     message = 'It looks like another instance of this client is already running, so this instance cannot start.'
     message += os.linesep * 2
     message += 'If the old instance is closing and does not quit for a _very_ long time, it is usually safe to force-close it from task manager.'
     
     with ClientGUIDialogs.DialogYesNo( self._splash, message, 'The client is already running.', yes_label = 'wait a bit, then try again', no_label = 'forget it' ) as dlg:
         
         if dlg.ShowModal() != wx.ID_YES:
             
             raise HydrusExceptions.PermissionException()
Пример #8
0
 def _parseAccessKey( self, request ):
     
     if not request.requestHeaders.hasHeader( 'Hydrus-Key' ): raise HydrusExceptions.PermissionException( 'No hydrus key header found!' )
     
     hex_keys = request.requestHeaders.getRawHeaders( 'Hydrus-Key' )
     
     hex_key = hex_keys[0]
     
     try: access_key = hex_key.decode( 'hex' )
     except: raise HydrusExceptions.ForbiddenException( 'Could not parse the hydrus key!' )
     
     return access_key
Пример #9
0
    def InitCheckPassword(self):

        while True:

            with wx.PasswordEntryDialog(None, 'Enter your password',
                                        'Enter password') as dlg:

                if dlg.ShowModal() == wx.ID_OK:

                    if hashlib.sha256(
                            dlg.GetValue()).digest() == HC.options['password']:
                        break

                else:
                    raise HydrusExceptions.PermissionException()
Пример #10
0
 def wx_code_password():
     
     while True:
         
         with wx.PasswordEntryDialog( self._splash, 'Enter your password', 'Enter password' ) as dlg:
             
             if dlg.ShowModal() == wx.ID_OK:
                 
                 # this can produce unicode with cyrillic or w/e keyboards, which hashlib can't handle
                 password = HydrusData.ToByteString( dlg.GetValue() )
                 
                 if hashlib.sha256( password ).digest() == self.options[ 'password' ]: break
                 
             else:
                 
                 raise HydrusExceptions.PermissionException( 'Bad password check' )
Пример #11
0
            def wx_code_password():

                while True:

                    with wx.PasswordEntryDialog(self._splash,
                                                'Enter your password',
                                                'Enter password') as dlg:

                        if dlg.ShowModal() == wx.ID_OK:

                            if hashlib.sha256(dlg.GetValue()).digest(
                            ) == self._options['password']:
                                break

                        else:
                            raise HydrusExceptions.PermissionException(
                                'Bad password check')
Пример #12
0
 def CheckIfAdminPortInUse( self ):
     
     ( service_type, options ) = self.Read( 'service_info', HC.SERVER_ADMIN_KEY )
     
     port = options[ 'port' ]
     
     already_bound = False
     
     try:
         
         connection = HydrusNetworking.GetLocalConnection( port )
         connection.close()
         
         already_bound = True
         
     except: pass
     
     if already_bound:
         
         raise HydrusExceptions.PermissionException( 'Something was already bound to port ' + str( port ) )
Пример #13
0
 def _threadDoGETJob( self, request ):
     
     subject_identifier = request.hydrus_args[ 'subject_identifier' ]
     
     if subject_identifier.HasAccountKey():
         
         subject_account_key = subject_identifier.GetData()
         
     else:
         
         raise HydrusExceptions.PermissionException( 'I was expecting an account key, but did not get one!' )
         
     
     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 )
     
     body = HydrusNetwork.DumpToBodyString( { 'account_info' : account_info } )
     
     response_context = HydrusServerResources.ResponseContext( 200, body = body )
     
     return response_context
Пример #14
0
def ShutdownSiblingInstance(db_dir):

    port_found = False

    ports = HydrusData.GetSiblingProcessPorts(db_dir, 'server')

    if ports is None:

        raise HydrusExceptions.PermissionException(
            'Could not figure out the existing server\'s ports, so could not shut it down!'
        )

    for port in ports:

        try:

            connection = HydrusNetworking.GetLocalConnection(port, https=True)

            connection.request('GET', '/')

            response = connection.getresponse()

            response.read()

            server_name = response.getheader('Server')

        except:

            text = 'Could not contact existing server\'s port ' + str(
                port) + '!'
            text += os.linesep
            text += traceback.format_exc()

            raise HydrusExceptions.PermissionException(text)

        if 'server administration' in server_name:

            port_found = True

            HydrusData.Print(u'Sending shut down instruction\u2026')

            connection.request('POST', '/shutdown')

            response = connection.getresponse()

            result = response.read()

            if response.status != 200:

                text = 'When told to shut down, the existing server gave an error!'
                text += os.linesep
                text += result

                raise HydrusExceptions.PermissionException(text)

            time_waited = 0

            while HydrusData.IsAlreadyRunning(db_dir, 'server'):

                time.sleep(1)

                time_waited += 1

                if time_waited > 20:

                    raise HydrusExceptions.PermissionException(
                        'Attempted to shut the existing server down, but it took too long!'
                    )

            break

    if not port_found:

        raise HydrusExceptions.PermissionException(
            'The existing server did not have an administration service!')

    HydrusData.Print('The existing server is shut down!')
Пример #15
0
    def Request(self,
                method,
                path_and_query,
                request_headers,
                body,
                report_hooks=[],
                response_to_path=False):

        if method == HC.GET: method_string = 'GET'
        elif method == HC.POST: method_string = 'POST'

        if 'User-Agent' not in request_headers:
            request_headers['User-Agent'] = 'hydrus/' + HC.u(
                HC.NETWORK_VERSION)

        # it is important to only send str, not unicode, to httplib
        # it uses += to extend the message body, which propagates the unicode (and thus fails) when
        # you try to push non-ascii bytes as the body (e.g. during a file upload!)

        method_string = str(method_string)
        path_and_query = str(path_and_query)

        request_headers = {
            str(k): str(v)
            for (k, v) in request_headers.items()
        }

        try:

            self._connection.request(method_string,
                                     path_and_query,
                                     headers=request_headers,
                                     body=body)

            response = self._connection.getresponse()

        except (httplib.CannotSendRequest, httplib.BadStatusLine):

            # for some reason, we can't send a request on the current connection, so let's make a new one and try again!

            self._RefreshConnection()

            self._connection.request(method_string,
                                     path_and_query,
                                     headers=request_headers,
                                     body=body)

            response = self._connection.getresponse()

        if response.status == 200 and response_to_path:

            (temp_path, size_of_response) = self._WriteResponseToPath(
                response, report_hooks)

            parsed_response = temp_path

        else:

            (parsed_response,
             size_of_response) = self._ParseResponse(response, report_hooks)

        response_headers = {
            k: v
            for (k, v) in response.getheaders() if k != 'set-cookie'
        }

        cookies = self._ParseCookies(response.getheader('set-cookie'))

        self._last_request_time = HC.GetNow()

        if response.status == 200:
            return (parsed_response, None, size_of_response, response_headers,
                    cookies)
        elif response.status in (301, 302, 303, 307):

            location = response.getheader('Location')

            if location is None: raise Exception(parsed_response)
            else:

                url = location

                if ' ' in url:

                    # some booru is giving daft redirect responses
                    print(url)
                    url = urllib.quote(url, safe='/?=&')
                    print(url)

                if not url.startswith(self._scheme):

                    # assume it is like 'index.php' or '/index.php', rather than 'http://blah.com/index.php'

                    if url.startswith('/'): slash_sep = ''
                    else: slash_sep = '/'

                    url = self._scheme + '://' + self._host + slash_sep + url

                if response.status in (301, 307):

                    # 301: moved permanently, repeat request
                    # 307: moved temporarily, repeat request

                    redirect_info = (method, url)

                elif response.status in (302, 303):

                    # 302: moved temporarily, repeat request (except everyone treats it like 303 for no good f*****g reason)
                    # 303: thanks, now go here with GET

                    redirect_info = (HC.GET, url)

                return (parsed_response, redirect_info, size_of_response,
                        response_headers, cookies)

        elif response.status == 304:
            raise HydrusExceptions.NotModifiedException()
        else:

            if response.status == 401:
                raise HydrusExceptions.PermissionException(parsed_response)
            elif response.status == 403:
                raise HydrusExceptions.ForbiddenException(parsed_response)
            elif response.status == 404:
                raise HydrusExceptions.NotFoundException(parsed_response)
            elif response.status == 426:
                raise HydrusExceptions.NetworkVersionException(parsed_response)
            elif response.status in (500, 501, 502, 503):
                raise Exception(parsed_response)
            else:
                raise Exception(parsed_response)
Пример #16
0
 def Request( self, method, path_and_query, request_headers, body, report_hooks = None, temp_path = None ):
     
     if report_hooks is None: report_hooks = []
     
     if method == HC.GET: method_string = 'GET'
     elif method == HC.POST: method_string = 'POST'
     
     if 'User-Agent' not in request_headers:
         
         request_headers[ 'User-Agent' ] = 'hydrus/' + str( HC.NETWORK_VERSION )
         
     
     path_and_query = HydrusData.ToByteString( path_and_query )
     
     request_headers = { str( k ) : str( v ) for ( k, v ) in request_headers.items() }
     
     response = self._GetResponse( method_string, path_and_query, request_headers, body )
     
     ( parsed_response, size_of_response ) = self._ReadResponse( response, report_hooks, temp_path )
     
     response_headers = { k : v for ( k, v ) in response.getheaders() if k != 'set-cookie' }
     
     cookies = self._ParseCookies( response.getheader( 'set-cookie' ) )
     
     self._last_request_time = HydrusData.GetNow()
     
     if response.status == 200:
         
         return ( parsed_response, None, size_of_response, response_headers, cookies )
         
     elif response.status in ( 301, 302, 303, 307 ):
         
         location = response.getheader( 'Location' )
         
         if location is None: raise Exception( 'Received an invalid redirection response.' )
         else:
             
             url = location
             
             if ', ' in url:
                 
                 url = url.split( ', ' )[0]
                 
             elif ' ' in url:
                 
                 # some booru is giving daft redirect responses
                 HydrusData.Print( url )
                 url = urllib.quote( HydrusData.ToByteString( url ), safe = '/?=&' )
                 HydrusData.Print( url )
                 
             
             if not url.startswith( self._scheme ):
                 
                 # assume it is like 'index.php' or '/index.php', rather than 'http://blah.com/index.php'
                 
                 if url.startswith( '/' ): slash_sep = ''
                 else: slash_sep = '/'
                 
                 url = self._scheme + '://' + self._host + slash_sep + url
                 
             
             if response.status in ( 301, 307 ):
                 
                 # 301: moved permanently, repeat request
                 # 307: moved temporarily, repeat request
                 
                 redirect_info = ( method, url )
                 
             elif response.status in ( 302, 303 ):
                 
                 # 302: moved temporarily, repeat request (except everyone treats it like 303 for no good f*****g reason)
                 # 303: thanks, now go here with GET
                 
                 redirect_info = ( HC.GET, url )
                 
             
             return ( parsed_response, redirect_info, size_of_response, response_headers, cookies )
             
         
     elif response.status == 304: raise HydrusExceptions.NotModifiedException()
     else:
         
         if response.status == 401: raise HydrusExceptions.PermissionException( parsed_response )
         elif response.status == 403: raise HydrusExceptions.ForbiddenException( parsed_response )
         elif response.status == 404: raise HydrusExceptions.NotFoundException( parsed_response )
         elif response.status == 419: raise HydrusExceptions.SessionException( parsed_response )
         elif response.status == 426: raise HydrusExceptions.NetworkVersionException( parsed_response )
         elif response.status in ( 500, 501, 502, 503 ):
             
             server_header = response.getheader( 'Server' )
             
             if server_header is not None and 'hydrus' in server_header:
                 
                 hydrus_service = True
                 
             else:
                 
                 hydrus_service = False
                 
             
             if response.status == 503 and hydrus_service:
                 
                 raise HydrusExceptions.ServerBusyException( 'Server is busy, please try again later.' )
                 
             else:
                 
                 raise Exception( parsed_response )
                 
             
         else: raise Exception( parsed_response )
Пример #17
0
def GetStartingAction():

    action = 'help'

    args = sys.argv[1:]

    if len(args) > 0:

        command = args[0]

        while command.startswith('-'):

            command = command[1:]

        if command == 'help':

            action = 'help'

        else:

            already_running = HydrusData.IsAlreadyRunning(HC.DB_DIR, 'server')

            if command == 'start':

                if already_running:

                    raise HydrusExceptions.PermissionException(
                        'The server is already running!')

                else:

                    action = 'start'

            elif command == 'stop':

                if already_running:

                    action = 'stop'

                else:

                    raise HydrusExceptions.PermissionException(
                        'The server is not running, so it cannot be stopped!')

            elif command == 'restart':

                if already_running:

                    action = 'restart'

                else:

                    action = 'start'

    else:

        already_running = HydrusData.IsAlreadyRunning(HC.DB_DIR, 'server')

        if not already_running:

            action = 'start'

        else:

            HydrusData.Print(
                'The server is already running. Would you like to [s]top it, or [r]estart it?'
            )

            answer = raw_input()

            if len(answer) > 0:

                answer = answer[0]

                if answer == 's':

                    action = 'stop'

                elif answer == 'r':

                    action = 'restart'

    return action