Add TagKey

- tags generated automatically & managed by the system & extractors
- can be found by searching for their tag keys
master
Felix Stupp 1 year ago
parent b5ac2ab931
commit c5eb23ebff
Signed by: zocker
GPG Key ID: 93E1BD26F6B02FB7

@ -13,6 +13,7 @@ from .entities import (
MediaUriMapping,
Tag,
Tagable,
TagKey,
are_multiple_considered,
db,
get_all_considered,

@ -192,6 +192,8 @@ class Tag(db.Entity, Tagable, TagProto["Tag"]):
use_for_preferences: bool = orm.Required(bool, default=True)
tag_keys: Iterable[TagKey] = orm.Set(lambda: TagKey)
super_tag_list: Iterable[Tag] = orm.Set(lambda: Tag, reverse="sub_tag_list")
sub_tag_list: Iterable[Tag] = orm.Set(lambda: Tag, reverse="super_tag_list")
@ -207,6 +209,78 @@ class Tag(db.Entity, Tagable, TagProto["Tag"]):
return self.super_tag_list
class TagKey(db.Entity):
num_id: int = orm.PrimaryKey(int, auto=True)
tag_key: str = orm.Required(str, unique=True)
"""Format: <domain>[/<kind>][/<id>]
These IDs are distinctive of URLs.
Multiple sub-kinds can be used if required.
They should not contain unnecceray information
like names, titles, descriptions, dates
(or only when part of the one unique ID).
Domains must be used in reverse domain name notation
to allow for efficient prefix searches.
Domains must not start or end with a ".",
all domains are meant to be absolute.
Internal identifiers should use "." as domain and should omit the first "/"
to avoid collisions with TLDs,
e.g. ".automatic/collection/<id>".
Identifiers from extractors which want to avoid collisions
because of multiple ones supporting the same site
should choose a domain for their own product
and use the format: <extractor-domain>/<source-domain>[/<kind>][/<id>]
"""
tag: Tag = orm.Required(Tag)
@classmethod
def get_by_prefix(cls, tag_key_prefix: str) -> Set[Tag]:
key_set = orm.select(
key for key in cls if key.tag_key.startswith(tag_key_prefix)
)
return {key.tag for key in key_set}
@classmethod
def get_or_create_tag(
cls,
tag_key: str,
title: Optional[str] = None,
notes: Optional[str] = None,
use_for_preferences: bool = False,
super_tags: Iterable[str] = [],
) -> Tag:
tag = cls.get_tag(tag_key)
if tag is not None:
if title is not None and not tag.title:
tag.title = title
if notes is not None and not tag.notes:
tag.notes = notes
if tag is None:
tag = Tag(
title=title,
notes=notes,
use_for_preferences=use_for_preferences,
)
cls(
tag_key=tag_key,
tag=tag,
)
for super_tag_key in super_tags:
super_tag = cls.get_tag(tag_key=super_tag_key)
if super_tag is not None:
tag.super_tag_list.add(super_tag)
return tag
@classmethod
def get_tag(cls, tag_key: str) -> Optional[Tag]:
tag: Tag = orm.select(key.tag for key in cls if key.tag_key == tag_key).first()
return tag if tag is not None else None
## Element <-> Collection Linking

Loading…
Cancel
Save