diff --git a/boofilsic/settings.py b/boofilsic/settings.py index 3f3156d9..af7ca52b 100644 --- a/boofilsic/settings.py +++ b/boofilsic/settings.py @@ -1,6 +1,7 @@ import os import environ +from django.utils.translation import gettext_lazy as _ from boofilsic import __version__ @@ -34,7 +35,10 @@ env = environ.FileAwareEnv( NEODB_USER_ICON=(str, "/s/img/avatar.svg"), NEODB_SITE_INTRO=(str, ""), NEODB_SITE_HEAD=(str, ""), - NEODB_SITE_DESCRIPTION=(str, "一个自由、开放、互联的书籍、电影、音乐和游戏收藏评论交流社区"), + NEODB_SITE_DESCRIPTION=( + str, + "reviews about book, film, music, podcast and game.", + ), # Links in site footer NEODB_SITE_LINKS=(dict, {}), # Invite only mode @@ -384,6 +388,11 @@ MARKDOWNX_MARKDOWNIFY_FUNCTION = "journal.models.render_md" # https://docs.djangoproject.com/en/3.0/topics/i18n/ LANGUAGE_CODE = "zh-hans" +LOCALE_PATHS = [os.path.join(BASE_DIR, "locale")] +# LANGUAGES = ( +# ("en", _("English")), +# ("zh-hans", _("Simplified Chinese")), +# ) TIME_ZONE = env("NEODB_TIMEZONE", default="Asia/Shanghai") # type: ignore diff --git a/catalog/book/models.py b/catalog/book/models.py index 9df59394..ba410487 100644 --- a/catalog/book/models.py +++ b/catalog/book/models.py @@ -61,7 +61,6 @@ class EditionSchema(EditionInSchema, BaseSchema): class Edition(Item): category = ItemCategory.Book url_path = "book" - demonstrative = _("这本书") isbn = PrimaryLookupIdDescriptor(IdType.ISBN) asin = PrimaryLookupIdDescriptor(IdType.ASIN) @@ -88,53 +87,53 @@ class Edition(Item): "contents", ] subtitle = jsondata.CharField( - _("副标题"), null=True, blank=True, default=None, max_length=500 + _("subtitle"), null=True, blank=True, default=None, max_length=500 ) orig_title = jsondata.CharField( - _("原名"), null=True, blank=True, default=None, max_length=500 + _("original title"), null=True, blank=True, default=None, max_length=500 ) author = jsondata.ArrayField( - verbose_name=_("作者"), + verbose_name=_("author"), base_field=models.CharField(max_length=500), null=False, blank=False, default=list, ) translator = jsondata.ArrayField( - verbose_name=_("译者"), + verbose_name=_("translator"), base_field=models.CharField(max_length=500), null=True, blank=True, default=list, ) language = jsondata.CharField( - _("语言"), null=True, blank=True, default=None, max_length=500 + _("language"), null=True, blank=True, default=None, max_length=500 ) pub_house = jsondata.CharField( - _("出版社"), null=True, blank=False, default=None, max_length=500 + _("publisher"), null=True, blank=False, default=None, max_length=500 ) pub_year = jsondata.IntegerField( - _("出版年份"), + _("publication year"), null=True, blank=False, validators=[MinValueValidator(1), MaxValueValidator(2999)], ) pub_month = jsondata.IntegerField( - _("出版月份"), + _("publication month"), null=True, blank=True, validators=[MinValueValidator(1), MaxValueValidator(12)], ) binding = jsondata.CharField( - _("装订"), null=True, blank=True, default=None, max_length=500 + _("binding"), null=True, blank=True, default=None, max_length=500 ) - pages = jsondata.IntegerField(_("页数"), blank=True, default=None) + pages = jsondata.IntegerField(_("pages"), blank=True, default=None) series = jsondata.CharField( - _("丛书"), null=True, blank=True, default=None, max_length=500 + _("series"), null=True, blank=True, default=None, max_length=500 ) - contents = jsondata.TextField(_("目录"), null=True, blank=True, default=None) - price = jsondata.CharField(_("价格"), null=True, blank=True, max_length=500) - imprint = jsondata.CharField(_("出品方"), null=True, blank=True, max_length=500) + contents = jsondata.TextField(_("contents"), null=True, blank=True, default=None) + price = jsondata.CharField(_("price"), null=True, blank=True, max_length=500) + imprint = jsondata.CharField(_("imprint"), null=True, blank=True, max_length=500) @property def isbn10(self): diff --git a/catalog/common/jsondata.py b/catalog/common/jsondata.py index 0be189cd..74afe267 100644 --- a/catalog/common/jsondata.py +++ b/catalog/common/jsondata.py @@ -244,7 +244,7 @@ class URLField(JSONFieldMixin, fields.URLField): class ArrayField(JSONFieldMixin, DJANGO_ArrayField): # def __init__(self, *args, **kwargs): - # kwargs["help_text"] = _("多项之间以英文逗号分隔") + # kwargs["help_text"] = _("comma separated list of values") # super().__init__(*args, **kwargs) def from_json(self, value): # backward compatible with dirty legacy data diff --git a/catalog/common/models.py b/catalog/common/models.py index 8422469a..d122fd1f 100644 --- a/catalog/common/models.py +++ b/catalog/common/models.py @@ -22,19 +22,17 @@ from .mixins import SoftDeleteMixin from .utils import DEFAULT_ITEM_COVER, item_cover_path, resource_cover_path if TYPE_CHECKING: - from django.utils.functional import _StrOrPromise - from users.models import User _logger = logging.getLogger(__name__) class SiteName(models.TextChoices): - Unknown = "unknown", _("未知站点") - Douban = "douban", _("豆瓣") + Unknown = "unknown", _("Unknown") + Douban = "douban", _("Douban") Goodreads = "goodreads", _("Goodreads") - GoogleBooks = "googlebooks", _("谷歌图书") - BooksTW = "bookstw", _("博客来") + GoogleBooks = "googlebooks", _("Google Books") + BooksTW = "bookstw", _("BooksTW") IMDB = "imdb", _("IMDb") TMDB = "tmdb", _("TMDB") Bandcamp = "bandcamp", _("Bandcamp") @@ -43,57 +41,57 @@ class SiteName(models.TextChoices): Steam = "steam", _("Steam") Bangumi = "bangumi", _("Bangumi") BGG = "bgg", _("BGG") - # ApplePodcast = "apple_podcast", _("苹果播客") + # ApplePodcast = "apple_podcast", _("Apple Podcast") RSS = "rss", _("RSS") Discogs = "discogs", _("Discogs") - AppleMusic = "apple_music", _("苹果音乐") - Fediverse = "fedi", _("联邦实例") + AppleMusic = "apple_music", _("Apple Music") + Fediverse = "fedi", _("Fediverse") class IdType(models.TextChoices): - WikiData = "wikidata", _("维基数据") + WikiData = "wikidata", _("WikiData") ISBN10 = "isbn10", _("ISBN10") ISBN = "isbn", _("ISBN") # ISBN 13 ASIN = "asin", _("ASIN") ISSN = "issn", _("ISSN") - CUBN = "cubn", _("统一书号") + CUBN = "cubn", _("CUBN") ISRC = "isrc", _("ISRC") # only for songs - GTIN = "gtin", _("GTIN UPC EAN码") # GTIN-13, ISBN is separate + GTIN = "gtin", _("GTIN UPC EAN") # GTIN-13, ISBN is separate RSS = "rss", _("RSS Feed URL") IMDB = "imdb", _("IMDb") - TMDB_TV = "tmdb_tv", _("TMDB剧集") - TMDB_TVSeason = "tmdb_tvseason", _("TMDB剧集") - TMDB_TVEpisode = "tmdb_tvepisode", _("TMDB剧集") - TMDB_Movie = "tmdb_movie", _("TMDB电影") + TMDB_TV = "tmdb_tv", _("TMDB TV Serie") + TMDB_TVSeason = "tmdb_tvseason", _("TMDB TV Season") + TMDB_TVEpisode = "tmdb_tvepisode", _("TMDB TV Episode") + TMDB_Movie = "tmdb_movie", _("TMDB Movie") Goodreads = "goodreads", _("Goodreads") - Goodreads_Work = "goodreads_work", _("Goodreads著作") - GoogleBooks = "googlebooks", _("谷歌图书") - DoubanBook = "doubanbook", _("豆瓣读书") - DoubanBook_Work = "doubanbook_work", _("豆瓣读书著作") - DoubanMovie = "doubanmovie", _("豆瓣电影") - DoubanMusic = "doubanmusic", _("豆瓣音乐") - DoubanGame = "doubangame", _("豆瓣游戏") - DoubanDrama = "doubandrama", _("豆瓣舞台剧") - DoubanDramaVersion = "doubandrama_version", _("豆瓣舞台剧版本") - BooksTW = "bookstw", _("博客来图书") + Goodreads_Work = "goodreads_work", _("Goodreads Work") + GoogleBooks = "googlebooks", _("Google Books") + DoubanBook = "doubanbook", _("Douban Book") + DoubanBook_Work = "doubanbook_work", _("Douban Book Work") + DoubanMovie = "doubanmovie", _("Douban Movie") + DoubanMusic = "doubanmusic", _("Douban Music") + DoubanGame = "doubangame", _("Douban Game") + DoubanDrama = "doubandrama", _("Douban Drama") + DoubanDramaVersion = "doubandrama_version", _("Douban Drama Version") + BooksTW = "bookstw", _("BooksTW Book") Bandcamp = "bandcamp", _("Bandcamp") - Spotify_Album = "spotify_album", _("Spotify专辑") - Spotify_Show = "spotify_show", _("Spotify播客") + Spotify_Album = "spotify_album", _("Spotify Album") + Spotify_Show = "spotify_show", _("Spotify Podcast") Discogs_Release = "discogs_release", ("Discogs Release") Discogs_Master = "discogs_master", ("Discogs Master") MusicBrainz = "musicbrainz", ("MusicBrainz ID") - DoubanBook_Author = "doubanbook_author", _("豆瓣读书作者") - DoubanCelebrity = "doubanmovie_celebrity", _("豆瓣电影影人") - Goodreads_Author = "goodreads_author", _("Goodreads作者") - Spotify_Artist = "spotify_artist", _("Spotify艺术家") - TMDB_Person = "tmdb_person", _("TMDB影人") - IGDB = "igdb", _("IGDB游戏") - BGG = "bgg", _("BGG桌游") - Steam = "steam", _("Steam游戏") + # DoubanBook_Author = "doubanbook_author", _("豆瓣读书作者") + # DoubanCelebrity = "doubanmovie_celebrity", _("豆瓣电影影人") + # Goodreads_Author = "goodreads_author", _("Goodreads作者") + # Spotify_Artist = "spotify_artist", _("Spotify艺术家") + # TMDB_Person = "tmdb_person", _("TMDB影人") + IGDB = "igdb", _("IGDB Game") + BGG = "bgg", _("BGG Boardgame") + Steam = "steam", _("Steam Game") Bangumi = "bangumi", _("Bangumi") - ApplePodcast = "apple_podcast", _("苹果播客") - AppleMusic = "apple_music", _("苹果音乐") - Fediverse = "fedi", _("联邦实例") + ApplePodcast = "apple_podcast", _("Apple Podcast") + AppleMusic = "apple_music", _("Apple Music") + Fediverse = "fedi", _("Fediverse") IdealIdTypes = [ @@ -109,46 +107,43 @@ IdealIdTypes = [ class ItemType(models.TextChoices): - Book = "book", _("书") - TVShow = "tvshow", _("剧集") - TVSeason = "tvseason", _("剧集分季") - TVEpisode = "tvepisode", _("剧集分集") - Movie = "movie", _("电影") - Album = "music", _("音乐专辑") - Game = "game", _("游戏") - Podcast = "podcast", _("播客") - PodcastEpisode = "podcastepisode", _("播客单集") - FanFic = "fanfic", _("网文") - Performance = "performance", _("剧目") - PerformanceProduction = "production", _("上演") - Exhibition = "exhibition", _("展览") - Collection = "collection", _("收藏单") + Book = "book", _("Book") + TVShow = "tvshow", _("TV Serie") + TVSeason = "tvseason", _("TV Season") + TVEpisode = "tvepisode", _("TV Episode") + Movie = "movie", _("Movie") + Album = "music", _("Album") + Game = "game", _("Game") + Podcast = "podcast", _("Podcast Program") + PodcastEpisode = "podcastepisode", _("Podcast Episode") + Performance = "performance", _("Performance") + PerformanceProduction = "production", _("Production") + FanFic = "fanfic", _("Fanfix") + Exhibition = "exhibition", _("Exhibition") + Collection = "collection", _("Collection") class ItemCategory(models.TextChoices): - Book = "book", _("书") - Movie = "movie", _("电影") - TV = "tv", _("剧集") - Music = "music", _("音乐") - Game = "game", _("游戏") - Podcast = "podcast", _("播客") - FanFic = "fanfic", _("网文") - Performance = "performance", _("演出") - Exhibition = "exhibition", _("展览") - Collection = "collection", _("收藏单") + Book = "book", _("Book") + Movie = "movie", _("Movie") + TV = "tv", _("TV") + Music = "music", _("Music") + Game = "game", _("Game") + Podcast = "podcast", _("Podcast") + Performance = "performance", _("Performance") + FanFic = "fanfic", _("FanFic") + Exhibition = "exhibition", _("Exhibition") + Collection = "collection", _("Collection") class AvailableItemCategory(models.TextChoices): - Book = "book", _("书") - Movie = "movie", _("电影") - TV = "tv", _("剧集") - Music = "music", _("音乐") - Game = "game", _("游戏") - Podcast = "podcast", _("播客") - Performance = "performance", _("演出") - # FanFic = "fanfic", _("网文") - # Exhibition = "exhibition", _("展览") - # Collection = "collection", _("收藏单") + Book = "book", _("Book") + Movie = "movie", _("Movie") + TV = "tv", _("TV") + Music = "music", _("Music") + Game = "game", _("Game") + Podcast = "podcast", _("Podcast") + Performance = "performance", _("Performance") # class SubItemType(models.TextChoices): @@ -258,19 +253,22 @@ class Item(SoftDeleteMixin, PolymorphicModel): child_class = None # subclass may specify this to allow link to parent item parent_class = None # subclass may specify this to allow create child item category: ItemCategory # subclass must specify this - demonstrative: "_StrOrPromise | None" = None # subclass must specify this uid = models.UUIDField(default=uuid.uuid4, editable=False, db_index=True) - title = models.CharField(_("标题"), max_length=1000, default="") - brief = models.TextField(_("简介"), blank=True, default="") + title = models.CharField(_("title"), max_length=1000, default="") + brief = models.TextField(_("description"), blank=True, default="") primary_lookup_id_type = models.CharField( - _("主要标识类型"), blank=False, null=True, max_length=50 + _("Primary ID Type"), blank=False, null=True, max_length=50 ) primary_lookup_id_value = models.CharField( - _("主要标识数值"), blank=False, null=True, max_length=1000 + _("Primary ID Value"), + blank=False, + null=True, + max_length=1000, + help_text="automatically detected, usually no change necessary, left empty if unsure", ) - metadata = models.JSONField(_("其它信息"), blank=True, null=True, default=dict) + metadata = models.JSONField(_("metadata"), blank=True, null=True, default=dict) cover = models.ImageField( - _("封面"), upload_to=item_cover_path, default=DEFAULT_ITEM_COVER, blank=True + _("cover"), upload_to=item_cover_path, default=DEFAULT_ITEM_COVER, blank=True ) created_time = models.DateTimeField(auto_now_add=True) edited_time = models.DateTimeField(auto_now=True) @@ -552,10 +550,12 @@ class ItemLookupId(models.Model): Item, null=True, on_delete=models.SET_NULL, related_name="lookup_ids" ) id_type = models.CharField( - _("源网站"), blank=True, choices=IdType.choices, max_length=50 + _("source site"), blank=True, choices=IdType.choices, max_length=50 + ) + id_value = models.CharField(_("ID on source site"), blank=True, max_length=1000) + raw_url = models.CharField( + _("source url"), blank=True, max_length=1000, unique=True ) - id_value = models.CharField(_("源网站ID"), blank=True, max_length=1000) - raw_url = models.CharField(_("源网站ID"), blank=True, max_length=1000, unique=True) class Meta: unique_together = [["id_type", "id_value"]] diff --git a/catalog/forms.py b/catalog/forms.py index 8be61780..29d836f7 100644 --- a/catalog/forms.py +++ b/catalog/forms.py @@ -23,10 +23,13 @@ def _EditForm(item_model): primary_lookup_id_type = forms.ChoiceField( required=False, choices=item_model.lookup_id_type_choices(), - label=_("主要标识类型"), + label=_("Primary ID Type"), + help_text="automatically detected, usually no change necessary", ) primary_lookup_id_value = forms.CharField( - required=False, label=_("主要标识数据通常由系统自动检测,请勿随意更改现有值,新增条目不确定留空即可") + required=False, + label=_("Primary ID Value"), + help_text="automatically detected, usually no change necessary, left empty if unsure", ) class Meta: diff --git a/catalog/game/models.py b/catalog/game/models.py index 22d1672c..8d500e79 100644 --- a/catalog/game/models.py +++ b/catalog/game/models.py @@ -34,7 +34,6 @@ class Game(Item): type = ItemType.Game category = ItemCategory.Game url_path = "game" - demonstrative = _("这个游戏") igdb = PrimaryLookupIdDescriptor(IdType.IGDB) steam = PrimaryLookupIdDescriptor(IdType.Steam) douban_game = PrimaryLookupIdDescriptor(IdType.DoubanGame) @@ -56,7 +55,7 @@ class Game(Item): other_title = jsondata.ArrayField( base_field=models.CharField(blank=True, default="", max_length=500), - verbose_name=_("其它标题"), + verbose_name=_("other title"), null=True, blank=True, default=list, @@ -64,7 +63,7 @@ class Game(Item): designer = jsondata.ArrayField( base_field=models.CharField(blank=True, default="", max_length=500), - verbose_name=_("设计者"), + verbose_name=_("designer"), null=True, blank=True, default=list, @@ -72,7 +71,7 @@ class Game(Item): artist = jsondata.ArrayField( base_field=models.CharField(blank=True, default="", max_length=500), - verbose_name=_("艺术家"), + verbose_name=_("artist"), null=True, blank=True, default=list, @@ -80,7 +79,7 @@ class Game(Item): developer = jsondata.ArrayField( base_field=models.CharField(blank=True, default="", max_length=500), - verbose_name=_("开发商"), + verbose_name=_("developer"), null=True, blank=True, default=list, @@ -88,16 +87,18 @@ class Game(Item): publisher = jsondata.ArrayField( base_field=models.CharField(blank=True, default="", max_length=500), - verbose_name=_("发行商"), + verbose_name=_("publisher"), null=True, blank=True, default=list, ) - release_year = jsondata.IntegerField(verbose_name=_("发布年份"), null=True, blank=True) + release_year = jsondata.IntegerField( + verbose_name=_("year of publication"), null=True, blank=True + ) release_date = jsondata.DateField( - verbose_name=_("发布日期"), + verbose_name=_("date of publication"), auto_now=False, auto_now_add=False, null=True, @@ -106,7 +107,7 @@ class Game(Item): ) genre = jsondata.ArrayField( - verbose_name=_("类型"), + verbose_name=_("genre"), base_field=models.CharField(blank=True, default="", max_length=200), null=True, blank=True, @@ -114,13 +115,13 @@ class Game(Item): ) platform = jsondata.ArrayField( - verbose_name=_("平台"), + verbose_name=_("platform"), base_field=models.CharField(blank=True, default="", max_length=200), default=list, ) official_site = jsondata.CharField( - verbose_name=_("官方网站"), max_length=1000, null=True, blank=True + verbose_name=_("website"), max_length=1000, null=True, blank=True ) @classmethod diff --git a/catalog/jobs/discover.py b/catalog/jobs/discover.py index 9041f6cd..0e22e755 100644 --- a/catalog/jobs/discover.py +++ b/catalog/jobs/discover.py @@ -3,6 +3,7 @@ from datetime import timedelta from django.core.cache import cache from django.db.models import Count, F from django.utils import timezone +from django.utils.translation import gettext_lazy as _ from loguru import logger from catalog.models import * @@ -87,7 +88,7 @@ class DiscoverGenerator(BaseJob): { "name": "popular_" + category.value, "title": "" - + (category.label if category != ItemCategory.Book else "图书"), + + (category.label if category != ItemCategory.Book else _("Book")), "items": items, } ) diff --git a/catalog/movie/models.py b/catalog/movie/models.py index 10d75ee4..a92cf780 100644 --- a/catalog/movie/models.py +++ b/catalog/movie/models.py @@ -41,7 +41,6 @@ class Movie(Item): imdb = PrimaryLookupIdDescriptor(IdType.IMDB) tmdb_movie = PrimaryLookupIdDescriptor(IdType.TMDB_Movie) douban_movie = PrimaryLookupIdDescriptor(IdType.DoubanMovie) - demonstrative = _("这部电影") METADATA_COPY_LIST = [ "title", @@ -63,45 +62,45 @@ class Movie(Item): "brief", ] orig_title = jsondata.CharField( - verbose_name=_("原始标题"), blank=True, default="", max_length=500 + verbose_name=_("original title"), blank=True, default="", max_length=500 ) other_title = jsondata.ArrayField( - verbose_name=_("其它标题"), + verbose_name=_("other title"), base_field=models.CharField(blank=True, default="", max_length=200), null=True, blank=True, default=list, ) director = jsondata.ArrayField( - verbose_name=_("导演"), + verbose_name=_("director"), base_field=models.CharField(blank=True, default="", max_length=200), null=True, blank=True, default=list, ) playwright = jsondata.ArrayField( - verbose_name=_("编剧"), + verbose_name=_("playwright"), base_field=models.CharField(blank=True, default="", max_length=200), null=True, blank=True, default=list, ) actor = jsondata.ArrayField( - verbose_name=_("演员"), + verbose_name=_("actor"), base_field=models.CharField(blank=True, default="", max_length=200), null=True, blank=True, default=list, ) genre = jsondata.ArrayField( - verbose_name=_("类型"), + verbose_name=_("genre"), base_field=models.CharField(blank=True, default="", max_length=50), null=True, blank=True, default=list, ) # , choices=MovieGenreEnum.choices showtime = jsondata.JSONField( - _("上映日期"), + _("release date"), null=True, blank=True, default=list, @@ -113,13 +112,15 @@ class Movie(Item): "keys": { "time": { "type": "string", - "title": _("日期"), - "placeholder": _("必填"), + "title": _("date"), + "placeholder": _("required"), }, "region": { "type": "string", - "title": _("区域或类型"), - "placeholder": _("如中国大陆或柏林电影节"), + "title": _("region or event"), + "placeholder": _( + "Germany or Toronto International Film Festival" + ), }, }, "required": ["time"], @@ -127,10 +128,10 @@ class Movie(Item): }, ) site = jsondata.URLField( - verbose_name=_("官方网站"), blank=True, default="", max_length=200 + verbose_name=_("website"), blank=True, default="", max_length=200 ) area = jsondata.ArrayField( - verbose_name=_("国家地区"), + verbose_name=_("region"), base_field=models.CharField( blank=True, default="", @@ -141,7 +142,7 @@ class Movie(Item): default=list, ) language = jsondata.ArrayField( - verbose_name=_("语言"), + verbose_name=_("language"), base_field=models.CharField( blank=True, default="", @@ -151,9 +152,9 @@ class Movie(Item): blank=True, default=list, ) - year = jsondata.IntegerField(verbose_name=_("年份"), null=True, blank=True) + year = jsondata.IntegerField(verbose_name=_("year"), null=True, blank=True) duration = jsondata.CharField( - verbose_name=_("片长"), blank=True, default="", max_length=200 + verbose_name=_("length"), blank=True, default="", max_length=200 ) season_number = jsondata.IntegerField( null=True, blank=True diff --git a/catalog/music/models.py b/catalog/music/models.py index 1d2d7a97..c00e3f99 100644 --- a/catalog/music/models.py +++ b/catalog/music/models.py @@ -36,7 +36,6 @@ class Album(Item): type = ItemType.Album url_path = "album" category = ItemCategory.Music - demonstrative = _("这张专辑") barcode = PrimaryLookupIdDescriptor(IdType.GTIN) douban_music = PrimaryLookupIdDescriptor(IdType.DoubanMusic) spotify_album = PrimaryLookupIdDescriptor(IdType.Spotify_Album) @@ -56,16 +55,18 @@ class Album(Item): "bandcamp_album_id", ] release_date = jsondata.DateField( - _("发行日期"), null=True, blank=True, help_text=_("YYYY-MM-DD") + _("release date"), null=True, blank=True, help_text=_("YYYY-MM-DD") + ) + duration = jsondata.IntegerField( + _("length"), null=True, blank=True, help_text=_("milliseconds") ) - duration = jsondata.IntegerField(_("时长"), null=True, blank=True, help_text=_("毫秒数")) artist = jsondata.ArrayField( models.CharField(blank=True, default="", max_length=200), - verbose_name=_("艺术家"), + verbose_name=_("artist"), default=list, ) genre = jsondata.ArrayField( - verbose_name=_("流派"), + verbose_name=_("genre"), base_field=models.CharField(blank=True, default="", max_length=50), null=True, blank=True, @@ -73,23 +74,27 @@ class Album(Item): ) company = jsondata.ArrayField( models.CharField(blank=True, default="", max_length=500), - verbose_name=_("发行方"), + verbose_name=_("publisher"), null=True, blank=True, default=list, ) - track_list = jsondata.TextField(_("曲目"), blank=True, default="") + track_list = jsondata.TextField(_("tracks"), blank=True, default="") other_title = jsondata.ArrayField( - verbose_name=_("其它标题"), + verbose_name=_("other title"), base_field=models.CharField(blank=True, default="", max_length=200), null=True, blank=True, default=list, ) - album_type = jsondata.CharField(_("专辑类型"), blank=True, default="", max_length=500) - media = jsondata.CharField(_("介质"), blank=True, default="", max_length=500) + album_type = jsondata.CharField( + _("album type"), blank=True, default="", max_length=500 + ) + media = jsondata.CharField(_("media type"), blank=True, default="", max_length=500) bandcamp_album_id = jsondata.CharField(blank=True, default="", max_length=500) - disc_count = jsondata.IntegerField(_("碟片数"), blank=True, default="", max_length=500) + disc_count = jsondata.IntegerField( + _("number of disc"), blank=True, default="", max_length=500 + ) def get_embed_link(self): for res in self.external_resources.all(): diff --git a/catalog/performance/models.py b/catalog/performance/models.py index bb6be480..795dd33a 100644 --- a/catalog/performance/models.py +++ b/catalog/performance/models.py @@ -4,8 +4,15 @@ from django.db import models from django.utils.translation import gettext_lazy as _ from ninja import Schema -from catalog.common import * -from catalog.common.models import ItemSchema +from catalog.common import ( + ExternalResource, + IdType, + Item, + ItemCategory, + ItemSchema, + ItemType, + jsondata, +) from catalog.common.utils import DEFAULT_ITEM_COVER @@ -54,8 +61,8 @@ _CREW_SCHEMA = { "items": { "type": "dict", "keys": { - "name": {"type": "string", "title": _("名字")}, - "role": {"type": "string", "title": _("职能")}, + "name": {"type": "string", "title": _("name")}, + "role": {"type": "string", "title": _("role")}, }, "required": ["role", "name"], }, @@ -67,8 +74,16 @@ _ACTOR_SCHEMA = { "items": { "type": "dict", "keys": { - "name": {"type": "string", "title": _("名字"), "placeholder": _("演员名字,必填")}, - "role": {"type": "string", "title": _("角色"), "placeholder": _("也可不填写")}, + "name": { + "type": "string", + "title": _("name"), + "placeholder": _("required"), + }, + "role": { + "type": "string", + "title": _("role"), + "placeholder": _("optional"), + }, }, "required": ["name"], }, @@ -89,109 +104,108 @@ class Performance(Item): child_class = "PerformanceProduction" category = ItemCategory.Performance url_path = "performance" - demonstrative = _("这部剧作") orig_title = jsondata.CharField( - verbose_name=_("原名"), blank=True, default="", max_length=500 + verbose_name=_("original name"), blank=True, default="", max_length=500 ) other_title = jsondata.ArrayField( - verbose_name=_("其它标题"), + verbose_name=_("other title"), base_field=models.CharField(blank=False, default="", max_length=200), null=False, blank=True, default=list, ) genre = jsondata.ArrayField( - verbose_name=_("类型"), + verbose_name=_("genre"), base_field=models.CharField(blank=False, default="", max_length=200), null=False, blank=False, default=list, ) language = jsondata.ArrayField( - verbose_name=_("语言"), + verbose_name=_("language"), base_field=models.CharField(blank=False, default="", max_length=200), null=False, blank=True, default=list, ) director = jsondata.ArrayField( - verbose_name=_("导演"), + verbose_name=_("director"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) playwright = jsondata.ArrayField( - verbose_name=_("编剧"), + verbose_name=_("playwright"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) orig_creator = jsondata.ArrayField( - verbose_name=_("原作者"), + verbose_name=_("original creator"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) composer = jsondata.ArrayField( - verbose_name=_("作曲"), + verbose_name=_("composer"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) choreographer = jsondata.ArrayField( - verbose_name=_("编舞"), + verbose_name=_("choreographer"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) actor = jsondata.JSONField( - verbose_name=_("演员"), + verbose_name=_("actor"), null=False, blank=True, default=list, schema=_ACTOR_SCHEMA, ) performer = jsondata.ArrayField( - verbose_name=_("表演者"), + verbose_name=_("performer"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) troupe = jsondata.ArrayField( - verbose_name=_("剧团"), + verbose_name=_("troupe"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) crew = jsondata.JSONField( - verbose_name=_("其他演职人员和团体"), + verbose_name=_("crew"), null=False, blank=True, default=list, schema=_CREW_SCHEMA, ) location = jsondata.ArrayField( - verbose_name=_("剧场空间"), + verbose_name=_("theater"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) opening_date = jsondata.CharField( - verbose_name=_("首演日期"), max_length=100, null=True, blank=True + verbose_name=_("opening date"), max_length=100, null=True, blank=True ) closing_date = jsondata.CharField( - verbose_name=_("结束日期"), max_length=100, null=True, blank=True + verbose_name=_("closing date"), max_length=100, null=True, blank=True ) official_site = jsondata.CharField( - verbose_name=_("官方网站"), max_length=1000, null=True, blank=True + verbose_name=_("website"), max_length=1000, null=True, blank=True ) METADATA_COPY_LIST = [ "title", @@ -236,105 +250,104 @@ class PerformanceProduction(Item): type = ItemType.PerformanceProduction category = ItemCategory.Performance url_path = "performance/production" - demonstrative = _("这次上演") show = models.ForeignKey( Performance, null=True, on_delete=models.SET_NULL, related_name="productions" ) orig_title = jsondata.CharField( - verbose_name=_("原名"), blank=True, default="", max_length=500 + verbose_name=_("original title"), blank=True, default="", max_length=500 ) other_title = jsondata.ArrayField( - verbose_name=_("其它标题"), + verbose_name=_("other title"), base_field=models.CharField(blank=False, default="", max_length=200), null=False, blank=True, default=list, ) language = jsondata.ArrayField( - verbose_name=_("语言"), + verbose_name=_("language"), base_field=models.CharField(blank=False, default="", max_length=200), null=False, blank=True, default=list, ) director = jsondata.ArrayField( - verbose_name=_("导演"), + verbose_name=_("director"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) playwright = jsondata.ArrayField( - verbose_name=_("编剧"), + verbose_name=_("playwright"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) orig_creator = jsondata.ArrayField( - verbose_name=_("原作者"), + verbose_name=_("original creator"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) composer = jsondata.ArrayField( - verbose_name=_("作曲"), + verbose_name=_("composer"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) choreographer = jsondata.ArrayField( - verbose_name=_("编舞"), + verbose_name=_("choreographer"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) actor = jsondata.JSONField( - verbose_name=_("演员"), + verbose_name=_("actor"), null=False, blank=True, default=list, schema=_ACTOR_SCHEMA, ) performer = jsondata.ArrayField( - verbose_name=_("表演者"), + verbose_name=_("performer"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) troupe = jsondata.ArrayField( - verbose_name=_("剧团"), + verbose_name=_("troupe"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) crew = jsondata.JSONField( - verbose_name=_("其他演职人员和团体"), + verbose_name=_("crew"), null=False, blank=True, default=list, schema=_CREW_SCHEMA, ) location = jsondata.ArrayField( - verbose_name=_("剧场空间"), + verbose_name=_("theater"), base_field=models.CharField(blank=False, default="", max_length=500), null=False, blank=True, default=list, ) opening_date = jsondata.CharField( - verbose_name=_("首演日期"), max_length=100, null=True, blank=False + verbose_name=_("opening date"), max_length=100, null=True, blank=False ) closing_date = jsondata.CharField( - verbose_name=_("结束日期"), max_length=100, null=True, blank=True + verbose_name=_("closing date"), max_length=100, null=True, blank=True ) official_site = jsondata.CharField( - verbose_name=_("官方网站"), max_length=1000, null=True, blank=True + verbose_name=_("website"), max_length=1000, null=True, blank=True ) METADATA_COPY_LIST = [ "title", diff --git a/catalog/podcast/models.py b/catalog/podcast/models.py index ad62c9ae..8fbda661 100644 --- a/catalog/podcast/models.py +++ b/catalog/podcast/models.py @@ -29,12 +29,11 @@ class Podcast(Item): category = ItemCategory.Podcast child_class = "PodcastEpisode" url_path = "podcast" - demonstrative = _("这档播客") # apple_podcast = PrimaryLookupIdDescriptor(IdType.ApplePodcast) # ximalaya = LookupIdDescriptor(IdType.Ximalaya) # xiaoyuzhou = LookupIdDescriptor(IdType.Xiaoyuzhou) genre = jsondata.ArrayField( - verbose_name=_("类型"), + verbose_name=_("genre"), base_field=models.CharField(blank=True, default="", max_length=200), null=True, blank=True, @@ -42,13 +41,13 @@ class Podcast(Item): ) hosts = jsondata.ArrayField( - verbose_name=_("主播"), + verbose_name=_("host"), base_field=models.CharField(blank=True, default="", max_length=200), default=list, ) official_site = jsondata.CharField( - verbose_name=_("官方网站"), max_length=1000, null=True, blank=True + verbose_name=_("website"), max_length=1000, null=True, blank=True ) METADATA_COPY_LIST = [ @@ -87,12 +86,11 @@ class Podcast(Item): class PodcastEpisode(Item): category = ItemCategory.Podcast url_path = "podcast/episode" - demonstrative = _("这集节目") # uid = models.UUIDField(default=uuid.uuid4, editable=False, db_index=True) program = models.ForeignKey(Podcast, models.CASCADE, related_name="episodes") guid = models.CharField(null=True, max_length=1000) pub_date = models.DateTimeField( - verbose_name=_("发布时间"), help_text="yyyy/mm/dd hh:mm" + verbose_name=_("date of publication"), help_text="yyyy/mm/dd hh:mm" ) media_url = models.CharField(null=True, max_length=1000) # title = models.CharField(default="", max_length=1000) diff --git a/catalog/templates/item_base.html b/catalog/templates/item_base.html index 0d4b2b38..a4984772 100644 --- a/catalog/templates/item_base.html +++ b/catalog/templates/item_base.html @@ -141,7 +141,7 @@