Example #1
0
    def _RefreshExternalIP(self):
        def work_callable():

            try:

                external_ip = HydrusNATPunch.GetExternalIP()

                external_ip_text = 'External IP: {}'.format(external_ip)

            except Exception as e:

                external_ip_text = 'Error finding external IP: ' + str(e)

            return external_ip_text

        def publish_callable(external_ip_text):

            self._external_ip = external_ip_text

            self._status_st.setText(self._external_ip)

        self._status_st.setText('Loading external IP\u2026')

        async_job = ClientGUIAsync.AsyncQtJob(self, work_callable,
                                              publish_callable)

        async_job.start()
Example #2
0
 def _InitialiseAccountTypes( self ):
     
     service = self._service
     
     def work_callable():
         
         response = service.Request( HC.GET, 'account_types' )
         
         account_types = response[ 'account_types' ]
         
         return account_types
         
     
     def publish_callable( result ):
         
         self._account_types = result
         
         self._account_types_choice.setEnabled( True )
         self._account_types_button.setEnabled( True )
         
         self._account_types.sort( key = lambda at: str( at ) )
         
         for account_type in self._account_types:
             
             self._account_types_choice.addItem( str( account_type ), account_type )
             
         
     
     self._account_types_choice.setEnabled( False )
     self._account_types_button.setEnabled( False )
     
     job = ClientGUIAsync.AsyncQtJob( self, work_callable, publish_callable )
     
     job.start()
Example #3
0
    def _DoSetMessage(self):

        subject_accounts = self._account_panel.GetCheckedAccounts()

        if len(subject_accounts) == 0:

            QW.QMessageBox.information(self, 'Information',
                                       'No accounts selected for action!')

            return

        message = self._message_text.text()

        if message == '':

            yn_message = 'Clear message for the selected accounts?'

        else:

            yn_message = 'Set this message for the selected accounts?'

        result = ClientGUIDialogsQuick.GetYesNo(self, yn_message)

        if result != QW.QDialog.Accepted:

            return

        subject_account_keys = [
            subject_account.GetAccountKey()
            for subject_account in subject_accounts
        ]

        service = self._service

        def work_callable():

            for subject_account_key in subject_account_keys:

                service.Request(
                    HC.POST, 'modify_account_set_message', {
                        'subject_identifier':
                        HydrusNetwork.AccountIdentifier(
                            account_key=subject_account_key),
                        'message':
                        message
                    })

            return 1

        def publish_callable(gumpf):

            QW.QMessageBox.information(self, 'Information', 'Done!')

            self._account_panel.RefreshAccounts()

        self._DisableUIForJob('setting message\u2026')

        job = ClientGUIAsync.AsyncQtJob(self, work_callable, publish_callable)

        job.start()
Example #4
0
 def _DoExpires( self, subject_account_keys_and_new_expires ):
     
     if len( subject_account_keys_and_new_expires ) == 0:
         
         QW.QMessageBox.information( self, 'Information', 'No accounts selected for action!' )
         
         return
         
     
     service = self._service
     
     def work_callable():
         
         for ( subject_account_key, new_expires ) in subject_account_keys_and_new_expires:
             
             service.Request( HC.POST, 'modify_account_expires', { 'subject_identifier' : HydrusNetwork.AccountIdentifier( account_key = subject_account_key ), 'expires' : new_expires } )
             
         
         return 1
         
     
     def publish_callable( gumpf ):
         
         QW.QMessageBox.information( self, 'Information', 'Done!' )
         
         self._account_panel.RefreshAccounts()
         
     
     self._DisableUIForJob( 'setting new expiry\u2026' )
     
     job = ClientGUIAsync.AsyncQtJob( self, work_callable, publish_callable )
     
     job.start()
Example #5
0
 def _Add( self ):
     
     external_port = HC.DEFAULT_SERVICE_PORT
     protocol = 'TCP'
     internal_port = HC.DEFAULT_SERVICE_PORT
     description = 'hydrus service'
     duration = 0
     
     with ClientGUIDialogs.DialogInputUPnPMapping( self, external_port, protocol, internal_port, description, duration ) as dlg:
         
         if dlg.exec() == QW.QDialog.Accepted:
             
             ( external_port, protocol, internal_port, description, duration ) = dlg.GetInfo()
             
             remove_existing = False
             
             if self._MappingExists( external_port, protocol ):
                 
                 remove_existing = True
                 
                 text = '{}:({}) is already mapped! Ok to overwrite whatever it currently is?'
                 
                 result = ClientGUIDialogsQuick.GetYesNo( self, text, yes_label = 'do it', no_label = 'forget it' )
                 
                 if result != QW.QDialog.Accepted:
                     
                     return
                     
                 
             
             def work_callable():
                 
                 if remove_existing:
                     
                     HydrusNATPunch.RemoveUPnPMapping( external_port, protocol )
                     
                 
                 internal_client = HydrusNATPunch.GetLocalIP()
                 
                 HydrusNATPunch.AddUPnPMapping( internal_client, internal_port, external_port, protocol, description, duration = duration )
                 
                 return True
                 
             
             def publish_callable( result ):
                 
                 self._mappings_listctrl_panel.setEnabled( True )
                 
                 self._RefreshMappings()
                 
             
             self._mappings_listctrl_panel.setEnabled( False )
             
             async_job = ClientGUIAsync.AsyncQtJob( self, work_callable, publish_callable )
             
             async_job.start()
Example #6
0
    def _DoUnban(self):

        subject_accounts = self._account_panel.GetCheckedAccounts()

        if len(subject_accounts) == 0:

            QW.QMessageBox.information(self, 'Information',
                                       'No accounts selected for action!')

            return

        subject_accounts = [
            subject_account for subject_account in subject_accounts
            if subject_account.IsBanned()
        ]

        if len(subject_accounts) == 0:

            QW.QMessageBox.information(
                self, 'Information',
                'None of the selected accounts are banned!')

            return

        subject_account_keys = [
            subject_account.GetAccountKey()
            for subject_account in subject_accounts
        ]

        service = self._service

        def work_callable():

            for subject_account_key in subject_account_keys:

                service.Request(
                    HC.POST, 'modify_account_unban', {
                        'subject_identifier':
                        HydrusNetwork.AccountIdentifier(
                            account_key=subject_account_key)
                    })

            return 1

        def publish_callable(gumpf):

            QW.QMessageBox.information(self, 'Information', 'Done!')

            self._account_panel.RefreshAccounts()

        self._DisableUIForJob('unbanning\u2026')

        job = ClientGUIAsync.AsyncQtJob(self, work_callable, publish_callable)

        job.start()
Example #7
0
 def _Edit( self ):
     
     selected_mappings = self._mappings_list.GetData( only_selected = True )
     
     if len( selected_mappings ) > 0:
         
         selected_mapping = selected_mappings[0]
         
         ( description, internal_ip, internal_port, old_external_port, old_protocol, duration ) = selected_mapping
         
         with ClientGUIDialogs.DialogInputUPnPMapping( self, old_external_port, old_protocol, internal_port, description, duration ) as dlg:
             
             if dlg.exec() == QW.QDialog.Accepted:
                 
                 ( external_port, protocol, internal_port, description, duration ) = dlg.GetInfo()
                 
                 remove_old = self._MappingExists( old_external_port, old_protocol )
                 remove_existing = ( old_external_port != external_port or old_protocol != protocol ) and self._MappingExists( external_port, protocol )
                 
                 def work_callable():
                     
                     if remove_old:
                         
                         HydrusNATPunch.RemoveUPnPMapping( old_external_port, old_protocol )
                         
                     
                     if remove_existing:
                         
                         HydrusNATPunch.RemoveUPnPMapping( external_port, protocol )
                         
                     
                     internal_client = HydrusNATPunch.GetLocalIP()
                     
                     HydrusNATPunch.AddUPnPMapping( internal_client, internal_port, external_port, protocol, description, duration = duration )
                     
                     return True
                     
                 
                 def publish_callable( result ):
                     
                     self._mappings_listctrl_panel.setEnabled( True )
                     
                     self._RefreshMappings()
                     
                 
                 self._mappings_listctrl_panel.setEnabled( False )
                 
                 async_job = ClientGUIAsync.AsyncQtJob( self, work_callable, publish_callable )
                 
                 async_job.start()
Example #8
0
    def __init__(self, controller, ui):

        self._controller = controller

        self._lock = threading.Lock()

        self._updater = ClientGUIAsync.FastThreadToGUIUpdater(ui, ui.SetDirty)

        self._title_text = ''
        self._status_text = ''
        self._status_subtext = ''

        self._controller.sub(self, 'SetTitleText', 'splash_set_title_text')
        self._controller.sub(self, 'SetText', 'splash_set_status_text')
        self._controller.sub(self, 'SetSubtext', 'splash_set_status_subtext')
Example #9
0
    def _DoAccountType(self):

        subject_account_keys = self._account_panel.GetCheckedAccountKeys()

        if len(subject_account_keys) == 0:

            QW.QMessageBox.information(self, 'Information',
                                       'No accounts selected for action!')

            return

        service = self._service

        account_type = self._account_types_choice.GetValue()

        account_type_key = account_type.GetAccountTypeKey()

        def work_callable():

            for subject_account_key in subject_account_keys:

                service.Request(
                    HC.POST, 'modify_account_account_type', {
                        'subject_identifier':
                        HydrusNetwork.AccountIdentifier(
                            account_key=subject_account_key),
                        'account_type_key':
                        account_type_key
                    })

            return 1

        def publish_callable(gumpf):

            QW.QMessageBox.information(self, 'Information', 'Done!')

            self._account_panel.RefreshAccounts()

        self._DisableUIForJob('setting new account type\u2026')

        job = ClientGUIAsync.AsyncQtJob(self, work_callable, publish_callable)

        job.start()
Example #10
0
    def _Remove(self):

        text = 'Remove these port mappings?'
        text += os.linesep * 2
        text += 'If a mapping does not disappear after a remove, it may be hard-added in the router\'s settings interface. In this case, you will have to go there to fix it.'

        result = ClientGUIDialogsQuick.GetYesNo(self,
                                                text,
                                                yes_label='do it',
                                                no_label='forget it')

        if result != QW.QDialog.Accepted:

            return

        selected_mappings = self._mappings_list.GetData(only_selected=True)

        def work_callable():

            for selected_mapping in selected_mappings:

                (description, internal_ip, internal_port, external_port,
                 protocol, duration) = selected_mapping

                HydrusNATPunch.RemoveUPnPMapping(external_port, protocol)

            return True

        def publish_callable(result):

            self._mappings_listctrl_panel.setEnabled(True)

            self._RefreshMappings()

        self._mappings_listctrl_panel.setEnabled(False)

        async_job = ClientGUIAsync.AsyncQtJob(self, work_callable,
                                              publish_callable)

        async_job.start()
    def SetWindow(self, ui: FrameSplashPanel):

        self._updater = ClientGUIAsync.FastThreadToGUIUpdater(ui, ui.SetDirty)
Example #12
0
    def _RefreshMappings(self):
        def work_callable():

            try:

                mappings = HydrusNATPunch.GetUPnPMappings()

            except Exception as e:

                HydrusData.ShowException(e)

                return e

            return mappings

        def publish_callable(result):

            if isinstance(result, Exception):

                e = result

                QP.CallAfter(
                    QW.QMessageBox.critical, self, 'Error',
                    'Could not load mappings:' + os.linesep * 2 + str(e))

                self._status_st.setText(str(e))

                return

            self._mappings_listctrl_panel.setEnabled(True)

            mappings = result

            self._mappings_lookup = {
                (external_port, protocol)
                for (description, internal_ip, internal_port, external_port,
                     protocol, duration) in mappings
            }

            self._mappings_list.SetData(mappings)

            self._status_st.clear()

            if self._external_ip is not None:

                self._status_st.setText(self._external_ip)

            elif not self._started_external_ip_fetch:

                self._started_external_ip_fetch = True

                self._RefreshExternalIP()

        self._status_st.setText('Refreshing mappings--please wait\u2026')

        self._mappings_list.SetData([])

        self._mappings_listctrl_panel.setEnabled(False)

        async_job = ClientGUIAsync.AsyncQtJob(self, work_callable,
                                              publish_callable)

        async_job.start()
Example #13
0
 def _RefreshAccounts( self ):
     
     account_identifiers = self._account_identifiers
     service = self._service
     
     selected_account_keys = self.GetCheckedAccountKeys()
     
     def work_callable():
         
         account_errors = set()
         
         account_keys_to_accounts = {}
         account_keys_to_account_info = {}
         
         for account_identifier in account_identifiers:
             
             try:
                 
                 result = service.Request( HC.GET, 'other_account', { 'subject_identifier' : account_identifier } )
                 
             except Exception as e:
                 
                 account_errors.add( str( e ) )
                 
                 continue
                 
             
             if 'account' in result:
                 
                 account = result[ 'account' ]
                 
                 account_key = account.GetAccountKey()
                 
                 if account_key in account_keys_to_accounts:
                     
                     continue
                     
                 
                 account_keys_to_accounts[ account_key ] = account
                 
                 try:
                     
                     response = self._service.Request( HC.GET, 'account_info', { 'subject_identifier' : HydrusNetwork.AccountIdentifier( account_key = account_key ) } )
                     
                 except Exception as e:
                     
                     HydrusData.PrintException( e )
                     
                     continue
                     
                 
                 account_string = str( response[ 'account_info' ] )
                 
                 account_keys_to_account_info[ account_key ] = account_string
                 
             
         
         return ( account_keys_to_accounts, account_keys_to_account_info, account_errors )
         
     
     def publish_callable( result ):
         
         ( self._account_keys_to_accounts, self._account_keys_to_account_info, account_errors ) = result
         
         if len( account_errors ) > 0:
             
             account_errors = sorted( account_errors )
             
             QW.QMessageBox.information( self, 'Information', 'Errors were encountered during account fetch:{}{}'.format( os.linesep * 2, os.linesep.join( account_errors ) ) )
             
         
         if not self._done_first_fetch:
             
             # if we launched with CPU-expensive mapping identifiers, let's move to nice account keys for future refreshes
             
             self._account_identifiers = [ HydrusNetwork.AccountIdentifier( account_key = account_key ) for account_key in self._account_keys_to_accounts.keys() ]
             
         
         #
         
         account_keys_sorted = sorted(
             list( self._account_keys_to_accounts.keys() ),
             key = lambda sak: ( self._account_keys_to_accounts[ sak ].GetAccountType().GetTitle(), sak.hex() )
         )
         
         my_admin_account = self._service.GetAccount()
         
         my_admin_account_key = my_admin_account.GetAccountKey()
         
         for account_key in account_keys_sorted:
             
             item = QW.QListWidgetItem()
             
             item.setFlags( item.flags() | QC.Qt.ItemIsUserCheckable )
             
             account = self._account_keys_to_accounts[ account_key ]
             
             text = account.GetSingleLineTitle()
             
             if account_key == my_admin_account_key:
                 
                 text = 'THIS IS YOU: {}'.format( text )
                 
             
             item.setText( text )
             
             if not self._done_first_fetch or account_key in selected_account_keys:
                 
                 item.setCheckState( QC.Qt.Checked )
                 
             else:
                 
                 item.setCheckState( QC.Qt.Unchecked )
                 
             
             item.setData( QC.Qt.UserRole, account_key )
             
             self._account_list.addItem( item )
             
         
         #
         
         self._status_st.setVisible( False )
         self._status_st.setText( '' )
         
         if self._account_list.count() > 0:
             
             self._account_list.item( 0 ).setSelected( True )
             
             self._AccountClicked()
             
         
         self._accounts_loaded = True
         self._done_first_fetch = True
         
         self.accountsFetchFinished.emit()
         
     
     self._status_st.setVisible( True )
     self._status_st.setText( 'fetching accounts\u2026' )
     
     self._accounts_loaded = False
     
     self._account_list.clear()
     
     self._account_info_box.clear()
     
     self._account_keys_to_accounts = {}
     self._account_keys_to_account_info = {}
     
     self.accountsFetchStarted.emit()
     
     job = ClientGUIAsync.AsyncQtJob( self, work_callable, publish_callable )
     
     job.start()
Example #14
0
 def _DoBan( self ):
     
     subject_accounts = self._account_panel.GetCheckedAccounts()
     
     if len( subject_accounts ) == 0:
         
         QW.QMessageBox.information( self, 'Information', 'No accounts selected for action!' )
         
         return
         
     
     some_are_banned =  True in ( subject_account.IsBanned() for subject_account in subject_accounts )
     
     if some_are_banned:
         
         message = 'Some of these selected accounts are already banned. Sure you want to overwrite the bans?'
         
         result = ClientGUIDialogsQuick.GetYesNo( self, message )
         
         if result != QW.QDialog.Accepted:
             
             return
             
         
     
     subject_account_keys = [ subject_account.GetAccountKey() for subject_account in subject_accounts ]
     
     reason = self._ban_reason.text()
     
     if reason == '':
         
         QW.QMessageBox.information( self, 'Information', 'The ban reason is empty!' )
         
         return
         
     
     message = 'Ban these user(s)? All of their pending petitions will be deleted serverside.'
     
     result = ClientGUIDialogsQuick.GetYesNo( self, message )
     
     if result != QW.QDialog.Accepted:
         
         return
         
     
     expires = self._ban_expires.GetValue()
     
     if expires is not None:
         
         expires += HydrusData.GetNow()
         
     
     service = self._service
     
     def work_callable():
         
         for subject_account_key in subject_account_keys:
             
             service.Request( HC.POST, 'modify_account_ban', { 'subject_identifier' : HydrusNetwork.AccountIdentifier( account_key = subject_account_key ), 'reason' : reason, 'expires' : expires } )
             
         
         return 1
         
     
     def publish_callable( gumpf ):
         
         QW.QMessageBox.information( self, 'Information', 'Done!' )
         
         self._account_panel.RefreshAccounts()
         
     
     self._DisableUIForJob( 'banning\u2026' )
     
     job = ClientGUIAsync.AsyncQtJob( self, work_callable, publish_callable )
     
     job.start()
Example #15
0
def MoveOrDuplicateLocalFiles( win: QW.QWidget, dest_service_key: bytes, action: int, media: typing.Collection[ ClientMedia.MediaSingleton ], source_service_key: typing.Optional[ bytes ] = None ):
    
    dest_service_name = HG.client_controller.services_manager.GetName( dest_service_key )
    
    applicable_media = [ m for m in media if m.GetLocationsManager().IsLocal() and dest_service_key not in m.GetLocationsManager().GetCurrent() and m.GetMime() not in HC.HYDRUS_UPDATE_FILES ]
    
    if len( applicable_media ) == 0:
        
        return
        
    
    ( local_duplicable_to_file_service_keys, local_moveable_from_and_to_file_service_keys ) = GetLocalFileActionServiceKeys( media )
    
    do_yes_no = True
    yes_no_text = 'Add {} files to {}?'.format( HydrusData.ToHumanInt( len( applicable_media ) ), dest_service_name )
    
    if action == HC.CONTENT_UPDATE_MOVE:
        
        local_moveable_from_and_to_file_service_keys = { pair for pair in local_moveable_from_and_to_file_service_keys if pair[1] == dest_service_key }
        
        potential_source_service_keys = { pair[0] for pair in local_moveable_from_and_to_file_service_keys }
        
        potential_source_service_keys_to_applicable_media = collections.defaultdict( list )
        
        for m in applicable_media:
            
            current = m.GetLocationsManager().GetCurrent()
            
            for potential_source_service_key in potential_source_service_keys:
                
                if potential_source_service_key in current:
                    
                    potential_source_service_keys_to_applicable_media[ potential_source_service_key ].append( m )
                    
                
            
        
        if source_service_key is None:
            
            if len( potential_source_service_keys ) == 0:
                
                return
                
            elif len( potential_source_service_keys ) == 1:
                
                ( source_service_key, ) = potential_source_service_keys
                
            else:
                
                do_yes_no = False
                
                num_applicable_media = len( applicable_media )
                
                choice_tuples = []
                
                for potential_source_service_key in potential_source_service_keys:
                    
                    potential_source_service_name = HG.client_controller.services_manager.GetName( potential_source_service_key )
                    
                    text = 'move {} in "{}" to "{}"'.format( len( potential_source_service_keys_to_applicable_media[ potential_source_service_key ] ), potential_source_service_name, dest_service_name )
                    
                    description = 'Move from {} to {}.'.format( potential_source_service_name, dest_service_name )
                    
                    choice_tuples.append( ( text, potential_source_service_key, description ) )
                    
                
                choice_tuples.sort()
                
                try:
                    
                    source_service_key = ClientGUIDialogsQuick.SelectFromListButtons( win, 'select source service', choice_tuples, message = 'Select where we are moving from. Note this may not cover all files.' )
                    
                except HydrusExceptions.CancelledException:
                    
                    return
                    
                
            
        
        source_service_name = HG.client_controller.services_manager.GetName( source_service_key )
        
        applicable_media = potential_source_service_keys_to_applicable_media[ source_service_key ]
        
        yes_no_text = 'Move {} files from {} to {}?'.format( HydrusData.ToHumanInt( len( applicable_media ) ), source_service_name, dest_service_name )
        
    
    if len( applicable_media ) == 0:
        
        return
        
    
    if do_yes_no:
        
        result = ClientGUIDialogsQuick.GetYesNo( win, yes_no_text )
        
        if result != QW.QDialog.Accepted:
            
            return
            
        
    
    def work_callable():
        
        job_key = ClientThreading.JobKey( cancellable = True )
        
        title = 'moving files' if action == HC.CONTENT_UPDATE_MOVE else 'adding files'
        
        job_key.SetStatusTitle( title )
        
        BLOCK_SIZE = 64
        
        if len( applicable_media ) > BLOCK_SIZE:
            
            HG.client_controller.pub( 'message', job_key )
            
        
        pauser = HydrusData.BigJobPauser()
        
        num_to_do = len( applicable_media )
        
        now = HydrusData.GetNow()
        
        for ( i, block_of_media ) in enumerate( HydrusData.SplitListIntoChunks( applicable_media, BLOCK_SIZE ) ):
            
            if job_key.IsCancelled():
                
                break
                
            
            job_key.SetVariable( 'popup_text_1', HydrusData.ConvertValueRangeToPrettyString( i * BLOCK_SIZE, num_to_do ) )
            job_key.SetVariable( 'popup_gauge_1', ( i * BLOCK_SIZE, num_to_do ) )
            
            content_updates = []
            undelete_hashes = set()
            
            for m in block_of_media:
                
                if dest_service_key in m.GetLocationsManager().GetDeleted():
                    
                    undelete_hashes.add( m.GetHash() )
                    
                else:
                    
                    content_updates.append( HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_ADD, ( m.GetMediaResult().GetFileInfoManager(), now ) ) )
                    
                
            
            if len( undelete_hashes ) > 0:
                
                content_updates.append( HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_UNDELETE, undelete_hashes ) )
                
            
            HG.client_controller.WriteSynchronous( 'content_updates', { dest_service_key : content_updates } )
            
            if action == HC.CONTENT_UPDATE_MOVE:
                
                block_of_hashes = [ m.GetHash() for m in block_of_media ]
                
                content_updates = [ HydrusData.ContentUpdate( HC.CONTENT_TYPE_FILES, HC.CONTENT_UPDATE_DELETE, block_of_hashes, reason = 'Moved to {}'.format( dest_service_name ) ) ]
                
                HG.client_controller.WriteSynchronous( 'content_updates', { source_service_key : content_updates } )
                
            
            pauser.Pause()
            
        
        job_key.Delete()
        
    
    def publish_callable( result ):
        
        pass
        
    
    job = ClientGUIAsync.AsyncQtJob( win, work_callable, publish_callable )
    
    job.start()