Ejemplo n.º 1
0
 def FilterServiceKeysToStatusesToTags( self, service_keys_to_statuses_to_tags ):
     
     filtered_service_keys_to_statuses_to_tags = collections.defaultdict( HydrusData.default_dict_set )
     
     for ( service_key, statuses_to_tags ) in service_keys_to_statuses_to_tags.items():
         
         for service_key_lookup in ( CC.COMBINED_TAG_SERVICE_KEY, service_key ):
             
             if service_key_lookup in self._service_keys_to_predicates:
                 
                 combined_predicate = self._service_keys_to_predicates[ service_key_lookup ]
                 
                 new_statuses_to_tags = HydrusData.default_dict_set()
                 
                 for ( status, tags ) in statuses_to_tags.items():
                     
                     new_statuses_to_tags[ status ] = { tag for tag in tags if combined_predicate( tag ) }
                     
                 
                 statuses_to_tags = new_statuses_to_tags
                 
             
         
         filtered_service_keys_to_statuses_to_tags[ service_key ] = statuses_to_tags
         
     
     return filtered_service_keys_to_statuses_to_tags
Ejemplo n.º 2
0
def BuildSimpleChildrenToParents( pairs ):
    
    simple_children_to_parents = HydrusData.default_dict_set()
    
    for ( child, parent ) in pairs:
        
        if child == parent: continue
        
        if LoopInSimpleChildrenToParents( simple_children_to_parents, child, parent ): continue
        
        simple_children_to_parents[ child ].add( parent )
        
    
    return simple_children_to_parents
Ejemplo n.º 3
0
    def _RefreshParents(self):

        service_keys_to_statuses_to_pairs = HydrusGlobals.client_controller.Read("tag_parents")

        # first collapse siblings

        sibling_manager = HydrusGlobals.client_controller.GetManager("tag_siblings")

        collapsed_service_keys_to_statuses_to_pairs = collections.defaultdict(HydrusData.default_dict_set)

        for (service_key, statuses_to_pairs) in service_keys_to_statuses_to_pairs.items():

            if service_key == CC.COMBINED_TAG_SERVICE_KEY:
                continue

            for (status, pairs) in statuses_to_pairs.items():

                pairs = sibling_manager.CollapsePairs(pairs)

                collapsed_service_keys_to_statuses_to_pairs[service_key][status] = pairs

        # now collapse current and pending

        service_keys_to_pairs_flat = HydrusData.default_dict_set()

        for (service_key, statuses_to_pairs) in collapsed_service_keys_to_statuses_to_pairs.items():

            pairs_flat = statuses_to_pairs[HC.CURRENT].union(statuses_to_pairs[HC.PENDING])

            service_keys_to_pairs_flat[service_key] = pairs_flat

        # now create the combined tag service

        combined_pairs_flat = set()

        for pairs_flat in service_keys_to_pairs_flat.values():

            combined_pairs_flat.update(pairs_flat)

        service_keys_to_pairs_flat[CC.COMBINED_TAG_SERVICE_KEY] = combined_pairs_flat

        #

        service_keys_to_simple_children_to_parents = BuildServiceKeysToSimpleChildrenToParents(
            service_keys_to_pairs_flat
        )

        self._service_keys_to_children_to_parents = BuildServiceKeysToChildrenToParents(
            service_keys_to_simple_children_to_parents
        )
Ejemplo n.º 4
0
 def RefreshAllAccounts( self ):
     
     with self._lock:
         
         self._service_keys_to_sessions = collections.defaultdict( dict )
         
         self._account_keys_to_session_keys = HydrusData.default_dict_set()
         
         self._account_keys_to_accounts = {}
         
         #
         
         existing_sessions = HydrusGlobals.controller.Read( 'sessions' )
         
         for ( session_key, service_key, account, expires ) in existing_sessions:
             
             account_key = account.GetAccountKey()
             
             self._service_keys_to_sessions[ service_key ][ session_key ] = ( account, expires )
             
             self._account_keys_to_session_keys[ account_key ].add( session_key )
             
             self._account_keys_to_accounts[ account_key ] = account
Ejemplo n.º 5
0
def ConvertParsableContentToPrettyString(parsable_content, include_veto=False):

    pretty_strings = []

    content_type_to_additional_infos = HydrusData.BuildKeyToSetDict(
        ((content_type, additional_infos)
         for (name, content_type, additional_infos) in parsable_content))

    for (content_type,
         additional_infos) in content_type_to_additional_infos.items():

        if content_type == HC.CONTENT_TYPE_MAPPINGS:

            namespaces = [
                namespace for namespace in additional_infos if namespace != ''
            ]

            if '' in additional_infos:

                namespaces.append('unnamespaced')

            pretty_strings.append('tags: ' + ', '.join(namespaces))

        elif content_type == HC.CONTENT_TYPE_VETO:

            if include_veto:

                pretty_strings.append('veto')

    if len(pretty_strings) == 0:

        return 'nothing'

    else:

        return ', '.join(pretty_strings)
Ejemplo n.º 6
0
    def wait_for_free_slot(controller, subs_jobs,
                           max_simultaneous_subscriptions):

        time.sleep(0.1)

        while True:

            p1 = controller.options['pause_subs_sync']
            p2 = HydrusThreading.IsThreadShuttingDown()

            if p1 or p2:

                if HG.subscription_report_mode:

                    HydrusData.ShowText(
                        'Subscriptions cancelling. Global sub pause is ' +
                        str(p1) +
                        ' and sub daemon thread shutdown status is ' +
                        str(p2) + '.')

                if p2:

                    for (thread, job) in subs_jobs:

                        HydrusThreading.ShutdownThread(thread)

                raise HydrusExceptions.CancelledException(
                    'subs cancelling or thread shutting down')

            filter_finished_jobs(subs_jobs)

            if len(subs_jobs) < max_simultaneous_subscriptions:

                return

            time.sleep(1.0)
Ejemplo n.º 7
0
    def CheckMouseIdle(self):

        mouse_position = wx.GetMousePosition()

        if self._last_mouse_position is None:

            self._last_mouse_position = mouse_position

        elif mouse_position != self._last_mouse_position:

            idle_before_position_update = self.CurrentlyIdle()

            self._timestamps['last_mouse_action'] = HydrusData.GetNow()

            self._last_mouse_position = mouse_position

            idle_after_position_update = self.CurrentlyIdle()

            move_knocked_us_out_of_idle = (
                not idle_before_position_update) and idle_after_position_update

            if move_knocked_us_out_of_idle:

                self.pub('refresh_status')
Ejemplo n.º 8
0
    def GetAccount(self, service_key, session_key):

        with self._lock:

            session_keys_to_sessions = self._service_keys_to_session_keys_to_sessions[
                service_key]

            if session_key in session_keys_to_sessions:

                (account_key, expires) = session_keys_to_sessions[session_key]

                if HydrusData.TimeHasPassed(expires):

                    del session_keys_to_sessions[session_key]

                else:

                    account = self._service_keys_to_account_keys_to_accounts[
                        service_key][account_key]

                    return account

            raise HydrusExceptions.SessionException(
                'Did not find that session! Try again!')
Ejemplo n.º 9
0
    def Export(self):

        width = self._width.GetValue()

        (payload_description,
         payload_string) = ClientSerialisable.GetPayloadDescriptionAndString(
             self._payload_obj)

        title = self._title.GetValue()
        text = self._text.GetValue()
        path = HydrusData.ToUnicode(self._filepicker.GetPath())

        if not path.endswith('.png'):

            path += '.png'

        ClientSerialisable.DumpToPng(width, payload_string, title,
                                     payload_description, text, path)

        self._export.SetLabelText('done!')

        HG.client_controller.CallLaterWXSafe(self._export, 2.0,
                                             self._export.SetLabelText,
                                             'export')
Ejemplo n.º 10
0
def FilterFreePaths( paths ):
    
    free_paths = []
    
    for path in paths:
        
        if HydrusThreading.IsThreadShuttingDown():
            
            raise HydrusExceptions.ShutdownException()
            
        
        try:
            
            os.rename( path, path ) # rename a path to itself
            
            free_paths.append( path )
            
        except OSError as e: # 'already in use by another process'
            
            HydrusData.Print( 'Already in use: ' + path )
            
        
    
    return free_paths
Ejemplo n.º 11
0
def HasSpaceForDBTransaction(db_dir, num_bytes):

    temp_dir = tempfile.gettempdir()

    temp_disk_free_space = GetFreeSpace(temp_dir)

    a = GetDevice(temp_dir)
    b = GetDevice(db_dir)

    if GetDevice(temp_dir) == GetDevice(db_dir):

        space_needed = int(num_bytes * 2.2)

        if temp_disk_free_space < space_needed:

            return (
                False, 'I believe you need about ' +
                HydrusData.ConvertIntToBytes(space_needed) +
                ' on your db\'s partition, which I think also holds your temporary path, but you only seem to have '
                + HydrusData.ConvertIntToBytes(temp_disk_free_space) + '.')

    else:

        space_needed = int(num_bytes * 1.1)

        if temp_disk_free_space < space_needed:

            return (False, 'I believe you need about ' +
                    HydrusData.ConvertIntToBytes(space_needed) +
                    ' on your temporary path\'s partition, which I think is ' +
                    temp_dir + ', but you only seem to have ' +
                    HydrusData.ConvertIntToBytes(temp_disk_free_space) + '.')

        db_disk_free_space = GetFreeSpace(db_dir)

        if db_disk_free_space < space_needed:

            return (False, 'I believe you need about ' +
                    HydrusData.ConvertIntToBytes(space_needed) +
                    ' on your db\'s partition, but you only seem to have ' +
                    HydrusData.ConvertIntToBytes(db_disk_free_space) + '.')

    return (True, 'You seem to have enough space!')
Ejemplo n.º 12
0
    def __init__(self,
                 pausable=False,
                 cancellable=False,
                 only_when_idle=False,
                 only_start_if_unbusy=False,
                 stop_time=None,
                 cancel_on_shutdown=True):

        self._key = HydrusData.GenerateKey()

        self._creation_time = HydrusData.GetNowFloat()

        self._pausable = pausable
        self._cancellable = cancellable
        self._only_when_idle = only_when_idle
        self._only_start_if_unbusy = only_start_if_unbusy
        self._stop_time = stop_time
        self._cancel_on_shutdown = cancel_on_shutdown

        self._start_time = HydrusData.GetNow()

        self._deleted = threading.Event()
        self._deletion_time = None
        self._begun = threading.Event()
        self._done = threading.Event()
        self._cancelled = threading.Event()
        self._paused = threading.Event()

        self._yield_pause_period = 10
        self._next_yield_pause = HydrusData.GetNow() + self._yield_pause_period

        self._bigger_pause_period = 100
        self._next_bigger_pause = HydrusData.GetNow(
        ) + self._bigger_pause_period

        self._longer_pause_period = 1000
        self._next_longer_pause = HydrusData.GetNow(
        ) + self._longer_pause_period

        self._urls = []
        self._variable_lock = threading.Lock()
        self._variables = dict()
Ejemplo n.º 13
0
 def MaintainMemorySlow( self ):
     
     HydrusController.HydrusController.MaintainMemorySlow( self )
     
     if HydrusData.TimeHasPassed( self._timestamps[ 'last_page_change' ] + 30 * 60 ):
         
         self.pub( 'delete_old_closed_pages' )
         
         self._timestamps[ 'last_page_change' ] = HydrusData.GetNow()
         
     
     disk_cache_maintenance_mb = self.new_options.GetNoneableInteger( 'disk_cache_maintenance_mb' )
     
     if disk_cache_maintenance_mb is not None:
         
         if self.CurrentlyVeryIdle():
             
             cache_period = 3600
             disk_cache_stop_time = HydrusData.GetNow() + 30
             
         elif self.CurrentlyIdle():
             
             cache_period = 1800
             disk_cache_stop_time = HydrusData.GetNow() + 10
             
         else:
             
             cache_period = 240
             disk_cache_stop_time = HydrusData.GetNow() + 2
             
         
         if HydrusData.TimeHasPassed( self._timestamps[ 'last_disk_cache_population' ] + cache_period ):
             
             self.Read( 'load_into_disk_cache', stop_time = disk_cache_stop_time, caller_limit = disk_cache_maintenance_mb * 1024 * 1024 )
             
             self._timestamps[ 'last_disk_cache_population' ] = HydrusData.GetNow()
Ejemplo n.º 14
0
 def Run( self ):
     
     HydrusData.RecordRunningStart( self._db_dir, 'server' )
     
     HydrusData.Print( u'Initialising db\u2026' )
     
     self.InitModel()
     
     HydrusData.Print( u'Initialising daemons and services\u2026' )
     
     self.InitView()
     
     HydrusData.Print( 'Server is running. Press Ctrl+C to quit.' )
     
     interrupt_received = False
     
     while not self._model_shutdown:
         
         try:
             
             time.sleep( 1 )
             
         except KeyboardInterrupt:
             
             if not interrupt_received:
                 
                 interrupt_received = True
                 
                 HydrusData.Print( u'Received a keyboard interrupt\u2026' )
                 
                 def do_it():
                     
                     self.Exit()
                     
                 
                 self.CallToThread( do_it )
                 
             
         
     
     HydrusData.Print( u'Shutting down controller\u2026' )
Ejemplo n.º 15
0
    def WaitIfNeeded(self):

        if HydrusData.TimeHasPassed(self._next_yield_pause):

            time.sleep(0.1)

            self._next_yield_pause = HydrusData.GetNow(
            ) + self._yield_pause_period

            if HydrusData.TimeHasPassed(self._next_bigger_pause):

                time.sleep(1)

                self._next_bigger_pause = HydrusData.GetNow(
                ) + self._bigger_pause_period

                if HydrusData.TimeHasPassed(self._longer_pause_period):

                    time.sleep(10)

                    self._next_longer_pause = HydrusData.GetNow(
                    ) + self._longer_pause_period

        i_paused = False
        should_quit = False

        while self.IsPaused():

            i_paused = True

            time.sleep(0.1)

            if self.IsDone():

                break

        if self.IsCancelled():

            should_quit = True

        return (i_paused, should_quit)
Ejemplo n.º 16
0
 def do_it( launch_path ):
     
     if HC.PLATFORM_WINDOWS and launch_path is None:
         
         os.startfile( path )
         
     else:
         
         if launch_path is None:
             
             launch_path = GetDefaultLaunchPath()
             
         
         cmd = launch_path.replace( '%path%', path )
         
         if HC.PLATFORM_WINDOWS:
             
             preexec_fn = None
             
         else:
             
             # setsid call un-childs this new process
             
             preexec_fn = os.setsid
             
             cmd = shlex.split( cmd )
             
         
         if HG.callto_report_mode:
             
             message = 'Attempting to launch ' + path + ' using command ' + repr( cmd ) + '.'
             
         
         try:
             
             process = subprocess.Popen( cmd, preexec_fn = preexec_fn, startupinfo = HydrusData.GetHideTerminalSubprocessStartupInfo() )
             
             process.wait()
             
             ( stdout, stderr ) = process.communicate()
             
             if HG.callto_report_mode:
                 
                 HydrusData.ShowText( message )
                 
                 if stdout is None and stderr is None:
                     
                     HydrusData.ShowText( 'No stdout or stderr came back.' )
                     
                 
                 if stdout is not None:
                     
                     HydrusData.ShowText( 'stdout: ' + repr( stdout ) )
                     
                 
                 if stderr is not None:
                     
                     HydrusData.ShowText( 'stderr: ' + repr( stderr ) )
                     
                 
             
         except Exception as e:
             
             HydrusData.ShowText( 'Could not launch a file! Command used was:' + os.linesep + HydrusData.ToUnicode( cmd ) )
             
             HydrusData.ShowException( e )
Ejemplo n.º 17
0
 def do_it():
     
     if HC.PLATFORM_WINDOWS:
         
         os.startfile( path )
         
     else:
         
         if HC.PLATFORM_OSX:
             
             cmd = 'open'
             
         elif HC.PLATFORM_LINUX:
             
             cmd = 'xdg-open'
             
         
         # setsid call un-childs this new process
         
         process = subprocess.Popen( [ cmd, path ], preexec_fn = os.setsid, startupinfo = HydrusData.GetHideTerminalSubprocessStartupInfo() )
         
         process.wait()
         
         process.communicate()
Ejemplo n.º 18
0
 def RestartBooru( self ):
     
     service = self.services_manager.GetService( CC.LOCAL_BOORU_SERVICE_KEY )
     
     port = service.GetPort()
     
     def TWISTEDRestartServer():
         
         def StartServer( *args, **kwargs ):
             
             try:
                 
                 try:
                     
                     connection = HydrusNetworking.GetLocalConnection( port )
                     connection.close()
                     
                     text = 'The client\'s booru server could not start because something was already bound to port ' + str( port ) + '.'
                     text += os.linesep * 2
                     text += 'This usually means another hydrus client is already running and occupying that port. It could be a previous instantiation of this client that has yet to shut itself down.'
                     text += os.linesep * 2
                     text += 'You can change the port this client tries to host its local server on in services->manage services.'
                     
                     HydrusData.ShowText( text )
                     
                 except:
                     
                     import ClientLocalServer
                     
                     self._booru_port_connection = reactor.listenTCP( port, ClientLocalServer.HydrusServiceBooru( service ) )
                     
                     try:
                         
                         connection = HydrusNetworking.GetLocalConnection( port )
                         connection.close()
                         
                     except Exception as e:
                         
                         text = 'Tried to bind port ' + str( port ) + ' for the local booru, but it failed:'
                         text += os.linesep * 2
                         text += HydrusData.ToUnicode( e )
                         
                         HydrusData.ShowText( text )
                         
                     
                 
             except Exception as e:
                 
                 wx.CallAfter( HydrusData.ShowException, e )
                 
             
         
         if self._booru_port_connection is None:
             
             if port is not None:
                 
                 StartServer()
                 
             
         else:
             
             deferred = defer.maybeDeferred( self._booru_port_connection.stopListening )
             
             if port is not None:
                 
                 deferred.addCallback( StartServer )
                 
             
         
     
     if HG.twisted_is_broke:
         
         HydrusData.ShowText( 'Twisted failed to import, so could not restart the booru! Please contact hydrus dev!' )
         
     else:
         
         reactor.callFromThread( TWISTEDRestartServer )
Ejemplo n.º 19
0
 def ResetPageChangeTimer( self ):
     
     self._timestamps[ 'last_page_change' ] = HydrusData.GetNow()
Ejemplo n.º 20
0
 def ResetIdleTimer( self ):
     
     self._timestamps[ 'last_user_action' ] = HydrusData.GetNow()
Ejemplo n.º 21
0
 def MaintainDB( self, stop_time = None ):
     
     if self.new_options.GetBoolean( 'maintain_similar_files_duplicate_pairs_during_idle' ):
         
         phashes_stop_time = stop_time
         
         if phashes_stop_time is None:
             
             phashes_stop_time = HydrusData.GetNow() + 15
             
         
         self.WriteInterruptable( 'maintain_similar_files_phashes', stop_time = phashes_stop_time )
         
         tree_stop_time = stop_time
         
         if tree_stop_time is None:
             
             tree_stop_time = HydrusData.GetNow() + 30
             
         
         self.WriteInterruptable( 'maintain_similar_files_tree', stop_time = tree_stop_time, abandon_if_other_work_to_do = True )
         
         search_distance = self.new_options.GetInteger( 'similar_files_duplicate_pairs_search_distance' )
         
         search_stop_time = stop_time
         
         if search_stop_time is None:
             
             search_stop_time = HydrusData.GetNow() + 60
             
         
         self.WriteInterruptable( 'maintain_similar_files_duplicate_pairs', search_distance, stop_time = search_stop_time, abandon_if_other_work_to_do = True )
         
     
     if stop_time is None or not HydrusData.TimeHasPassed( stop_time ):
         
         self.WriteInterruptable( 'vacuum', stop_time = stop_time )
         
     
     if stop_time is None or not HydrusData.TimeHasPassed( stop_time ):
         
         self.WriteInterruptable( 'analyze', stop_time = stop_time )
         
     
     if stop_time is None or not HydrusData.TimeHasPassed( stop_time ):
         
         if HydrusData.TimeHasPassed( self._timestamps[ 'last_service_info_cache_fatten' ] + ( 60 * 20 ) ):
             
             self.pub( 'splash_set_status_text', 'fattening service info' )
             
             services = self.services_manager.GetServices()
             
             for service in services:
                 
                 self.pub( 'splash_set_status_subtext', service.GetName() )
                 
                 try: self.Read( 'service_info', service.GetServiceKey() )
                 except: pass # sometimes this breaks when a service has just been removed and the client is closing, so ignore the error
                 
             
             self._timestamps[ 'last_service_info_cache_fatten' ] = HydrusData.GetNow()
Ejemplo n.º 22
0
 def InitView( self ):
     
     if self.options[ 'password' ] is not None:
         
         self.pub( 'splash_set_status_text', 'waiting for password' )
         
         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' )
                         
                     
                 
             
         
         self.CallBlockingToWx( wx_code_password )
         
     
     self.pub( 'splash_set_title_text', u'booting gui\u2026' )
     
     def wx_code_gui():
         
         self.gui = ClientGUI.FrameGUI( self )
         
         self.ResetIdleTimer()
         
     
     self.CallBlockingToWx( wx_code_gui )
     
     # ShowText will now popup as a message, as popup message manager has overwritten the hooks
     
     HydrusController.HydrusController.InitView( self )
     
     self._booru_port_connection = None
     
     self.RestartBooru()
     
     if not self._no_daemons:
         
         self._daemons.append( HydrusThreading.DAEMONWorker( self, 'CheckMouseIdle', ClientDaemons.DAEMONCheckMouseIdle, period = 10 ) )
         self._daemons.append( HydrusThreading.DAEMONWorker( self, 'SynchroniseAccounts', ClientDaemons.DAEMONSynchroniseAccounts, ( 'notify_unknown_accounts', ) ) )
         self._daemons.append( HydrusThreading.DAEMONWorker( self, 'SaveDirtyObjects', ClientDaemons.DAEMONSaveDirtyObjects, ( 'important_dirt_to_clean', ), period = 30 ) )
         
         self._daemons.append( HydrusThreading.DAEMONForegroundWorker( self, 'DownloadFiles', ClientDaemons.DAEMONDownloadFiles, ( 'notify_new_downloads', 'notify_new_permissions' ) ) )
         self._daemons.append( HydrusThreading.DAEMONForegroundWorker( self, 'SynchroniseSubscriptions', ClientDaemons.DAEMONSynchroniseSubscriptions, ( 'notify_restart_subs_sync_daemon', 'notify_new_subscriptions' ), period = 14400, init_wait = 60, pre_call_wait = 3 ) )
         self._daemons.append( HydrusThreading.DAEMONForegroundWorker( self, 'CheckImportFolders', ClientDaemons.DAEMONCheckImportFolders, ( 'notify_restart_import_folders_daemon', 'notify_new_import_folders' ), period = 180 ) )
         self._daemons.append( HydrusThreading.DAEMONForegroundWorker( self, 'CheckExportFolders', ClientDaemons.DAEMONCheckExportFolders, ( 'notify_restart_export_folders_daemon', 'notify_new_export_folders' ), period = 180 ) )
         self._daemons.append( HydrusThreading.DAEMONForegroundWorker( self, 'MaintainTrash', ClientDaemons.DAEMONMaintainTrash, init_wait = 120 ) )
         self._daemons.append( HydrusThreading.DAEMONForegroundWorker( self, 'SynchroniseRepositories', ClientDaemons.DAEMONSynchroniseRepositories, ( 'notify_restart_repo_sync_daemon', 'notify_new_permissions' ), period = 4 * 3600, pre_call_wait = 1 ) )
         
         self._daemons.append( HydrusThreading.DAEMONBackgroundWorker( self, 'UPnP', ClientDaemons.DAEMONUPnP, ( 'notify_new_upnp_mappings', ), init_wait = 120, pre_call_wait = 6 ) )
         
     
     if self.db.IsFirstStart():
         
         message = 'Hi, this looks like the first time you have started the hydrus client.'
         message += os.linesep * 2
         message += 'Don\'t forget to check out the help if you haven\'t already.'
         message += os.linesep * 2
         message += 'To dismiss popup messages like this, right-click them.'
         
         HydrusData.ShowText( message )
         
     
     if self.db.IsDBUpdated():
         
         HydrusData.ShowText( 'The client has updated to version ' + str( HC.SOFTWARE_VERSION ) + '!' )
         
     
     for message in self.db.GetInitialMessages():
         
         HydrusData.ShowText( message )
Ejemplo n.º 23
0
    def GetUnicode(self,
                   with_count=True,
                   sibling_service_key=None,
                   render_for_user=False):

        count_text = u''

        if with_count:

            if self._min_current_count > 0:

                number_text = HydrusData.ConvertIntToPrettyString(
                    self._min_current_count)

                if self._max_current_count is not None:

                    number_text += u'-' + HydrusData.ConvertIntToPrettyString(
                        self._max_current_count)

                count_text += u' (' + number_text + u')'

            if self._min_pending_count > 0:

                number_text = HydrusData.ConvertIntToPrettyString(
                    self._min_pending_count)

                if self._max_pending_count is not None:

                    number_text += u'-' + HydrusData.ConvertIntToPrettyString(
                        self._max_pending_count)

                count_text += u' (+' + number_text + u')'

        if self._predicate_type in HC.SYSTEM_PREDICATES:

            if self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_EVERYTHING:
                base = u'everything'
            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_INBOX:
                base = u'inbox'
            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_ARCHIVE:
                base = u'archive'
            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_UNTAGGED:
                base = u'untagged'
            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_LOCAL:
                base = u'local'
            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_NOT_LOCAL:
                base = u'not local'
            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_DIMENSIONS:
                base = u'dimensions'
            elif self._predicate_type in (HC.PREDICATE_TYPE_SYSTEM_NUM_TAGS,
                                          HC.PREDICATE_TYPE_SYSTEM_WIDTH,
                                          HC.PREDICATE_TYPE_SYSTEM_HEIGHT,
                                          HC.PREDICATE_TYPE_SYSTEM_NUM_WORDS):

                if self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_NUM_TAGS:
                    base = u'number of tags'
                elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_WIDTH:
                    base = u'width'
                elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_HEIGHT:
                    base = u'height'
                elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_NUM_WORDS:
                    base = u'number of words'

                if self._value is not None:

                    (operator, value) = self._value

                    base += u' ' + operator + u' ' + HydrusData.ConvertIntToPrettyString(
                        value)

            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_DURATION:

                base = u'duration'

                if self._value is not None:

                    (operator, value) = self._value

                    base += u' ' + operator + u' ' + HydrusData.ConvertMillisecondsToPrettyTime(
                        value)

            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_RATIO:

                base = u'ratio'

                if self._value is not None:

                    (operator, ratio_width, ratio_height) = self._value

                    base += u' ' + operator + u' ' + str(
                        ratio_width) + u':' + str(ratio_height)

            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_SIZE:

                base = u'size'

                if self._value is not None:

                    (operator, size, unit) = self._value

                    base += u' ' + operator + u' ' + str(
                        size) + HydrusData.ConvertIntToUnit(unit)

            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_LIMIT:

                base = u'limit'

                if self._value is not None:

                    value = self._value

                    base += u' is ' + HydrusData.ConvertIntToPrettyString(
                        value)

            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_AGE:

                base = u'age'

                if self._value is not None:

                    (operator, years, months, days, hours) = self._value

                    base += u' ' + operator + u' ' + str(years) + u'y' + str(
                        months) + u'm' + str(days) + u'd' + str(hours) + u'h'

            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_NUM_PIXELS:

                base = u'num_pixels'

                if self._value is not None:

                    (operator, num_pixels, unit) = self._value

                    base += u' ' + operator + u' ' + str(
                        num_pixels) + ' ' + HydrusData.ConvertIntToPixels(unit)

            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_HASH:

                base = u'hash'

                if self._value is not None:

                    (hash, hash_type) = self._value

                    base = hash_type + ' hash is ' + hash.encode('hex')

            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_MIME:

                base = u'mime'

                if self._value is not None:

                    mimes = self._value

                    if set(mimes) == set(HC.SEARCHABLE_MIMES):

                        mime_text = 'anything'

                    elif set(mimes) == set(HC.SEARCHABLE_MIMES).intersection(
                            set(HC.APPLICATIONS)):

                        mime_text = 'application'

                    elif set(mimes) == set(HC.SEARCHABLE_MIMES).intersection(
                            set(HC.AUDIO)):

                        mime_text = 'audio'

                    elif set(mimes) == set(HC.SEARCHABLE_MIMES).intersection(
                            set(HC.IMAGES)):

                        mime_text = 'image'

                    elif set(mimes) == set(HC.SEARCHABLE_MIMES).intersection(
                            set(HC.VIDEO)):

                        mime_text = 'video'

                    else:

                        mime_text = ', '.join(
                            [HC.mime_string_lookup[mime] for mime in mimes])

                    base += u' is ' + mime_text

            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_RATING:

                base = u'rating'

                if self._value is not None:

                    (operator, value, service_key) = self._value

                    service = HydrusGlobals.client_controller.GetServicesManager(
                    ).GetService(service_key)

                    base += u' for ' + service.GetName(
                    ) + u' ' + operator + u' ' + HydrusData.ToUnicode(value)

            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_SIMILAR_TO:

                base = u'similar to'

                if self._value is not None:

                    (hash, max_hamming) = self._value

                    base += u' ' + hash.encode(
                        'hex') + u' using max hamming of ' + str(max_hamming)

            elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_FILE_SERVICE:

                if self._value is None:

                    base = 'file service'

                else:

                    (operator, current_or_pending, service_key) = self._value

                    if operator == True: base = u'is'
                    else: base = u'is not'

                    if current_or_pending == HC.CONTENT_STATUS_PENDING:
                        base += u' pending to '
                    else:
                        base += u' currently in '

                    service = HydrusGlobals.client_controller.GetServicesManager(
                    ).GetService(service_key)

                    base += service.GetName()

            base += count_text

            base = HydrusTags.CombineTag('system', base)

        elif self._predicate_type == HC.PREDICATE_TYPE_TAG:

            tag = self._value

            if not self._inclusive: base = u'-'
            else: base = u''

            base += tag

            base += count_text

            if sibling_service_key is not None:

                siblings_manager = HydrusGlobals.client_controller.GetManager(
                    'tag_siblings')

                sibling = siblings_manager.GetSibling(sibling_service_key, tag)

                if sibling is not None:

                    sibling = ClientTags.RenderTag(sibling, render_for_user)

                    base += u' (will display as ' + sibling + ')'

        elif self._predicate_type == HC.PREDICATE_TYPE_PARENT:

            base = '    '

            tag = self._value

            base += tag

            base += count_text

        elif self._predicate_type == HC.PREDICATE_TYPE_NAMESPACE:

            namespace = self._value

            if not self._inclusive: base = u'-'
            else: base = u''

            rendered_tag = HydrusTags.CombineTag(namespace, '*anything*')

            base += rendered_tag

        elif self._predicate_type == HC.PREDICATE_TYPE_WILDCARD:

            wildcard = self._value

            if not self._inclusive: base = u'-'
            else: base = u''

            base += wildcard

        base = ClientTags.RenderTag(base, render_for_user)

        return base
Ejemplo n.º 24
0
    def __init__(self, system_predicates):

        self._inbox = False
        self._archive = False
        self._local = False
        self._not_local = False

        self._common_info = {}

        self._limit = None
        self._similar_to = None

        self._file_services_to_include_current = []
        self._file_services_to_include_pending = []
        self._file_services_to_exclude_current = []
        self._file_services_to_exclude_pending = []

        self._ratings_predicates = []

        new_options = HydrusGlobals.client_controller.GetNewOptions()

        forced_search_limit = new_options.GetNoneableInteger(
            'forced_search_limit')

        if forced_search_limit is not None:

            self._limit = forced_search_limit

        for predicate in system_predicates:

            predicate_type = predicate.GetType()
            value = predicate.GetValue()

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_INBOX:
                self._inbox = True
            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_ARCHIVE:
                self._archive = True
            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_LOCAL:
                self._local = True
            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_NOT_LOCAL:
                self._not_local = True

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_HASH:

                (hash, hash_type) = value

                self._common_info['hash'] = (hash, hash_type)

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_AGE:

                (operator, years, months, days, hours) = value

                age = ((((((
                    (years * 12) + months) * 30) + days) * 24) + hours) * 3600)

                now = HydrusData.GetNow()

                # this is backwards because we are talking about age, not timestamp

                if operator == '<':
                    self._common_info['min_timestamp'] = now - age
                elif operator == '>':
                    self._common_info['max_timestamp'] = now - age
                elif operator == u'\u2248':

                    self._common_info['min_timestamp'] = now - int(age * 1.15)
                    self._common_info['max_timestamp'] = now - int(age * 0.85)

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_MIME:

                mimes = value

                if isinstance(mimes, int): mimes = (mimes, )

                self._common_info['mimes'] = mimes

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_DURATION:

                (operator, duration) = value

                if operator == '<':
                    self._common_info['max_duration'] = duration
                elif operator == '>':
                    self._common_info['min_duration'] = duration
                elif operator == '=':
                    self._common_info['duration'] = duration
                elif operator == u'\u2248':

                    if duration == 0: self._common_info['duration'] = 0
                    else:

                        self._common_info['min_duration'] = int(duration *
                                                                0.85)
                        self._common_info['max_duration'] = int(duration *
                                                                1.15)

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_RATING:

                (operator, value, service_key) = value

                self._ratings_predicates.append((operator, value, service_key))

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_RATIO:

                (operator, ratio_width, ratio_height) = value

                if operator == '=':
                    self._common_info['ratio'] = (ratio_width, ratio_height)
                elif operator == 'wider than':

                    self._common_info['min_ratio'] = (ratio_width,
                                                      ratio_height)

                elif operator == 'taller than':

                    self._common_info['max_ratio'] = (ratio_width,
                                                      ratio_height)

                elif operator == u'\u2248':

                    self._common_info['min_ratio'] = (ratio_width * 0.85,
                                                      ratio_height)
                    self._common_info['max_ratio'] = (ratio_width * 1.15,
                                                      ratio_height)

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_SIZE:

                (operator, size, unit) = value

                size = size * unit

                if operator == '<': self._common_info['max_size'] = size
                elif operator == '>': self._common_info['min_size'] = size
                elif operator == '=': self._common_info['size'] = size
                elif operator == u'\u2248':

                    self._common_info['min_size'] = int(size * 0.85)
                    self._common_info['max_size'] = int(size * 1.15)

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_NUM_TAGS:

                (operator, num_tags) = value

                if operator == '<':
                    self._common_info['max_num_tags'] = num_tags
                elif operator == '=':
                    self._common_info['num_tags'] = num_tags
                elif operator == '>':
                    self._common_info['min_num_tags'] = num_tags

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_WIDTH:

                (operator, width) = value

                if operator == '<': self._common_info['max_width'] = width
                elif operator == '>': self._common_info['min_width'] = width
                elif operator == '=': self._common_info['width'] = width
                elif operator == u'\u2248':

                    if width == 0: self._common_info['width'] = 0
                    else:

                        self._common_info['min_width'] = int(width * 0.85)
                        self._common_info['max_width'] = int(width * 1.15)

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_NUM_PIXELS:

                (operator, num_pixels, unit) = value

                num_pixels = num_pixels * unit

                if operator == '<':
                    self._common_info['max_num_pixels'] = num_pixels
                elif operator == '>':
                    self._common_info['min_num_pixels'] = num_pixels
                elif operator == '=':
                    self._common_info['num_pixels'] = num_pixels
                elif operator == u'\u2248':

                    self._common_info['min_num_pixels'] = int(num_pixels *
                                                              0.85)
                    self._common_info['max_num_pixels'] = int(num_pixels *
                                                              1.15)

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_HEIGHT:

                (operator, height) = value

                if operator == '<': self._common_info['max_height'] = height
                elif operator == '>': self._common_info['min_height'] = height
                elif operator == '=': self._common_info['height'] = height
                elif operator == u'\u2248':

                    if height == 0: self._common_info['height'] = 0
                    else:

                        self._common_info['min_height'] = int(height * 0.85)
                        self._common_info['max_height'] = int(height * 1.15)

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_NUM_WORDS:

                (operator, num_words) = value

                if operator == '<':
                    self._common_info['max_num_words'] = num_words
                elif operator == '>':
                    self._common_info['min_num_words'] = num_words
                elif operator == '=':
                    self._common_info['num_words'] = num_words
                elif operator == u'\u2248':

                    if num_words == 0: self._common_info['num_words'] = 0
                    else:

                        self._common_info['min_num_words'] = int(num_words *
                                                                 0.85)
                        self._common_info['max_num_words'] = int(num_words *
                                                                 1.15)

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_LIMIT:

                limit = value

                if self._limit is None:

                    self._limit = limit

                else:

                    self._limit = min(limit, self._limit)

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_FILE_SERVICE:

                (operator, current_or_pending, service_key) = value

                if operator == True:

                    if current_or_pending == HC.CONTENT_STATUS_CURRENT:
                        self._file_services_to_include_current.append(
                            service_key)
                    else:
                        self._file_services_to_include_pending.append(
                            service_key)

                else:

                    if current_or_pending == HC.CONTENT_STATUS_CURRENT:
                        self._file_services_to_exclude_current.append(
                            service_key)
                    else:
                        self._file_services_to_exclude_pending.append(
                            service_key)

            if predicate_type == HC.PREDICATE_TYPE_SYSTEM_SIMILAR_TO:

                (hash, max_hamming) = value

                self._similar_to = (hash, max_hamming)
Ejemplo n.º 25
0
def GetMime( path ):
    
    with open( path, 'rb' ) as f:
        
        f.seek( 0 )
        
        bit_to_check = f.read( 256 )
        
    
    for ( offset, header, mime ) in header_and_mime:
        
        offset_bit_to_check = bit_to_check[ offset: ]
        
        if offset_bit_to_check.startswith( header ):
            
            if mime == HC.UNDETERMINED_WM:
                
                if HydrusVideoHandling.HasVideoStream( path ):
                    
                    return HC.VIDEO_WMV
                    
                
                # we'll catch and verify wma later
                
            elif mime == HC.UNDETERMINED_PNG:
                
                return HC.IMAGE_PNG
                
                # atm (Feb 2016), ffmpeg doesn't report duration for apngs, so can't do this just yet.
                #
                #if HydrusVideoHandling.HasVideoStream( path ):
                #    
                #    return HC.VIDEO_APNG
                #    
                #else:
                #    
                #    return HC.IMAGE_PNG
                #    
                
            else:
                
                return mime
                
            
        
    
    try:
        
        mime = HydrusVideoHandling.GetMimeFromFFMPEG( path )
        
        if mime != HC.APPLICATION_UNKNOWN:
            
            return mime
            
        
    except HydrusExceptions.MimeException:
        
        HydrusData.Print( 'FFMPEG couldn\'t figure out the mime for: ' + path )
        
    except Exception as e:
        
        HydrusData.Print( 'FFMPEG couldn\'t figure out the mime for: ' + path )
        HydrusData.PrintException( e, do_wait = False )
        
    
    hsaudio_object = hsaudiotag.auto.File( path )
    
    if hsaudio_object.valid:
        
        if isinstance( hsaudio_object.original, hsaudiotag.mpeg.Mpeg ): return HC.AUDIO_MP3
        elif isinstance( hsaudio_object.original, hsaudiotag.flac.FLAC ): return HC.AUDIO_FLAC
        elif isinstance( hsaudio_object.original, hsaudiotag.ogg.Vorbis ): return HC.AUDIO_OGG
        elif isinstance( hsaudio_object.original, hsaudiotag.wma.WMADecoder ): return HC.AUDIO_WMA
        
    
    return HC.APPLICATION_UNKNOWN
Ejemplo n.º 26
0
def MergeTree( source, dest, text_update_hook = None ):
    
    pauser = HydrusData.BigJobPauser()
    
    if not os.path.exists( dest ):
        
        try:
            
            shutil.move( source, dest )
            
        except OSError:
            
            # if there were read only files in source and this was partition to partition, the copy2 goes ok but the subsequent source unlink fails
            # so, if it seems this has happened, let's just try a walking mergetree, which should be able to deal with these readonlies on a file-by-file basis
            if os.path.exists( dest ):
                
                MergeTree( source, dest, text_update_hook = text_update_hook )
                
            
        
    else:
        
        if len( os.listdir( dest ) ) == 0:
            
            for filename in os.listdir( source ):
                
                source_path = os.path.join( source, filename )
                dest_path = os.path.join( dest, filename )
                
                if not os.path.isdir( source_path ):
                    
                    MakeFileWritable( source_path )
                    
                
                shutil.move( source_path, dest_path )
                
            
        else:
            
            num_errors = 0
            
            for ( root, dirnames, filenames ) in os.walk( source ):
                
                if text_update_hook is not None:
                    
                    text_update_hook( 'Copying ' + root + '.' )
                    
                
                dest_root = root.replace( source, dest )
                
                for dirname in dirnames:
                    
                    pauser.Pause()
                    
                    source_path = os.path.join( root, dirname )
                    dest_path = os.path.join( dest_root, dirname )
                    
                    MakeSureDirectoryExists( dest_path )
                    
                    shutil.copystat( source_path, dest_path )
                    
                
                for filename in filenames:
                    
                    if num_errors > 5:
                        
                        raise Exception( 'Too many errors, directory move abandoned.' )
                        
                    
                    pauser.Pause()
                    
                    source_path = os.path.join( root, filename )
                    dest_path = os.path.join( dest_root, filename )
                    
                    ok = MergeFile( source_path, dest_path )
                    
                    if not ok:
                        
                        num_errors += 1
                        
                    
                
            
            if num_errors == 0:
                
                DeletePath( source )
Ejemplo n.º 27
0
def MirrorTree( source, dest, text_update_hook = None, is_cancelled_hook = None ):
    
    pauser = HydrusData.BigJobPauser()
    
    MakeSureDirectoryExists( dest )
    
    num_errors = 0
    
    for ( root, dirnames, filenames ) in os.walk( source ):
        
        if is_cancelled_hook is not None and is_cancelled_hook():
            
            return
            
        
        if text_update_hook is not None:
            
            text_update_hook( 'Copying ' + root + '.' )
            
        
        dest_root = root.replace( source, dest )
        
        surplus_dest_paths = { os.path.join( dest_root, dest_filename ) for dest_filename in os.listdir( dest_root ) }
        
        for dirname in dirnames:
            
            pauser.Pause()
            
            source_path = os.path.join( root, dirname )
            dest_path = os.path.join( dest_root, dirname )
            
            surplus_dest_paths.discard( dest_path )
            
            MakeSureDirectoryExists( dest_path )
            
            shutil.copystat( source_path, dest_path )
            
        
        for filename in filenames:
            
            if num_errors > 5:
                
                raise Exception( 'Too many errors, directory copy abandoned.' )
                
            
            pauser.Pause()
            
            source_path = os.path.join( root, filename )
            
            dest_path = os.path.join( dest_root, filename )
            
            surplus_dest_paths.discard( dest_path )
            
            ok = MirrorFile( source_path, dest_path )
            
            if not ok:
                
                num_errors += 1
                
            
        
        for dest_path in surplus_dest_paths:
            
            pauser.Pause()
            
            DeletePath( dest_path )
Ejemplo n.º 28
0
def GetThumbnailPath(hash, full_size=True):

    if not full_size:

        options = HydrusGlobals.client_controller.GetOptions()

        thumbnail_dimensions = options['thumbnail_dimensions']

        if tuple(thumbnail_dimensions) == HC.UNSCALED_THUMBNAIL_DIMENSIONS:

            full_size = True

    path = GetExpectedThumbnailPath(hash, full_size)

    if not os.path.exists(path):

        if full_size:

            client_files_manager = HydrusGlobals.client_controller.GetClientFilesManager(
            )

            try:

                file_path = client_files_manager.GetFilePath(hash)

            except HydrusExceptions.FileMissingException:

                raise HydrusExceptions.FileMissingException(
                    'The thumbnail for file ' + hash.encode('hex') +
                    ' was missing. It could not be regenerated because the original file was also missing. This event could indicate hard drive corruption or an unplugged external drive. Please check everything is ok.'
                )

            try:

                thumbnail = HydrusFileHandling.GenerateThumbnail(file_path)

            except Exception as e:

                HydrusData.ShowException(e)

                raise HydrusExceptions.FileMissingException(
                    'The thumbnail for file ' + hash.encode('hex') +
                    ' was missing. It could not be regenerated from the original file for the above reason. This event could indicate hard drive corruption. Please check everything is ok.'
                )

            try:

                with open(path, 'wb') as f:

                    f.write(thumbnail)

            except Exception as e:

                HydrusData.ShowException(e)

                raise HydrusExceptions.FileMissingException(
                    'The thumbnail for file ' + hash.encode('hex') +
                    ' was missing. It was regenerated from the original file, but hydrus could not write it to the location '
                    + path +
                    ' for the above reason. This event could indicate hard drive corruption, and it also suggests that hydrus does not have permission to write to its thumbnail folder. Please check everything is ok.'
                )

            HydrusData.ShowText(
                'The thumbnail for file ' + hash.encode('hex') +
                ' was missing. It has been regenerated from the original file, but this event could indicate hard drive corruption. Please check everything is ok.'
            )

        else:

            full_size_path = GetThumbnailPath(hash, True)

            try:

                thumbnail_resized = HydrusFileHandling.GenerateThumbnail(
                    full_size_path, thumbnail_dimensions)

            except:

                try:

                    os.remove(full_size_path)

                except:

                    raise HydrusExceptions.FileMissingException(
                        'The thumbnail for file ' + hash.encode('hex') +
                        ' was found, but it would not render. An attempt to delete it was made, but that failed as well. This event could indicate hard drive corruption, and it also suggests that hydrus does not have permission to write to its thumbnail folder. Please check everything is ok.'
                    )

                full_size_path = GetThumbnailPath(hash, True)

                thumbnail_resized = HydrusFileHandling.GenerateThumbnail(
                    full_size_path, thumbnail_dimensions)

            with open(path, 'wb') as f:

                f.write(thumbnail_resized)

    return path
Ejemplo n.º 29
0
    def EventShowMenu(self, event):

        seed_cache = self._seed_cache_get_callable()

        menu_items = []

        num_failures = seed_cache.GetSeedCount(CC.STATUS_FAILED)

        if num_failures > 0:

            menu_items.append(
                ('normal',
                 'retry ' + HydrusData.ConvertIntToPrettyString(num_failures) +
                 ' failures', 'Tell this cache to reattempt all its failures.',
                 self._RetryFailures))

        num_unknown = seed_cache.GetSeedCount(CC.STATUS_UNKNOWN)

        num_processed = len(seed_cache) - num_unknown

        if num_processed > 0:

            menu_items.append((
                'normal', 'delete ' +
                HydrusData.ConvertIntToPrettyString(num_processed) +
                ' \'processed\' files from the queue',
                'Tell this cache to clear out processed files, reducing the size of the queue.',
                self._ClearProcessed))

        if len(menu_items) > 0:

            menu = wx.Menu()

            for (item_type, title, description, data) in menu_items:

                if item_type == 'normal':

                    func = data

                    ClientGUIMenus.AppendMenuItem(self, menu, title,
                                                  description, func)

                elif item_type == 'check':

                    check_manager = data

                    current_value = check_manager.GetCurrentValue()
                    func = check_manager.Invert

                    if current_value is not None:

                        ClientGUIMenus.AppendMenuCheckItem(
                            self, menu, title, description, current_value,
                            func)

                elif item_type == 'separator':

                    ClientGUIMenus.AppendSeparator(menu)

            HG.client_controller.PopupMenu(self, menu)

        else:

            event.Skip()
Ejemplo n.º 30
0
    def DoWork(self):

        if HydrusData.TimeHasPassed(self._last_checked + self._period):

            folder_path = HydrusData.ToUnicode(self._name)

            if os.path.exists(folder_path) and os.path.isdir(folder_path):

                query_hash_ids = HydrusGlobals.client_controller.Read(
                    'file_query_ids', self._file_search_context)

                media_results = []

                i = 0

                base = 256

                while i < len(query_hash_ids):

                    if HC.options['pause_export_folders_sync']:

                        return

                    if i == 0: (last_i, i) = (0, base)
                    else: (last_i, i) = (i, i + base)

                    sub_query_hash_ids = query_hash_ids[last_i:i]

                    more_media_results = HydrusGlobals.client_controller.Read(
                        'media_results_from_ids', sub_query_hash_ids)

                    media_results.extend(more_media_results)

                #

                terms = ParseExportPhrase(self._phrase)

                previous_filenames = set(os.listdir(folder_path))

                sync_filenames = set()

                client_files_manager = HydrusGlobals.client_controller.GetClientFilesManager(
                )

                num_copied = 0

                for media_result in media_results:

                    hash = media_result.GetHash()
                    mime = media_result.GetMime()
                    size = media_result.GetSize()

                    source_path = client_files_manager.GetFilePath(hash, mime)

                    filename = GenerateExportFilename(media_result, terms)

                    dest_path = os.path.join(folder_path, filename)

                    do_copy = True

                    if filename in sync_filenames:

                        do_copy = False

                    elif HydrusPaths.PathsHaveSameSizeAndDate(
                            source_path, dest_path):

                        do_copy = False

                    if do_copy:

                        shutil.copy2(source_path, dest_path)

                        num_copied += 1

                        try:
                            os.chmod(dest_path, stat.S_IWRITE | stat.S_IREAD)
                        except:
                            pass

                    sync_filenames.add(filename)

                if num_copied > 0:

                    HydrusData.Print(
                        'Export folder ' + self._name + ' exported ' +
                        HydrusData.ConvertIntToPrettyString(num_copied) +
                        ' files.')

                if self._export_type == HC.EXPORT_FOLDER_TYPE_SYNCHRONISE:

                    deletee_filenames = previous_filenames.difference(
                        sync_filenames)

                    for deletee_filename in deletee_filenames:

                        deletee_path = os.path.join(folder_path,
                                                    deletee_filename)

                        ClientData.DeletePath(deletee_path)

                    if len(deletee_filenames) > 0:

                        HydrusData.Print('Export folder ' + self._name +
                                         ' deleted ' +
                                         HydrusData.ConvertIntToPrettyString(
                                             len(deletee_filenames)) +
                                         ' files.')

            self._last_checked = HydrusData.GetNow()

            HydrusGlobals.client_controller.WriteSynchronous(
                'serialisable', self)
Ejemplo n.º 31
0
    def __repr__(self):

        return 'Predicate: ' + HydrusData.ToUnicode(
            (self._predicate_type, self._value, self._inclusive,
             self.GetCount()))
Ejemplo n.º 32
0
def ImportFromHTA( parent, hta_path, tag_service_key, hashes ):
    
    hta = HydrusTagArchive.HydrusTagArchive( hta_path )
    
    potential_namespaces = list( hta.GetNamespaces() )
    
    potential_namespaces.sort()
    
    hash_type = hta.GetHashType() # this tests if the hta can produce a hashtype
    
    del hta
    
    service = HG.client_controller.services_manager.GetService( tag_service_key )
    
    service_type = service.GetServiceType()
    
    can_delete = True
    
    if service_type == HC.TAG_REPOSITORY:
        
        if service.HasPermission( HC.CONTENT_TYPE_MAPPINGS, HC.PERMISSION_ACTION_OVERRULE ):
            
            can_delete = False
            
        
    
    if can_delete:
        
        text = 'Would you like to add or delete the archive\'s tags?'
        
        with ClientGUIDialogs.DialogYesNo( parent, text, title = 'Add or delete?', yes_label = 'add', no_label = 'delete' ) as dlg_add:
            
            result = dlg_add.ShowModal()
            
            if result == wx.ID_YES: adding = True
            elif result == wx.ID_NO: adding = False
            else: return
            
        
    else:
        
        text = 'You cannot quickly delete tags from this service, so I will assume you want to add tags.'
        
        wx.MessageBox( text )
        
        adding = True
        
    
    text = 'Choose which namespaces to '
    
    if adding: text += 'add.'
    else: text += 'delete.'
    
    list_of_tuples = [ ( HydrusData.ConvertUglyNamespaceToPrettyString( namespace ), namespace, False ) for namespace in potential_namespaces ]
    
    with ClientGUIDialogs.DialogCheckFromList( parent, text, list_of_tuples ) as dlg_namespaces:
        
        if dlg_namespaces.ShowModal() == wx.ID_OK:
            
            namespaces = dlg_namespaces.GetChecked()
            
            if hash_type == HydrusTagArchive.HASH_TYPE_SHA256:
                
                text = 'This tag archive can be fully merged into your database, but this may be more than you want.'
                text += os.linesep * 2
                text += 'Would you like to import the tags only for files you actually have, or do you want absolutely everything?'
                
                with ClientGUIDialogs.DialogYesNo( parent, text, title = 'How much do you want?', yes_label = 'just for my local files', no_label = 'everything' ) as dlg_add:
                    
                    result = dlg_add.ShowModal()
                    
                    if result == wx.ID_YES:
                        
                        file_service_key = CC.LOCAL_FILE_SERVICE_KEY
                        
                    elif result == wx.ID_NO:
                        
                        file_service_key = CC.COMBINED_FILE_SERVICE_KEY
                        
                    else:
                        
                        return
                        
                    
                
            else:
                
                file_service_key = CC.LOCAL_FILE_SERVICE_KEY
                
            
            text = 'Are you absolutely sure you want to '
            
            if adding: text += 'add'
            else: text += 'delete'
            
            text += ' the namespaces:'
            text += os.linesep * 2
            text += os.linesep.join( HydrusData.ConvertUglyNamespacesToPrettyStrings( namespaces ) )
            text += os.linesep * 2
            
            file_service = HG.client_controller.services_manager.GetService( file_service_key )
            
            text += 'For '
            
            if hashes is None:
                
                text += 'all'
                
            else:
                
                text += HydrusData.ToHumanInt( len( hashes ) )
                
            
            text += ' files in \'' + file_service.GetName() + '\''
            
            if adding: text += ' to '
            else: text += ' from '
            
            text += '\'' + service.GetName() + '\'?'
            
            with ClientGUIDialogs.DialogYesNo( parent, text ) as dlg_final:
                
                if dlg_final.ShowModal() == wx.ID_YES:
                    
                    HG.client_controller.pub( 'sync_to_tag_archive', hta_path, tag_service_key, file_service_key, adding, namespaces, hashes )
Ejemplo n.º 33
0
    def test_undo(self):

        hash_1 = HydrusData.GenerateKey()
        hash_2 = HydrusData.GenerateKey()
        hash_3 = HydrusData.GenerateKey()

        command_1 = {
            CC.COMBINED_LOCAL_FILE_SERVICE_KEY: [
                HydrusData.ContentUpdate(HC.CONTENT_TYPE_FILES,
                                         HC.CONTENT_UPDATE_ARCHIVE, {hash_1})
            ]
        }
        command_2 = {
            CC.COMBINED_LOCAL_FILE_SERVICE_KEY: [
                HydrusData.ContentUpdate(HC.CONTENT_TYPE_FILES,
                                         HC.CONTENT_UPDATE_INBOX, {hash_2})
            ]
        }
        command_3 = {
            CC.COMBINED_LOCAL_FILE_SERVICE_KEY: [
                HydrusData.ContentUpdate(HC.CONTENT_TYPE_FILES,
                                         HC.CONTENT_UPDATE_ARCHIVE,
                                         {hash_1, hash_3})
            ]
        }

        command_1_inverted = {
            CC.COMBINED_LOCAL_FILE_SERVICE_KEY: [
                HydrusData.ContentUpdate(HC.CONTENT_TYPE_FILES,
                                         HC.CONTENT_UPDATE_INBOX, {hash_1})
            ]
        }
        command_2_inverted = {
            CC.COMBINED_LOCAL_FILE_SERVICE_KEY: [
                HydrusData.ContentUpdate(HC.CONTENT_TYPE_FILES,
                                         HC.CONTENT_UPDATE_ARCHIVE, {hash_2})
            ]
        }

        undo_manager = ClientCaches.UndoManager(HG.client_controller)

        #

        undo_manager.AddCommand('content_updates', command_1)

        self.assertEqual((u'undo archive 1 files', None),
                         undo_manager.GetUndoRedoStrings())

        undo_manager.AddCommand('content_updates', command_2)

        self.assertEqual((u'undo inbox 1 files', None),
                         undo_manager.GetUndoRedoStrings())

        undo_manager.Undo()

        self.assertEqual((u'undo archive 1 files', u'redo inbox 1 files'),
                         undo_manager.GetUndoRedoStrings())

        self.assertEqual(HG.test_controller.GetWrite('content_updates'),
                         [((command_2_inverted, ), {})])

        undo_manager.Redo()

        self.assertEqual(HG.test_controller.GetWrite('content_updates'),
                         [((command_2, ), {})])

        self.assertEqual((u'undo inbox 1 files', None),
                         undo_manager.GetUndoRedoStrings())

        undo_manager.Undo()

        self.assertEqual(HG.test_controller.GetWrite('content_updates'),
                         [((command_2_inverted, ), {})])

        undo_manager.Undo()

        self.assertEqual(HG.test_controller.GetWrite('content_updates'),
                         [((command_1_inverted, ), {})])

        self.assertEqual((None, u'redo archive 1 files'),
                         undo_manager.GetUndoRedoStrings())

        undo_manager.AddCommand('content_updates', command_3)

        self.assertEqual((u'undo archive 2 files', None),
                         undo_manager.GetUndoRedoStrings())
Ejemplo n.º 34
0
 def Exit( self ):
     
     if HG.emergency_exit:
         
         self.ShutdownView()
         self.ShutdownModel()
         
         HydrusData.CleanRunningFile( self.db_dir, 'client' )
         
     else:
         
         try:
             
             idle_shutdown_action = self.options[ 'idle_shutdown' ]
             
             if idle_shutdown_action in ( CC.IDLE_ON_SHUTDOWN, CC.IDLE_ON_SHUTDOWN_ASK_FIRST ):
                 
                 idle_shutdown_max_minutes = self.options[ 'idle_shutdown_max_minutes' ]
                 
                 time_to_stop = HydrusData.GetNow() + ( idle_shutdown_max_minutes * 60 )
                 
                 if self.ThereIsIdleShutdownWorkDue( time_to_stop ):
                     
                     if idle_shutdown_action == CC.IDLE_ON_SHUTDOWN_ASK_FIRST:
                         
                         text = 'Is now a good time for the client to do up to ' + HydrusData.ConvertIntToPrettyString( idle_shutdown_max_minutes ) + ' minutes\' maintenance work? (Will auto-no in 15 seconds)'
                         
                         with ClientGUIDialogs.DialogYesNo( self._splash, text, title = 'Maintenance is due' ) as dlg_yn:
                             
                             job = self.CallLaterWXSafe( dlg_yn, 15, dlg_yn.EndModal, wx.ID_NO )
                             
                             try:
                                 
                                 if dlg_yn.ShowModal() == wx.ID_YES:
                                     
                                     HG.do_idle_shutdown_work = True
                                     
                                 
                             finally:
                                 
                                 job.Cancel()
                                 
                             
                         
                     else:
                         
                         HG.do_idle_shutdown_work = True
                         
                     
                 
             
             self.CallToThreadLongRunning( self.THREADExitEverything )
             
         except:
             
             self._DestroySplash()
             
             HydrusData.DebugPrint( traceback.format_exc() )
             
             HG.emergency_exit = True
             
             self.Exit()