2018-01-31 22:58:15 +00:00
|
|
|
import calendar
|
2019-01-09 22:59:03 +00:00
|
|
|
from . import ClientConstants as CC
|
|
|
|
from . import ClientData
|
|
|
|
from . import ClientTags
|
2018-01-31 22:58:15 +00:00
|
|
|
import datetime
|
2019-01-09 22:59:03 +00:00
|
|
|
from . import HydrusConstants as HC
|
|
|
|
from . import HydrusData
|
|
|
|
from . import HydrusExceptions
|
|
|
|
from . import HydrusGlobals as HG
|
|
|
|
from . import HydrusSerialisable
|
|
|
|
from . import HydrusTags
|
2015-03-25 22:04:19 +00:00
|
|
|
import re
|
2018-02-07 23:40:33 +00:00
|
|
|
import time
|
2015-03-25 22:04:19 +00:00
|
|
|
import wx
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
IGNORED_TAG_SEARCH_CHARACTERS = '[](){}"\''
|
2017-02-01 21:11:17 +00:00
|
|
|
IGNORED_TAG_SEARCH_CHARACTERS_UNICODE_TRANSLATE = { ord( char ) : None for char in IGNORED_TAG_SEARCH_CHARACTERS }
|
|
|
|
|
|
|
|
def ConvertTagToSearchable( tag ):
|
|
|
|
|
2017-03-08 23:23:12 +00:00
|
|
|
if tag == '':
|
2017-02-01 21:11:17 +00:00
|
|
|
|
2017-03-08 23:23:12 +00:00
|
|
|
return ''
|
2017-02-01 21:11:17 +00:00
|
|
|
|
|
|
|
|
2017-03-08 23:23:12 +00:00
|
|
|
while '**' in tag:
|
|
|
|
|
|
|
|
tag = tag.replace( '**', '*' )
|
|
|
|
|
|
|
|
|
2018-10-17 21:00:09 +00:00
|
|
|
if IsComplexWildcard( tag ):
|
|
|
|
|
|
|
|
return tag
|
|
|
|
|
|
|
|
|
|
|
|
tag = tag.translate( IGNORED_TAG_SEARCH_CHARACTERS_UNICODE_TRANSLATE )
|
|
|
|
|
2017-03-08 23:23:12 +00:00
|
|
|
return tag
|
|
|
|
|
|
|
|
def ConvertEntryTextToSearchText( entry_text ):
|
|
|
|
|
|
|
|
entry_text = HydrusTags.CleanTag( entry_text )
|
|
|
|
|
|
|
|
entry_text = ConvertTagToSearchable( entry_text )
|
|
|
|
|
|
|
|
if not IsComplexWildcard( entry_text ) and not entry_text.endswith( '*' ):
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
entry_text = entry_text + '*'
|
2017-03-08 23:23:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
return entry_text
|
|
|
|
|
|
|
|
def FilterPredicatesBySearchText( service_key, search_text, predicates ):
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2016-03-16 22:19:14 +00:00
|
|
|
tags_to_predicates = {}
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2016-03-16 22:19:14 +00:00
|
|
|
for predicate in predicates:
|
|
|
|
|
|
|
|
( predicate_type, value, inclusive ) = predicate.GetInfo()
|
|
|
|
|
|
|
|
if predicate_type == HC.PREDICATE_TYPE_TAG:
|
|
|
|
|
|
|
|
tags_to_predicates[ value ] = predicate
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
matching_tags = FilterTagsBySearchText( service_key, search_text, list(tags_to_predicates.keys()) )
|
2016-03-16 22:19:14 +00:00
|
|
|
|
2016-03-23 19:42:56 +00:00
|
|
|
matches = [ tags_to_predicates[ tag ] for tag in matching_tags ]
|
|
|
|
|
|
|
|
return matches
|
2016-03-16 22:19:14 +00:00
|
|
|
|
2017-03-08 23:23:12 +00:00
|
|
|
def FilterTagsBySearchText( service_key, search_text, tags, search_siblings = True ):
|
2015-03-25 22:04:19 +00:00
|
|
|
|
|
|
|
def compile_re( s ):
|
|
|
|
|
|
|
|
regular_parts_of_s = s.split( '*' )
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
escaped_parts_of_s = list(map( re.escape, regular_parts_of_s ))
|
2015-03-25 22:04:19 +00:00
|
|
|
|
|
|
|
s = '.*'.join( escaped_parts_of_s )
|
|
|
|
|
2017-03-08 23:23:12 +00:00
|
|
|
# \A is start of string
|
|
|
|
# \Z is end of string
|
|
|
|
# \s is whitespace
|
|
|
|
|
|
|
|
if s.startswith( '.*' ):
|
2017-02-01 21:11:17 +00:00
|
|
|
|
2017-03-08 23:23:12 +00:00
|
|
|
beginning = '(\\A|:)'
|
2017-02-01 21:11:17 +00:00
|
|
|
|
|
|
|
else:
|
|
|
|
|
2017-03-08 23:23:12 +00:00
|
|
|
beginning = '(\\A|:|\\s)'
|
2017-02-01 21:11:17 +00:00
|
|
|
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2017-03-08 23:23:12 +00:00
|
|
|
if s.endswith( '.*' ):
|
|
|
|
|
|
|
|
end = '\\Z' # end of string
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
end = '(\\s|\\Z)' # whitespace or end of string
|
|
|
|
|
2017-02-01 21:11:17 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
return re.compile( beginning + s + end )
|
2017-02-01 21:11:17 +00:00
|
|
|
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2017-03-08 23:23:12 +00:00
|
|
|
re_predicate = compile_re( search_text )
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2017-05-10 21:33:58 +00:00
|
|
|
sibling_manager = HG.client_controller.GetManager( 'tag_siblings' )
|
2016-03-16 22:19:14 +00:00
|
|
|
|
|
|
|
result = []
|
2015-03-25 22:04:19 +00:00
|
|
|
|
|
|
|
for tag in tags:
|
|
|
|
|
2016-03-16 22:19:14 +00:00
|
|
|
if search_siblings:
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2016-09-14 18:03:59 +00:00
|
|
|
possible_tags = sibling_manager.GetAllSiblings( service_key, tag )
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2016-03-16 22:19:14 +00:00
|
|
|
else:
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2016-03-16 22:19:14 +00:00
|
|
|
possible_tags = [ tag ]
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2016-03-16 22:19:14 +00:00
|
|
|
|
2018-10-17 21:00:09 +00:00
|
|
|
if not IsComplexWildcard( search_text ):
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
possible_tags = list(map( ConvertTagToSearchable, possible_tags ))
|
2018-10-17 21:00:09 +00:00
|
|
|
|
2017-03-08 23:23:12 +00:00
|
|
|
|
2016-03-16 22:19:14 +00:00
|
|
|
for possible_tag in possible_tags:
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2017-04-05 21:16:40 +00:00
|
|
|
if re_predicate.search( possible_tag ) is not None:
|
2016-03-16 22:19:14 +00:00
|
|
|
|
2017-02-08 23:56:22 +00:00
|
|
|
result.append( tag )
|
2016-03-16 22:19:14 +00:00
|
|
|
|
|
|
|
break
|
|
|
|
|
2015-03-25 22:04:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2016-03-16 22:19:14 +00:00
|
|
|
return result
|
|
|
|
|
2017-03-08 23:23:12 +00:00
|
|
|
def IsComplexWildcard( search_text ):
|
|
|
|
|
|
|
|
num_stars = search_text.count( '*' )
|
|
|
|
|
|
|
|
if num_stars > 1:
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
if num_stars == 1 and not search_text.endswith( '*' ):
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
|
|
return False
|
|
|
|
|
2015-12-02 22:32:18 +00:00
|
|
|
def SortPredicates( predicates ):
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
key = lambda p: p.GetCount()
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
predicates.sort( key = key, reverse = True )
|
2015-03-25 22:04:19 +00:00
|
|
|
|
|
|
|
return predicates
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
class FileSearchContext( HydrusSerialisable.SerialisableBase ):
|
|
|
|
|
|
|
|
SERIALISABLE_TYPE = HydrusSerialisable.SERIALISABLE_TYPE_FILE_SEARCH_CONTEXT
|
2017-11-29 21:48:23 +00:00
|
|
|
SERIALISABLE_NAME = 'File Search Context'
|
2015-12-09 23:16:41 +00:00
|
|
|
SERIALISABLE_VERSION = 1
|
|
|
|
|
|
|
|
def __init__( self, file_service_key = CC.COMBINED_FILE_SERVICE_KEY, tag_service_key = CC.COMBINED_TAG_SERVICE_KEY, include_current_tags = True, include_pending_tags = True, predicates = None ):
|
|
|
|
|
|
|
|
if predicates is None: predicates = []
|
|
|
|
|
|
|
|
self._file_service_key = file_service_key
|
|
|
|
self._tag_service_key = tag_service_key
|
|
|
|
|
|
|
|
self._include_current_tags = include_current_tags
|
|
|
|
self._include_pending_tags = include_pending_tags
|
|
|
|
|
|
|
|
self._predicates = predicates
|
|
|
|
|
|
|
|
self._search_complete = False
|
|
|
|
|
|
|
|
self._InitialiseTemporaryVariables()
|
|
|
|
|
|
|
|
|
|
|
|
def _GetSerialisableInfo( self ):
|
|
|
|
|
|
|
|
serialisable_predicates = [ predicate.GetSerialisableTuple() for predicate in self._predicates ]
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
return ( self._file_service_key.hex(), self._tag_service_key.hex(), self._include_current_tags, self._include_pending_tags, serialisable_predicates, self._search_complete )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
def _InitialiseFromSerialisableInfo( self, serialisable_info ):
|
|
|
|
|
|
|
|
( file_service_key, tag_service_key, self._include_current_tags, self._include_pending_tags, serialisable_predicates, self._search_complete ) = serialisable_info
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
self._file_service_key = bytes.fromhex( file_service_key )
|
|
|
|
self._tag_service_key = bytes.fromhex( tag_service_key )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2017-06-28 20:23:21 +00:00
|
|
|
services_manager = HG.client_controller.services_manager
|
2016-12-21 22:30:54 +00:00
|
|
|
|
|
|
|
if not services_manager.ServiceExists( self._file_service_key ):
|
|
|
|
|
|
|
|
self._file_service_key = CC.COMBINED_LOCAL_FILE_SERVICE_KEY
|
|
|
|
|
|
|
|
|
|
|
|
if not services_manager.ServiceExists( self._tag_service_key ):
|
|
|
|
|
|
|
|
self._tag_service_key = CC.COMBINED_TAG_SERVICE_KEY
|
|
|
|
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
self._predicates = [ HydrusSerialisable.CreateFromSerialisableTuple( pred_tuple ) for pred_tuple in serialisable_predicates ]
|
|
|
|
|
|
|
|
self._InitialiseTemporaryVariables()
|
|
|
|
|
|
|
|
|
|
|
|
def _InitialiseTemporaryVariables( self ):
|
|
|
|
|
|
|
|
system_predicates = [ predicate for predicate in self._predicates if predicate.GetType() in HC.SYSTEM_PREDICATES ]
|
|
|
|
|
|
|
|
self._system_predicates = FileSystemPredicates( system_predicates )
|
|
|
|
|
|
|
|
tag_predicates = [ predicate for predicate in self._predicates if predicate.GetType() == HC.PREDICATE_TYPE_TAG ]
|
|
|
|
|
|
|
|
self._tags_to_include = []
|
|
|
|
self._tags_to_exclude = []
|
|
|
|
|
|
|
|
for predicate in tag_predicates:
|
|
|
|
|
|
|
|
tag = predicate.GetValue()
|
|
|
|
|
|
|
|
if predicate.GetInclusive(): self._tags_to_include.append( tag )
|
|
|
|
else: self._tags_to_exclude.append( tag )
|
|
|
|
|
|
|
|
|
|
|
|
namespace_predicates = [ predicate for predicate in self._predicates if predicate.GetType() == HC.PREDICATE_TYPE_NAMESPACE ]
|
|
|
|
|
|
|
|
self._namespaces_to_include = []
|
|
|
|
self._namespaces_to_exclude = []
|
|
|
|
|
|
|
|
for predicate in namespace_predicates:
|
|
|
|
|
|
|
|
namespace = predicate.GetValue()
|
|
|
|
|
|
|
|
if predicate.GetInclusive(): self._namespaces_to_include.append( namespace )
|
|
|
|
else: self._namespaces_to_exclude.append( namespace )
|
|
|
|
|
|
|
|
|
|
|
|
wildcard_predicates = [ predicate for predicate in self._predicates if predicate.GetType() == HC.PREDICATE_TYPE_WILDCARD ]
|
|
|
|
|
|
|
|
self._wildcards_to_include = []
|
|
|
|
self._wildcards_to_exclude = []
|
|
|
|
|
|
|
|
for predicate in wildcard_predicates:
|
|
|
|
|
|
|
|
wildcard = predicate.GetValue()
|
|
|
|
|
|
|
|
if predicate.GetInclusive(): self._wildcards_to_include.append( wildcard )
|
|
|
|
else: self._wildcards_to_exclude.append( wildcard )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def GetFileServiceKey( self ): return self._file_service_key
|
|
|
|
def GetNamespacesToExclude( self ): return self._namespaces_to_exclude
|
|
|
|
def GetNamespacesToInclude( self ): return self._namespaces_to_include
|
|
|
|
def GetPredicates( self ): return self._predicates
|
|
|
|
def GetSystemPredicates( self ): return self._system_predicates
|
|
|
|
def GetTagServiceKey( self ): return self._tag_service_key
|
|
|
|
def GetTagsToExclude( self ): return self._tags_to_exclude
|
|
|
|
def GetTagsToInclude( self ): return self._tags_to_include
|
|
|
|
def GetWildcardsToExclude( self ): return self._wildcards_to_exclude
|
|
|
|
def GetWildcardsToInclude( self ): return self._wildcards_to_include
|
|
|
|
def IncludeCurrentTags( self ): return self._include_current_tags
|
|
|
|
def IncludePendingTags( self ): return self._include_pending_tags
|
|
|
|
def IsComplete( self ): return self._search_complete
|
|
|
|
def SetComplete( self ): self._search_complete = True
|
|
|
|
|
2016-01-13 22:08:19 +00:00
|
|
|
def SetFileServiceKey( self, file_service_key ):
|
|
|
|
|
|
|
|
self._file_service_key = file_service_key
|
|
|
|
|
|
|
|
|
|
|
|
def SetIncludeCurrentTags( self, value ):
|
|
|
|
|
|
|
|
self._include_current_tags = value
|
|
|
|
|
|
|
|
|
|
|
|
def SetIncludePendingTags( self, value ):
|
|
|
|
|
|
|
|
self._include_pending_tags = value
|
|
|
|
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
def SetPredicates( self, predicates ):
|
|
|
|
|
|
|
|
self._predicates = predicates
|
|
|
|
|
|
|
|
self._InitialiseTemporaryVariables()
|
|
|
|
|
|
|
|
|
2016-01-13 22:08:19 +00:00
|
|
|
def SetTagServiceKey( self, tag_service_key ):
|
|
|
|
|
|
|
|
self._tag_service_key = tag_service_key
|
|
|
|
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
HydrusSerialisable.SERIALISABLE_TYPES_TO_OBJECT_TYPES[ HydrusSerialisable.SERIALISABLE_TYPE_FILE_SEARCH_CONTEXT ] = FileSearchContext
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
class FileSystemPredicates( object ):
|
|
|
|
|
|
|
|
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 = []
|
|
|
|
|
2017-05-24 20:28:24 +00:00
|
|
|
self._duplicate_predicates = []
|
|
|
|
|
2018-12-12 22:15:46 +00:00
|
|
|
self._file_viewing_stats_predicates = []
|
|
|
|
|
2017-12-06 22:06:56 +00:00
|
|
|
new_options = HG.client_controller.new_options
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2018-03-28 21:55:58 +00:00
|
|
|
if predicate_type == HC.PREDICATE_TYPE_SYSTEM_KNOWN_URLS:
|
|
|
|
|
|
|
|
( operator, rule_type, rule, description ) = value
|
|
|
|
|
|
|
|
if 'known_url_rules' not in self._common_info:
|
|
|
|
|
|
|
|
self._common_info[ 'known_url_rules' ] = []
|
|
|
|
|
|
|
|
|
|
|
|
self._common_info[ 'known_url_rules' ].append( ( operator, rule_type, rule ) )
|
|
|
|
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
if predicate_type == HC.PREDICATE_TYPE_SYSTEM_HASH:
|
|
|
|
|
2015-12-30 23:44:09 +00:00
|
|
|
( hash, hash_type ) = value
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2015-12-30 23:44:09 +00:00
|
|
|
self._common_info[ 'hash' ] = ( hash, hash_type )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
if predicate_type == HC.PREDICATE_TYPE_SYSTEM_AGE:
|
|
|
|
|
2018-01-31 22:58:15 +00:00
|
|
|
( operator, age_type, age_value ) = value
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2018-01-31 22:58:15 +00:00
|
|
|
if age_type == 'delta':
|
|
|
|
|
|
|
|
( years, months, days, hours ) = age_value
|
|
|
|
|
|
|
|
age = ( ( ( ( ( ( ( years * 12 ) + months ) * 30 ) + days ) * 24 ) + hours ) * 3600 )
|
|
|
|
|
|
|
|
now = HydrusData.GetNow()
|
|
|
|
|
|
|
|
# this is backwards (less than means min timestamp) 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
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
elif operator == '\u2248':
|
2018-01-31 22:58:15 +00:00
|
|
|
|
|
|
|
self._common_info[ 'min_timestamp' ] = now - int( age * 1.15 )
|
|
|
|
self._common_info[ 'max_timestamp' ] = now - int( age * 0.85 )
|
|
|
|
|
|
|
|
|
|
|
|
elif age_type == 'date':
|
|
|
|
|
|
|
|
( year, month, day ) = age_value
|
|
|
|
|
2018-02-07 23:40:33 +00:00
|
|
|
# convert this dt, which is in local time, to a gmt timestamp
|
|
|
|
|
2018-01-31 22:58:15 +00:00
|
|
|
day_dt = datetime.datetime( year, month, day )
|
2018-02-07 23:40:33 +00:00
|
|
|
timestamp = int( time.mktime( day_dt.timetuple() ) )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2018-01-31 22:58:15 +00:00
|
|
|
if operator == '<':
|
|
|
|
|
|
|
|
self._common_info[ 'max_timestamp' ] = timestamp
|
|
|
|
|
|
|
|
elif operator == '>':
|
|
|
|
|
|
|
|
self._common_info[ 'min_timestamp' ] = timestamp + 86400
|
|
|
|
|
|
|
|
elif operator == '=':
|
|
|
|
|
|
|
|
self._common_info[ 'min_timestamp' ] = timestamp
|
|
|
|
self._common_info[ 'max_timestamp' ] = timestamp + 86400
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
elif operator == '\u2248':
|
2018-01-31 22:58:15 +00:00
|
|
|
|
|
|
|
self._common_info[ 'min_timestamp' ] = timestamp - 86400 * 30
|
|
|
|
self._common_info[ 'max_timestamp' ] = timestamp + 86400 * 30
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
2019-01-09 22:59:03 +00:00
|
|
|
elif operator == '\u2248':
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
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 )
|
2016-06-08 20:27:22 +00:00
|
|
|
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 )
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
elif operator == '\u2248':
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
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
|
2019-01-09 22:59:03 +00:00
|
|
|
elif operator == '\u2248':
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
2017-06-21 21:15:59 +00:00
|
|
|
if predicate_type == HC.PREDICATE_TYPE_SYSTEM_TAG_AS_NUMBER:
|
|
|
|
|
|
|
|
( namespace, operator, num ) = value
|
|
|
|
|
|
|
|
if operator == '<': self._common_info[ 'max_tag_as_number' ] = ( namespace, num )
|
|
|
|
elif operator == '>': self._common_info[ 'min_tag_as_number' ] = ( namespace, num )
|
2019-01-09 22:59:03 +00:00
|
|
|
elif operator == '\u2248':
|
2017-06-21 21:15:59 +00:00
|
|
|
|
|
|
|
self._common_info[ 'min_tag_as_number' ] = ( namespace, int( num * 0.85 ) )
|
|
|
|
self._common_info[ 'max_tag_as_number' ] = ( namespace, int( num * 1.15 ) )
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
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
|
2019-01-09 22:59:03 +00:00
|
|
|
elif operator == '\u2248':
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
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
|
2019-01-09 22:59:03 +00:00
|
|
|
elif operator == '\u2248':
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
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
|
2019-01-09 22:59:03 +00:00
|
|
|
elif operator == '\u2248':
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
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
|
2019-01-09 22:59:03 +00:00
|
|
|
elif operator == '\u2248':
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
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:
|
|
|
|
|
2017-03-02 02:14:56 +00:00
|
|
|
if current_or_pending == HC.CONTENT_STATUS_CURRENT: self._file_services_to_include_current.append( service_key )
|
2015-12-09 23:16:41 +00:00
|
|
|
else: self._file_services_to_include_pending.append( service_key )
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
2017-03-02 02:14:56 +00:00
|
|
|
if current_or_pending == HC.CONTENT_STATUS_CURRENT: self._file_services_to_exclude_current.append( service_key )
|
2015-12-09 23:16:41 +00:00
|
|
|
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 )
|
|
|
|
|
|
|
|
|
2017-05-24 20:28:24 +00:00
|
|
|
if predicate_type == HC.PREDICATE_TYPE_SYSTEM_DUPLICATE_RELATIONSHIPS:
|
|
|
|
|
|
|
|
( operator, num_relationships, dupe_type ) = value
|
|
|
|
|
|
|
|
self._duplicate_predicates.append( ( operator, num_relationships, dupe_type ) )
|
|
|
|
|
|
|
|
|
2018-12-12 22:15:46 +00:00
|
|
|
if predicate_type == HC.PREDICATE_TYPE_SYSTEM_FILE_VIEWING_STATS:
|
|
|
|
|
|
|
|
( view_type, viewing_locations, operator, viewing_value ) = value
|
|
|
|
|
|
|
|
self._file_viewing_stats_predicates.append( ( view_type, viewing_locations, operator, viewing_value ) )
|
|
|
|
|
|
|
|
|
2017-05-24 20:28:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
def GetDuplicateRelationshipsPredicates( self ):
|
|
|
|
|
|
|
|
return self._duplicate_predicates
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
2018-12-12 22:15:46 +00:00
|
|
|
def GetFileServiceInfo( self ):
|
|
|
|
|
|
|
|
return ( self._file_services_to_include_current, self._file_services_to_include_pending, self._file_services_to_exclude_current, self._file_services_to_exclude_pending )
|
|
|
|
|
|
|
|
|
|
|
|
def GetFileViewingStatsPredicates( self ):
|
|
|
|
|
|
|
|
return self._file_viewing_stats_predicates
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2018-03-28 21:55:58 +00:00
|
|
|
def GetSimpleInfo( self ):
|
|
|
|
|
|
|
|
return self._common_info
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
def GetLimit( self ): return self._limit
|
|
|
|
|
|
|
|
def GetRatingsPredicates( self ): return self._ratings_predicates
|
|
|
|
|
|
|
|
def GetSimilarTo( self ): return self._similar_to
|
|
|
|
|
|
|
|
def HasSimilarTo( self ): return self._similar_to is not None
|
|
|
|
|
|
|
|
def MustBeArchive( self ): return self._archive
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
def MustBeInbox( self ): return self._inbox
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
def MustBeLocal( self ): return self._local
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
def MustNotBeLocal( self ): return self._not_local
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
class Predicate( HydrusSerialisable.SerialisableBase ):
|
2015-03-25 22:04:19 +00:00
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
SERIALISABLE_TYPE = HydrusSerialisable.SERIALISABLE_TYPE_PREDICATE
|
2017-11-29 21:48:23 +00:00
|
|
|
SERIALISABLE_NAME = 'File Search Predicate'
|
2018-01-31 22:58:15 +00:00
|
|
|
SERIALISABLE_VERSION = 2
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2016-06-22 20:59:24 +00:00
|
|
|
def __init__( self, predicate_type = None, value = None, inclusive = True, min_current_count = 0, min_pending_count = 0, max_current_count = None, max_pending_count = None ):
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2016-01-13 22:08:19 +00:00
|
|
|
if isinstance( value, list ):
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
value = tuple( value )
|
|
|
|
|
|
|
|
|
|
|
|
self._predicate_type = predicate_type
|
|
|
|
self._value = value
|
|
|
|
|
|
|
|
self._inclusive = inclusive
|
|
|
|
|
2016-06-22 20:59:24 +00:00
|
|
|
self._min_current_count = min_current_count
|
|
|
|
self._min_pending_count = min_pending_count
|
|
|
|
self._max_current_count = max_current_count
|
|
|
|
self._max_pending_count = max_pending_count
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
def __eq__( self, other ):
|
|
|
|
|
|
|
|
return self.__hash__() == other.__hash__()
|
|
|
|
|
|
|
|
|
|
|
|
def __hash__( self ):
|
|
|
|
|
|
|
|
return ( self._predicate_type, self._value, self._inclusive ).__hash__()
|
|
|
|
|
|
|
|
|
|
|
|
def __ne__( self, other ):
|
|
|
|
|
|
|
|
return self.__hash__() != other.__hash__()
|
|
|
|
|
|
|
|
|
|
|
|
def __repr__( self ):
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
return 'Predicate: ' + str( ( self._predicate_type, self._value, self._inclusive, self.GetCount() ) )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
def _GetSerialisableInfo( self ):
|
|
|
|
|
|
|
|
if self._predicate_type in ( HC.PREDICATE_TYPE_SYSTEM_RATING, HC.PREDICATE_TYPE_SYSTEM_FILE_SERVICE ):
|
|
|
|
|
|
|
|
( operator, value, service_key ) = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
serialisable_value = ( operator, value, service_key.hex() )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_SIMILAR_TO:
|
|
|
|
|
|
|
|
( hash, max_hamming ) = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
serialisable_value = ( hash.hex(), max_hamming )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2018-03-28 21:55:58 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_KNOWN_URLS:
|
|
|
|
|
|
|
|
( operator, rule_type, rule, description ) = self._value
|
|
|
|
|
|
|
|
if rule_type == 'url_match':
|
|
|
|
|
|
|
|
serialisable_rule = rule.GetSerialisableTuple()
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
serialisable_rule = rule
|
|
|
|
|
|
|
|
|
|
|
|
serialisable_value = ( operator, rule_type, serialisable_rule, description )
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_HASH:
|
|
|
|
|
2015-12-30 23:44:09 +00:00
|
|
|
( hash, hash_type ) = self._value
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
serialisable_value = ( hash.hex(), hash_type )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
serialisable_value = self._value
|
|
|
|
|
|
|
|
|
|
|
|
return ( self._predicate_type, serialisable_value, self._inclusive )
|
|
|
|
|
|
|
|
|
|
|
|
def _InitialiseFromSerialisableInfo( self, serialisable_info ):
|
|
|
|
|
|
|
|
( self._predicate_type, serialisable_value, self._inclusive ) = serialisable_info
|
|
|
|
|
|
|
|
if self._predicate_type in ( HC.PREDICATE_TYPE_SYSTEM_RATING, HC.PREDICATE_TYPE_SYSTEM_FILE_SERVICE ):
|
|
|
|
|
|
|
|
( operator, value, service_key ) = serialisable_value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
self._value = ( operator, value, bytes.fromhex( service_key ) )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_SIMILAR_TO:
|
|
|
|
|
|
|
|
( serialisable_hash, max_hamming ) = serialisable_value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
self._value = ( bytes.fromhex( serialisable_hash ), max_hamming )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2018-03-28 21:55:58 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_KNOWN_URLS:
|
|
|
|
|
|
|
|
( operator, rule_type, serialisable_rule, description ) = serialisable_value
|
|
|
|
|
|
|
|
if rule_type == 'url_match':
|
|
|
|
|
|
|
|
rule = HydrusSerialisable.CreateFromSerialisableTuple( serialisable_rule )
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
rule = serialisable_rule
|
|
|
|
|
|
|
|
|
|
|
|
self._value = ( operator, rule_type, rule, description )
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_HASH:
|
|
|
|
|
2015-12-30 23:44:09 +00:00
|
|
|
( serialisable_hash, hash_type ) = serialisable_value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
self._value = ( bytes.fromhex( serialisable_hash ), hash_type )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2018-01-31 22:58:15 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_AGE:
|
|
|
|
|
|
|
|
( operator, age_type, age_value ) = serialisable_value
|
|
|
|
|
|
|
|
self._value = ( operator, age_type, tuple( age_value ) )
|
|
|
|
|
2018-12-12 22:15:46 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_FILE_VIEWING_STATS:
|
|
|
|
|
|
|
|
( view_type, viewing_locations, operator, viewing_value ) = serialisable_value
|
|
|
|
|
|
|
|
self._value = ( view_type, tuple( viewing_locations ), operator, viewing_value )
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
else:
|
|
|
|
|
|
|
|
self._value = serialisable_value
|
|
|
|
|
|
|
|
|
2016-01-13 22:08:19 +00:00
|
|
|
if isinstance( self._value, list ):
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
self._value = tuple( self._value )
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-01-31 22:58:15 +00:00
|
|
|
def _UpdateSerialisableInfo( self, version, old_serialisable_info ):
|
|
|
|
|
|
|
|
if version == 1:
|
|
|
|
|
|
|
|
( predicate_type, serialisable_value, inclusive ) = old_serialisable_info
|
|
|
|
|
|
|
|
if predicate_type == HC.PREDICATE_TYPE_SYSTEM_AGE:
|
|
|
|
|
|
|
|
( operator, years, months, days, hours ) = serialisable_value
|
|
|
|
|
|
|
|
serialisable_value = ( operator, 'delta', ( years, months, days, hours ) )
|
|
|
|
|
|
|
|
|
|
|
|
new_serialisable_info = ( predicate_type, serialisable_value, inclusive )
|
|
|
|
|
|
|
|
return ( 2, new_serialisable_info )
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-08-17 20:07:22 +00:00
|
|
|
def AddCounts( self, predicate ):
|
2016-06-22 20:59:24 +00:00
|
|
|
|
2016-08-17 20:07:22 +00:00
|
|
|
( min_current_count, max_current_count, min_pending_count, max_pending_count ) = predicate.GetAllCounts()
|
2016-06-22 20:59:24 +00:00
|
|
|
|
2016-08-17 20:07:22 +00:00
|
|
|
( self._min_current_count, self._max_current_count ) = ClientData.MergeCounts( self._min_current_count, self._max_current_count, min_current_count, max_current_count )
|
|
|
|
( self._min_pending_count, self._max_pending_count) = ClientData.MergeCounts( self._min_pending_count, self._max_pending_count, min_pending_count, max_pending_count )
|
|
|
|
|
|
|
|
|
|
|
|
def GetAllCounts( self ):
|
|
|
|
|
|
|
|
return ( self._min_current_count, self._max_current_count, self._min_pending_count, self._max_pending_count )
|
2016-06-22 20:59:24 +00:00
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2017-02-08 22:27:00 +00:00
|
|
|
def GetCopy( self ):
|
|
|
|
|
|
|
|
return Predicate( self._predicate_type, self._value, self._inclusive, self._min_current_count, self._min_pending_count, self._max_current_count, self._max_pending_count )
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2017-02-08 22:27:00 +00:00
|
|
|
def GetCountlessCopy( self ):
|
|
|
|
|
|
|
|
return Predicate( self._predicate_type, self._value, self._inclusive )
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
def GetCount( self, current_or_pending = None ):
|
|
|
|
|
2016-06-22 20:59:24 +00:00
|
|
|
if current_or_pending is None:
|
|
|
|
|
|
|
|
return self._min_current_count + self._min_pending_count
|
|
|
|
|
2017-03-02 02:14:56 +00:00
|
|
|
elif current_or_pending == HC.CONTENT_STATUS_CURRENT:
|
2016-06-22 20:59:24 +00:00
|
|
|
|
|
|
|
return self._min_current_count
|
|
|
|
|
2017-03-02 02:14:56 +00:00
|
|
|
elif current_or_pending == HC.CONTENT_STATUS_PENDING:
|
2016-06-22 20:59:24 +00:00
|
|
|
|
|
|
|
return self._min_pending_count
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
2017-03-22 22:38:15 +00:00
|
|
|
def GetNamespace( self ):
|
|
|
|
|
|
|
|
if self._predicate_type in HC.SYSTEM_PREDICATES:
|
|
|
|
|
|
|
|
return 'system'
|
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_NAMESPACE:
|
|
|
|
|
|
|
|
namespace = self._value
|
|
|
|
|
|
|
|
return namespace
|
|
|
|
|
|
|
|
elif self._predicate_type in ( HC.PREDICATE_TYPE_PARENT, HC.PREDICATE_TYPE_TAG, HC.PREDICATE_TYPE_WILDCARD ):
|
|
|
|
|
|
|
|
tag_analogue = self._value
|
|
|
|
|
|
|
|
( namespace, subtag ) = HydrusTags.SplitTag( tag_analogue )
|
|
|
|
|
|
|
|
return namespace
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
def GetInclusive( self ):
|
|
|
|
|
|
|
|
# patch from an upgrade mess-up ~v144
|
|
|
|
if not hasattr( self, '_inclusive' ):
|
|
|
|
|
|
|
|
if self._predicate_type not in HC.SYSTEM_PREDICATES:
|
|
|
|
|
|
|
|
( operator, value ) = self._value
|
|
|
|
|
|
|
|
self._value = value
|
|
|
|
|
|
|
|
self._inclusive = operator == '+'
|
|
|
|
|
|
|
|
else: self._inclusive = True
|
|
|
|
|
|
|
|
|
|
|
|
return self._inclusive
|
|
|
|
|
|
|
|
|
2017-02-08 22:27:00 +00:00
|
|
|
def GetInfo( self ):
|
|
|
|
|
|
|
|
return ( self._predicate_type, self._value, self._inclusive )
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
def GetInverseCopy( self ):
|
|
|
|
|
|
|
|
if self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_ARCHIVE:
|
|
|
|
|
|
|
|
return Predicate( HC.PREDICATE_TYPE_SYSTEM_INBOX )
|
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_INBOX:
|
|
|
|
|
|
|
|
return Predicate( HC.PREDICATE_TYPE_SYSTEM_ARCHIVE )
|
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_LOCAL:
|
|
|
|
|
|
|
|
return Predicate( HC.PREDICATE_TYPE_SYSTEM_NOT_LOCAL )
|
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_NOT_LOCAL:
|
|
|
|
|
|
|
|
return Predicate( HC.PREDICATE_TYPE_SYSTEM_LOCAL )
|
|
|
|
|
|
|
|
elif self._predicate_type in ( HC.PREDICATE_TYPE_TAG, HC.PREDICATE_TYPE_NAMESPACE, HC.PREDICATE_TYPE_WILDCARD ):
|
|
|
|
|
|
|
|
return Predicate( self._predicate_type, self._value, not self._inclusive )
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-01-13 22:08:19 +00:00
|
|
|
def GetType( self ):
|
|
|
|
|
|
|
|
return self._predicate_type
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
def ToString( self, with_count = True, sibling_service_key = None, render_for_user = False ):
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
count_text = ''
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
if with_count:
|
|
|
|
|
2016-06-22 20:59:24 +00:00
|
|
|
if self._min_current_count > 0:
|
|
|
|
|
2018-07-04 20:48:28 +00:00
|
|
|
number_text = HydrusData.ToHumanInt( self._min_current_count )
|
2016-06-22 20:59:24 +00:00
|
|
|
|
|
|
|
if self._max_current_count is not None:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
number_text += '-' + HydrusData.ToHumanInt( self._max_current_count )
|
2016-06-22 20:59:24 +00:00
|
|
|
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
count_text += ' (' + number_text + ')'
|
2016-06-22 20:59:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
if self._min_pending_count > 0:
|
|
|
|
|
2018-07-04 20:48:28 +00:00
|
|
|
number_text = HydrusData.ToHumanInt( self._min_pending_count )
|
2016-06-22 20:59:24 +00:00
|
|
|
|
|
|
|
if self._max_pending_count is not None:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
number_text += '-' + HydrusData.ToHumanInt( self._max_pending_count )
|
2016-06-22 20:59:24 +00:00
|
|
|
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
count_text += ' (+' + number_text + ')'
|
2016-06-22 20:59:24 +00:00
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
if self._predicate_type in HC.SYSTEM_PREDICATES:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
if self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_EVERYTHING: base = 'everything'
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_INBOX: base = 'inbox'
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_ARCHIVE: base = 'archive'
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_UNTAGGED: base = 'untagged'
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_LOCAL: base = 'local'
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_NOT_LOCAL: base = 'not local'
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_DIMENSIONS: base = 'dimensions'
|
2015-12-30 23:44:09 +00:00
|
|
|
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 ):
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
if self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_NUM_TAGS: base = 'number of tags'
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_WIDTH: base = 'width'
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_HEIGHT: base = 'height'
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_NUM_WORDS: base = 'number of words'
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
if self._value is not None:
|
|
|
|
|
|
|
|
( operator, value ) = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base += ' ' + operator + ' ' + HydrusData.ToHumanInt( value )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
2015-12-30 23:44:09 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_DURATION:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base = 'duration'
|
2015-12-30 23:44:09 +00:00
|
|
|
|
|
|
|
if self._value is not None:
|
|
|
|
|
|
|
|
( operator, value ) = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base += ' ' + operator + ' ' + HydrusData.ConvertMillisecondsToPrettyTime( value )
|
2015-12-30 23:44:09 +00:00
|
|
|
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_RATIO:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base = 'ratio'
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
if self._value is not None:
|
|
|
|
|
|
|
|
( operator, ratio_width, ratio_height ) = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base += ' ' + operator + ' ' + str( ratio_width ) + ':' + str( ratio_height )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_SIZE:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base = 'size'
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
if self._value is not None:
|
|
|
|
|
|
|
|
( operator, size, unit ) = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base += ' ' + operator + ' ' + str( size ) + HydrusData.ConvertIntToUnit( unit )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_LIMIT:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base = 'limit'
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
if self._value is not None:
|
|
|
|
|
|
|
|
value = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base += ' is ' + HydrusData.ToHumanInt( value )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_AGE:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base = 'time imported'
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
if self._value is not None:
|
|
|
|
|
2018-01-31 22:58:15 +00:00
|
|
|
( operator, age_type, age_value ) = self._value
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2018-01-31 22:58:15 +00:00
|
|
|
if age_type == 'delta':
|
|
|
|
|
|
|
|
( years, months, days, hours ) = age_value
|
|
|
|
|
|
|
|
DAY = 86400
|
|
|
|
MONTH = DAY * 30
|
|
|
|
YEAR = MONTH * 12
|
|
|
|
|
|
|
|
time_delta = 0
|
|
|
|
|
|
|
|
time_delta += hours * 3600
|
|
|
|
time_delta += days * DAY
|
|
|
|
time_delta += months * MONTH
|
|
|
|
time_delta += years * YEAR
|
|
|
|
|
|
|
|
if operator == '<':
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
pretty_operator = 'since '
|
2018-01-31 22:58:15 +00:00
|
|
|
|
|
|
|
elif operator == '>':
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
pretty_operator = 'before '
|
2018-01-31 22:58:15 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
elif operator == '\u2248':
|
2018-01-31 22:58:15 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
pretty_operator = 'around '
|
2018-01-31 22:58:15 +00:00
|
|
|
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base += ': ' + pretty_operator + HydrusData.TimeDeltaToPrettyTimeDelta( time_delta ) + ' ago'
|
2018-01-31 22:58:15 +00:00
|
|
|
|
|
|
|
elif age_type == 'date':
|
|
|
|
|
|
|
|
( year, month, day ) = age_value
|
|
|
|
|
|
|
|
dt = datetime.datetime( year, month, day )
|
|
|
|
|
2018-02-07 23:40:33 +00:00
|
|
|
# make a timestamp (IN GMT SECS SINCE 1970) from the local meaning of 2018/02/01
|
|
|
|
timestamp = int( time.mktime( dt.timetuple() ) )
|
2018-01-31 22:58:15 +00:00
|
|
|
|
|
|
|
if operator == '<':
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
pretty_operator = 'before '
|
2018-01-31 22:58:15 +00:00
|
|
|
|
|
|
|
elif operator == '>':
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
pretty_operator = 'since '
|
2018-01-31 22:58:15 +00:00
|
|
|
|
|
|
|
elif operator == '=':
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
pretty_operator = 'on the day of '
|
2018-01-31 22:58:15 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
elif operator == '\u2248':
|
2018-01-31 22:58:15 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
pretty_operator = 'a month either side of '
|
2018-01-31 22:58:15 +00:00
|
|
|
|
|
|
|
|
2018-02-07 23:40:33 +00:00
|
|
|
# convert this GMT TIMESTAMP to a pretty local string
|
2019-01-09 22:59:03 +00:00
|
|
|
base += ': ' + pretty_operator + HydrusData.ConvertTimestampToPrettyTime( timestamp, include_24h_time = False )
|
2018-01-31 22:58:15 +00:00
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_NUM_PIXELS:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base = 'num_pixels'
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
if self._value is not None:
|
|
|
|
|
|
|
|
( operator, num_pixels, unit ) = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base += ' ' + operator + ' ' + str( num_pixels ) + ' ' + HydrusData.ConvertIntToPixels( unit )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
2018-03-28 21:55:58 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_KNOWN_URLS:
|
|
|
|
|
|
|
|
base = 'known url'
|
|
|
|
|
|
|
|
if self._value is not None:
|
|
|
|
|
|
|
|
( operator, rule_type, rule, description ) = self._value
|
|
|
|
|
|
|
|
base = description
|
|
|
|
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_HASH:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base = 'hash'
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
if self._value is not None:
|
|
|
|
|
2015-12-30 23:44:09 +00:00
|
|
|
( hash, hash_type ) = self._value
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base = hash_type + ' hash is ' + hash.hex()
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_MIME:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base = 'mime'
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
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 ] )
|
|
|
|
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base += ' is ' + mime_text
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_RATING:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base = 'rating'
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
if self._value is not None:
|
|
|
|
|
|
|
|
( operator, value, service_key ) = self._value
|
|
|
|
|
2018-02-21 21:59:37 +00:00
|
|
|
try:
|
2017-04-05 21:16:40 +00:00
|
|
|
|
2018-02-21 21:59:37 +00:00
|
|
|
service = HG.client_controller.services_manager.GetService( service_key )
|
2017-04-05 21:16:40 +00:00
|
|
|
|
2018-02-21 21:59:37 +00:00
|
|
|
service_type = service.GetServiceType()
|
2017-04-05 21:16:40 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
pretty_value = str( value )
|
2018-02-21 21:59:37 +00:00
|
|
|
|
|
|
|
if service_type == HC.LOCAL_RATING_LIKE:
|
2017-04-05 21:16:40 +00:00
|
|
|
|
2018-02-21 21:59:37 +00:00
|
|
|
if value == 0:
|
2017-04-05 21:16:40 +00:00
|
|
|
|
2018-02-21 21:59:37 +00:00
|
|
|
pretty_value = 'dislike'
|
2017-04-05 21:16:40 +00:00
|
|
|
|
2018-02-21 21:59:37 +00:00
|
|
|
elif value == 1:
|
2017-04-05 21:16:40 +00:00
|
|
|
|
2018-02-21 21:59:37 +00:00
|
|
|
pretty_value = 'like'
|
2017-04-05 21:16:40 +00:00
|
|
|
|
|
|
|
|
2018-02-21 21:59:37 +00:00
|
|
|
elif service_type == HC.LOCAL_RATING_NUMERICAL:
|
2017-04-05 21:16:40 +00:00
|
|
|
|
2018-02-21 21:59:37 +00:00
|
|
|
if isinstance( value, float ):
|
2017-04-05 21:16:40 +00:00
|
|
|
|
2018-02-21 21:59:37 +00:00
|
|
|
allow_zero = service.AllowZero()
|
|
|
|
num_stars = service.GetNumStars()
|
|
|
|
|
|
|
|
if allow_zero:
|
|
|
|
|
|
|
|
star_range = num_stars
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
star_range = num_stars - 1
|
|
|
|
|
|
|
|
|
|
|
|
pretty_x = int( round( value * star_range ) )
|
|
|
|
pretty_y = num_stars
|
|
|
|
|
|
|
|
if not allow_zero:
|
|
|
|
|
|
|
|
pretty_x += 1
|
|
|
|
|
|
|
|
|
|
|
|
pretty_value = HydrusData.ConvertValueRangeToPrettyString( pretty_x, pretty_y )
|
2017-04-05 21:16:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base += ' for ' + service.GetName() + ' ' + operator + ' ' + pretty_value
|
2018-02-21 21:59:37 +00:00
|
|
|
|
|
|
|
except HydrusExceptions.DataMissing:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base = 'system:unknown rating service system predicate'
|
2018-02-21 21:59:37 +00:00
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_SIMILAR_TO:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base = 'similar to'
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
if self._value is not None:
|
|
|
|
|
|
|
|
( hash, max_hamming ) = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base += ' ' + hash.hex() + ' using max hamming of ' + str( max_hamming )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_FILE_SERVICE:
|
|
|
|
|
|
|
|
if self._value is None:
|
|
|
|
|
2017-03-22 22:38:15 +00:00
|
|
|
base = 'file service'
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
( operator, current_or_pending, service_key ) = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
if operator == True: base = 'is'
|
|
|
|
else: base = 'is not'
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
if current_or_pending == HC.CONTENT_STATUS_PENDING: base += ' pending to '
|
|
|
|
else: base += ' currently in '
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2018-02-21 21:59:37 +00:00
|
|
|
try:
|
|
|
|
|
|
|
|
service = HG.client_controller.services_manager.GetService( service_key )
|
|
|
|
|
|
|
|
base += service.GetName()
|
|
|
|
|
|
|
|
except HydrusExceptions.DataMissing:
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base = 'unknown file service system predicate'
|
2018-02-21 21:59:37 +00:00
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
2017-06-21 21:15:59 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_TAG_AS_NUMBER:
|
|
|
|
|
|
|
|
if self._value is None:
|
|
|
|
|
|
|
|
base = 'tag as number'
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
( namespace, operator, num ) = self._value
|
|
|
|
|
|
|
|
if namespace == '':
|
|
|
|
|
|
|
|
n_text = 'tag'
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
n_text = namespace
|
|
|
|
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
if operator == '\u2248':
|
2017-06-21 21:15:59 +00:00
|
|
|
|
|
|
|
o_text = ' about '
|
|
|
|
|
|
|
|
elif operator == '<':
|
|
|
|
|
|
|
|
o_text = ' less than '
|
|
|
|
|
|
|
|
elif operator == '>':
|
|
|
|
|
|
|
|
o_text = ' more than '
|
|
|
|
|
|
|
|
|
2018-07-04 20:48:28 +00:00
|
|
|
base = n_text + o_text + HydrusData.ToHumanInt( num )
|
2017-06-21 21:15:59 +00:00
|
|
|
|
|
|
|
|
2017-05-24 20:28:24 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_DUPLICATE_RELATIONSHIPS:
|
|
|
|
|
2017-06-07 22:05:15 +00:00
|
|
|
base = 'num duplicate relationships'
|
2017-05-24 20:28:24 +00:00
|
|
|
|
|
|
|
if self._value is not None:
|
|
|
|
|
|
|
|
( operator, num_relationships, dupe_type ) = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
if operator == '\u2248':
|
2017-05-24 20:28:24 +00:00
|
|
|
|
|
|
|
o_text = ' about '
|
|
|
|
|
|
|
|
elif operator == '<':
|
|
|
|
|
|
|
|
o_text = ' less than '
|
|
|
|
|
|
|
|
elif operator == '>':
|
|
|
|
|
|
|
|
o_text = ' more than '
|
|
|
|
|
|
|
|
elif operator == '=':
|
|
|
|
|
|
|
|
o_text = ' '
|
|
|
|
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base += ' - has' + o_text + HydrusData.ToHumanInt( num_relationships ) + ' ' + HC.duplicate_type_string_lookup[ dupe_type ]
|
2017-05-24 20:28:24 +00:00
|
|
|
|
|
|
|
|
2018-12-12 22:15:46 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_SYSTEM_FILE_VIEWING_STATS:
|
|
|
|
|
|
|
|
base = 'file viewing statistics'
|
|
|
|
|
|
|
|
if self._value is not None:
|
|
|
|
|
|
|
|
( view_type, viewing_locations, operator, viewing_value ) = self._value
|
|
|
|
|
|
|
|
include_media = 'media' in viewing_locations
|
|
|
|
include_previews = 'preview' in viewing_locations
|
|
|
|
|
|
|
|
if include_media and include_previews:
|
|
|
|
|
|
|
|
domain = 'all '
|
|
|
|
|
|
|
|
elif include_media:
|
|
|
|
|
|
|
|
domain = 'media '
|
|
|
|
|
|
|
|
elif include_previews:
|
|
|
|
|
|
|
|
domain = 'preview '
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
domain = 'unknown '
|
|
|
|
|
|
|
|
|
|
|
|
if view_type == 'views':
|
|
|
|
|
|
|
|
value_string = HydrusData.ToHumanInt( viewing_value )
|
|
|
|
|
|
|
|
elif view_type == 'viewtime':
|
|
|
|
|
|
|
|
value_string = HydrusData.TimeDeltaToPrettyTimeDelta( viewing_value )
|
|
|
|
|
|
|
|
|
|
|
|
base = domain + view_type + operator + value_string
|
|
|
|
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2017-03-22 22:38:15 +00:00
|
|
|
base = HydrusTags.CombineTag( 'system', base )
|
|
|
|
|
2017-04-05 21:16:40 +00:00
|
|
|
base = ClientTags.RenderTag( base, render_for_user )
|
|
|
|
|
|
|
|
base += count_text
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_TAG:
|
|
|
|
|
|
|
|
tag = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
if not self._inclusive: base = '-'
|
|
|
|
else: base = ''
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2017-04-05 21:16:40 +00:00
|
|
|
base += ClientTags.RenderTag( tag, render_for_user )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
base += count_text
|
|
|
|
|
2016-09-14 18:03:59 +00:00
|
|
|
if sibling_service_key is not None:
|
|
|
|
|
2017-05-10 21:33:58 +00:00
|
|
|
siblings_manager = HG.client_controller.GetManager( 'tag_siblings' )
|
2016-09-14 18:03:59 +00:00
|
|
|
|
|
|
|
sibling = siblings_manager.GetSibling( sibling_service_key, tag )
|
|
|
|
|
|
|
|
if sibling is not None:
|
|
|
|
|
2017-03-22 22:38:15 +00:00
|
|
|
sibling = ClientTags.RenderTag( sibling, render_for_user )
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
base += ' (will display as ' + sibling + ')'
|
2016-09-14 18:03:59 +00:00
|
|
|
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_PARENT:
|
|
|
|
|
|
|
|
base = ' '
|
|
|
|
|
|
|
|
tag = self._value
|
|
|
|
|
2017-04-05 21:16:40 +00:00
|
|
|
base += ClientTags.RenderTag( tag, render_for_user )
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
base += count_text
|
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_NAMESPACE:
|
|
|
|
|
|
|
|
namespace = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
if not self._inclusive: base = '-'
|
|
|
|
else: base = ''
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2017-04-05 21:16:40 +00:00
|
|
|
anything_tag = HydrusTags.CombineTag( namespace, '*anything*' )
|
|
|
|
|
|
|
|
anything_tag = ClientTags.RenderTag( anything_tag, render_for_user )
|
2017-03-22 22:38:15 +00:00
|
|
|
|
2017-04-05 21:16:40 +00:00
|
|
|
base += anything_tag
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
elif self._predicate_type == HC.PREDICATE_TYPE_WILDCARD:
|
|
|
|
|
|
|
|
wildcard = self._value
|
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
if not self._inclusive: base = '-'
|
|
|
|
else: base = ''
|
2015-12-09 23:16:41 +00:00
|
|
|
|
2017-03-22 22:38:15 +00:00
|
|
|
base += wildcard
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
return base
|
|
|
|
|
|
|
|
|
2017-02-08 22:27:00 +00:00
|
|
|
def GetUnnamespacedCopy( self ):
|
|
|
|
|
|
|
|
if self._predicate_type == HC.PREDICATE_TYPE_TAG:
|
|
|
|
|
|
|
|
( namespace, subtag ) = HydrusTags.SplitTag( self._value )
|
|
|
|
|
|
|
|
return Predicate( self._predicate_type, subtag, self._inclusive, self._min_current_count, self._min_pending_count, self._max_current_count, self._max_pending_count )
|
|
|
|
|
|
|
|
|
|
|
|
return self.GetCopy()
|
|
|
|
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
def GetValue( self ): return self._value
|
|
|
|
|
2017-02-08 22:27:00 +00:00
|
|
|
def HasNonZeroCount( self ):
|
|
|
|
|
|
|
|
return self._min_current_count > 0 or self._min_pending_count > 0
|
|
|
|
|
|
|
|
|
|
|
|
def SetInclusive( self, inclusive ):
|
|
|
|
|
|
|
|
self._inclusive = inclusive
|
|
|
|
|
2015-12-09 23:16:41 +00:00
|
|
|
|
|
|
|
HydrusSerialisable.SERIALISABLE_TYPES_TO_OBJECT_TYPES[ HydrusSerialisable.SERIALISABLE_TYPE_PREDICATE ] = Predicate
|
|
|
|
|
|
|
|
SYSTEM_PREDICATE_INBOX = Predicate( HC.PREDICATE_TYPE_SYSTEM_INBOX, None )
|
|
|
|
|
|
|
|
SYSTEM_PREDICATE_ARCHIVE = Predicate( HC.PREDICATE_TYPE_SYSTEM_ARCHIVE, None )
|
|
|
|
|
|
|
|
SYSTEM_PREDICATE_LOCAL = Predicate( HC.PREDICATE_TYPE_SYSTEM_LOCAL, None )
|
|
|
|
|
|
|
|
SYSTEM_PREDICATE_NOT_LOCAL = Predicate( HC.PREDICATE_TYPE_SYSTEM_NOT_LOCAL, None )
|