def subtag_lexicographic_key(tag):

        (namespace, subtag) = HydrusTags.SplitTag(tag)

        comparable_subtag = HydrusTags.ConvertTagToSortable(subtag)

        return comparable_subtag
Beispiel #2
0
 def GetTagId( self, tag ) -> int:
     
     clean_tag = HydrusTags.CleanTag( tag )
     
     try:
         
         HydrusTags.CheckTagNotEmpty( clean_tag )
         
     except HydrusExceptions.TagSizeException:
         
         # update this to instead go 'hey, does the dirty tag exist?' if it does, run the fix invalid tags routine
         
         raise HydrusExceptions.TagSizeException( '"{}" tag seems not valid--when cleaned, it ends up with zero size!'.format( tag ) )
         
     
     ( namespace, subtag ) = HydrusTags.SplitTag( clean_tag )
     
     namespace_id = self.GetNamespaceId( namespace )
     subtag_id = self.GetSubtagId( subtag )
     
     result = self._c.execute( 'SELECT tag_id FROM tags WHERE namespace_id = ? AND subtag_id = ?;', ( namespace_id, subtag_id ) ).fetchone()
     
     if result is None:
         
         self._c.execute( 'INSERT INTO tags ( namespace_id, subtag_id ) VALUES ( ?, ? );', ( namespace_id, subtag_id ) )
         
         tag_id = self._c.lastrowid
         
     else:
         
         ( tag_id, ) = result
         
     
     return tag_id
Beispiel #3
0
    def GetComparableNamespaceSlice(self, namespaces, tag_display_type):

        with self._lock:

            service_keys_to_statuses_to_tags = self._GetServiceKeysToStatusesToTags(
                tag_display_type)

            combined_statuses_to_tags = service_keys_to_statuses_to_tags[
                CC.COMBINED_TAG_SERVICE_KEY]

            combined_current = combined_statuses_to_tags[
                HC.CONTENT_STATUS_CURRENT]
            combined_pending = combined_statuses_to_tags[
                HC.CONTENT_STATUS_PENDING]

            combined = combined_current.union(combined_pending)

            pairs = [HydrusTags.SplitTag(tag) for tag in combined]

            slice = []

            for desired_namespace in namespaces:

                subtags = [
                    HydrusTags.ConvertTagToSortable(subtag)
                    for (namespace, subtag) in pairs
                    if namespace == desired_namespace
                ]

                subtags.sort()

                slice.append(tuple(subtags))

            return tuple(slice)
Beispiel #4
0
    def GetTagId(self, tag) -> int:

        clean_tag = HydrusTags.CleanTag(tag)

        try:

            HydrusTags.CheckTagNotEmpty(clean_tag)

        except HydrusExceptions.TagSizeException:

            raise HydrusExceptions.TagSizeException(
                '"{}" tag seems not valid--when cleaned, it ends up with zero size!'
                .format(tag))

        result = self._Execute(
            'SELECT tag_id FROM local_tags_cache WHERE tag = ?;',
            (tag, )).fetchone()

        if result is None:

            return self.modules_tags.GetTagId(tag)

        else:

            (tag_id, ) = result

        return tag_id
Beispiel #5
0
 def _PopulateTagIdsToTagsCache( self, tag_ids ):
     
     if len( self._tag_ids_to_tags_cache ) > 100000:
         
         if not isinstance( tag_ids, set ):
             
             tag_ids = set( tag_ids )
             
         
         self._tag_ids_to_tags_cache = { tag_id : tag for ( tag_id, tag ) in self._tag_ids_to_tags_cache.items() if tag_id in tag_ids }
         
     
     uncached_tag_ids = { tag_id for tag_id in tag_ids if tag_id not in self._tag_ids_to_tags_cache }
     
     if len( uncached_tag_ids ) > 0:
         
         if len( uncached_tag_ids ) == 1:
             
             ( uncached_tag_id, ) = uncached_tag_ids
             
             rows = self._c.execute( 'SELECT tag_id, namespace, subtag FROM tags NATURAL JOIN namespaces NATURAL JOIN subtags WHERE tag_id = ?;', ( uncached_tag_id, ) ).fetchall()
             
         else:
             
             with HydrusDB.TemporaryIntegerTable( self._c, uncached_tag_ids, 'tag_id' ) as temp_table_name:
                 
                 # temp tag_ids to tags to subtags and namespaces
                 rows = self._c.execute( 'SELECT tag_id, namespace, subtag FROM {} CROSS JOIN tags USING ( tag_id ) CROSS JOIN subtags USING ( subtag_id ) CROSS JOIN namespaces USING ( namespace_id );'.format( temp_table_name ) ).fetchall()
                 
             
         
         uncached_tag_ids_to_tags = { tag_id : HydrusTags.CombineTag( namespace, subtag ) for ( tag_id, namespace, subtag ) in rows }
         
         if len( uncached_tag_ids_to_tags ) < len( uncached_tag_ids ):
             
             for tag_id in uncached_tag_ids:
                 
                 if tag_id not in uncached_tag_ids_to_tags:
                     
                     tag = 'unknown tag:' + HydrusData.GenerateKey().hex()
                     
                     ( namespace, subtag ) = HydrusTags.SplitTag( tag )
                     
                     namespace_id = self.GetNamespaceId( namespace )
                     subtag_id = self.GetSubtagId( subtag )
                     
                     self._c.execute( 'REPLACE INTO tags ( tag_id, namespace_id, subtag_id ) VALUES ( ?, ?, ? );', ( tag_id, namespace_id, subtag_id ) )
                     
                     uncached_tag_ids_to_tags[ tag_id ] = tag
                     
                 
             
         
         self._tag_ids_to_tags_cache.update( uncached_tag_ids_to_tags )
    def namespace_lexicographic_key(tag):

        # '{' is above 'z' in ascii, so this works for most situations

        (namespace, subtag) = HydrusTags.SplitTag(tag)

        if namespace == '':

            return ('{', HydrusTags.ConvertTagToSortable(subtag))

        else:

            return (namespace, HydrusTags.ConvertTagToSortable(subtag))
    def GetCopyableText(self, with_counts: bool = False) -> str:

        if self._namespace is None:

            return HydrusTags.ConvertTagSliceToString(':')

        elif self._namespace == '':

            return HydrusTags.ConvertTagSliceToString('')

        else:

            return HydrusTags.ConvertTagSliceToString('{}:'.format(
                self._namespace))
    def lexicographic_key(tag):

        (namespace, subtag) = HydrusTags.SplitTag(tag)

        comparable_namespace = HydrusTags.ConvertTagToSortable(namespace)
        comparable_subtag = HydrusTags.ConvertTagToSortable(subtag)

        if namespace == '':

            return (comparable_subtag, comparable_subtag)

        else:

            return (comparable_namespace, comparable_subtag)
Beispiel #9
0
 def TagExists( self, tag ):
     
     try:
         
         tag = HydrusTags.CleanTag( tag )
         
     except:
         
         return False
         
     
     try:
         
         HydrusTags.CheckTagNotEmpty( tag )
         
     except HydrusExceptions.TagSizeException:
         
         return False
         
     
     ( namespace, subtag ) = HydrusTags.SplitTag( tag )
     
     if self.NamespaceExists( namespace ):
         
         namespace_id = self.GetNamespaceId( namespace )
         
     else:
         
         return False
         
     
     if self.SubtagExists( subtag ):
         
         subtag_id = self.GetSubtagId( subtag )
         
         result = self._c.execute( 'SELECT 1 FROM tags WHERE namespace_id = ? AND subtag_id = ?;', ( namespace_id, subtag_id ) ).fetchone()
         
         if result is None:
             
             return False
             
         else:
             
             return True
             
         
     else:
         
         return False
def RenderTag(tag, render_for_user):

    (namespace, subtag) = HydrusTags.SplitTag(tag)

    if namespace == '':

        return subtag

    else:

        if render_for_user:

            new_options = HG.client_controller.new_options

            if new_options.GetBoolean('show_namespaces'):

                connector = new_options.GetString('namespace_connector')

            else:

                return subtag

        else:

            connector = ':'

        return namespace + connector + subtag
Beispiel #11
0
 def GetHashIdsFromTag( self, tag_display_type: int, location_context: ClientLocation.LocationContext, tag_search_context: ClientSearch.TagSearchContext, tag, hash_ids = None, hash_ids_table_name = None, allow_unnamespaced_to_fetch_namespaced = True, job_key = None ):
     
     ( file_service_keys, file_location_is_cross_referenced ) = location_context.GetCoveringCurrentFileServiceKeys()
     
     if not file_location_is_cross_referenced and hash_ids_table_name is not None:
         
         file_location_is_cross_referenced = True
         
     
     ( namespace, subtag ) = HydrusTags.SplitTag( tag )
     
     subtag_id = self.modules_tags.GetSubtagId( subtag )
     
     if not self.modules_tags.SubtagExists( subtag ):
         
         return set()
         
     
     tag_service_id = self.modules_services.GetServiceId( tag_search_context.service_key )
     
     results = set()
     
     for file_service_key in file_service_keys:
         
         if namespace == '' and allow_unnamespaced_to_fetch_namespaced:
             
             file_service_id = self.modules_services.GetServiceId( file_service_key )
             
             tag_ids = self.modules_tag_search.GetTagIdsFromSubtagIds( file_service_id, tag_service_id, ( subtag_id, ) )
             
         else:
             
             if not self.modules_tags.TagExists( tag ):
                 
                 return set()
                 
             
             tag_id = self.modules_tags.GetTagId( tag )
             
             tag_ids = ( tag_id, )
             
         
         some_results = self.GetHashIdsFromTagIds( tag_display_type, file_service_key, tag_search_context, tag_ids, hash_ids = hash_ids, hash_ids_table_name = hash_ids_table_name, job_key = job_key )
         
         if len( results ) == 0:
             
             results = some_results
             
         else:
             
             results.update( some_results )
             
         
     
     if not file_location_is_cross_referenced:
         
         results = self.modules_files_storage.FilterHashIds( location_context, results )
         
     
     return results
Beispiel #12
0
def RenderTag(tag, render_for_user: bool):

    if render_for_user:

        new_options = HG.client_controller.new_options

        if new_options.GetBoolean('replace_tag_underscores_with_spaces'):

            tag = tag.replace('_', ' ')

    (namespace, subtag) = HydrusTags.SplitTag(tag)

    if namespace == '':

        return subtag

    else:

        if render_for_user:

            if new_options.GetBoolean('show_namespaces'):

                connector = new_options.GetString('namespace_connector')

            else:

                return subtag

        else:

            connector = ':'

        return namespace + connector + subtag
    def GetRowsOfPresentationTextsWithNamespaces(
        self, render_for_user: bool, sibling_decoration_allowed: bool,
        child_rows_allowed: bool
    ) -> typing.List[typing.List[typing.Tuple[str, str]]]:

        # this should be with counts or whatever, but we need to think about this more lad

        (namespace, subtag) = HydrusTags.SplitTag(self._tag)

        tag_text = ClientTags.RenderTag(self._tag, render_for_user)

        first_row_of_texts_with_namespaces = [(tag_text, namespace)]

        if sibling_decoration_allowed and self._ideal_tag is not None:

            self._AppendIdealTagTextWithNamespace(
                first_row_of_texts_with_namespaces, render_for_user)

        rows_of_texts_with_namespaces = [first_row_of_texts_with_namespaces]

        if self._parent_tags is not None:

            if child_rows_allowed:

                self._AppendParentsTextWithNamespaces(
                    rows_of_texts_with_namespaces, render_for_user)

            elif sibling_decoration_allowed:

                self._AppendParentSuffixTagTextWithNamespace(
                    first_row_of_texts_with_namespaces)

        return rows_of_texts_with_namespaces
Beispiel #14
0
 def __init__( self, name = 'new api permissions', access_key = None, basic_permissions = None, search_tag_filter = None ):
     
     if access_key is None:
         
         access_key = HydrusData.GenerateKey()
         
     
     if basic_permissions is None:
         
         basic_permissions = set()
         
     
     if search_tag_filter is None:
         
         search_tag_filter = HydrusTags.TagFilter()
         
     
     HydrusSerialisable.SerialisableBaseNamed.__init__( self, name )
     
     self._access_key = access_key
     
     self._basic_permissions = set( basic_permissions )
     self._search_tag_filter = search_tag_filter
     
     self._last_search_results = None
     self._search_results_timeout = 0
     
     self._lock = threading.Lock()
Beispiel #15
0
    def __init__(
            self,
            fetch_tags_even_if_url_recognised_and_file_already_in_db=False,
            fetch_tags_even_if_hash_recognised_and_file_already_in_db=False,
            tag_blacklist=None,
            tag_whitelist=None,
            service_keys_to_service_tag_import_options=None,
            is_default=False):

        HydrusSerialisable.SerialisableBase.__init__(self)

        if tag_blacklist is None:

            tag_blacklist = HydrusTags.TagFilter()

        if tag_whitelist is None:

            tag_whitelist = []

        if service_keys_to_service_tag_import_options is None:

            service_keys_to_service_tag_import_options = {}

        self._fetch_tags_even_if_url_recognised_and_file_already_in_db = fetch_tags_even_if_url_recognised_and_file_already_in_db
        self._fetch_tags_even_if_hash_recognised_and_file_already_in_db = fetch_tags_even_if_hash_recognised_and_file_already_in_db
        self._tag_blacklist = tag_blacklist
        self._tag_whitelist = tag_whitelist
        self._service_keys_to_service_tag_import_options = service_keys_to_service_tag_import_options
        self._is_default = is_default
Beispiel #16
0
    def GetServiceKeysToContentUpdates(
            self,
            status: int,
            media_result: ClientMediaResult.MediaResult,
            filterable_tags: typing.Iterable[str],
            external_filterable_tags=None,
            external_additional_service_keys_to_tags=None):

        if external_filterable_tags is None:

            external_filterable_tags = set()

        if external_additional_service_keys_to_tags is None:

            external_additional_service_keys_to_tags = ClientTags.ServiceKeysToTags(
            )

        filterable_tags = HydrusTags.CleanTags(filterable_tags)

        service_keys_to_tags = ClientTags.ServiceKeysToTags()

        for service_key in HG.client_controller.services_manager.GetServiceKeys(
                HC.REAL_TAG_SERVICES):

            service_additional_tags = set()

            if service_key in external_additional_service_keys_to_tags:

                service_additional_tags.update(
                    external_additional_service_keys_to_tags[service_key])

            if service_key in self._service_keys_to_service_tag_import_options:

                service_tag_import_options = self._service_keys_to_service_tag_import_options[
                    service_key]

                service_filterable_tags = set(filterable_tags)

                service_filterable_tags.update(external_filterable_tags)

                service_tags = service_tag_import_options.GetTags(
                    service_key, status, media_result, service_filterable_tags,
                    service_additional_tags)

            else:

                service_tags = service_additional_tags

            if len(service_tags) > 0:

                service_keys_to_tags[service_key] = service_tags

        hash = media_result.GetHash()

        service_keys_to_content_updates = ClientData.ConvertServiceKeysToTagsToServiceKeysToContentUpdates(
            {hash}, service_keys_to_tags)

        return service_keys_to_content_updates
    def namespace_key(tag):

        (namespace, subtag) = HydrusTags.SplitTag(tag)

        if namespace == '':

            namespace = '{'  # '{' is above 'z' in ascii, so this works for most situations

        return namespace
    def _AppendIdealTagTextWithNamespace(self, texts_with_namespaces,
                                         render_for_user):

        (namespace, subtag) = HydrusTags.SplitTag(self._ideal_tag)

        ideal_text = ' (displays as {})'.format(
            ClientTags.RenderTag(self._ideal_tag, render_for_user))

        texts_with_namespaces.append((ideal_text, namespace))
Beispiel #19
0
    def GetTags(
            self,
            service_key: bytes,
            status: int,
            media_result: ClientMediaResult.MediaResult,
            filterable_tags: typing.Collection[str],
            additional_tags: typing.Optional[typing.Collection[str]] = None):

        if additional_tags is None:

            additional_tags = set()

        tags = set()

        in_inbox = media_result.GetInbox()

        if ClientImportOptions.NewInboxArchiveMatch(
                self._to_new_files, self._to_already_in_inbox,
                self._to_already_in_archive, status, in_inbox):

            if self._get_tags:

                filtered_tags = self._get_tags_filter.Filter(filterable_tags)

                if not self._get_tags_overwrite_deleted:

                    filtered_tags = ClientImportOptions.FilterDeletedTags(
                        service_key, media_result, filtered_tags)

                tags.update(filtered_tags)

            additional_tags = set(additional_tags)
            additional_tags.update(self._additional_tags)

            additional_tags = HydrusTags.CleanTags(additional_tags)

            if not self._additional_tags_overwrite_deleted:

                additional_tags = ClientImportOptions.FilterDeletedTags(
                    service_key, media_result, additional_tags)

            tags.update(additional_tags)

            if self._only_add_existing_tags:

                applicable_tags = self._only_add_existing_tags_filter.Filter(
                    tags)

                tags.difference_update(applicable_tags)

                existing_applicable_tags = HG.client_controller.Read(
                    'filter_existing_tags', service_key, applicable_tags)

                tags.update(existing_applicable_tags)

        return tags
 def _UpdateSerialisableInfo( self, version, old_serialisable_info ):
     
     if version == 1:
         
         ( serialisable_service_actions, delete_second_file ) = old_serialisable_info
         
         tag_service_actions = []
         rating_service_actions = []
         
         # As the client isn't booted when this is loaded in options, there isn't a good way to figure out tag from rating
         # So, let's just dupe and purge later on, in serialisation
         for ( service_key_encoded, action ) in serialisable_service_actions:
             
             service_key = bytes.fromhex( service_key_encoded )
             
             tag_filter = HydrusTags.TagFilter()
             
             tag_service_actions.append( ( service_key, action, tag_filter ) )
             
             rating_service_actions.append( ( service_key, action ) )
             
         
         serialisable_tag_service_actions = [ ( service_key.hex(), action, tag_filter.GetSerialisableTuple() ) for ( service_key, action, tag_filter ) in tag_service_actions ]
         serialisable_rating_service_actions = [ ( service_key.hex(), action ) for ( service_key, action ) in rating_service_actions ]
         
         sync_archive = delete_second_file
         delete_both_files = False
         
         new_serialisable_info = ( serialisable_tag_service_actions, serialisable_rating_service_actions, delete_second_file, sync_archive, delete_both_files )
         
         return ( 2, new_serialisable_info )
         
     
     if version == 2:
         
         ( serialisable_tag_service_actions, serialisable_rating_service_actions, delete_second_file, sync_archive, delete_both_files ) = old_serialisable_info
         
         sync_urls_action = None
         
         new_serialisable_info = ( serialisable_tag_service_actions, serialisable_rating_service_actions, delete_second_file, sync_archive, delete_both_files, sync_urls_action )
         
         return ( 3, new_serialisable_info )
         
     
     if version == 3:
         
         ( serialisable_tag_service_actions, serialisable_rating_service_actions, delete_second_file, sync_archive, delete_both_files, sync_urls_action ) = old_serialisable_info
         
         new_serialisable_info = ( serialisable_tag_service_actions, serialisable_rating_service_actions, sync_archive, sync_urls_action )
         
         return ( 4, new_serialisable_info )
    def _AppendParentsTextWithNamespaces(self, rows_of_texts_with_namespaces,
                                         render_for_user):

        indent = '    '

        for parent in self._parent_tags:

            (namespace, subtag) = HydrusTags.SplitTag(parent)

            tag_text = ClientTags.RenderTag(parent, render_for_user)

            texts_with_namespaces = [(indent + tag_text, namespace)]

            rows_of_texts_with_namespaces.append(texts_with_namespaces)
Beispiel #22
0
    def CheckTagsVeto(self, tags: typing.Collection[str],
                      sibling_tags: typing.Collection[str]):

        tags = set(tags)

        sibling_tags = set(sibling_tags)

        for test_tags in (tags, sibling_tags):

            ok_tags = self._tag_blacklist.Filter(
                test_tags, apply_unnamespaced_rules_to_namespaced_tags=True)

            if len(ok_tags) < len(test_tags):

                bad_tags = test_tags.difference(ok_tags)

                bad_tags = HydrusTags.SortNumericTags(bad_tags)

                raise HydrusExceptions.VetoException(', '.join(bad_tags) +
                                                     ' is blacklisted!')

        if len(self._tag_whitelist) > 0:

            all_tags = tags.union(sibling_tags)

            for tag in list(all_tags):

                (namespace, subtag) = HydrusTags.SplitTag(tag)

                all_tags.add(subtag)

            intersecting_tags = all_tags.intersection(self._tag_whitelist)

            if len(intersecting_tags) == 0:

                raise HydrusExceptions.VetoException(
                    'did not pass the whitelist!')
Beispiel #23
0
    def __init__(self,
                 get_tags=False,
                 get_tags_filter=None,
                 additional_tags=None,
                 to_new_files=True,
                 to_already_in_inbox=True,
                 to_already_in_archive=True,
                 only_add_existing_tags=False,
                 only_add_existing_tags_filter=None,
                 get_tags_overwrite_deleted=False,
                 additional_tags_overwrite_deleted=False):

        if get_tags_filter is None:

            get_tags_filter = HydrusTags.TagFilter()

        if additional_tags is None:

            additional_tags = []

        if only_add_existing_tags_filter is None:

            only_add_existing_tags_filter = HydrusTags.TagFilter()

        HydrusSerialisable.SerialisableBase.__init__(self)

        self._get_tags = get_tags
        self._get_tags_filter = get_tags_filter
        self._additional_tags = additional_tags
        self._to_new_files = to_new_files
        self._to_already_in_inbox = to_already_in_inbox
        self._to_already_in_archive = to_already_in_archive
        self._only_add_existing_tags = only_add_existing_tags
        self._only_add_existing_tags_filter = only_add_existing_tags_filter
        self._get_tags_overwrite_deleted = get_tags_overwrite_deleted
        self._additional_tags_overwrite_deleted = additional_tags_overwrite_deleted
    def GetRowsOfPresentationTextsWithNamespaces(
            self, render_for_user: bool, sibling_decoration_allowed: bool,
            child_rows_allowed: bool) -> typing.List[typing.Tuple[str, str]]:

        presentation_text = self.GetCopyableText()

        if self._tag_slice in ('', ':'):

            namespace = ''

        else:

            (namespace, subtag) = HydrusTags.SplitTag(self._tag_slice)

        return [[(presentation_text, namespace)]]
    def GetRowsOfPresentationTextsWithNamespaces(
        self, render_for_user: bool, sibling_decoration_allowed: bool,
        child_rows_allowed: bool
    ) -> typing.List[typing.List[typing.Tuple[str, str]]]:

        rows_of_texts_and_namespaces = []

        first_row_of_texts_and_namespaces = self._predicate.GetTextsAndNamespaces(
            render_for_user,
            or_under_construction=self._i_am_an_or_under_construction)

        if sibling_decoration_allowed and self._predicate.HasIdealSibling():

            ideal_sibling = self._predicate.GetIdealSibling()

            (ideal_namespace,
             ideal_subtag) = HydrusTags.SplitTag(ideal_sibling)

            ideal_text = ' (displays as {})'.format(
                ClientTags.RenderTag(ideal_sibling, render_for_user))

            first_row_of_texts_and_namespaces.append(
                (ideal_text, ideal_namespace))

        rows_of_texts_and_namespaces.append(first_row_of_texts_and_namespaces)

        parent_preds = self._predicate.GetParentPredicates()

        if len(parent_preds) > 0:

            if child_rows_allowed:

                for parent_pred in self._predicate.GetParentPredicates():

                    rows_of_texts_and_namespaces.append(
                        parent_pred.GetTextsAndNamespaces(render_for_user))

            elif sibling_decoration_allowed:

                parents_text = ' ({} parents)'.format(
                    HydrusData.ToHumanInt(len(parent_preds)))

                first_row_of_texts_and_namespaces.append((parents_text, ''))

        return rows_of_texts_and_namespaces
    def GetCopyableText(self, with_counts: bool = False) -> str:

        if self._predicate.GetType() == ClientSearch.PREDICATE_TYPE_NAMESPACE:

            namespace = self._predicate.GetValue()

            # this is useful for workflow
            text = '{}:*'.format(namespace)

        elif self._predicate.GetType() == ClientSearch.PREDICATE_TYPE_PARENT:

            text = HydrusTags.CleanTag(self._predicate.GetValue())

        else:

            text = self._predicate.ToString(with_count=with_counts)

        return text
Beispiel #27
0
    def SubtagExists(self, subtag):

        try:

            HydrusTags.CheckTagNotEmpty(subtag)

        except HydrusExceptions.TagSizeException:

            return False

        result = self._Execute('SELECT 1 FROM subtags WHERE subtag = ?;',
                               (subtag, )).fetchone()

        if result is None:

            return False

        else:

            return True
Beispiel #28
0
    def _IterateTagSlices(self, tag,
                          apply_unnamespaced_rules_to_namespaced_tags):

        # this guy gets called a lot, so we are making it an iterator

        yield tag

        (namespace, subtag) = HydrusTags.SplitTag(tag)

        if tag != subtag and apply_unnamespaced_rules_to_namespaced_tags:

            yield subtag

        if namespace != '':

            yield '{}:'.format(namespace)
            yield ':'

        else:

            yield ''
    def _GetTagSlices(self, tag, apply_unnamespaced_rules_to_namespaced_tags):

        (namespace, subtag) = HydrusTags.SplitTag(tag)

        tag_slices = []

        tag_slices.append(tag)

        if tag != subtag and apply_unnamespaced_rules_to_namespaced_tags:

            tag_slices.append(subtag)

        if namespace != '':

            tag_slices.append(namespace + ':')
            tag_slices.append(':')

        else:

            tag_slices.append('')

        return tag_slices
Beispiel #30
0
def GenerateExportFilename( destination_directory, media, terms, do_not_use_filenames = None ):
    
    def clean_tag_text( t ):
        
        if HC.PLATFORM_WINDOWS:
            
            t = re.sub( r'\\', '_', t )
            
        else:
            
            t = re.sub( '/', '_', t )
            
        
        return t
        
    
    if len( destination_directory ) > ( MAX_PATH_LENGTH - 10 ):
        
        raise Exception( 'The destination directory is too long!' )
        
    
    filename = ''
    
    for ( term_type, term ) in terms:
        
        tags_manager = media.GetTagsManager()
        
        if term_type == 'string':
            
            filename += term
            
        elif term_type == 'namespace':
            
            tags = tags_manager.GetNamespaceSlice( ( term, ), ClientTags.TAG_DISPLAY_ACTUAL )
            
            subtags = sorted( ( HydrusTags.SplitTag( tag )[1] for tag in tags ) )
            
            filename += clean_tag_text( ', '.join( subtags ) )
            
        elif term_type == 'predicate':
            
            if term in ( 'tags', 'nn tags' ):
                
                current = tags_manager.GetCurrent( CC.COMBINED_TAG_SERVICE_KEY, ClientTags.TAG_DISPLAY_ACTUAL )
                pending = tags_manager.GetPending( CC.COMBINED_TAG_SERVICE_KEY, ClientTags.TAG_DISPLAY_ACTUAL )
                
                tags = sorted( current.union( pending ) )
                
                if term == 'nn tags':
                    
                    tags = [ tag for tag in tags if ':' not in tag ]
                    
                else:
                    
                    tags = [ HydrusTags.SplitTag( tag )[1] for tag in tags ]
                    
                
                filename += clean_tag_text( ', '.join( tags ) )
                
            elif term == 'hash':
                
                hash = media.GetHash()
                
                filename += hash.hex()
                
            elif term == 'file_id':
                
                hash_id = media.GetHashId()
                
                filename += str( hash_id )
                
            
        elif term_type == 'tag':
            
            tag = term
            
            ( namespace, subtag ) = HydrusTags.SplitTag( tag )
            
            if tags_manager.HasTag( subtag, ClientTags.TAG_DISPLAY_ACTUAL ):
                
                filename += clean_tag_text( subtag )
                
            
        
    
    while filename.startswith( os.path.sep ):
        
        filename = filename[1:]
        
    
    if HC.PLATFORM_WINDOWS:
        
        # replace many consecutive backspace with single backspace
        filename = re.sub( '\\\\+', '\\\\', filename )
        
        # /, :, *, ?, ", <, >, |
        filename = re.sub( r'/|:|\*|\?|"|<|>|\|', '_', filename )
        
    else:
        
        filename = re.sub( '/+', '/', filename )
        
    
    #
    
    mime = media.GetMime()
    
    ext = HC.mime_ext_lookup[ mime ]
    
    if filename.endswith( ext ):
        
        filename = filename[ : - len( ext ) ]
        
    
    example_dest_path = os.path.join( destination_directory, filename + ext )
    
    excess_chars = len( example_dest_path ) - MAX_PATH_LENGTH
    
    if excess_chars > 0:
        
        filename = filename[ : - excess_chars ]
        
    
    if do_not_use_filenames is not None:
        
        i = 1
        
        possible_filename = '{}{}'.format( filename, ext )
        
        while possible_filename in do_not_use_filenames:
            
            possible_filename = '{} ({}){}'.format( filename, i, ext )
            
            i += 1
            
        
        filename = possible_filename
        
    else:
        
        filename += ext
        
    
    return filename