diff --git a/catalog/book/models.py b/catalog/book/models.py index 3fbefe83..8598402b 100644 --- a/catalog/book/models.py +++ b/catalog/book/models.py @@ -23,6 +23,7 @@ from django.db import models from django.utils.translation import gettext_lazy as _ from loguru import logger +from ninja import Field from catalog.common import ( BaseSchema, @@ -36,18 +37,23 @@ PrimaryLookupIdDescriptor, jsondata, ) -from catalog.common.models import SCRIPT_CHOICES +from catalog.common.models import ( + LOCALE_CHOICES_JSONFORM, + SCRIPT_CHOICES, + LanguageListField, +) +from common.models.lang import get_current_locales from common.models.misc import uniq from .utils import * class EditionInSchema(ItemInSchema): - subtitle: str | None = None + subtitle: str | None = Field(default=None, alias="display_subtitle") orig_title: str | None = None author: list[str] translator: list[str] - language: str | None = None + language: list[str] pub_house: str | None = None pub_year: int | None = None pub_month: int | None = None @@ -63,6 +69,45 @@ class EditionSchema(EditionInSchema, BaseSchema): pass +EDITION_LOCALIZED_TITLE_SCHEMA = { + "type": "list", + "items": { + "type": "dict", + "keys": { + "lang": { + "type": "string", + "title": _("locale"), + "choices": LOCALE_CHOICES_JSONFORM, + }, + "text": {"type": "string", "title": _("text content")}, + }, + "required": ["lang", "s"], + }, + "minItems": 1, + "maxItems": 1, + # "uniqueItems": True, +} + +EDITION_LOCALIZED_SUBTITLE_SCHEMA = { + "type": "list", + "items": { + "type": "dict", + "keys": { + "lang": { + "type": "string", + "title": _("locale"), + "choices": LOCALE_CHOICES_JSONFORM, + }, + "text": {"type": "string", "title": _("text content")}, + }, + "required": ["lang", "s"], + }, + "minItems": 0, + "maxItems": 1, + # "uniqueItems": True, +} + + class Edition(Item): if TYPE_CHECKING: works: "models.ManyToManyField[Work, Edition]" @@ -76,8 +121,10 @@ class Edition(Item): # goodreads = LookupIdDescriptor(IdType.Goodreads) METADATA_COPY_LIST = [ - "title", - "subtitle", + "localized_title", + "localized_subtitle", + # "title", + # "subtitle", "author", "pub_house", "pub_year", @@ -94,9 +141,18 @@ class Edition(Item): "localized_description", "contents", ] - subtitle = jsondata.CharField( - _("subtitle"), null=True, blank=True, default=None, max_length=500 + # force Edition to have only one title + localized_title_schema = EDITION_LOCALIZED_TITLE_SCHEMA + localized_subtitle = jsondata.JSONField( + verbose_name=_("subtitle"), + null=False, + blank=True, + default=list, + schema=EDITION_LOCALIZED_SUBTITLE_SCHEMA, ) + # subtitle = jsondata.CharField( + # _("subtitle"), null=True, blank=True, default=None, max_length=500 + # ) orig_title = jsondata.CharField( _("original title"), null=True, blank=True, default=None, max_length=500 ) @@ -114,14 +170,7 @@ class Edition(Item): blank=True, default=list, ) - language = jsondata.CharField( - _("language"), - null=False, - blank=True, - default=None, - max_length=500, - choices=SCRIPT_CHOICES, - ) + language = LanguageListField() pub_house = jsondata.CharField( _("publishing house"), null=True, blank=False, default=None, max_length=500 ) @@ -148,6 +197,13 @@ class Edition(Item): price = jsondata.CharField(_("price"), null=True, blank=True, max_length=500) imprint = jsondata.CharField(_("imprint"), null=True, blank=True, max_length=500) + def get_localized_subtitle(self) -> str | None: + return self.localized_title[0]["text"] if self.localized_subtitle else None + + @property + def display_subtitle(self) -> str | None: + return self.get_localized_subtitle() + @property def isbn10(self): return isbn_13_to_10(self.isbn) @@ -265,6 +321,7 @@ class Work(Item): douban_work = PrimaryLookupIdDescriptor(IdType.DoubanBook_Work) goodreads_work = PrimaryLookupIdDescriptor(IdType.Goodreads_Work) editions = models.ManyToManyField(Edition, related_name="works") + language = LanguageListField() author = jsondata.ArrayField( verbose_name=_("author"), base_field=models.CharField(max_length=500), @@ -272,18 +329,18 @@ class Work(Item): blank=True, default=list, ) - other_title = jsondata.ArrayField( - verbose_name=_("other title"), - base_field=models.CharField(blank=True, default="", max_length=200), - null=True, - blank=True, - default=list, - ) + # other_title = jsondata.ArrayField( + # verbose_name=_("other title"), + # base_field=models.CharField(blank=True, default="", max_length=200), + # null=True, + # blank=True, + # default=list, + # ) METADATA_COPY_LIST = [ - "title", - "other_title", + "localized_title", "author", - "brief", + "language", + "localized_description", ] # TODO: we have many duplicates due to 302 # a lazy fix is to remove smaller DoubanBook_Work ids diff --git a/catalog/common/jsondata.py b/catalog/common/jsondata.py index 5c544cb8..920fa2e3 100644 --- a/catalog/common/jsondata.py +++ b/catalog/common/jsondata.py @@ -15,6 +15,7 @@ from django.utils import dateparse, timezone from django.utils.encoding import force_bytes from django.utils.translation import gettext_lazy as _ +from django_jsonform.forms.fields import JSONFormField as DJANGO_JSONFormField # from django.db.models import JSONField as DJANGO_JSONField # from jsoneditor.fields.django3_jsonfield import JSONField as DJANGO_JSONField @@ -24,6 +25,20 @@ from loguru import logger +class Patched_DJANGO_JSONField(DJANGO_JSONField): + def formfield(self, **kwargs): + schema = getattr(self.model, self.attname + "_schema", self.schema) + return super().formfield( + **{ + "form_class": DJANGO_JSONFormField, + "schema": schema, + "model_name": self.model.__name__, + "file_handler": self.file_handler, + **kwargs, + } + ) + + def _get_crypter(): configured_keys = [settings.SECRET_KEY] + settings.SECRET_KEY_FALLBACKS keys = [Fernet(b64encode(sha256(force_bytes(k)).digest())) for k in configured_keys] @@ -299,7 +314,7 @@ def from_json(self, value): # backward compatible with dirty legacy data return [] -class JSONField(JSONFieldMixin, DJANGO_JSONField): +class JSONField(JSONFieldMixin, Patched_DJANGO_JSONField): pass diff --git a/catalog/common/models.py b/catalog/common/models.py index efe8f327..55c53480 100644 --- a/catalog/common/models.py +++ b/catalog/common/models.py @@ -268,13 +268,15 @@ class LocalizedTitleSchema(Schema): class ItemInSchema(Schema): - title: str - brief: str + title: str = Field(alias="display_title") + description: str = Field(default=None, alias="display_description") localized_title: list[LocalizedTitleSchema] = [] localized_description: list[LocalizedTitleSchema] = [] cover_image_url: str | None rating: float | None rating_count: int | None + # brief is deprecated + brief: str = Field(deprecated=True, alias="display_description") class ItemSchema(BaseSchema, ItemInSchema): @@ -296,13 +298,14 @@ def get_locale_choices_for_jsonform(choices): "keys": { "lang": { "type": "string", - "title": _("language"), + "title": _("locale"), "choices": LOCALE_CHOICES_JSONFORM, }, - "text": {"type": "string", "title": _("content")}, + "text": {"type": "string", "title": _("text content")}, }, "required": ["lang", "s"], }, + "minItems": 1, "uniqueItems": True, } @@ -313,10 +316,14 @@ def get_locale_choices_for_jsonform(choices): "keys": { "lang": { "type": "string", - "title": _("language"), + "title": _("locale"), "choices": LOCALE_CHOICES_JSONFORM, }, - "text": {"type": "string", "title": _("content"), "widget": "textarea"}, + "text": { + "type": "string", + "title": _("text content"), + "widget": "textarea", + }, }, "required": ["lang", "s"], }, @@ -669,8 +676,8 @@ def update_lookup_ids(self, lookup_ids: list[tuple[str, str]]): self.primary_lookup_id_value = v METADATA_COPY_LIST = [ - "title", - "brief", + # "title", + # "brief", "localized_title", "localized_description", ] # list of metadata keys to copy from resource to item diff --git a/catalog/game/models.py b/catalog/game/models.py index 404f7e55..dd275b57 100644 --- a/catalog/game/models.py +++ b/catalog/game/models.py @@ -43,7 +43,6 @@ class Game(Item): # "brief", # "other_title", "localized_title", - "localized_description", "designer", "artist", "developer", @@ -53,6 +52,7 @@ class Game(Item): "genre", "platform", "official_site", + "localized_description", ] other_title = jsondata.ArrayField( diff --git a/catalog/management/commands/catalog.py b/catalog/management/commands/catalog.py index e9020784..e484042e 100644 --- a/catalog/management/commands/catalog.py +++ b/catalog/management/commands/catalog.py @@ -1,4 +1,5 @@ import pprint +import re from django.contrib.contenttypes.models import ContentType from django.core.management.base import BaseCommand @@ -51,20 +52,36 @@ def handle(self, *args, **options): self.stdout.write(self.style.SUCCESS(f"Done.")) def localize(self): - for i in tqdm(Item.objects.all()): + for i in tqdm( + Item.objects.filter(is_deleted=False, merged_to_item__isnull=True) + ): localized_title = [{"lang": detect_language(i.title), "text": i.title}] - if hasattr(i, "orig_title") and i.orig_title: # type:ignore - localized_title += [ - { - "lang": detect_language(i.orig_title), # type:ignore - "text": i.orig_title, # type:ignore - } - ] - if hasattr(i, "other_title") and i.other_title: # type:ignore - for title in i.other_title: # type:ignore - localized_title += [{"lang": detect_language(title), "text": title}] - localized_desc = [{"lang": detect_language(i.brief), "text": i.brief}] + if i.__class__ != Edition: + if hasattr(i, "orig_title") and i.orig_title: # type:ignore + localized_title += [ + { + "lang": detect_language(i.orig_title), # type:ignore + "text": i.orig_title, # type:ignore + } + ] + if hasattr(i, "other_title") and i.other_title: # type:ignore + for title in i.other_title: # type:ignore + localized_title += [ + {"lang": detect_language(title), "text": title} + ] + else: + # Edition has no other_title + subtitle = i.metadata.get("subtitle") + i.metadata["localized_subtitle"] = ( + [{"lang": detect_language(subtitle), "text": subtitle}] + if subtitle + else [] + ) + lang = i.metadata.get("language") + if isinstance(lang, str): + i.metadata["language"] = [lang] i.localized_title = uniq(localized_title) + localized_desc = [{"lang": detect_language(i.brief), "text": i.brief}] i.localized_description = localized_desc i.save(update_fields=["metadata"]) diff --git a/catalog/movie/models.py b/catalog/movie/models.py index 10a0be6d..ee009915 100644 --- a/catalog/movie/models.py +++ b/catalog/movie/models.py @@ -44,10 +44,10 @@ class Movie(Item): douban_movie = PrimaryLookupIdDescriptor(IdType.DoubanMovie) METADATA_COPY_LIST = [ - "title", + # "title", + # "other_title", "localized_title", "orig_title", - # "other_title", "director", "playwright", "actor", diff --git a/catalog/podcast/models.py b/catalog/podcast/models.py index 99f2fd2f..20ffcb48 100644 --- a/catalog/podcast/models.py +++ b/catalog/podcast/models.py @@ -2,6 +2,8 @@ from django.db import models from django.utils.translation import gettext_lazy as _ +from ninja import Field +from typing_extensions import deprecated from catalog.common import ( BaseSchema, @@ -20,8 +22,11 @@ class PodcastInSchema(ItemInSchema): genre: list[str] - hosts: list[str] + host: list[str] + language: list[str] official_site: str | None = None + # hosts is deprecated + hosts: list[str] = Field(deprecated=True, alias="host") class PodcastSchema(PodcastInSchema, BaseSchema): @@ -61,11 +66,11 @@ class Podcast(Item): # "title", # "brief", "localized_title", - "localized_description", "language", "hosts", "genre", "official_site", + "localized_description", ] @classmethod diff --git a/catalog/search/typesense.py b/catalog/search/typesense.py index 8e0ba9e5..ccb263ec 100644 --- a/catalog/search/typesense.py +++ b/catalog/search/typesense.py @@ -16,10 +16,9 @@ from catalog.models import Item SEARCHABLE_ATTRIBUTES = [ - "title", + "localized_title", + "localized_subtitle", "orig_title", - "other_title", - "subtitle", "artist", "author", "translator", @@ -145,23 +144,29 @@ def config(cls): {"name": "author", "optional": True, "locale": "zh", "type": "string[]"}, {"name": "orig_title", "optional": True, "locale": "zh", "type": "string"}, {"name": "pub_house", "optional": True, "locale": "zh", "type": "string"}, - {"name": "title", "optional": True, "locale": "zh", "type": "string"}, + # {"name": "title", "optional": True, "locale": "zh", "type": "string"}, { - "name": "translator", + "name": "localized_title", + "optional": True, + "locale": "zh", + "type": "string[]", + }, + # {"name": "subtitle", "optional": True, "locale": "zh", "type": "string"}, + { + "name": "localized_subtitle", "optional": True, "locale": "zh", "type": "string[]", }, - {"name": "subtitle", "optional": True, "locale": "zh", "type": "string"}, - {"name": "artist", "optional": True, "locale": "zh", "type": "string[]"}, - {"name": "company", "optional": True, "locale": "zh", "type": "string[]"}, - {"name": "developer", "optional": True, "locale": "zh", "type": "string[]"}, { - "name": "other_title", + "name": "translator", "optional": True, "locale": "zh", "type": "string[]", }, + {"name": "artist", "optional": True, "locale": "zh", "type": "string[]"}, + {"name": "company", "optional": True, "locale": "zh", "type": "string[]"}, + {"name": "developer", "optional": True, "locale": "zh", "type": "string[]"}, {"name": "publisher", "optional": True, "locale": "zh", "type": "string[]"}, {"name": "actor", "optional": True, "locale": "zh", "type": "string[]"}, {"name": "director", "optional": True, "locale": "zh", "type": "string[]"}, @@ -252,7 +257,8 @@ def update_model_indexable(cls, model): model.indexable_fields.append(field.name) elif type in INDEXABLE_TIME_TYPES: model.indexable_fields_time.append(field.name) - elif type in INDEXABLE_DICT_TYPES: + elif type in INDEXABLE_DICT_TYPES and field.name != "metadata": + # ignore metadata since it holds other fields model.indexable_fields_dict.append(field.name) elif type in INDEXABLE_FLOAT_TYPES: model.indexable_fields_float.append(field.name) @@ -287,9 +293,8 @@ def obj_to_dict(cls, obj): for field in obj.__class__.indexable_fields_float: item[field] = float(getattr(obj, field)) if getattr(obj, field) else None for field in obj.__class__.indexable_fields_dict: - d = getattr(obj, field) - if d.__class__ is dict: - item.update(d) + if field.startswith("localized_"): + item[field] = [t["text"] for t in getattr(obj, field, [])] item["id"] = obj.uuid item["category"] = obj.category.value @@ -302,7 +307,6 @@ def obj_to_dict(cls, obj): } # typesense requires primary key to be named 'id', type string item["rating_count"] = obj.rating_count - return item @classmethod diff --git a/catalog/tv/models.py b/catalog/tv/models.py index cf9eae04..e97219c3 100644 --- a/catalog/tv/models.py +++ b/catalog/tv/models.py @@ -270,11 +270,12 @@ class TVSeason(Item): ) METADATA_COPY_LIST = [ - "title", + # "title", + "localized_title", "season_number", "episode_count", "orig_title", - "other_title", + # "other_title", "director", "playwright", "actor", @@ -286,7 +287,8 @@ class TVSeason(Item): "year", "duration", "single_episode_length", - "brief", + "localized_description", + # "brief", ] orig_title = jsondata.CharField( verbose_name=_("original title"), blank=True, default="", max_length=500 diff --git a/common/models/lang.py b/common/models/lang.py index 9564d8fe..f797fb64 100644 --- a/common/models/lang.py +++ b/common/models/lang.py @@ -303,14 +303,27 @@ def get_current_locales() -> list[str]: return ["en"] if lng[0] == "en" else [lng[0], "en"] -_eng = re.compile(r"^[A-Za-z0-9\s]{1,13}$") +_eng = re.compile(r"^[A-Za-z0-9]+$") +_chn = re.compile( + r"^[\u4E00-\u9FFF\u3400-\u4DBF\uF900-\uFAFF\uff01-\uff5e\s,。、·︰:— 0-9\-\(\)]+$" +) +# https://github.com/BYVoid/OpenCC/blob/master/data/dictionary/TSCharacters.txt +# print("".join([l.split("\t", 1)[0] for l in open("TSCharacters.txt", "r")])) +_tc_char = "㑮㑯㑳㑶㒓㓄㓨㔋㖮㗲㗿㘉㘓㘔㘚㛝㜄㜏㜐㜗㜢㜷㞞㟺㠏㠣㢗㢝㥮㦎㦛㦞㨻㩋㩜㩳㩵㪎㯤㰙㵗㵾㶆㷍㷿㸇㹽㺏㺜㻶㿖㿗㿧䀉䀹䁪䁻䂎䃮䅐䅳䆉䉑䉙䉬䉲䉶䊭䊷䊺䋃䋔䋙䋚䋦䋹䋻䋼䋿䌈䌋䌖䌝䌟䌥䌰䍤䍦䍽䎙䎱䓣䕤䕳䖅䗅䗿䙔䙡䙱䚩䛄䛳䜀䜖䝭䝻䝼䞈䞋䞓䟃䟆䟐䠆䠱䡐䡩䡵䢨䤤䥄䥇䥑䥕䥗䥩䥯䥱䦘䦛䦟䦯䦳䧢䪊䪏䪗䪘䪴䪾䫀䫂䫟䫴䫶䫻䫾䬓䬘䬝䬞䬧䭀䭃䭑䭔䭿䮄䮝䮞䮠䮫䮰䮳䮾䯀䯤䰾䱀䱁䱙䱧䱬䱰䱷䱸䱽䲁䲅䲖䲘䲰䳜䳢䳤䳧䳫䴉䴋䴬䴱䴴䴽䵳䵴䶕䶲丟並乾亂亙亞佇佈佔併來侖侶侷俁係俓俔俠俥俬倀倆倈倉個們倖倫倲偉偑側偵偽傌傑傖傘備傢傭傯傳傴債傷傾僂僅僉僑僕僞僤僥僨僱價儀儁儂億儈儉儎儐儔儕儘償儣優儭儲儷儸儺儻儼兇兌兒兗內兩冊冑冪凈凍凙凜凱別刪剄則剋剎剗剛剝剮剴創剷剾劃劇劉劊劌劍劏劑劚勁勑動務勛勝勞勢勣勩勱勳勵勸勻匭匯匱區協卹卻卽厙厠厤厭厲厴參叄叢吒吳吶呂咼員哯唄唓唸問啓啞啟啢喎喚喪喫喬單喲嗆嗇嗊嗎嗚嗩嗰嗶嗹嘆嘍嘓嘔嘖嘗嘜嘩嘪嘮嘯嘰嘳嘵嘸嘺嘽噁噅噓噚噝噞噠噥噦噯噲噴噸噹嚀嚇嚌嚐嚕嚙嚛嚥嚦嚧嚨嚮嚲嚳嚴嚶嚽囀囁囂囃囅囈囉囌囑囒囪圇國圍園圓圖團圞垻埡埨埬埰執堅堊堖堚堝堯報場塊塋塏塒塗塚塢塤塵塸塹塿墊墜墠墮墰墲墳墶墻墾壇壈壋壎壓壗壘壙壚壜壞壟壠壢壣壩壪壯壺壼壽夠夢夥夾奐奧奩奪奬奮奼妝姍姦娙娛婁婡婦婭媈媧媯媰媼媽嫋嫗嫵嫺嫻嫿嬀嬃嬇嬈嬋嬌嬙嬡嬣嬤嬦嬪嬰嬸嬻孃孄孆孇孋孌孎孫學孻孾孿宮寀寠寢實寧審寫寬寵寶將專尋對導尷屆屍屓屜屢層屨屩屬岡峯峴島峽崍崑崗崙崢崬嵐嵗嵼嵽嵾嶁嶄嶇嶈嶔嶗嶘嶠嶢嶧嶨嶮嶸嶹嶺嶼嶽巊巋巒巔巖巗巘巰巹帥師帳帶幀幃幓幗幘幝幟幣幩幫幬幹幾庫廁廂廄廈廎廕廚廝廞廟廠廡廢廣廧廩廬廳弒弔弳張強彃彄彆彈彌彎彔彙彠彥彫彲彷彿後徑從徠復徵徹徿恆恥悅悞悵悶悽惡惱惲惻愛愜愨愴愷愻愾慄態慍慘慚慟慣慤慪慫慮慳慶慺慼慾憂憊憐憑憒憖憚憢憤憫憮憲憶憸憹懀懇應懌懍懎懞懟懣懤懨懲懶懷懸懺懼懾戀戇戔戧戩戰戱戲戶拋挩挱挾捨捫捱捲掃掄掆掗掙掚掛採揀揚換揮揯損搖搗搵搶摋摐摑摜摟摯摳摶摺摻撈撊撏撐撓撝撟撣撥撧撫撲撳撻撾撿擁擄擇擊擋擓擔據擟擠擣擫擬擯擰擱擲擴擷擺擻擼擽擾攄攆攋攏攔攖攙攛攜攝攢攣攤攪攬敎敓敗敘敵數斂斃斅斆斕斬斷斸於旂旣昇時晉晛晝暈暉暐暘暢暫曄曆曇曉曊曏曖曠曥曨曬書會朥朧朮東枴柵柺査桱桿梔梖梘梜條梟梲棄棊棖棗棟棡棧棲棶椏椲楇楊楓楨業極榘榦榪榮榲榿構槍槓槤槧槨槫槮槳槶槼樁樂樅樑樓標樞樠樢樣樤樧樫樳樸樹樺樿橈橋機橢橫橯檁檉檔檜檟檢檣檭檮檯檳檵檸檻櫃櫅櫍櫓櫚櫛櫝櫞櫟櫠櫥櫧櫨櫪櫫櫬櫱櫳櫸櫻欄欅欇權欍欏欐欑欒欓欖欘欞欽歎歐歟歡歲歷歸歿殘殞殢殤殨殫殭殮殯殰殲殺殻殼毀毆毊毿氂氈氌氣氫氬氭氳氾汎汙決沒沖況泝洩洶浹浿涇涗涼淒淚淥淨淩淪淵淶淺渙減渢渦測渾湊湋湞湧湯溈準溝溡溫溮溳溼滄滅滌滎滙滬滯滲滷滸滻滾滿漁漊漍漚漢漣漬漲漵漸漿潁潑潔潕潙潚潛潣潤潯潰潷潿澀澅澆澇澐澗澠澤澦澩澫澬澮澱澾濁濃濄濆濕濘濚濛濜濟濤濧濫濰濱濺濼濾濿瀂瀃瀅瀆瀇瀉瀋瀏瀕瀘瀝瀟瀠瀦瀧瀨瀰瀲瀾灃灄灍灑灒灕灘灙灝灡灣灤灧灩災為烏烴無煇煉煒煙煢煥煩煬煱熂熅熉熌熒熓熗熚熡熰熱熲熾燀燁燈燉燒燖燙燜營燦燬燭燴燶燻燼燾爃爄爇爍爐爖爛爥爧爭爲爺爾牀牆牘牴牽犖犛犞犢犧狀狹狽猌猙猶猻獁獃獄獅獊獎獨獩獪獫獮獰獱獲獵獷獸獺獻獼玀玁珼現琱琺琿瑋瑒瑣瑤瑩瑪瑲瑻瑽璉璊璕璗璝璡璣璦璫璯環璵璸璼璽璾璿瓄瓅瓊瓏瓔瓕瓚瓛甌甕產産甦甯畝畢畫異畵當畼疇疊痙痠痮痾瘂瘋瘍瘓瘞瘡瘧瘮瘱瘲瘺瘻療癆癇癉癐癒癘癟癡癢癤癥癧癩癬癭癮癰癱癲發皁皚皟皰皸皺盃盜盞盡監盤盧盨盪眝眞眥眾睍睏睜睞瞘瞜瞞瞤瞭瞶瞼矇矉矑矓矚矯硃硜硤硨硯碕碙碩碭碸確碼碽磑磚磠磣磧磯磽磾礄礆礎礐礒礙礦礪礫礬礮礱祇祕祿禍禎禕禡禦禪禮禰禱禿秈稅稈稏稜稟種稱穀穇穌積穎穠穡穢穩穫穭窩窪窮窯窵窶窺竄竅竇竈竊竚竪竱競筆筍筧筴箇箋箏節範築篋篔篘篠篢篤篩篳篸簀簂簍簑簞簡簢簣簫簹簽簾籃籅籋籌籔籙籛籜籟籠籤籩籪籬籮籲粵糉糝糞糧糰糲糴糶糹糺糾紀紂紃約紅紆紇紈紉紋納紐紓純紕紖紗紘紙級紛紜紝紞紟紡紬紮細紱紲紳紵紹紺紼紿絀絁終絃組絅絆絍絎結絕絙絛絝絞絡絢絥給絧絨絪絰統絲絳絶絹絺綀綁綃綄綆綇綈綉綋綌綎綏綐綑經綖綜綝綞綟綠綡綢綣綧綪綫綬維綯綰綱網綳綴綵綸綹綺綻綽綾綿緄緇緊緋緍緑緒緓緔緗緘緙線緝緞緟締緡緣緤緦編緩緬緮緯緰緱緲練緶緷緸緹緻緼縈縉縊縋縍縎縐縑縕縗縛縝縞縟縣縧縫縬縭縮縯縰縱縲縳縴縵縶縷縸縹縺總績繂繃繅繆繈繏繐繒繓織繕繚繞繟繡繢繨繩繪繫繬繭繮繯繰繳繶繷繸繹繻繼繽繾繿纁纆纇纈纊續纍纏纓纔纕纖纗纘纚纜缽罃罈罌罎罰罵罷羅羆羈羋羣羥羨義羵羶習翫翬翹翽耬耮聖聞聯聰聲聳聵聶職聹聻聽聾肅脅脈脛脣脥脩脫脹腎腖腡腦腪腫腳腸膃膕膚膞膠膢膩膹膽膾膿臉臍臏臗臘臚臟臠臢臥臨臺與興舉舊舘艙艣艤艦艫艱艷芻苧茲荊莊莖莢莧菕華菴菸萇萊萬萴萵葉葒葝葤葦葯葷蒍蒐蒓蒔蒕蒞蒭蒼蓀蓆蓋蓧蓮蓯蓴蓽蔄蔔蔘蔞蔣蔥蔦蔭蔯蔿蕁蕆蕎蕒蕓蕕蕘蕝蕢蕩蕪蕭蕳蕷蕽薀薆薈薊薌薑薔薘薟薦薩薳薴薵薹薺藉藍藎藝藥藪藭藴藶藷藹藺蘀蘄蘆蘇蘊蘋蘚蘞蘟蘢蘭蘺蘿虆虉處虛虜號虧虯蛺蛻蜆蝀蝕蝟蝦蝨蝸螄螞螢螮螻螿蟂蟄蟈蟎蟘蟜蟣蟬蟯蟲蟳蟶蟻蠀蠁蠅蠆蠍蠐蠑蠔蠙蠟蠣蠦蠨蠱蠶蠻蠾衆衊術衕衚衛衝衹袞裊裏補裝裡製複褌褘褲褳褸褻襀襇襉襏襓襖襗襘襝襠襤襪襬襯襰襲襴襵覆覈見覎規覓視覘覛覡覥覦親覬覯覲覷覹覺覼覽覿觀觴觶觸訁訂訃計訊訌討訏訐訑訒訓訕訖託記訛訜訝訞訟訢訣訥訨訩訪設許訴訶診註証詀詁詆詊詎詐詑詒詓詔評詖詗詘詛詝詞詠詡詢詣試詩詪詫詬詭詮詰話該詳詵詷詼詿誂誄誅誆誇誋誌認誑誒誕誘誚語誠誡誣誤誥誦誨說誫説誰課誳誴誶誷誹誺誼誾調諂諄談諉請諍諏諑諒諓論諗諛諜諝諞諟諡諢諣諤諥諦諧諫諭諮諯諰諱諲諳諴諶諷諸諺諼諾謀謁謂謄謅謆謉謊謎謏謐謔謖謗謙謚講謝謠謡謨謫謬謭謯謱謳謸謹謾譁譂譅譆證譊譎譏譑譓譖識譙譚譜譞譟譨譫譭譯議譴護譸譽譾讀讅變讋讌讎讒讓讕讖讚讜讞豈豎豐豔豬豵豶貓貗貙貝貞貟負財貢貧貨販貪貫責貯貰貲貳貴貶買貸貺費貼貽貿賀賁賂賃賄賅資賈賊賑賒賓賕賙賚賜賝賞賟賠賡賢賣賤賦賧質賫賬賭賰賴賵賺賻購賽賾贃贄贅贇贈贉贊贋贍贏贐贑贓贔贖贗贚贛贜赬趕趙趨趲跡踐踰踴蹌蹔蹕蹟蹠蹣蹤蹳蹺蹻躂躉躊躋躍躎躑躒躓躕躘躚躝躡躥躦躪軀軉車軋軌軍軏軑軒軔軕軗軛軜軝軟軤軨軫軬軲軷軸軹軺軻軼軾軿較輄輅輇輈載輊輋輒輓輔輕輖輗輛輜輝輞輟輢輥輦輨輩輪輬輮輯輳輶輷輸輻輼輾輿轀轂轄轅轆轇轉轊轍轎轐轔轗轟轠轡轢轣轤辦辭辮辯農迴逕這連週進遊運過達違遙遜遞遠遡適遱遲遷選遺遼邁還邇邊邏邐郟郵鄆鄉鄒鄔鄖鄟鄧鄩鄭鄰鄲鄳鄴鄶鄺酇酈醃醖醜醞醟醣醫醬醱醲醶釀釁釃釅釋釐釒釓釔釕釗釘釙釚針釟釣釤釦釧釨釩釲釳釴釵釷釹釺釾釿鈀鈁鈃鈄鈅鈆鈇鈈鈉鈋鈍鈎鈐鈑鈒鈔鈕鈖鈗鈛鈞鈠鈡鈣鈥鈦鈧鈮鈯鈰鈲鈳鈴鈷鈸鈹鈺鈽鈾鈿鉀鉁鉅鉆鉈鉉鉊鉋鉍鉑鉔鉕鉗鉚鉛鉝鉞鉠鉢鉤鉥鉦鉧鉬鉭鉮鉳鉶鉷鉸鉺鉻鉽鉾鉿銀銁銂銃銅銈銊銍銏銑銓銖銘銚銛銜銠銣銥銦銨銩銪銫銬銱銳銶銷銹銻銼鋁鋂鋃鋅鋇鋉鋌鋏鋐鋒鋗鋙鋝鋟鋠鋣鋤鋥鋦鋨鋩鋪鋭鋮鋯鋰鋱鋶鋸鋹鋼錀錁錂錄錆錇錈錏錐錒錕錘錙錚錛錜錝錞錟錠錡錢錤錥錦錨錩錫錮錯録錳錶錸錼錽鍀鍁鍃鍄鍅鍆鍇鍈鍉鍊鍋鍍鍒鍔鍘鍚鍛鍠鍤鍥鍩鍬鍭鍮鍰鍵鍶鍺鍼鍾鎂鎄鎇鎈鎊鎌鎍鎓鎔鎖鎘鎙鎚鎛鎝鎞鎡鎢鎣鎦鎧鎩鎪鎬鎭鎮鎯鎰鎲鎳鎵鎶鎷鎸鎿鏃鏆鏇鏈鏉鏌鏍鏏鏐鏑鏗鏘鏚鏜鏝鏞鏟鏡鏢鏤鏥鏦鏨鏰鏵鏷鏹鏺鏻鏽鏾鐃鐄鐇鐈鐋鐍鐎鐏鐐鐒鐓鐔鐘鐙鐝鐠鐥鐦鐧鐨鐩鐪鐫鐮鐯鐲鐳鐵鐶鐸鐺鐼鐽鐿鑀鑄鑉鑊鑌鑑鑒鑔鑕鑞鑠鑣鑥鑪鑭鑰鑱鑲鑴鑷鑹鑼鑽鑾鑿钁钂長門閂閃閆閈閉開閌閍閎閏閐閑閒間閔閗閘閝閞閡閣閤閥閨閩閫閬閭閱閲閵閶閹閻閼閽閾閿闃闆闇闈闉闊闋闌闍闐闑闒闓闔闕闖關闞闠闡闢闤闥阪陘陝陞陣陰陳陸陽隉隊階隑隕際隤隨險隮隯隱隴隸隻雋雖雙雛雜雞離難雲電霑霢霣霧霼霽靂靄靆靈靉靚靜靝靦靧靨鞏鞝鞦鞽鞾韁韃韆韉韋韌韍韓韙韚韛韜韝韞韠韻響頁頂頃項順頇須頊頌頍頎頏預頑頒頓頔頗領頜頠頡頤頦頫頭頮頰頲頴頵頷頸頹頻頽顂顃顅顆題額顎顏顒顓顔顗願顙顛類顢顣顥顧顫顬顯顰顱顳顴風颭颮颯颰颱颳颶颷颸颺颻颼颾飀飄飆飈飋飛飠飢飣飥飦飩飪飫飭飯飱飲飴飵飶飼飽飾飿餃餄餅餈餉養餌餎餏餑餒餓餔餕餖餗餘餚餛餜餞餡餦餧館餪餫餬餭餱餳餵餶餷餸餺餼餾餿饁饃饅饈饉饊饋饌饑饒饗饘饜饞饟饠饢馬馭馮馯馱馳馴馹馼駁駃駉駊駎駐駑駒駓駔駕駘駙駚駛駝駞駟駡駢駤駧駩駪駫駭駰駱駶駸駻駼駿騁騂騃騄騅騉騊騌騍騎騏騑騔騖騙騚騜騝騞騟騠騤騧騪騫騭騮騰騱騴騵騶騷騸騻騼騾驀驁驂驃驄驅驊驋驌驍驎驏驓驕驗驙驚驛驟驢驤驥驦驨驪驫骯髏髒體髕髖髮鬆鬍鬖鬚鬠鬢鬥鬧鬨鬩鬮鬱鬹魎魘魚魛魟魢魥魦魨魯魴魵魷魺魽鮀鮁鮃鮄鮅鮆鮈鮊鮋鮍鮎鮐鮑鮒鮓鮚鮜鮝鮞鮟鮠鮡鮣鮤鮦鮪鮫鮭鮮鮯鮰鮳鮵鮶鮸鮺鮿鯀鯁鯄鯆鯇鯉鯊鯒鯔鯕鯖鯗鯛鯝鯞鯡鯢鯤鯧鯨鯪鯫鯬鯰鯱鯴鯶鯷鯻鯽鯾鯿鰁鰂鰃鰆鰈鰉鰊鰋鰌鰍鰏鰐鰑鰒鰓鰕鰛鰜鰟鰠鰣鰤鰥鰦鰧鰨鰩鰫鰭鰮鰱鰲鰳鰵鰶鰷鰹鰺鰻鰼鰽鰾鱀鱂鱄鱅鱆鱇鱈鱉鱊鱒鱔鱖鱗鱘鱚鱝鱟鱠鱢鱣鱤鱧鱨鱭鱮鱯鱲鱷鱸鱺鳥鳧鳩鳬鳲鳳鳴鳶鳷鳼鳽鳾鴀鴃鴅鴆鴇鴉鴐鴒鴔鴕鴗鴛鴜鴝鴞鴟鴣鴥鴦鴨鴮鴯鴰鴲鴳鴴鴷鴻鴽鴿鵁鵂鵃鵊鵏鵐鵑鵒鵓鵚鵜鵝鵟鵠鵡鵧鵩鵪鵫鵬鵮鵯鵰鵲鵷鵾鶄鶇鶉鶊鶌鶒鶓鶖鶗鶘鶚鶠鶡鶥鶦鶩鶪鶬鶭鶯鶰鶱鶲鶴鶹鶺鶻鶼鶿鷀鷁鷂鷄鷅鷉鷊鷐鷓鷔鷖鷗鷙鷚鷟鷣鷤鷥鷦鷨鷩鷫鷭鷯鷲鷳鷴鷷鷸鷹鷺鷽鷿鸂鸇鸊鸋鸌鸏鸑鸕鸗鸘鸚鸛鸝鸞鹵鹹鹺鹼鹽麗麥麨麩麪麫麬麯麲麳麴麵麷麼麽黃黌點黨黲黴黶黷黽黿鼂鼉鼕鼴齊齋齎齏齒齔齕齗齘齙齜齟齠齡齣齦齧齩齪齬齭齮齯齰齲齴齶齷齼齾龍龎龐龑龓龔龕龜龭龯鿁鿓𠁞𠌥𠏢𠐊𠗣𠞆𠠎𠬙𠽃𠿕𡂡𡃄𡃕𡃤𡄔𡄣𡅏𡅯𡑍𡑭𡓁𡓾𡔖𡞵𡟫𡠹𡢃𡮉𡮣𡳳𡸗𡹬𡻕𡽗𡾱𡿖𢍰𢠼𢣐𢣚𢣭𢤩𢤱𢤿𢯷𢶒𢶫𢷮𢹿𢺳𣈶𣋋𣍐𣙎𣜬𣝕𣞻𣠩𣠲𣯩𣯴𣯶𣽏𣾷𣿉𤁣𤄷𤅶𤑳𤑹𤒎𤒻𤓌𤓎𤓩𤘀𤛮𤛱𤜆𤠮𤢟𤢻𤩂𤪺𤫩𤬅𤳷𤳸𤷃𤸫𤺔𥊝𥌃𥏝𥕥𥖅𥖲𥗇𥗽𥜐𥜰𥞵𥢢𥢶𥢷𥨐𥪂𥯤𥴨𥴼𥵃𥵊𥶽𥸠𥻦𥼽𥽖𥾯𥿊𦀖𦂅𦃄𦃩𦅇𦅈𦆲𦒀𦔖𦘧𦟼𦠅𦡝𦢈𦣎𦧺𦪙𦪽𦱌𦾟𧎈𧒯𧔥𧕟𧜗𧜵𧝞𧞫𧟀𧡴𧢄𧦝𧦧𧩕𧩙𧩼𧫝𧬤𧭈𧭹𧳟𧵳𧶔𧶧𧷎𧸘𧹈𧽯𨂐𨄣𨅍𨆪𨇁𨇞𨇤𨇰𨇽𨈊𨈌𨊰𨊸𨊻𨋢𨌈𨍰𨎌𨎮𨏠𨏥𨞺𨟊𨢿𨣈𨣞𨣧𨤻𨥛𨥟𨦫𨧀𨧜𨧰𨧱𨨏𨨛𨨢𨩰𨪕𨫒𨬖𨭆𨭎𨭖𨭸𨮂𨮳𨯅𨯟𨰃𨰋𨰥𨰲𨲳𨳑𨳕𨴗𨴹𨵩𨵸𨶀𨶏𨶮𨶲𨷲𨼳𨽏𩀨𩅙𩎖𩎢𩏂𩏠𩏪𩏷𩑔𩒎𩓣𩓥𩔑𩔳𩖰𩗀𩗓𩗴𩘀𩘝𩘹𩘺𩙈𩚛𩚥𩚩𩚵𩛆𩛌𩛡𩛩𩜇𩜦𩜵𩝔𩝽𩞄𩞦𩞯𩟐𩟗𩠴𩡣𩡺𩢡𩢴𩢸𩢾𩣏𩣑𩣫𩣵𩣺𩤊𩤙𩤲𩤸𩥄𩥇𩥉𩥑𩦠𩧆𩭙𩯁𩯳𩰀𩰹𩳤𩴵𩵦𩵩𩵹𩶁𩶘𩶰𩶱𩷰𩸃𩸄𩸡𩸦𩻗𩻬𩻮𩼶𩽇𩿅𩿤𩿪𪀖𪀦𪀾𪁈𪁖𪂆𪃍𪃏𪃒𪃧𪄆𪄕𪅂𪆷𪇳𪈼𪉸𪋿𪌭𪍠𪓰𪔵𪘀𪘯𪙏𪟖𪷓𫒡𫜦" +_chn_t = re.compile(r".*[" + _tc_char + "].*") def detect_language(s: str) -> str: + if _eng.match(s): + # doing this for now since langdetect is bad at single word + return "en" + if _chn.match(s): + if _chn_t.match(s): + return "zh-tw" + return "zh-cn" try: - if _eng.match(s): - return "en" - return detect(s).lower() + lang = detect(s).lower() + return lang except Exception: return "x" diff --git a/locale/zh_Hans/LC_MESSAGES/django.po b/locale/zh_Hans/LC_MESSAGES/django.po index 847e7cad..91ffe1bd 100644 --- a/locale/zh_Hans/LC_MESSAGES/django.po +++ b/locale/zh_Hans/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-13 01:27-0400\n" +"POT-Creation-Date: 2024-07-13 16:14-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -27,74 +27,70 @@ msgstr "简体中文" msgid "Traditional Chinese" msgstr "繁体中文" -#: catalog/book/models.py:98 +#: catalog/book/models.py:80 catalog/book/models.py:99 +#: catalog/common/models.py:301 catalog/common/models.py:319 +msgid "locale" +msgstr "区域语言" + +#: catalog/book/models.py:83 catalog/book/models.py:102 +#: catalog/common/models.py:304 catalog/common/models.py:324 +msgid "text content" +msgstr "文本内容" + +#: catalog/book/models.py:148 msgid "subtitle" msgstr "副标题" -#: catalog/book/models.py:101 catalog/movie/models.py:68 +#: catalog/book/models.py:158 catalog/movie/models.py:68 #: catalog/performance/models.py:257 catalog/tv/models.py:137 -#: catalog/tv/models.py:292 +#: catalog/tv/models.py:294 msgid "original title" msgstr "原名" -#: catalog/book/models.py:104 catalog/book/models.py:269 +#: catalog/book/models.py:161 catalog/book/models.py:327 msgid "author" msgstr "作者" -#: catalog/book/models.py:111 +#: catalog/book/models.py:168 msgid "translator" msgstr "译者" -#: catalog/book/models.py:118 catalog/common/models.py:299 -#: catalog/common/models.py:316 catalog/common/models.py:329 -#: catalog/templates/edition.html:47 catalog/tv/models.py:372 -#: users/models/user.py:114 -msgid "language" -msgstr "语言" - -#: catalog/book/models.py:126 catalog/templates/edition.html:26 +#: catalog/book/models.py:176 catalog/templates/edition.html:26 msgid "publishing house" msgstr "出版社" -#: catalog/book/models.py:129 +#: catalog/book/models.py:179 msgid "publication year" msgstr "发行年份" -#: catalog/book/models.py:135 +#: catalog/book/models.py:185 msgid "publication month" msgstr "发行月份" -#: catalog/book/models.py:141 catalog/templates/edition.html:52 +#: catalog/book/models.py:191 catalog/templates/edition.html:52 msgid "binding" msgstr "装订" -#: catalog/book/models.py:143 +#: catalog/book/models.py:193 msgid "pages" msgstr "页数" -#: catalog/book/models.py:145 catalog/templates/edition.html:42 +#: catalog/book/models.py:195 catalog/templates/edition.html:42 msgid "series" msgstr "丛书" -#: catalog/book/models.py:147 +#: catalog/book/models.py:197 msgid "contents" msgstr "目录" -#: catalog/book/models.py:148 catalog/templates/edition.html:57 +#: catalog/book/models.py:198 catalog/templates/edition.html:57 msgid "price" msgstr "价格" -#: catalog/book/models.py:149 catalog/templates/edition.html:31 +#: catalog/book/models.py:199 catalog/templates/edition.html:31 msgid "imprint" msgstr "出品方" -#: catalog/book/models.py:276 catalog/game/models.py:60 -#: catalog/movie/models.py:71 catalog/music/models.py:87 -#: catalog/performance/models.py:115 catalog/performance/models.py:260 -#: catalog/tv/models.py:141 catalog/tv/models.py:295 -msgid "other title" -msgstr "其它标题" - #: catalog/common/models.py:37 msgid "Unknown" msgstr "未知" @@ -377,60 +373,68 @@ msgstr "播客" msgid "FanFic" msgstr "网文" -#: catalog/common/models.py:302 catalog/common/models.py:319 -msgid "content" -msgstr "" +#: catalog/common/models.py:336 catalog/templates/edition.html:47 +#: catalog/tv/models.py:374 users/models/user.py:114 +msgid "language" +msgstr "语言" -#: catalog/common/models.py:352 catalog/common/models.py:380 +#: catalog/common/models.py:359 catalog/common/models.py:387 #: journal/models/collection.py:52 msgid "title" msgstr "标题" -#: catalog/common/models.py:353 catalog/common/models.py:388 +#: catalog/common/models.py:360 catalog/common/models.py:395 #: journal/models/collection.py:53 msgid "description" msgstr "描述" -#: catalog/common/models.py:355 catalog/forms.py:27 +#: catalog/common/models.py:362 catalog/forms.py:27 msgid "Primary ID Type" msgstr "主要标识类型" -#: catalog/common/models.py:358 catalog/forms.py:32 +#: catalog/common/models.py:365 catalog/forms.py:32 msgid "Primary ID Value" msgstr "主要标识数据" -#: catalog/common/models.py:364 +#: catalog/common/models.py:371 msgid "metadata" msgstr "元数据" -#: catalog/common/models.py:366 +#: catalog/common/models.py:373 msgid "cover" msgstr "封面" -#: catalog/common/models.py:769 +#: catalog/common/models.py:776 msgid "source site" msgstr "来源站点" -#: catalog/common/models.py:771 +#: catalog/common/models.py:778 msgid "ID on source site" msgstr "来源站点标识" -#: catalog/common/models.py:773 +#: catalog/common/models.py:780 msgid "source url" msgstr "来源站点网址" -#: catalog/common/models.py:789 +#: catalog/common/models.py:796 msgid "IdType of the source site" msgstr "来源站点的主要标识类型" -#: catalog/common/models.py:795 +#: catalog/common/models.py:802 msgid "Primary Id on the source site" msgstr "来源站点的主要标识数据" -#: catalog/common/models.py:798 +#: catalog/common/models.py:805 msgid "url to the resource" msgstr "指向外部资源的网址" +#: catalog/game/models.py:60 catalog/movie/models.py:71 +#: catalog/music/models.py:87 catalog/performance/models.py:115 +#: catalog/performance/models.py:260 catalog/tv/models.py:141 +#: catalog/tv/models.py:297 +msgid "other title" +msgstr "其它标题" + #: catalog/game/models.py:68 msgid "designer" msgstr "设计者" @@ -451,7 +455,7 @@ msgstr "出版发行" msgid "year of publication" msgstr "发行年份" -#: catalog/game/models.py:103 catalog/podcast/models.py:103 +#: catalog/game/models.py:103 catalog/podcast/models.py:108 msgid "date of publication" msgstr "发行日期" @@ -461,8 +465,8 @@ msgid "YYYY-MM-DD" msgstr "" #: catalog/game/models.py:112 catalog/movie/models.py:99 -#: catalog/performance/models.py:122 catalog/podcast/models.py:41 -#: catalog/tv/models.py:168 catalog/tv/models.py:323 +#: catalog/performance/models.py:122 catalog/podcast/models.py:46 +#: catalog/tv/models.py:168 catalog/tv/models.py:325 msgid "genre" msgstr "类型" @@ -472,30 +476,30 @@ msgstr "平台" #: catalog/game/models.py:126 catalog/movie/models.py:134 #: catalog/performance/models.py:206 catalog/performance/models.py:344 -#: catalog/podcast/models.py:57 catalog/templates/game.html:29 +#: catalog/podcast/models.py:62 catalog/templates/game.html:29 #: catalog/templates/movie.html:58 catalog/templates/performance.html:33 #: catalog/templates/performanceproduction.html:33 #: catalog/templates/podcast.html:20 catalog/templates/tvseason.html:75 #: catalog/templates/tvshow.html:70 catalog/tv/models.py:203 -#: catalog/tv/models.py:358 +#: catalog/tv/models.py:360 msgid "website" msgstr "网站" #: catalog/movie/models.py:78 catalog/performance/models.py:130 #: catalog/performance/models.py:268 catalog/tv/models.py:147 -#: catalog/tv/models.py:302 +#: catalog/tv/models.py:304 msgid "director" msgstr "导演" #: catalog/movie/models.py:85 catalog/performance/models.py:137 #: catalog/performance/models.py:275 catalog/tv/models.py:154 -#: catalog/tv/models.py:309 +#: catalog/tv/models.py:311 msgid "playwright" msgstr "编剧" #: catalog/movie/models.py:92 catalog/performance/models.py:165 #: catalog/performance/models.py:303 catalog/tv/models.py:161 -#: catalog/tv/models.py:316 +#: catalog/tv/models.py:318 msgid "actor" msgstr "演员" @@ -507,32 +511,32 @@ msgstr "演员" msgid "release date" msgstr "发布日期" -#: catalog/movie/models.py:118 catalog/tv/models.py:342 +#: catalog/movie/models.py:118 catalog/tv/models.py:344 #: journal/templates/_sidebar_user_mark_list.html:62 msgid "date" msgstr "日期" #: catalog/movie/models.py:119 catalog/performance/models.py:82 -#: catalog/tv/models.py:343 +#: catalog/tv/models.py:345 msgid "required" msgstr "必填" -#: catalog/movie/models.py:123 catalog/tv/models.py:347 +#: catalog/movie/models.py:123 catalog/tv/models.py:349 msgid "region or event" msgstr "地区或类型" #: catalog/movie/models.py:125 catalog/tv/models.py:194 -#: catalog/tv/models.py:349 +#: catalog/tv/models.py:351 msgid "Germany or Toronto International Film Festival" msgstr "德国或多伦多国际电影节" #: catalog/movie/models.py:137 catalog/tv/models.py:206 -#: catalog/tv/models.py:361 +#: catalog/tv/models.py:363 msgid "region" msgstr "地区" #: catalog/movie/models.py:148 catalog/tv/models.py:218 -#: catalog/tv/models.py:382 +#: catalog/tv/models.py:384 msgid "year" msgstr "年份" @@ -621,7 +625,7 @@ msgstr "上演日期" msgid "closing date" msgstr "结束日期" -#: catalog/podcast/models.py:51 +#: catalog/podcast/models.py:56 msgid "host" msgstr "主播" @@ -670,17 +674,17 @@ msgid "hide this tooltip" msgstr "不再提示" #: catalog/templates/_item_comments.html:82 -#: catalog/templates/_item_comments_by_episode.html:78 +#: catalog/templates/_item_comments_by_episode.html:80 #: catalog/templates/_item_reviews.html:43 #: catalog/templates/podcast_episode_data.html:41 msgid "show more" msgstr "显示更多" #: catalog/templates/_item_comments.html:86 -#: catalog/templates/_item_comments_by_episode.html:82 +#: catalog/templates/_item_comments_by_episode.html:84 #: catalog/templates/_item_reviews.html:47 #: catalog/templates/podcast_episode_data.html:44 -#: social/templates/events.html:43 social/templates/feed_events.html:133 +#: social/templates/events.html:43 social/templates/feed_events.html:135 msgid "nothing more." msgstr "没有更多内容了。" @@ -1111,7 +1115,7 @@ msgid "Popular Tags" msgstr "热门标签" #: catalog/templates/discover.html:177 catalog/templates/item_base.html:236 -#: catalog/templates/item_mark_list.html:54 +#: catalog/templates/item_mark_list.html:56 #: catalog/templates/item_review_list.html:50 common/templates/_sidebar.html:90 #: common/templates/_sidebar_anonymous.html:43 #: common/templates/_sidebar_anonymous.html:58 @@ -1348,7 +1352,7 @@ msgstr "集数" msgid "Editions" msgstr "版本" -#: catalog/tv/models.py:175 catalog/tv/models.py:330 +#: catalog/tv/models.py:175 catalog/tv/models.py:332 msgid "show time" msgstr "上映时间" @@ -1360,16 +1364,16 @@ msgstr "日期" msgid "Region or Event" msgstr "地区或场合" -#: catalog/tv/models.py:220 catalog/tv/models.py:384 +#: catalog/tv/models.py:220 catalog/tv/models.py:386 msgid "episode length" msgstr "单集长度" -#: catalog/tv/models.py:407 +#: catalog/tv/models.py:409 #, python-brace-format msgid "{show_title} S{season_number}" msgstr "{show_title} 第{season_number}季" -#: catalog/tv/models.py:459 +#: catalog/tv/models.py:461 #, python-brace-format msgid "{season_title} E{episode_number}" msgstr "{season_title} 第{episode_number}集" @@ -3970,7 +3974,7 @@ msgstr "标记" msgid "wrote a note" msgstr "写了笔记" -#: social/templates/feed_events.html:137 +#: social/templates/feed_events.html:139 #, python-format msgid "Find and mark some books/movies/podcasts/games, import your data from Goodreads/Letterboxd/Douban, follow some fellow %(site_name)s users on the fediverse, so their recent activities and yours will show up here." msgstr "搜索并标记一些书影音/播客/游戏,导入你的豆瓣、Letterboxd或Goodreads记录,去联邦宇宙(长毛象)关注一些正在使用%(site_name)s的用户,这里就会显示你和她们的近期动态。" diff --git a/locale/zh_Hant/LC_MESSAGES/django.po b/locale/zh_Hant/LC_MESSAGES/django.po index 01819d73..1c2de421 100644 --- a/locale/zh_Hant/LC_MESSAGES/django.po +++ b/locale/zh_Hant/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-13 01:27-0400\n" +"POT-Creation-Date: 2024-07-13 16:14-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -27,74 +27,70 @@ msgstr "簡體中文" msgid "Traditional Chinese" msgstr "繁體中文" -#: catalog/book/models.py:98 +#: catalog/book/models.py:80 catalog/book/models.py:99 +#: catalog/common/models.py:301 catalog/common/models.py:319 +msgid "locale" +msgstr "區域語言" + +#: catalog/book/models.py:83 catalog/book/models.py:102 +#: catalog/common/models.py:304 catalog/common/models.py:324 +msgid "text content" +msgstr "文本內容" + +#: catalog/book/models.py:148 msgid "subtitle" msgstr "副標題" -#: catalog/book/models.py:101 catalog/movie/models.py:68 +#: catalog/book/models.py:158 catalog/movie/models.py:68 #: catalog/performance/models.py:257 catalog/tv/models.py:137 -#: catalog/tv/models.py:292 +#: catalog/tv/models.py:294 msgid "original title" msgstr "原名" -#: catalog/book/models.py:104 catalog/book/models.py:269 +#: catalog/book/models.py:161 catalog/book/models.py:327 msgid "author" msgstr "作者" -#: catalog/book/models.py:111 +#: catalog/book/models.py:168 msgid "translator" msgstr "譯者" -#: catalog/book/models.py:118 catalog/common/models.py:299 -#: catalog/common/models.py:316 catalog/common/models.py:329 -#: catalog/templates/edition.html:47 catalog/tv/models.py:372 -#: users/models/user.py:114 -msgid "language" -msgstr "語言" - -#: catalog/book/models.py:126 catalog/templates/edition.html:26 +#: catalog/book/models.py:176 catalog/templates/edition.html:26 msgid "publishing house" msgstr "出版社" -#: catalog/book/models.py:129 +#: catalog/book/models.py:179 msgid "publication year" msgstr "發行年份" -#: catalog/book/models.py:135 +#: catalog/book/models.py:185 msgid "publication month" msgstr "發行月份" -#: catalog/book/models.py:141 catalog/templates/edition.html:52 +#: catalog/book/models.py:191 catalog/templates/edition.html:52 msgid "binding" msgstr "裝訂" -#: catalog/book/models.py:143 +#: catalog/book/models.py:193 msgid "pages" msgstr "頁數" -#: catalog/book/models.py:145 catalog/templates/edition.html:42 +#: catalog/book/models.py:195 catalog/templates/edition.html:42 msgid "series" msgstr "叢書" -#: catalog/book/models.py:147 +#: catalog/book/models.py:197 msgid "contents" msgstr "目錄" -#: catalog/book/models.py:148 catalog/templates/edition.html:57 +#: catalog/book/models.py:198 catalog/templates/edition.html:57 msgid "price" msgstr "價格" -#: catalog/book/models.py:149 catalog/templates/edition.html:31 +#: catalog/book/models.py:199 catalog/templates/edition.html:31 msgid "imprint" msgstr "出品方" -#: catalog/book/models.py:276 catalog/game/models.py:60 -#: catalog/movie/models.py:71 catalog/music/models.py:87 -#: catalog/performance/models.py:115 catalog/performance/models.py:260 -#: catalog/tv/models.py:141 catalog/tv/models.py:295 -msgid "other title" -msgstr "其它標題" - #: catalog/common/models.py:37 msgid "Unknown" msgstr "未知" @@ -377,60 +373,68 @@ msgstr "播客" msgid "FanFic" msgstr "網文" -#: catalog/common/models.py:302 catalog/common/models.py:319 -msgid "content" -msgstr "" +#: catalog/common/models.py:336 catalog/templates/edition.html:47 +#: catalog/tv/models.py:374 users/models/user.py:114 +msgid "language" +msgstr "語言" -#: catalog/common/models.py:352 catalog/common/models.py:380 +#: catalog/common/models.py:359 catalog/common/models.py:387 #: journal/models/collection.py:52 msgid "title" msgstr "標題" -#: catalog/common/models.py:353 catalog/common/models.py:388 +#: catalog/common/models.py:360 catalog/common/models.py:395 #: journal/models/collection.py:53 msgid "description" msgstr "描述" -#: catalog/common/models.py:355 catalog/forms.py:27 +#: catalog/common/models.py:362 catalog/forms.py:27 msgid "Primary ID Type" msgstr "主要標識類型" -#: catalog/common/models.py:358 catalog/forms.py:32 +#: catalog/common/models.py:365 catalog/forms.py:32 msgid "Primary ID Value" msgstr "主要標識數據" -#: catalog/common/models.py:364 +#: catalog/common/models.py:371 msgid "metadata" msgstr "元數據" -#: catalog/common/models.py:366 +#: catalog/common/models.py:373 msgid "cover" msgstr "封面" -#: catalog/common/models.py:769 +#: catalog/common/models.py:776 msgid "source site" msgstr "來源站點" -#: catalog/common/models.py:771 +#: catalog/common/models.py:778 msgid "ID on source site" msgstr "來源站點標識" -#: catalog/common/models.py:773 +#: catalog/common/models.py:780 msgid "source url" msgstr "來源站點網址" -#: catalog/common/models.py:789 +#: catalog/common/models.py:796 msgid "IdType of the source site" msgstr "來源站點的主要標識類型" -#: catalog/common/models.py:795 +#: catalog/common/models.py:802 msgid "Primary Id on the source site" msgstr "來源站點的主要標識數據" -#: catalog/common/models.py:798 +#: catalog/common/models.py:805 msgid "url to the resource" msgstr "指向外部資源的網址" +#: catalog/game/models.py:60 catalog/movie/models.py:71 +#: catalog/music/models.py:87 catalog/performance/models.py:115 +#: catalog/performance/models.py:260 catalog/tv/models.py:141 +#: catalog/tv/models.py:297 +msgid "other title" +msgstr "其它標題" + #: catalog/game/models.py:68 msgid "designer" msgstr "設計者" @@ -451,7 +455,7 @@ msgstr "出版發行" msgid "year of publication" msgstr "發行年份" -#: catalog/game/models.py:103 catalog/podcast/models.py:103 +#: catalog/game/models.py:103 catalog/podcast/models.py:108 msgid "date of publication" msgstr "發行日期" @@ -461,8 +465,8 @@ msgid "YYYY-MM-DD" msgstr "" #: catalog/game/models.py:112 catalog/movie/models.py:99 -#: catalog/performance/models.py:122 catalog/podcast/models.py:41 -#: catalog/tv/models.py:168 catalog/tv/models.py:323 +#: catalog/performance/models.py:122 catalog/podcast/models.py:46 +#: catalog/tv/models.py:168 catalog/tv/models.py:325 msgid "genre" msgstr "類型" @@ -472,30 +476,30 @@ msgstr "平臺" #: catalog/game/models.py:126 catalog/movie/models.py:134 #: catalog/performance/models.py:206 catalog/performance/models.py:344 -#: catalog/podcast/models.py:57 catalog/templates/game.html:29 +#: catalog/podcast/models.py:62 catalog/templates/game.html:29 #: catalog/templates/movie.html:58 catalog/templates/performance.html:33 #: catalog/templates/performanceproduction.html:33 #: catalog/templates/podcast.html:20 catalog/templates/tvseason.html:75 #: catalog/templates/tvshow.html:70 catalog/tv/models.py:203 -#: catalog/tv/models.py:358 +#: catalog/tv/models.py:360 msgid "website" msgstr "網站" #: catalog/movie/models.py:78 catalog/performance/models.py:130 #: catalog/performance/models.py:268 catalog/tv/models.py:147 -#: catalog/tv/models.py:302 +#: catalog/tv/models.py:304 msgid "director" msgstr "導演" #: catalog/movie/models.py:85 catalog/performance/models.py:137 #: catalog/performance/models.py:275 catalog/tv/models.py:154 -#: catalog/tv/models.py:309 +#: catalog/tv/models.py:311 msgid "playwright" msgstr "編劇" #: catalog/movie/models.py:92 catalog/performance/models.py:165 #: catalog/performance/models.py:303 catalog/tv/models.py:161 -#: catalog/tv/models.py:316 +#: catalog/tv/models.py:318 msgid "actor" msgstr "演員" @@ -507,32 +511,32 @@ msgstr "演員" msgid "release date" msgstr "發佈日期" -#: catalog/movie/models.py:118 catalog/tv/models.py:342 +#: catalog/movie/models.py:118 catalog/tv/models.py:344 #: journal/templates/_sidebar_user_mark_list.html:62 msgid "date" msgstr "日期" #: catalog/movie/models.py:119 catalog/performance/models.py:82 -#: catalog/tv/models.py:343 +#: catalog/tv/models.py:345 msgid "required" msgstr "必填" -#: catalog/movie/models.py:123 catalog/tv/models.py:347 +#: catalog/movie/models.py:123 catalog/tv/models.py:349 msgid "region or event" msgstr "地區或類型" #: catalog/movie/models.py:125 catalog/tv/models.py:194 -#: catalog/tv/models.py:349 +#: catalog/tv/models.py:351 msgid "Germany or Toronto International Film Festival" msgstr "德國或多倫多國際電影節" #: catalog/movie/models.py:137 catalog/tv/models.py:206 -#: catalog/tv/models.py:361 +#: catalog/tv/models.py:363 msgid "region" msgstr "地區" #: catalog/movie/models.py:148 catalog/tv/models.py:218 -#: catalog/tv/models.py:382 +#: catalog/tv/models.py:384 msgid "year" msgstr "年份" @@ -621,7 +625,7 @@ msgstr "上演日期" msgid "closing date" msgstr "結束日期" -#: catalog/podcast/models.py:51 +#: catalog/podcast/models.py:56 msgid "host" msgstr "主播" @@ -670,17 +674,17 @@ msgid "hide this tooltip" msgstr "不再提示" #: catalog/templates/_item_comments.html:82 -#: catalog/templates/_item_comments_by_episode.html:78 +#: catalog/templates/_item_comments_by_episode.html:80 #: catalog/templates/_item_reviews.html:43 #: catalog/templates/podcast_episode_data.html:41 msgid "show more" msgstr "顯示更多" #: catalog/templates/_item_comments.html:86 -#: catalog/templates/_item_comments_by_episode.html:82 +#: catalog/templates/_item_comments_by_episode.html:84 #: catalog/templates/_item_reviews.html:47 #: catalog/templates/podcast_episode_data.html:44 -#: social/templates/events.html:43 social/templates/feed_events.html:133 +#: social/templates/events.html:43 social/templates/feed_events.html:135 msgid "nothing more." msgstr "沒有更多內容了。" @@ -1111,7 +1115,7 @@ msgid "Popular Tags" msgstr "熱門標籤" #: catalog/templates/discover.html:177 catalog/templates/item_base.html:236 -#: catalog/templates/item_mark_list.html:54 +#: catalog/templates/item_mark_list.html:56 #: catalog/templates/item_review_list.html:50 common/templates/_sidebar.html:90 #: common/templates/_sidebar_anonymous.html:43 #: common/templates/_sidebar_anonymous.html:58 @@ -1348,7 +1352,7 @@ msgstr "集數" msgid "Editions" msgstr "版本" -#: catalog/tv/models.py:175 catalog/tv/models.py:330 +#: catalog/tv/models.py:175 catalog/tv/models.py:332 msgid "show time" msgstr "上映時間" @@ -1360,16 +1364,16 @@ msgstr "日期" msgid "Region or Event" msgstr "地區或場合" -#: catalog/tv/models.py:220 catalog/tv/models.py:384 +#: catalog/tv/models.py:220 catalog/tv/models.py:386 msgid "episode length" msgstr "單集長度" -#: catalog/tv/models.py:407 +#: catalog/tv/models.py:409 #, python-brace-format msgid "{show_title} S{season_number}" msgstr "{show_title} 第{season_number}季" -#: catalog/tv/models.py:459 +#: catalog/tv/models.py:461 #, python-brace-format msgid "{season_title} E{episode_number}" msgstr "{season_title} 第{episode_number}集" @@ -3970,7 +3974,7 @@ msgstr "標記" msgid "wrote a note" msgstr "寫了筆記" -#: social/templates/feed_events.html:137 +#: social/templates/feed_events.html:139 #, python-format msgid "Find and mark some books/movies/podcasts/games, import your data from Goodreads/Letterboxd/Douban, follow some fellow %(site_name)s users on the fediverse, so their recent activities and yours will show up here." msgstr "搜索並標記一些書影音/播客/遊戲,導入你的豆瓣、Letterboxd或Goodreads記錄,去聯邦宇宙(長毛象)關注一些正在使用%(site_name)s的用戶,這裏就會顯示你和她們的近期動態。"