Version 147

This commit is contained in:
Hydrus 2015-02-18 14:06:43 -06:00
parent b85c9cc442
commit 7507e55c2d
18 changed files with 567 additions and 602 deletions

View File

@ -8,6 +8,21 @@
<div class="content">
<h3>changelog</h3>
<ul>
<li><h3>version 147</h3></li>
<ul>
<li>fixed a problem when trying to do a multi-release update that contained the v146 update</li>
<li>fixed the 'canvas not resizing after media removal' bug</li>
<li>when an autocomplete appears in a dialog, the dropdown window will integrate into the dialog (rather than being a popup), allowing mouse interaction</li>
<li>refitted the paths-to-tags dialog so the different static boxes and newly embedded A/C dropdowns fit better</li>
<li>fixes to and cleanup of sibling tag retrieval code</li>
<li>fixes to and cleanup of sibling tag filter code</li>
<li>fixes to and cleanup of sibling tag search code</li>
<li>fixes to and cleanup of sibling tag display code</li>
<li>fixed a couple bugs in READ autocomplete tag search caching that was stopping namespaced queries searching properly if typed in manually rather than pasted</li>
<li>fixed a similar bug in WRITE autocomplete tag search</li>
<li>fixed a bug that was ignoring namespace entirely in WRITE autocomplete</li>
<li>synchronised subscription popups' new file buttons with the text</li>
</ul>
<li><h3>version 146</h3></li>
<ul>
<li>manage tags and ratings dialogs will now OK on F3/F4, not CANCEL</li>

View File

@ -390,6 +390,19 @@ def CatchExceptionClient( etype, value, tb ):
HC.ShowText( text )
def FilterPredicates( search_entry, predicates, service_key = None, expand_parents = False ):
matches = [ predicate for predicate in predicates if HC.SearchEntryMatchesPredicate( search_entry, predicate ) ]
if service_key is not None and expand_parents:
parents_manager = HC.app.GetManager( 'tag_parents' )
matches = parents_manager.ExpandPredicates( service_key, matches )
return matches
def GenerateCollectByChoices( sort_by_choices ):
already_added = set()
@ -485,7 +498,7 @@ def GenerateExportFilename( media, terms ):
if term_type == 'string': filename += term
elif term_type == 'namespace':
tags = tags_manager.GetNamespaceSlice( ( term, ) )
tags = tags_manager.GetNamespaceSlice( ( term, ), collapse_siblings = True )
filename += ', '.join( [ tag.split( ':' )[1] for tag in tags ] )
@ -862,66 +875,20 @@ def ShowTextClient( text ):
HC.pubsub.pub( 'message', job_key )
class AutocompleteMatches( object ):
def SortPredicates( predicates, collapse_siblings = False ):
def __init__( self, matches ):
if collapse_siblings:
self._matches = matches
siblings_manager = HC.app.GetManager( 'tag_siblings' )
self._matches.sort()
predicates = siblings_manager.CollapsePredicates( predicates )
def GetMatches( self, search ): return [ match for match in self._matches if HC.SearchEntryMatchesTag( search, match ) ]
def cmp_func( x, y ): return cmp( x.GetCount(), y.GetCount() )
class AutocompleteMatchesCounted( object ):
predicates.sort( cmp = cmp_func, reverse = True )
def __init__( self, matches_to_count ):
self._matches_to_count = matches_to_count
self._matches = self._matches_to_count.keys()
def cmp_func( x, y ): return cmp( matches_to_count[ x ], matches_to_count[ y ] )
self._matches.sort( cmp = cmp_func, reverse = True )
def GetMatches( self, search ): return [ ( match, self._matches_to_count[ match ] ) for match in self._matches if HC.SearchEntryMatchesTag( search, match ) ]
class AutocompleteMatchesPredicates( object ):
def __init__( self, service_key, predicates, collapse = True ):
self._service_key = service_key
self._predicates = predicates
self._collapse = collapse
# do siblings
if self._collapse:
siblings_manager = HC.app.GetManager( 'tag_siblings' )
self._predicates = siblings_manager.CollapsePredicates( self._predicates )
def cmp_func( x, y ): return cmp( x.GetCount(), y.GetCount() )
self._predicates.sort( cmp = cmp_func, reverse = True )
def GetMatches( self, search ):
matches = [ predicate for predicate in self._predicates if HC.SearchEntryMatchesPredicate( search, predicate ) ]
if not self._collapse:
parents_manager = HC.app.GetManager( 'tag_parents' )
matches = parents_manager.ExpandPredicates( self._service_key, matches )
return matches
return predicates
class Booru( HC.HydrusYAMLBase ):

View File

@ -603,9 +603,7 @@ class MessageDB( object ):
if name_to_exclude is not None: names = [ name for name in names if name != name_to_exclude ]
matches = CC.AutocompleteMatches( names )
return matches
return names
def _GetContact( self, parameter ):
@ -1819,12 +1817,12 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
tag_services = self._GetServices( ( HC.TAG_REPOSITORY, HC.LOCAL_TAG, HC.COMBINED_TAG ) )
file_services = self._GetServices( ( HC.FILE_REPOSITORY, HC.LOCAL_FILE, HC.COMBINED_FILE ) )
for ( tag_service, file_service ) in itertools.product( tag_services, file_services ): self._GetAutocompleteTags( tag_service_key = tag_service.GetServiceKey(), file_service_key = file_service.GetServiceKey(), collapse = False )
for ( tag_service, file_service ) in itertools.product( tag_services, file_services ): self._GetAutocompletePredicates( tag_service_key = tag_service.GetServiceKey(), file_service_key = file_service.GetServiceKey(), add_namespaceless = False )
self._c.execute( 'REPLACE INTO shutdown_timestamps ( shutdown_type, timestamp ) VALUES ( ?, ? );', ( CC.SHUTDOWN_TIMESTAMP_FATTEN_AC_CACHE, HC.GetNow() ) )
def _GetAutocompleteTags( self, tag_service_key = HC.COMBINED_TAG_SERVICE_KEY, file_service_key = HC.COMBINED_FILE_SERVICE_KEY, tag = '', half_complete_tag = '', include_current = True, include_pending = True, collapse = True ):
def _GetAutocompletePredicates( self, tag_service_key = HC.COMBINED_TAG_SERVICE_KEY, file_service_key = HC.COMBINED_FILE_SERVICE_KEY, tag = '', half_complete_tag = '', include_current = True, include_pending = True, add_namespaceless = False ):
tag_service_id = self._GetServiceId( tag_service_key )
file_service_id = self._GetServiceId( file_service_key )
@ -1885,7 +1883,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
( namespace, half_complete_tag ) = half_complete_tag.split( ':', 1 )
if half_complete_tag == '': return CC.AutocompleteMatchesCounted( {} )
if half_complete_tag == '': return []
else:
if '*' in namespace:
@ -1899,7 +1897,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
result = self._c.execute( 'SELECT namespace_id FROM namespaces WHERE namespace = ?;', ( namespace, ) ).fetchone()
if result is None: return CC.AutocompleteMatchesCounted( {} )
if result is None: return []
else:
( namespace_id, ) = result
@ -1938,26 +1936,28 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
results = { result for result in self._c.execute( 'SELECT namespace_id, tag_id FROM existing_tags WHERE ' + predicates_phrase + ';' ) }
if collapse:
# now fetch siblings, add to results set
siblings_manager = HC.app.GetManager( 'tag_siblings' )
if len( half_complete_tag ) > 0: all_associated_sibling_tags = siblings_manager.GetAutocompleteSiblings( half_complete_tag )
elif len( tag ) > 0: all_associated_sibling_tags = siblings_manager.GetAllSiblings( tag )
else: all_associated_sibling_tags = siblings_manager.GetAutocompleteSiblings( '' )
sibling_results = []
for sibling_tag in all_associated_sibling_tags:
# now fetch siblings, add to results set
siblings_manager = HC.app.GetManager( 'tag_siblings' )
if len( half_complete_tag ) > 0: all_associated_sibling_tags = siblings_manager.GetAutocompleteSiblings( half_complete_tag )
elif len( tag ) > 0: all_associated_sibling_tags = siblings_manager.GetAllSiblings( tag )
else: all_associated_sibling_tags = siblings_manager.GetAutocompleteSiblings( '' )
sibling_results = []
for sibling_tag in all_associated_sibling_tags:
try:
try: self._GetNamespaceIdTagId( sibling_tag )
except: continue
( namespace_id, tag_id ) = self._GetNamespaceIdTagId( sibling_tag )
sibling_results.append( ( namespace_id, tag_id ) )
except: continue
results.update( sibling_results )
results.update( sibling_results )
# fetch what we can from cache
@ -2019,7 +2019,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
current_ids_to_count = collections.Counter()
pending_ids_to_count = collections.Counter()
if collapse and not there_was_a_namespace:
if not there_was_a_namespace and add_namespaceless:
added_namespaceless_current_ids_to_count = collections.Counter()
added_namespaceless_pending_ids_to_count = collections.Counter()
@ -2033,7 +2033,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
# prepare to add any namespaced counts to the namespaceless count
if collapse and not there_was_a_namespace and ( current_count > 0 or pending_count > 0 ):
if not there_was_a_namespace and add_namespaceless and ( current_count > 0 or pending_count > 0 ):
tag_ids_to_incidence_count[ tag_id ] += 1
@ -2049,7 +2049,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
# e.g. 'series:evangelion (300)' is not benefitted by adding 'evangelion (300)'
# so do not add them
if collapse and not there_was_a_namespace:
if not there_was_a_namespace and add_namespaceless:
for ( tag_id, incidence ) in tag_ids_to_incidence_count.items():
@ -2080,9 +2080,7 @@ class ServiceDB( FileDB, MessageDB, TagDB, RatingDB ):
predicates = [ HC.Predicate( HC.PREDICATE_TYPE_TAG, tag, counts = { HC.CURRENT : current_count, HC.PENDING : pending_count } ) for ( tag, current_count, pending_count ) in tag_info if tag in filtered_tags ]
matches = CC.AutocompleteMatchesPredicates( tag_service_key, predicates, collapse = collapse )
return matches
return predicates
def _GetDownloads( self ): return { hash for ( hash, ) in self._c.execute( 'SELECT hash FROM file_transfers, hashes USING ( hash_id ) WHERE service_id = ?;', ( self._local_file_service_id, ) ) }
@ -5697,7 +5695,7 @@ class DB( ServiceDB ):
if version == 125:
( HC.options, ) = self._c.execute( 'SELECT options FROM options;' ).fetchone()
options = self._GetOptions()
HC.options[ 'default_tag_repository' ] = HC.options[ 'default_tag_repository' ].GetServiceKey()
@ -5765,7 +5763,7 @@ class DB( ServiceDB ):
#
( HC.options, ) = self._c.execute( 'SELECT options FROM options;' ).fetchone()
options = self._GetOptions()
client_size = HC.options[ 'client_size' ]
@ -5865,7 +5863,7 @@ class DB( ServiceDB ):
if version == 143:
( HC.options, ) = self._c.execute( 'SELECT options FROM options;' ).fetchone()
options = self._GetOptions()
HC.options[ 'shortcuts' ][ wx.ACCEL_CTRL ][ ord( 'E' ) ] = 'open_externally'
@ -5874,7 +5872,7 @@ class DB( ServiceDB ):
if version == 145:
( HC.options, ) = self._c.execute( 'SELECT options FROM options;' ).fetchone()
options = self._GetOptions()
HC.options[ 'gui_colours' ][ 'tags_box' ] = ( 255, 255, 255 )
@ -5944,7 +5942,7 @@ class DB( ServiceDB ):
elif action == 'tag_archive_info': result = self._GetTagArchiveInfo( *args, **kwargs )
elif action == 'tag_archive_tags': result = self._GetTagArchiveTags( *args, **kwargs )
elif action == 'autocomplete_contacts': result = self._GetAutocompleteContacts( *args, **kwargs )
elif action == 'autocomplete_tags': result = self._GetAutocompleteTags( *args, **kwargs )
elif action == 'autocomplete_predicates': result = self._GetAutocompletePredicates( *args, **kwargs )
elif action == 'contact_names': result = self._GetContactNames( *args, **kwargs )
elif action == 'do_message_query': result = self._DoMessageQuery( *args, **kwargs )
elif action == 'downloads': result = self._GetDownloads( *args, **kwargs )
@ -7346,6 +7344,13 @@ def DAEMONSynchroniseSubscriptions():
job_key.SetVariable( 'popup_message_text_1', x_out_of_y + 'checking url status' )
job_key.SetVariable( 'popup_message_gauge_1', ( i, len( all_url_args ) ) )
if len( successful_hashes ) > 0:
job_key_s_h = set( successful_hashes )
job_key.SetVariable( 'popup_message_files', job_key_s_h )
( status, hash ) = HC.app.ReadDaemon( 'url_status', url )
if status == 'deleted' and 'exclude_deleted_files' not in advanced_import_options: status = 'new'
@ -7392,14 +7397,7 @@ def DAEMONSynchroniseSubscriptions():
try: os.remove( temp_path )
except: pass # sometimes this fails, I think due to old handles not being cleaned up fast enough. np--it'll be cleaned up later
if status in ( 'successful', 'redundant' ):
successful_hashes.add( hash )
job_key_s_h = set( successful_hashes )
job_key.SetVariable( 'popup_message_files', job_key_s_h )
if status in ( 'successful', 'redundant' ): successful_hashes.add( hash )
except Exception as e:

File diff suppressed because it is too large Load Diff

View File

@ -2641,7 +2641,7 @@ class DialogInputLocalFiles( Dialog ):
paths_to_send_to_dialog.append( pretty_path )
with DialogPathsToTagsRegex( self, paths_to_send_to_dialog ) as dlg:
with DialogPathsToTags( self, paths_to_send_to_dialog ) as dlg:
if dlg.ShowModal() == wx.ID_OK:
@ -4143,7 +4143,7 @@ class DialogPageChooser( Dialog ):
class DialogPathsToTagsRegex( Dialog ):
class DialogPathsToTags( Dialog ):
def __init__( self, parent, paths ):
@ -4206,7 +4206,12 @@ class DialogPathsToTagsRegex( Dialog ):
self.SetSizer( vbox )
self.SetInitialSize( ( 980, 680 ) )
( width, height ) = self.GetMinSize()
width = max( width, 930 )
height = max( height, 680 )
self.SetInitialSize( ( width, height ) )
Dialog.__init__( self, parent, 'path tagging' )
@ -4292,12 +4297,15 @@ class DialogPathsToTagsRegex( Dialog ):
self._add_quick_namespace_button = wx.Button( self._quick_namespaces_panel, label = 'add' )
self._add_quick_namespace_button.Bind( wx.EVT_BUTTON, self.EventAddQuickNamespace )
self._add_quick_namespace_button.SetMinSize( ( 20, -1 ) )
self._edit_quick_namespace_button = wx.Button( self._quick_namespaces_panel, label = 'edit' )
self._edit_quick_namespace_button.Bind( wx.EVT_BUTTON, self.EventEditQuickNamespace )
self._edit_quick_namespace_button.SetMinSize( ( 20, -1 ) )
self._delete_quick_namespace_button = wx.Button( self._quick_namespaces_panel, label = 'delete' )
self._delete_quick_namespace_button.Bind( wx.EVT_BUTTON, self.EventDeleteQuickNamespace )
self._delete_quick_namespace_button.SetMinSize( ( 20, -1 ) )
#
@ -4317,22 +4325,22 @@ class DialogPathsToTagsRegex( Dialog ):
self._num_panel = ClientGUICommon.StaticBox( self, '#' )
self._num_base = wx.SpinCtrl( self._num_panel, min = -10000000, max = 10000000, size = ( 80, -1 ) )
self._num_base = wx.SpinCtrl( self._num_panel, min = -10000000, max = 10000000, size = ( 60, -1 ) )
self._num_base.SetValue( 1 )
self._num_base.Bind( wx.EVT_SPINCTRL, self.EventRecalcNum )
self._num_step = wx.SpinCtrl( self._num_panel, min = -1000000, max = 1000000, size = ( 80, -1 ) )
self._num_step = wx.SpinCtrl( self._num_panel, min = -1000000, max = 1000000, size = ( 60, -1 ) )
self._num_step.SetValue( 1 )
self._num_step.Bind( wx.EVT_SPINCTRL, self.EventRecalcNum )
self._num_namespace = wx.TextCtrl( self._num_panel )
self._num_namespace = wx.TextCtrl( self._num_panel, size = ( 100, -1 ) )
self._num_namespace.Bind( wx.EVT_TEXT, self.EventNumNamespaceChanged )
#
self._tags_panel = ClientGUICommon.StaticBox( self, 'tags for all' )
self._tags = ClientGUICommon.ListBoxTagsFlat( self._tags_panel, self.TagRemoved )
self._tags = ClientGUICommon.ListBoxTagsStrings( self._tags_panel, self.TagRemoved )
self._tag_box = ClientGUICommon.AutoCompleteDropdownTagsWrite( self._tags_panel, self.AddTag, HC.LOCAL_FILE_SERVICE_KEY, service_key )
@ -4342,7 +4350,7 @@ class DialogPathsToTagsRegex( Dialog ):
self._paths_to_single_tags = collections.defaultdict( list )
self._single_tags = ClientGUICommon.ListBoxTagsFlat( self._single_tags_panel, self.SingleTagRemoved )
self._single_tags = ClientGUICommon.ListBoxTagsStrings( self._single_tags_panel, self.SingleTagRemoved )
self._single_tag_box = ClientGUICommon.AutoCompleteDropdownTagsWrite( self._single_tags_panel, self.AddTagSingle, HC.LOCAL_FILE_SERVICE_KEY, service_key )
@ -4372,12 +4380,12 @@ class DialogPathsToTagsRegex( Dialog ):
button_box = wx.BoxSizer( wx.HORIZONTAL )
button_box.AddF( self._add_quick_namespace_button, FLAGS_MIXED )
button_box.AddF( self._edit_quick_namespace_button, FLAGS_MIXED )
button_box.AddF( self._delete_quick_namespace_button, FLAGS_MIXED )
button_box.AddF( self._add_quick_namespace_button, FLAGS_EXPAND_BOTH_WAYS )
button_box.AddF( self._edit_quick_namespace_button, FLAGS_EXPAND_BOTH_WAYS )
button_box.AddF( self._delete_quick_namespace_button, FLAGS_EXPAND_BOTH_WAYS )
self._quick_namespaces_panel.AddF( self._quick_namespaces_list, FLAGS_EXPAND_BOTH_WAYS )
self._quick_namespaces_panel.AddF( button_box, FLAGS_BUTTON_SIZER )
self._quick_namespaces_panel.AddF( button_box, FLAGS_EXPAND_SIZER_PERPENDICULAR )
#
@ -5472,7 +5480,7 @@ class DialogSetupExport( Dialog ):
self._tags_box = ClientGUICommon.StaticBoxSorterForListBoxTags( self, 'files\' tags' )
t = ClientGUICommon.ListBoxTagsCDPP( self._tags_box )
t = ClientGUICommon.ListBoxTagsSelection( self._tags_box, collapse_siblings = True )
self._tags_box.SetTagsBox( t )

View File

@ -6771,8 +6771,8 @@ class DialogManageTagParents( ClientGUIDialogs.Dialog ):
removed_callable = lambda tag: 1
self._children = ClientGUICommon.ListBoxTagsFlat( self, removed_callable )
self._parents = ClientGUICommon.ListBoxTagsFlat( self, removed_callable )
self._children = ClientGUICommon.ListBoxTagsStrings( self, removed_callable )
self._parents = ClientGUICommon.ListBoxTagsStrings( self, removed_callable )
self._child_input = ClientGUICommon.AutoCompleteDropdownTagsWrite( self, self.AddChild, HC.LOCAL_FILE_SERVICE_KEY, service_key )
self._parent_input = ClientGUICommon.AutoCompleteDropdownTagsWrite( self, self.AddParent, HC.LOCAL_FILE_SERVICE_KEY, service_key )
@ -7234,7 +7234,7 @@ class DialogManageTagSiblings( ClientGUIDialogs.Dialog ):
removed_callable = lambda tags: 1
self._old_siblings = ClientGUICommon.ListBoxTagsFlat( self, removed_callable )
self._old_siblings = ClientGUICommon.ListBoxTagsStrings( self, removed_callable )
self._new_sibling = wx.StaticText( self )
self._old_input = ClientGUICommon.AutoCompleteDropdownTagsWrite( self, self.AddOld, HC.LOCAL_FILE_SERVICE_KEY, service_key )
@ -7823,7 +7823,7 @@ class DialogManageTags( ClientGUIDialogs.Dialog ):
self._tags_box_sorter = ClientGUICommon.StaticBoxSorterForListBoxTags( self, 'tags' )
self._tags_box = ClientGUICommon.ListBoxTagsCDPPTagsDialog( self._tags_box_sorter, self.AddTag )
self._tags_box = ClientGUICommon.ListBoxTagsSelectionTagsDialog( self._tags_box_sorter, self.AddTag )
self._tags_box_sorter.SetTagsBox( self._tags_box )

View File

@ -378,7 +378,7 @@ class ManagementPanel( wx.lib.scrolledpanel.ScrolledPanel ):
tags_box = ClientGUICommon.StaticBoxSorterForListBoxTags( self, 'selection tags' )
t = ClientGUICommon.ListBoxTagsCDPPManagementPanel( tags_box, self._page_key )
t = ClientGUICommon.ListBoxTagsSelectionManagementPanel( tags_box, self._page_key )
tags_box.SetTagsBox( t )

View File

@ -567,6 +567,8 @@ class MediaPanel( ClientGUIMixins.ListeningMediaList, wx.ScrolledWindow ):
self._shift_focussed_media = None
self._RefitCanvas()
self._RedrawCanvas()
self._PublishSelectionChange()
@ -1450,6 +1452,19 @@ class MediaPanelThumbnails( MediaPanel ):
self._canvas_bmp = wx.EmptyBitmap( new_canvas_width, new_canvas_height, 24 )
if not self._canvas_bmp.Ok():
text = 'Attempting to create a canvas bmp failed!'
text += os.linesep
text += 'Old dimensions: ' + str( ( old_canvas_width, old_canvas_height ) )
text += os.linesep
text += 'New (failed) dimensions: ' + str( ( new_canvas_width, new_canvas_height ) )
HC.ShowText( text )
raise Exception( 'Canvas bmp failure!' )
if new_canvas_width == old_canvas_width:
dc = wx.MemoryDC( self._canvas_bmp )
@ -1458,12 +1473,13 @@ class MediaPanelThumbnails( MediaPanel ):
del dc
self._CleanCanvas()
else: self._RedrawCanvas()
wx.CallAfter( old_canvas_bmp.Destroy )
self._CleanCanvas()
else: self._CleanCanvas()

View File

@ -54,7 +54,7 @@ class MediaList( object ):
for media in medias:
if len( namespaces_to_collect_by ) > 0: namespace_key = media.GetTagsManager().GetNamespaceSlice( namespaces_to_collect_by )
if len( namespaces_to_collect_by ) > 0: namespace_key = media.GetTagsManager().GetNamespaceSlice( namespaces_to_collect_by, collapse_siblings = True )
else: namespace_key = None
if len( ratings_to_collect_by ) > 0:
@ -320,7 +320,7 @@ class MediaList( object ):
x_tags_manager = x.GetTagsManager()
return [ x_tags_manager.GetComparableNamespaceSlice( ( namespace, ) ) for namespace in namespaces ]
return [ x_tags_manager.GetComparableNamespaceSlice( ( namespace, ), collapse_siblings = True ) for namespace in namespaces ]
sort_function = lambda x: namespace_sort_function( sort_by_data, x )

View File

@ -66,7 +66,7 @@ options = {}
# Misc
NETWORK_VERSION = 15
SOFTWARE_VERSION = 146
SOFTWARE_VERSION = 147
UNSCALED_THUMBNAIL_DIMENSIONS = ( 200, 200 )
@ -1283,7 +1283,7 @@ def SearchEntryMatchesPredicate( search_entry, predicate ):
( predicate_type, value, inclusive ) = predicate.GetInfo()
if predicate_type == PREDICATE_TYPE_TAG: return SearchEntryMatchesTag( search_entry, value )
if predicate_type == PREDICATE_TYPE_TAG: return SearchEntryMatchesTag( search_entry, value, search_siblings = True )
else: return False
def SearchEntryMatchesTag( search_entry, tag, search_siblings = True ):
@ -2375,7 +2375,7 @@ class Predicate( HydrusYAMLBase ):
sibling = siblings_manager.GetSibling( tag )
if sibling is not None: base += u' (' + sibling + u')'
if sibling is not None: base += u' (will display as ' + sibling + ')'
elif self._predicate_type == PREDICATE_TYPE_PARENT:

View File

@ -307,7 +307,7 @@ class TagsManagerSimple( object ):
return result
def GetComparableNamespaceSlice( self, namespaces, collapse = True ):
def GetComparableNamespaceSlice( self, namespaces, collapse_siblings = False ):
combined_statuses_to_tags = self._service_keys_to_statuses_to_tags[ HC.COMBINED_TAG_SERVICE_KEY ]
@ -338,7 +338,7 @@ class TagsManagerSimple( object ):
return tuple( slice )
def GetNamespaceSlice( self, namespaces, collapse = True ):
def GetNamespaceSlice( self, namespaces, collapse_siblings = False ):
combined_statuses_to_tags = self._service_keys_to_statuses_to_tags[ HC.COMBINED_TAG_SERVICE_KEY ]
@ -347,7 +347,7 @@ class TagsManagerSimple( object ):
slice = { tag for tag in combined_current.union( combined_pending ) if True in ( tag.startswith( namespace + ':' ) for namespace in namespaces ) }
if collapse:
if collapse_siblings:
siblings_manager = HC.app.GetManager( 'tag_siblings' )
@ -821,7 +821,7 @@ class TagSiblingsManager( object ):
( old_pred_type, old_value, old_inclusive ) = old_predicate.GetInfo()
new_predicate = HC.Predicate( old_pred_type, old_value, inclusive = old_inclusive )
new_predicate = HC.Predicate( old_pred_type, new_tag, inclusive = old_inclusive )
tags_to_predicates[ new_tag ] = new_predicate

View File

@ -93,13 +93,13 @@ class TestClientDB( unittest.TestCase ):
self._clear_db()
result = self._read( 'autocomplete_tags', half_complete_tag = 'c' )
result = self._read( 'autocomplete_predicates', half_complete_tag = 'c' )
self.assertEqual( result.GetMatches( 'c' ), [] )
self.assertEqual( result, [] )
result = self._read( 'autocomplete_tags', half_complete_tag = 'series:' )
result = self._read( 'autocomplete_predicates', half_complete_tag = 'series:' )
self.assertEqual( result.GetMatches( 'series:' ), [] )
self.assertEqual( result, [] )
#
@ -125,36 +125,43 @@ class TestClientDB( unittest.TestCase ):
# cars
result = self._read( 'autocomplete_tags', half_complete_tag = 'c' )
result = self._read( 'autocomplete_predicates', half_complete_tag = 'c', add_namespaceless = True )
preds = set()
preds.add( HC.Predicate( HC.PREDICATE_TYPE_TAG, 'car', counts = { HC.CURRENT : 1 } ) )
preds.add( HC.Predicate( HC.PREDICATE_TYPE_TAG, 'series:cars', counts = { HC.CURRENT : 1 } ) )
read_preds = result.GetMatches( 'c' )
for p in result: self.assertEqual( p.GetCount( HC.CURRENT ), 1 )
# count isn't tested in predicate.__eq__, I think
self.assertEqual( set( result ), preds )
for p in read_preds: self.assertEqual( p.GetCount( HC.CURRENT ), 1 )
# cars
self.assertEqual( set( read_preds ), preds )
result = self._read( 'autocomplete_predicates', half_complete_tag = 'c', add_namespaceless = False )
preds = set()
preds.add( HC.Predicate( HC.PREDICATE_TYPE_TAG, 'series:cars', counts = { HC.CURRENT : 1 } ) )
preds.add( HC.Predicate( HC.PREDICATE_TYPE_TAG, 'car', counts = { HC.CURRENT : 1 } ) )
for p in result: self.assertEqual( p.GetCount( HC.CURRENT ), 1 )
self.assertEqual( set( result ), preds )
#
result = self._read( 'autocomplete_tags', half_complete_tag = 'ser' )
result = self._read( 'autocomplete_predicates', half_complete_tag = 'ser' )
read_preds = result.GetMatches( 'ser' )
self.assertEqual( read_preds, [] )
self.assertEqual( result, [] )
#
result = self._read( 'autocomplete_tags', half_complete_tag = 'series:c' )
result = self._read( 'autocomplete_predicates', half_complete_tag = 'series:c' )
pred = HC.Predicate( HC.PREDICATE_TYPE_TAG, 'series:cars', counts = { HC.CURRENT : 1 } )
( read_pred, ) = result.GetMatches( 'series:c' )
( read_pred, ) = result
self.assertEqual( read_pred.GetCount( HC.CURRENT ), 1 )
@ -162,11 +169,11 @@ class TestClientDB( unittest.TestCase ):
#
result = self._read( 'autocomplete_tags', tag = 'car' )
result = self._read( 'autocomplete_predicates', tag = 'car' )
pred = HC.Predicate( HC.PREDICATE_TYPE_TAG, 'car', counts = { HC.CURRENT : 1 } )
( read_pred, ) = result.GetMatches( 'car' )
( read_pred, ) = result
self.assertEqual( read_pred.GetCount( HC.CURRENT ), 1 )
@ -174,11 +181,9 @@ class TestClientDB( unittest.TestCase ):
#
result = self._read( 'autocomplete_tags', tag = 'c' )
result = self._read( 'autocomplete_predicates', tag = 'c' )
read_preds = result.GetMatches( 'c' )
self.assertEqual( read_preds, [] )
self.assertEqual( result, [] )
def test_booru( self ):

View File

@ -162,8 +162,8 @@ class TestTagsManager( unittest.TestCase ):
def test_get_namespace_slice( self ):
self.assertEqual( self._tags_manager.GetNamespaceSlice( ( 'creator', 'series' ), collapse = False ), frozenset( { 'creator:tsutomu nihei', 'series:blame!' } ) )
self.assertEqual( self._tags_manager.GetNamespaceSlice( (), collapse = False ), frozenset() )
self.assertEqual( self._tags_manager.GetNamespaceSlice( ( 'creator', 'series' ), collapse_siblings = False ), frozenset( { 'creator:tsutomu nihei', 'series:blame!' } ) )
self.assertEqual( self._tags_manager.GetNamespaceSlice( (), collapse_siblings = False ), frozenset() )
self.assertEqual( self._tags_manager.GetNamespaceSlice( ( 'creator', 'series' ) ), frozenset( { 'creator:tsutomu nihei', 'series:blame!' } ) )
self.assertEqual( self._tags_manager.GetNamespaceSlice( () ), frozenset() )

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 17 KiB