{% trans "No items matching the search query." %}
+ {% endfor %} +diff --git a/boofilsic/settings.py b/boofilsic/settings.py index fc6586bf..8fe469cb 100644 --- a/boofilsic/settings.py +++ b/boofilsic/settings.py @@ -118,6 +118,7 @@ NEODB_SENTRY_DSN=(str, ""), NEODB_SENTRY_SAMPLE_RATE=(float, 0), NEODB_FANOUT_LIMIT_DAYS=(int, 9), + INDEX_ALIASES=(dict, {}), ) # ====== End of user configuration variables ====== @@ -561,6 +562,8 @@ def _init_language_settings(preferred_lanugages_env): SEARCH_INDEX_NEW_ONLY = False +INDEX_ALIASES = env("INDEX_ALIASES") + DOWNLOADER_SAVEDIR = env("NEODB_DOWNLOADER_SAVE_DIR", default="/tmp") # type: ignore DISABLE_MODEL_SIGNAL = False # disable index and social feeds during importing/etc diff --git a/catalog/book/models.py b/catalog/book/models.py index 866e0a32..c1caae34 100644 --- a/catalog/book/models.py +++ b/catalog/book/models.py @@ -216,6 +216,12 @@ def get_localized_subtitle(self) -> str | None: def display_subtitle(self) -> str | None: return self.get_localized_subtitle() + def to_indexable_titles(self) -> list[str]: + titles = [t["text"] for t in self.localized_title if t] + titles += [t["text"] for t in self.localized_subtitle if t] + titles += [self.orig_title] if self.orig_title else [] + return list(set(titles)) + @property def isbn10(self): return isbn_13_to_10(self.isbn) diff --git a/catalog/collection/models.py b/catalog/collection/models.py index d33924e5..b5da4902 100644 --- a/catalog/collection/models.py +++ b/catalog/collection/models.py @@ -10,6 +10,10 @@ class Collection(Item): journal_item: "JournalCollection" category = ItemCategory.Collection + @property + def url(self): + return self.journal_item.url if self.journal_item else super().url + @property def owner_id(self): return self.journal_item.owner_id if self.journal_item else None diff --git a/catalog/common/models.py b/catalog/common/models.py index 47085c6f..db8fa015 100644 --- a/catalog/common/models.py +++ b/catalog/common/models.py @@ -470,7 +470,7 @@ def clear(self): res.save() def __str__(self): - return f"{self.__class__.__name__}|{self.pk}|{self.uuid} {self.primary_lookup_id_type}:{self.primary_lookup_id_value if self.primary_lookup_id_value else ''} ({self.title})" + return f"{self.__class__.__name__}|{self.pk}|{self.uuid} {self.primary_lookup_id_type}:{self.primary_lookup_id_value if self.primary_lookup_id_value else ''} ({self.display_title})" @classmethod def lookup_id_type_choices(cls): @@ -567,6 +567,12 @@ def merge_to(self, to_item: "Item | None"): res.item = to_item res.save() + @property + def final_item(self) -> Self: + if self.merged_to_item: + return self.merged_to_item.final_item + return self + def recast_to(self, model: "type[Any]") -> "Item": logger.warning(f"recast item {self} to {model}") if isinstance(self, model): @@ -657,6 +663,12 @@ def display_description(self) -> str: def brief_description(self): return (str(self.display_description) or "")[:155] + def to_indexable_titles(self) -> list[str]: + titles = [t["text"] for t in self.localized_title if t] + if self.parent_item: + titles += self.parent_item.to_indexable_titles() + return list(set(titles)) + @classmethod def get_by_url(cls, url_or_b62: str, resolve_merge=False) -> "Self | None": b62 = url_or_b62.strip().split("/")[-1] diff --git a/catalog/movie/models.py b/catalog/movie/models.py index 55624873..5955bf16 100644 --- a/catalog/movie/models.py +++ b/catalog/movie/models.py @@ -173,3 +173,8 @@ def lookup_id_cleanup(cls, lookup_id_type, lookup_id_value): else: return None, None return super().lookup_id_cleanup(lookup_id_type, lookup_id_value) + + def to_indexable_titles(self) -> list[str]: + titles = [t["text"] for t in self.localized_title if t] + titles += [self.orig_title] if self.orig_title else [] + return list(set(titles)) diff --git a/catalog/search/views.py b/catalog/search/views.py index 23d16f65..7d471559 100644 --- a/catalog/search/views.py +++ b/catalog/search/views.py @@ -1,4 +1,5 @@ import re +from urllib.parse import quote import django_rq from django.conf import settings @@ -6,12 +7,14 @@ from django.core.cache import cache from django.core.exceptions import BadRequest from django.shortcuts import redirect, render +from django.urls import reverse from django.utils.translation import gettext as _ from django.views.decorators.http import require_http_methods from rq.job import Job from catalog.common.models import ItemCategory, SiteName from catalog.common.sites import AbstractSite, SiteManager +from common.models import int_ from common.utils import ( HTTPResponseHXRedirect, PageLinksGenerator, @@ -37,7 +40,7 @@ def fetch_refresh(request, job_id): else: return HTTPResponseHXRedirect(item_url) else: - retry = int(request.GET.get("retry", 0)) + 1 + retry = int_(request.GET.get("retry", 0)) + 1 if retry > 10: return render(request, "_fetch_failed.html") else: @@ -97,10 +100,10 @@ def visible_categories(request): @user_identity_required def search(request): + category = request.GET.get("c", default="all").strip().lower() keywords = request.GET.get("q", default="").strip() if re.match(r"^[@@]", keywords): return query_identity(request, keywords.replace("@", "@")) - category = request.GET.get("c", default="all").strip().lower() hide_category = False if category == "all" or not category: category = None @@ -115,8 +118,7 @@ def search(request): categories = visible_categories(request) tag = request.GET.get("tag", default="").strip() tag = Tag.deep_cleanup_title(tag, default="") - p = request.GET.get("page", default="1") - p = int(p) if p.isdigit() else 1 + p = int_(request.GET.get("page", default="1"), 1) if not (keywords or tag): return render( request, @@ -158,7 +160,7 @@ def external_search(request): if category == "all": category = None keywords = request.GET.get("q", default="").strip() - page_number = int(request.GET.get("page", default=1)) + page_number = int_(request.GET.get("page"), 1) items = ExternalSources.search(category, keywords, page_number) if keywords else [] cache_key = f"search_{category if category!='movietv' else 'movie,tv'}_{keywords}" dedupe_urls = cache.get(cache_key, []) diff --git a/catalog/templates/_item_card_metadata_base.html b/catalog/templates/_item_card_metadata_base.html index adb3be2a..dfad9b1b 100644 --- a/catalog/templates/_item_card_metadata_base.html +++ b/catalog/templates/_item_card_metadata_base.html @@ -52,7 +52,7 @@
{% trans "No items matching the search query." %}
+ {% endfor %} +https://www.imdb.com/title/tt2513074/
) to the search box and press Enter."
msgstr ""
-#: catalog/templates/search_results.html:107
+#: catalog/templates/search_results.html:49
#, python-format
msgid " %(dups)s items are from the same work or have the same identifier, they are hidden from the search results, click here to show them. "
msgstr ""
-#: catalog/templates/search_results.html:121
+#: catalog/templates/search_results.html:63
msgid "Searching from other sites"
msgstr ""
-#: catalog/templates/search_results.html:124
+#: catalog/templates/search_results.html:66
msgid "Logged in user may see search results from other sites."
msgstr ""
@@ -1407,7 +1427,7 @@ msgstr ""
msgid "all seasons"
msgstr ""
-#: catalog/templates/tvseason.html:32 catalog/tv/models.py:268
+#: catalog/templates/tvseason.html:32 catalog/tv/models.py:273
msgid "season number"
msgstr ""
@@ -1417,7 +1437,7 @@ msgid "number of seasons"
msgstr ""
#: catalog/templates/tvseason.html:42 catalog/templates/tvshow.html:37
-#: catalog/tv/models.py:113 catalog/tv/models.py:271
+#: catalog/tv/models.py:113 catalog/tv/models.py:276
msgid "number of episodes"
msgstr ""
@@ -1425,7 +1445,7 @@ msgstr ""
msgid "Editions"
msgstr ""
-#: catalog/tv/models.py:176 catalog/tv/models.py:334
+#: catalog/tv/models.py:176 catalog/tv/models.py:339
msgid "show time"
msgstr ""
@@ -1437,16 +1457,16 @@ msgstr ""
msgid "Region or Event"
msgstr ""
-#: catalog/tv/models.py:219 catalog/tv/models.py:388
+#: catalog/tv/models.py:219 catalog/tv/models.py:393
msgid "episode length"
msgstr ""
-#: catalog/tv/models.py:419
+#: catalog/tv/models.py:424
#, python-brace-format
msgid "{show_title} Season {season_number}"
msgstr ""
-#: catalog/tv/models.py:483
+#: catalog/tv/models.py:494
#, python-brace-format
msgid "{season_title} E{episode_number}"
msgstr ""
@@ -1469,23 +1489,23 @@ msgstr ""
#: catalog/views_edit.py:147 catalog/views_edit.py:199
#: catalog/views_edit.py:275 catalog/views_edit.py:354
-#: journal/views/collection.py:50 journal/views/collection.py:100
-#: journal/views/collection.py:112 journal/views/collection.py:129
-#: journal/views/collection.py:195 journal/views/collection.py:214
-#: journal/views/collection.py:234 journal/views/collection.py:246
-#: journal/views/collection.py:260 journal/views/collection.py:274
-#: journal/views/collection.py:277 journal/views/collection.py:301
+#: journal/views/collection.py:51 journal/views/collection.py:101
+#: journal/views/collection.py:113 journal/views/collection.py:130
+#: journal/views/collection.py:196 journal/views/collection.py:215
+#: journal/views/collection.py:235 journal/views/collection.py:247
+#: journal/views/collection.py:261 journal/views/collection.py:275
+#: journal/views/collection.py:278 journal/views/collection.py:302
#: journal/views/common.py:136 journal/views/post.py:20
#: journal/views/post.py:42 journal/views/review.py:32
#: journal/views/review.py:46
msgid "Insufficient permission"
msgstr ""
-#: catalog/views_edit.py:202 journal/views/collection.py:263
-#: journal/views/collection.py:330 journal/views/common.py:83
+#: catalog/views_edit.py:202 journal/views/collection.py:264
+#: journal/views/collection.py:331 journal/views/common.py:83
#: journal/views/mark.py:146 journal/views/post.py:56 journal/views/post.py:70
#: journal/views/review.py:93 journal/views/review.py:96
-#: users/views/actions.py:168
+#: users/views/actions.py:169
msgid "Invalid parameter"
msgstr ""
@@ -2344,7 +2364,7 @@ msgstr ""
msgid "Source Code"
msgstr ""
-#: common/templates/_footer.html:16 users/templates/users/login.html:195
+#: common/templates/_footer.html:16 users/templates/users/login.html:207
#, python-format
msgid "You are visiting an alternative domain for %(site_name)s, please always use original version if possible."
msgstr ""
@@ -2354,61 +2374,69 @@ msgid "title, creator, ISBN, item url, @user, @user@instance"
msgstr ""
#: common/templates/_header.html:22
-msgid "Everything"
+msgid "All Items"
msgstr ""
#: common/templates/_header.html:29
msgid "Movie & TV"
msgstr ""
-#: common/templates/_header.html:68
+#: common/templates/_header.html:49
+msgid "Journal"
+msgstr ""
+
+#: common/templates/_header.html:51
+msgid "Posts"
+msgstr ""
+
+#: common/templates/_header.html:74
msgid "Explore"
msgstr ""
-#: common/templates/_header.html:71
+#: common/templates/_header.html:77
msgid "Feed"
msgstr ""
-#: common/templates/_header.html:74 journal/templates/profile.html:11
+#: common/templates/_header.html:80 journal/templates/profile.html:11
#: users/templates/users/preferences.html:45
msgid "Home"
msgstr ""
-#: common/templates/_header.html:89 social/templates/notification.html:11
+#: common/templates/_header.html:96 social/templates/notification.html:11
#: social/templates/notification.html:24
msgid "Notification"
msgstr ""
-#: common/templates/_header.html:92
+#: common/templates/_header.html:99
msgid "Data"
msgstr ""
-#: common/templates/_header.html:95 users/templates/users/preferences.html:11
+#: common/templates/_header.html:102 users/templates/users/preferences.html:11
#: users/templates/users/preferences.html:22
msgid "Preferences"
msgstr ""
-#: common/templates/_header.html:98
+#: common/templates/_header.html:105
msgid "Account"
msgstr ""
-#: common/templates/_header.html:101
+#: common/templates/_header.html:108
msgid "Logout"
msgstr ""
-#: common/templates/_header.html:105
+#: common/templates/_header.html:112
msgid "Database"
msgstr ""
-#: common/templates/_header.html:108
+#: common/templates/_header.html:115
msgid "Manage"
msgstr ""
-#: common/templates/_header.html:113
+#: common/templates/_header.html:120
msgid "Sign up or Login"
msgstr ""
-#: common/templates/_header.html:127
+#: common/templates/_header.html:134
msgid "Open"
msgstr ""
@@ -2503,16 +2531,16 @@ msgstr ""
msgid "following you"
msgstr ""
-#: common/utils.py:63 common/utils.py:93 users/views/actions.py:34
-#: users/views/actions.py:120
+#: common/utils.py:64 common/utils.py:94 users/views/actions.py:35
+#: users/views/actions.py:121
msgid "User not found"
msgstr ""
-#: common/utils.py:67 common/utils.py:97 users/views/actions.py:123
+#: common/utils.py:68 common/utils.py:98 users/views/actions.py:124
msgid "User no longer exists"
msgstr ""
-#: common/utils.py:75 common/utils.py:105
+#: common/utils.py:76 common/utils.py:106
msgid "Access denied"
msgstr ""
@@ -2525,14 +2553,14 @@ msgid "Content (Markdown)"
msgstr ""
#: journal/forms.py:21 journal/templates/comment.html:62
-#: journal/templates/mark.html:123 journal/views/note.py:26
+#: journal/templates/mark.html:117 journal/views/note.py:26
msgid "Crosspost to timeline"
msgstr ""
#: journal/forms.py:25 journal/forms.py:45
#: journal/templates/collection_share.html:24
#: journal/templates/wrapped_share.html:36 users/templates/users/data.html:38
-#: users/templates/users/data.html:130
+#: users/templates/users/data.html:139
msgid "Visibility"
msgstr ""
@@ -2548,7 +2576,7 @@ msgstr ""
msgid "Collaborative editing"
msgstr ""
-#: journal/importers/letterboxd.py:108
+#: journal/importers/letterboxd.py:107
#, python-brace-format
msgid "a review of {item_title}"
msgstr ""
@@ -2565,42 +2593,46 @@ msgstr ""
msgid "note"
msgstr ""
-#: journal/models/common.py:37 journal/templates/action_open_post.html:8
+#: journal/models/collection.py:143
+msgid "created collection"
+msgstr ""
+
+#: journal/models/common.py:38 journal/templates/action_open_post.html:8
#: journal/templates/action_open_post.html:14
#: journal/templates/action_open_post.html:16
#: journal/templates/collection_share.html:35 journal/templates/comment.html:35
-#: journal/templates/mark.html:96 journal/templates/tag_edit.html:42
+#: journal/templates/mark.html:90 journal/templates/tag_edit.html:42
#: journal/templates/wrapped_share.html:43 users/templates/users/data.html:47
-#: users/templates/users/data.html:139
+#: users/templates/users/data.html:148
#: users/templates/users/preferences.html:55
msgid "Public"
msgstr ""
-#: journal/models/common.py:38 journal/templates/action_open_post.html:10
+#: journal/models/common.py:39 journal/templates/action_open_post.html:10
#: journal/templates/collection_share.html:46 journal/templates/comment.html:42
-#: journal/templates/mark.html:103 journal/templates/wrapped_share.html:49
-#: users/templates/users/data.html:55 users/templates/users/data.html:147
+#: journal/templates/mark.html:97 journal/templates/wrapped_share.html:49
+#: users/templates/users/data.html:55 users/templates/users/data.html:156
#: users/templates/users/preferences.html:62
msgid "Followers Only"
msgstr ""
-#: journal/models/common.py:39 journal/templates/action_open_post.html:12
+#: journal/models/common.py:40 journal/templates/action_open_post.html:12
#: journal/templates/collection_share.html:57 journal/templates/comment.html:49
-#: journal/templates/mark.html:110 journal/templates/wrapped_share.html:55
-#: users/templates/users/data.html:63 users/templates/users/data.html:155
+#: journal/templates/mark.html:104 journal/templates/wrapped_share.html:55
+#: users/templates/users/data.html:63 users/templates/users/data.html:164
#: users/templates/users/preferences.html:69
msgid "Mentioned Only"
msgstr ""
-#: journal/models/common.py:368
+#: journal/models/common.py:370
msgid "A recent post was not posted to Threads."
msgstr ""
-#: journal/models/common.py:402
+#: journal/models/common.py:404
msgid "A recent post was not posted to Mastodon, please re-authorize."
msgstr ""
-#: journal/models/common.py:409
+#: journal/models/common.py:411
msgid "A recent post was not posted to Mastodon."
msgstr ""
@@ -3078,7 +3110,7 @@ msgstr ""
msgid "performances reviewed"
msgstr ""
-#: journal/models/shelf.py:534
+#: journal/models/shelf.py:562
msgid "removed mark"
msgstr ""
@@ -3253,7 +3285,7 @@ msgstr ""
msgid "Comment"
msgstr ""
-#: journal/templates/comment.html:24 journal/templates/mark.html:74
+#: journal/templates/comment.html:24 journal/templates/mark.html:68
msgid "Tips: use >!text!< for spoilers; some instances may not be able to show posts longer than 360 charactors."
msgstr ""
@@ -3265,20 +3297,19 @@ msgstr ""
msgid "Mark"
msgstr ""
-#: journal/templates/mark.html:51 journal/templates/mark.html:55
-#: journal/templates/mark.html:59
+#: journal/templates/mark.html:51
msgid "not rated"
msgstr ""
-#: journal/templates/mark.html:82
+#: journal/templates/mark.html:76
msgid "add a tag and press Enter"
msgstr ""
-#: journal/templates/mark.html:138
+#: journal/templates/mark.html:132
msgid "change mark date"
msgstr ""
-#: journal/templates/mark.html:164
+#: journal/templates/mark.html:158
msgid "Sure to delete mark, comment and tags for this item?"
msgstr ""
@@ -3352,20 +3383,20 @@ msgstr ""
msgid "Deletion cannot be undone, are you sure to continue?"
msgstr ""
-#: journal/templates/profile.html:55
+#: journal/templates/profile.html:51
msgid "calendar"
msgstr ""
-#: journal/templates/profile.html:58 journal/templates/wrapped.html:14
+#: journal/templates/profile.html:54 journal/templates/wrapped.html:14
#: journal/templates/wrapped.html:53
msgid "annual summary"
msgstr ""
-#: journal/templates/profile.html:131 journal/views/collection.py:165
+#: journal/templates/profile.html:119 journal/views/collection.py:166
msgid "collection"
msgstr ""
-#: journal/templates/profile.html:171
+#: journal/templates/profile.html:155
msgid "liked collection"
msgstr ""
@@ -3389,6 +3420,10 @@ msgstr ""
msgid "change review date"
msgstr ""
+#: journal/templates/search_journal.html:25
+msgid "No items matching the search query."
+msgstr ""
+
#: journal/templates/tag_edit.html:32
msgid "Pin"
msgstr ""
@@ -3491,25 +3526,25 @@ msgid_plural "%(count)d items"
msgstr[0] ""
msgstr[1] ""
-#: journal/views/collection.py:36
+#: journal/views/collection.py:37
#, python-brace-format
msgid "Collection by {0}"
msgstr ""
-#: journal/views/collection.py:170
+#: journal/views/collection.py:171
msgid "shared my collection"
msgstr ""
-#: journal/views/collection.py:173
+#: journal/views/collection.py:174
#, python-brace-format
msgid "shared {username}'s collection"
msgstr ""
-#: journal/views/collection.py:224
+#: journal/views/collection.py:225
msgid "Unable to find the item, please use item url from this site."
msgstr ""
-#: journal/views/collection.py:337 journal/views/collection.py:358
+#: journal/views/collection.py:338 journal/views/collection.py:359
#: journal/views/review.py:124
msgid "Login required"
msgstr ""
@@ -3593,12 +3628,12 @@ msgstr ""
msgid "Tag updated."
msgstr ""
-#: journal/views/wrapped.py:145
+#: journal/views/wrapped.py:146
msgid "Summary posted to timeline."
msgstr ""
#: mastodon/models/common.py:14 users/templates/users/account.html:44
-#: users/templates/users/login.html:57
+#: users/templates/users/login.html:60
msgid "Email"
msgstr ""
@@ -3606,7 +3641,7 @@ msgstr ""
msgid "Mastodon"
msgstr ""
-#: mastodon/models/common.py:16 users/templates/users/login.html:76
+#: mastodon/models/common.py:16 users/templates/users/login.html:85
msgid "Threads"
msgstr ""
@@ -3621,6 +3656,10 @@ msgid ""
"If you did not mean to register or login, please ignore this email. If you are concerned with your account security, please change the email linked with your account, or contact us."
msgstr ""
+#: mastodon/models/email.py:60 mastodon/models/email.py:65
+msgid "Verification Code"
+msgstr ""
+
#: mastodon/models/email.py:62
#, python-brace-format
msgid ""
@@ -3637,6 +3676,11 @@ msgid ""
"{code}"
msgstr ""
+#: mastodon/models/email.py:70 users/templates/users/login.html:16
+#: users/templates/users/register.html:8 users/templates/users/welcome.html:8
+msgid "Register"
+msgstr ""
+
#: mastodon/models/email.py:72
#, python-brace-format
msgid ""
@@ -3695,7 +3739,7 @@ msgstr ""
#: mastodon/views/common.py:30 mastodon/views/mastodon.py:37
#: mastodon/views/mastodon.py:44 mastodon/views/mastodon.py:54
#: mastodon/views/mastodon.py:61 mastodon/views/threads.py:41
-#: mastodon/views/threads.py:47 users/views/account.py:104
+#: mastodon/views/threads.py:47 users/views/account.py:105
msgid "Authentication failed"
msgstr ""
@@ -3951,7 +3995,7 @@ msgid ""
msgstr ""
#: social/templates/feed.html:11 social/templates/feed.html:23
-#: social/templates/notification.html:23
+#: social/templates/notification.html:23 social/templates/search_feed.html:11
msgid "Activities from those you follow"
msgstr ""
@@ -3983,7 +4027,11 @@ msgstr ""
msgid "wrote a note"
msgstr ""
-#: social/templates/feed_events.html:140
+#: social/templates/feed_events.html:139
+msgid "no matching activities."
+msgstr ""
+
+#: social/templates/feed_events.html:142
#, 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 ""
@@ -4024,23 +4072,19 @@ msgstr ""
msgid "Header picture"
msgstr ""
-#: takahe/utils.py:565
-msgid "created collection"
-msgstr ""
-
-#: users/models/task.py:17
+#: users/models/task.py:19
msgid "Pending"
msgstr ""
-#: users/models/task.py:18
+#: users/models/task.py:20
msgid "Started"
msgstr ""
-#: users/models/task.py:19
+#: users/models/task.py:21
msgid "Complete"
msgstr ""
-#: users/models/task.py:20
+#: users/models/task.py:22
msgid "Failed"
msgstr ""
@@ -4076,20 +4120,20 @@ msgstr ""
msgid "Username"
msgstr ""
-#: users/templates/users/account.html:50 users/templates/users/register.html:30
+#: users/templates/users/account.html:50 users/templates/users/register.html:37
msgid "Email address"
msgstr ""
-#: users/templates/users/account.html:59 users/templates/users/register.html:39
+#: users/templates/users/account.html:59 users/templates/users/register.html:46
#, python-format
msgid "Please click the confirmation link in the email sent to %(pending_email)s; if you haven't received it for more than a few minutes, please input and save again."
msgstr ""
-#: users/templates/users/account.html:61 users/templates/users/register.html:42
+#: users/templates/users/account.html:61 users/templates/users/register.html:49
msgid "Email is recommended as a backup login method, if you log in via a Fediverse instance"
msgstr ""
-#: users/templates/users/account.html:73 users/templates/users/login.html:63
+#: users/templates/users/account.html:73 users/templates/users/login.html:69
msgid "Fediverse (Mastodon)"
msgstr ""
@@ -4157,7 +4201,7 @@ msgstr ""
msgid "Disconnect with Threads"
msgstr ""
-#: users/templates/users/account.html:173 users/templates/users/login.html:83
+#: users/templates/users/account.html:173 users/templates/users/login.html:95
msgid "Bluesky (ATProto)"
msgstr ""
@@ -4169,7 +4213,7 @@ msgstr ""
msgid "Bluesky Login ID"
msgstr ""
-#: users/templates/users/account.html:202 users/templates/users/login.html:159
+#: users/templates/users/account.html:202 users/templates/users/login.html:171
msgid "Bluesky app password"
msgstr ""
@@ -4181,7 +4225,7 @@ msgstr ""
msgid "Link with an ATProto identity"
msgstr ""
-#: users/templates/users/account.html:209 users/templates/users/login.html:164
+#: users/templates/users/account.html:209 users/templates/users/login.html:176
msgid "App password can be created on bsky.app."
msgstr ""
@@ -4253,11 +4297,11 @@ msgstr ""
msgid "Once deleted, account data cannot be recovered."
msgstr ""
-#: users/templates/users/account.html:321
+#: users/templates/users/account.html:322
msgid "Importing in progress, can't delete now."
msgstr ""
-#: users/templates/users/account.html:324
+#: users/templates/users/account.html:326
msgid "Permanently Delete"
msgstr ""
@@ -4273,7 +4317,7 @@ msgstr ""
msgid "Select .xlsx
exported from Doufen"
msgstr ""
-#: users/templates/users/data.html:27 users/templates/users/data.html:185
+#: users/templates/users/data.html:27 users/templates/users/data.html:194
msgid "Import Method"
msgstr ""
@@ -4294,7 +4338,7 @@ msgid "Import in progress, please wait"
msgstr ""
#: users/templates/users/data.html:67 users/templates/users/data.html:86
-#: users/templates/users/data.html:158 users/templates/users/data.html:201
+#: users/templates/users/data.html:167 users/templates/users/data.html:210
msgid "Import"
msgstr ""
@@ -4306,74 +4350,81 @@ msgstr ""
msgid "Link to Goodreads Profile / Shelf / List"
msgstr ""
-#: users/templates/users/data.html:91
+#: users/templates/users/data.html:90 users/templates/users/data.html:172
+#: users/templates/users/data_import_status.html:2
+msgid "Last import started"
+msgstr ""
+
+#: users/templates/users/data.html:91 users/templates/users/data.html:173
+#: users/templates/users/data.html:226
+#: users/templates/users/data_import_status.html:3
+msgid "Status"
+msgstr ""
+
+#: users/templates/users/data.html:100
msgid "want-to-read / currently-reading / read books and their reviews will be imported."
msgstr ""
-#: users/templates/users/data.html:95
+#: users/templates/users/data.html:104
msgid "Shelf will be imported as a new collection."
msgstr ""
-#: users/templates/users/data.html:99
+#: users/templates/users/data.html:108
msgid "List will be imported as a new collection."
msgstr ""
-#: users/templates/users/data.html:110
+#: users/templates/users/data.html:119
msgid "Import from Letterboxd"
msgstr ""
-#: users/templates/users/data.html:160
+#: users/templates/users/data.html:169
msgid "Only forward changes(none->to-watch->watched) will be imported."
msgstr ""
-#: users/templates/users/data.html:163
-msgid "Last import started"
-msgstr ""
-
-#: users/templates/users/data.html:164
-msgid "Status"
-msgstr ""
-
-#: users/templates/users/data.html:168
+#: users/templates/users/data.html:177
msgid "Failed links, likely due to Letterboxd error, you may have to mark them manually"
msgstr ""
-#: users/templates/users/data.html:179
+#: users/templates/users/data.html:188
msgid "Import Podcast Subscriptions"
msgstr ""
-#: users/templates/users/data.html:192
+#: users/templates/users/data.html:201
msgid "Mark as listening"
msgstr ""
-#: users/templates/users/data.html:196
+#: users/templates/users/data.html:205
msgid "Import as a new collection"
msgstr ""
-#: users/templates/users/data.html:199
+#: users/templates/users/data.html:208
msgid "Select OPML file"
msgstr ""
-#: users/templates/users/data.html:208
+#: users/templates/users/data.html:217
msgid "Export Data"
msgstr ""
-#: users/templates/users/data.html:214
-msgid "Export in progress"
+#: users/templates/users/data.html:222
+msgid "Export marks and reviews"
msgstr ""
-#: users/templates/users/data.html:214
-msgid "Export marks and reviews"
+#: users/templates/users/data.html:225
+msgid "Last export"
msgstr ""
-#: users/templates/users/data.html:216
+#: users/templates/users/data.html:230
msgid "Download"
msgstr ""
-#: users/templates/users/data.html:223
+#: users/templates/users/data.html:238
msgid "View Annual Summary"
msgstr ""
+#: users/templates/users/data_import_status.html:11
+msgid "Failed links, you may have to mark them manually"
+msgstr ""
+
#: users/templates/users/fetch_identity_failed.html:4
msgid "Unable to find the user, please check your spelling; or the server may be busy, please try again later."
msgstr ""
@@ -4383,11 +4434,6 @@ msgstr ""
msgid "Searching the fediverse"
msgstr ""
-#: users/templates/users/login.html:16 users/templates/users/register.html:8
-#: users/templates/users/welcome.html:8
-msgid "Register"
-msgstr ""
-
#: users/templates/users/login.html:16
msgid "Login"
msgstr ""
@@ -4397,72 +4443,72 @@ msgstr ""
msgid "back to your home page."
msgstr ""
-#: users/templates/users/login.html:99
+#: users/templates/users/login.html:111
msgid "Enter your email address"
msgstr ""
-#: users/templates/users/login.html:101
+#: users/templates/users/login.html:113
msgid "Send verification code"
msgstr ""
-#: users/templates/users/login.html:116
+#: users/templates/users/login.html:128
msgid "Domain of your instance, e.g. mastodon.social"
msgstr ""
-#: users/templates/users/login.html:122
+#: users/templates/users/login.html:134
msgid "Please enter domain of your instance; e.g. if your id is @neodb@mastodon.social, only enter mastodon.social."
msgstr ""
-#: users/templates/users/login.html:125 users/templates/users/login.html:178
+#: users/templates/users/login.html:137 users/templates/users/login.html:190
msgid "Authorize via Fediverse instance"
msgstr ""
-#: users/templates/users/login.html:127
+#: users/templates/users/login.html:139
msgid "If you don't have a Fediverse (Mastodon) account yet, you may register or login with Email first, and link it with Fediverse (Mastodon) later in account settings."
msgstr ""
-#: users/templates/users/login.html:137
+#: users/templates/users/login.html:149
msgid "Authorize via Threads"
msgstr ""
-#: users/templates/users/login.html:150
+#: users/templates/users/login.html:162
msgid "ATProto handle"
msgstr ""
-#: users/templates/users/login.html:155
+#: users/templates/users/login.html:167
msgid "Please input your ATProto handle (e.g. neodb.bsky.social, without the leading @), do not use email. If you changed handle recently, just use the latest one."
msgstr ""
-#: users/templates/users/login.html:165
+#: users/templates/users/login.html:177
msgid "Authorize via bsky.app"
msgstr ""
-#: users/templates/users/login.html:169
+#: users/templates/users/login.html:181
#, python-format
msgid "Please choose one to register or login %(site_name)s. Have more than one of these identities? Don't worry, you may link them in account settings once logged in."
msgstr ""
-#: users/templates/users/login.html:185
+#: users/templates/users/login.html:197
msgid "Valid invitation code, please login or register."
msgstr ""
-#: users/templates/users/login.html:187
+#: users/templates/users/login.html:199
msgid "Please use invitation link to register a new account; existing user may login."
msgstr ""
-#: users/templates/users/login.html:189
+#: users/templates/users/login.html:201
msgid "Invitation code invalid or expired."
msgstr ""
-#: users/templates/users/login.html:197
+#: users/templates/users/login.html:209
msgid "Loading timed out, please check your network (VPN) settings."
msgstr ""
-#: users/templates/users/login.html:203
+#: users/templates/users/login.html:215
msgid "Continue using this site implies consent to our rules and terms, including using cookies to provide necessary functionality."
msgstr ""
-#: users/templates/users/login.html:209
+#: users/templates/users/login.html:221
msgid "Domain of your instance (excl. @)"
msgstr ""
@@ -4687,27 +4733,27 @@ msgstr ""
msgid "Your username on %(site_name)s"
msgstr ""
-#: users/templates/users/register.html:26
+#: users/templates/users/register.html:27
msgid "2-30 alphabets, numbers or underscore, can't be changed once saved"
msgstr ""
-#: users/templates/users/register.html:60
+#: users/templates/users/register.html:67
msgid "Turn on crosspost to other social networks by default"
msgstr ""
-#: users/templates/users/register.html:64
+#: users/templates/users/register.html:71
msgid "Use display name, bio and avatar from the social network you authenticated with"
msgstr ""
-#: users/templates/users/register.html:72
+#: users/templates/users/register.html:79
msgid "Add follow, mute and block list from the social network you authenticated with"
msgstr ""
-#: users/templates/users/register.html:77
+#: users/templates/users/register.html:84
msgid "Confirm and save"
msgstr ""
-#: users/templates/users/register.html:81 users/templates/users/welcome.html:27
+#: users/templates/users/register.html:88 users/templates/users/welcome.html:27
msgid "Cut the sh*t and get me in!"
msgstr ""
@@ -4748,66 +4794,70 @@ msgid ""
" "
msgstr ""
-#: users/views/account.py:78
+#: users/views/account.py:79
msgid "This username is already in use."
msgstr ""
-#: users/views/account.py:89
+#: users/views/account.py:90
msgid "This email address is already in use."
msgstr ""
-#: users/views/account.py:105
+#: users/views/account.py:106
msgid "Registration is for invitation only"
msgstr ""
-#: users/views/account.py:175
+#: users/views/account.py:176
msgid "Valid username required"
msgstr ""
-#: users/views/account.py:177
+#: users/views/account.py:178
msgid "Username in use"
msgstr ""
-#: users/views/account.py:247
+#: users/views/account.py:250
msgid "Account is being deleted."
msgstr ""
-#: users/views/account.py:250
+#: users/views/account.py:253
msgid "Account mismatch."
msgstr ""
-#: users/views/data.py:128
+#: users/views/data.py:129
msgid "Generating exports."
msgstr ""
-#: users/views/data.py:140
+#: users/views/data.py:135
+msgid "Export file not available."
+msgstr ""
+
+#: users/views/data.py:147
msgid "Export file expired. Please export again."
msgstr ""
-#: users/views/data.py:149
+#: users/views/data.py:156
msgid "Sync in progress."
msgstr ""
-#: users/views/data.py:163
+#: users/views/data.py:170
msgid "Settings saved."
msgstr ""
-#: users/views/data.py:174
+#: users/views/data.py:181
msgid "Reset completed."
msgstr ""
-#: users/views/data.py:183
+#: users/views/data.py:195
msgid "Import in progress."
msgstr ""
-#: users/views/data.py:185
+#: users/views/data.py:197
msgid "Invalid URL."
msgstr ""
-#: users/views/data.py:199 users/views/data.py:224 users/views/data.py:239
-msgid "File is uploaded and will be imported soon."
+#: users/views/data.py:215 users/views/data.py:265
+msgid "Invalid file."
msgstr ""
-#: users/views/data.py:202 users/views/data.py:242
-msgid "Invalid file."
+#: users/views/data.py:224 users/views/data.py:247 users/views/data.py:262
+msgid "File is uploaded and will be imported soon."
msgstr ""
diff --git a/locale/zh_Hans/LC_MESSAGES/django.po b/locale/zh_Hans/LC_MESSAGES/django.po
index 3dc97cca..a4750e26 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-12-01 16:06-0500\n"
+"POT-Creation-Date: 2024-12-30 01:47-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME https://www.imdb.com/title/tt2513074/
) to the search box and press Enter."
msgstr "如果你在以下网站找到了相关条目,也可以把链接(如 https://movie.douban.com/subject/1309046/
)输入到搜索栏中提交保存到本站。"
-#: catalog/templates/search_results.html:107
+#: catalog/templates/search_results.html:49
#, python-format
msgid " %(dups)s items are from the same work or have the same identifier, they are hidden from the search results, click here to show them. "
msgstr "已从结果中略去了来自同一作品或有相同标识号的%(dups)s个条目,点击这里可重新显示"
-#: catalog/templates/search_results.html:121
+#: catalog/templates/search_results.html:63
msgid "Searching from other sites"
msgstr "正在搜索站外条目"
-#: catalog/templates/search_results.html:124
+#: catalog/templates/search_results.html:66
msgid "Logged in user may see search results from other sites."
msgstr "登录用户可看到来自其它网站的搜索结果。"
@@ -1404,7 +1424,7 @@ msgstr "登录用户可看到来自其它网站的搜索结果。"
msgid "all seasons"
msgstr "本剧所有季"
-#: catalog/templates/tvseason.html:32 catalog/tv/models.py:268
+#: catalog/templates/tvseason.html:32 catalog/tv/models.py:273
msgid "season number"
msgstr "本季序号"
@@ -1414,7 +1434,7 @@ msgid "number of seasons"
msgstr "季数"
#: catalog/templates/tvseason.html:42 catalog/templates/tvshow.html:37
-#: catalog/tv/models.py:113 catalog/tv/models.py:271
+#: catalog/tv/models.py:113 catalog/tv/models.py:276
msgid "number of episodes"
msgstr "集数"
@@ -1422,7 +1442,7 @@ msgstr "集数"
msgid "Editions"
msgstr "版本"
-#: catalog/tv/models.py:176 catalog/tv/models.py:334
+#: catalog/tv/models.py:176 catalog/tv/models.py:339
msgid "show time"
msgstr "上映时间"
@@ -1434,16 +1454,16 @@ msgstr "日期"
msgid "Region or Event"
msgstr "地区或场合"
-#: catalog/tv/models.py:219 catalog/tv/models.py:388
+#: catalog/tv/models.py:219 catalog/tv/models.py:393
msgid "episode length"
msgstr "单集长度"
-#: catalog/tv/models.py:419
+#: catalog/tv/models.py:424
#, python-brace-format
msgid "{show_title} Season {season_number}"
msgstr "{show_title} 第{season_number}季"
-#: catalog/tv/models.py:483
+#: catalog/tv/models.py:494
#, python-brace-format
msgid "{season_title} E{episode_number}"
msgstr "{season_title} 第{episode_number}集"
@@ -1466,23 +1486,23 @@ msgstr "条目不可被删除。"
#: catalog/views_edit.py:147 catalog/views_edit.py:199
#: catalog/views_edit.py:275 catalog/views_edit.py:354
-#: journal/views/collection.py:50 journal/views/collection.py:100
-#: journal/views/collection.py:112 journal/views/collection.py:129
-#: journal/views/collection.py:195 journal/views/collection.py:214
-#: journal/views/collection.py:234 journal/views/collection.py:246
-#: journal/views/collection.py:260 journal/views/collection.py:274
-#: journal/views/collection.py:277 journal/views/collection.py:301
+#: journal/views/collection.py:51 journal/views/collection.py:101
+#: journal/views/collection.py:113 journal/views/collection.py:130
+#: journal/views/collection.py:196 journal/views/collection.py:215
+#: journal/views/collection.py:235 journal/views/collection.py:247
+#: journal/views/collection.py:261 journal/views/collection.py:275
+#: journal/views/collection.py:278 journal/views/collection.py:302
#: journal/views/common.py:136 journal/views/post.py:20
#: journal/views/post.py:42 journal/views/review.py:32
#: journal/views/review.py:46
msgid "Insufficient permission"
msgstr "权限不足"
-#: catalog/views_edit.py:202 journal/views/collection.py:263
-#: journal/views/collection.py:330 journal/views/common.py:83
+#: catalog/views_edit.py:202 journal/views/collection.py:264
+#: journal/views/collection.py:331 journal/views/common.py:83
#: journal/views/mark.py:146 journal/views/post.py:56 journal/views/post.py:70
#: journal/views/review.py:93 journal/views/review.py:96
-#: users/views/actions.py:168
+#: users/views/actions.py:169
msgid "Invalid parameter"
msgstr "无效参数"
@@ -2256,7 +2276,7 @@ msgstr "繁体中文(香港)"
#: common/models/lang.py:295
msgid "Portuguese (Brazil)"
-msgstr ""
+msgstr "葡萄牙语(巴西)"
#: common/models/lang.py:298
msgid "Simplified Chinese (Singapore)"
@@ -2341,7 +2361,7 @@ msgstr "开发者"
msgid "Source Code"
msgstr "源代码"
-#: common/templates/_footer.html:16 users/templates/users/login.html:195
+#: common/templates/_footer.html:16 users/templates/users/login.html:207
#, python-format
msgid "You are visiting an alternative domain for %(site_name)s, please always use original version if possible."
msgstr "这是%(site_name)s的临时镜像,请尽可能使用原始站点。"
@@ -2351,61 +2371,69 @@ msgid "title, creator, ISBN, item url, @user, @user@instance"
msgstr "标题、创作者、ISBN、站外条目链接、@用户名、@用户名@实例"
#: common/templates/_header.html:22
-msgid "Everything"
+msgid "All Items"
msgstr "全部"
#: common/templates/_header.html:29
msgid "Movie & TV"
msgstr "影视"
-#: common/templates/_header.html:68
+#: common/templates/_header.html:49
+msgid "Journal"
+msgstr "记录"
+
+#: common/templates/_header.html:51
+msgid "Posts"
+msgstr "帖文"
+
+#: common/templates/_header.html:74
msgid "Explore"
msgstr "发现"
-#: common/templates/_header.html:71
+#: common/templates/_header.html:77
msgid "Feed"
msgstr "动态"
-#: common/templates/_header.html:74 journal/templates/profile.html:11
+#: common/templates/_header.html:80 journal/templates/profile.html:11
#: users/templates/users/preferences.html:45
msgid "Home"
msgstr "主页"
-#: common/templates/_header.html:89 social/templates/notification.html:11
+#: common/templates/_header.html:96 social/templates/notification.html:11
#: social/templates/notification.html:24
msgid "Notification"
msgstr "通知"
-#: common/templates/_header.html:92
+#: common/templates/_header.html:99
msgid "Data"
msgstr "数据"
-#: common/templates/_header.html:95 users/templates/users/preferences.html:11
+#: common/templates/_header.html:102 users/templates/users/preferences.html:11
#: users/templates/users/preferences.html:22
msgid "Preferences"
msgstr "设置"
-#: common/templates/_header.html:98
+#: common/templates/_header.html:105
msgid "Account"
msgstr "账号"
-#: common/templates/_header.html:101
+#: common/templates/_header.html:108
msgid "Logout"
msgstr "登出"
-#: common/templates/_header.html:105
+#: common/templates/_header.html:112
msgid "Database"
msgstr "数据库"
-#: common/templates/_header.html:108
+#: common/templates/_header.html:115
msgid "Manage"
msgstr "管理"
-#: common/templates/_header.html:113
+#: common/templates/_header.html:120
msgid "Sign up or Login"
msgstr "注册或登录"
-#: common/templates/_header.html:127
+#: common/templates/_header.html:134
msgid "Open"
msgstr "打开"
@@ -2518,16 +2546,16 @@ msgstr "已关注"
msgid "following you"
msgstr "关注了你"
-#: common/utils.py:63 common/utils.py:93 users/views/actions.py:34
-#: users/views/actions.py:120
+#: common/utils.py:64 common/utils.py:94 users/views/actions.py:35
+#: users/views/actions.py:121
msgid "User not found"
msgstr "用户不存在"
-#: common/utils.py:67 common/utils.py:97 users/views/actions.py:123
+#: common/utils.py:68 common/utils.py:98 users/views/actions.py:124
msgid "User no longer exists"
msgstr "用户不存在了"
-#: common/utils.py:75 common/utils.py:105
+#: common/utils.py:76 common/utils.py:106
msgid "Access denied"
msgstr "访问被拒绝"
@@ -2540,14 +2568,14 @@ msgid "Content (Markdown)"
msgstr "内容 (Markdown格式)"
#: journal/forms.py:21 journal/templates/comment.html:62
-#: journal/templates/mark.html:123 journal/views/note.py:26
+#: journal/templates/mark.html:117 journal/views/note.py:26
msgid "Crosspost to timeline"
msgstr "转发到时间轴"
#: journal/forms.py:25 journal/forms.py:45
#: journal/templates/collection_share.html:24
#: journal/templates/wrapped_share.html:36 users/templates/users/data.html:38
-#: users/templates/users/data.html:130
+#: users/templates/users/data.html:139
msgid "Visibility"
msgstr "可见性"
@@ -2563,7 +2591,7 @@ msgstr "创建者和他们的互相关注"
msgid "Collaborative editing"
msgstr "协作编辑"
-#: journal/importers/letterboxd.py:108
+#: journal/importers/letterboxd.py:107
#, python-brace-format
msgid "a review of {item_title}"
msgstr "关于 {item_title} 的评论"
@@ -2580,42 +2608,46 @@ msgstr "{username} 的播客订阅"
msgid "note"
msgstr "备注"
-#: journal/models/common.py:37 journal/templates/action_open_post.html:8
+#: journal/models/collection.py:143
+msgid "created collection"
+msgstr "创建了收藏单"
+
+#: journal/models/common.py:38 journal/templates/action_open_post.html:8
#: journal/templates/action_open_post.html:14
#: journal/templates/action_open_post.html:16
#: journal/templates/collection_share.html:35 journal/templates/comment.html:35
-#: journal/templates/mark.html:96 journal/templates/tag_edit.html:42
+#: journal/templates/mark.html:90 journal/templates/tag_edit.html:42
#: journal/templates/wrapped_share.html:43 users/templates/users/data.html:47
-#: users/templates/users/data.html:139
+#: users/templates/users/data.html:148
#: users/templates/users/preferences.html:55
msgid "Public"
msgstr "公开"
-#: journal/models/common.py:38 journal/templates/action_open_post.html:10
+#: journal/models/common.py:39 journal/templates/action_open_post.html:10
#: journal/templates/collection_share.html:46 journal/templates/comment.html:42
-#: journal/templates/mark.html:103 journal/templates/wrapped_share.html:49
-#: users/templates/users/data.html:55 users/templates/users/data.html:147
+#: journal/templates/mark.html:97 journal/templates/wrapped_share.html:49
+#: users/templates/users/data.html:55 users/templates/users/data.html:156
#: users/templates/users/preferences.html:62
msgid "Followers Only"
msgstr "仅关注者"
-#: journal/models/common.py:39 journal/templates/action_open_post.html:12
+#: journal/models/common.py:40 journal/templates/action_open_post.html:12
#: journal/templates/collection_share.html:57 journal/templates/comment.html:49
-#: journal/templates/mark.html:110 journal/templates/wrapped_share.html:55
-#: users/templates/users/data.html:63 users/templates/users/data.html:155
+#: journal/templates/mark.html:104 journal/templates/wrapped_share.html:55
+#: users/templates/users/data.html:63 users/templates/users/data.html:164
#: users/templates/users/preferences.html:69
msgid "Mentioned Only"
msgstr "自己和提到的人"
-#: journal/models/common.py:368
+#: journal/models/common.py:370
msgid "A recent post was not posted to Threads."
msgstr "帖文未能发布到Threads。"
-#: journal/models/common.py:402
+#: journal/models/common.py:404
msgid "A recent post was not posted to Mastodon, please re-authorize."
msgstr "帖文未能发布到联邦实例,请重新验证登录。"
-#: journal/models/common.py:409
+#: journal/models/common.py:411
msgid "A recent post was not posted to Mastodon."
msgstr "帖文未能发布到联邦实例。"
@@ -3093,7 +3125,7 @@ msgstr "不看了"
msgid "performances reviewed"
msgstr "评论过的演出"
-#: journal/models/shelf.py:534
+#: journal/models/shelf.py:562
msgid "removed mark"
msgstr "移除标记"
@@ -3268,7 +3300,7 @@ msgstr "更新"
msgid "Comment"
msgstr "写短评"
-#: journal/templates/comment.html:24 journal/templates/mark.html:74
+#: journal/templates/comment.html:24 journal/templates/mark.html:68
msgid "Tips: use >!text!< for spoilers; some instances may not be able to show posts longer than 360 charactors."
msgstr "提示: 善用 >!文字!< 标记可隐藏剧透; 超过360字可能无法分享到联邦宇宙实例时间轴。"
@@ -3280,20 +3312,19 @@ msgstr "分享播放位置"
msgid "Mark"
msgstr "标记"
-#: journal/templates/mark.html:51 journal/templates/mark.html:55
-#: journal/templates/mark.html:59
+#: journal/templates/mark.html:51
msgid "not rated"
msgstr "未评分"
-#: journal/templates/mark.html:82
+#: journal/templates/mark.html:76
msgid "add a tag and press Enter"
msgstr "回车增加标签"
-#: journal/templates/mark.html:138
+#: journal/templates/mark.html:132
msgid "change mark date"
msgstr "指定标记日期"
-#: journal/templates/mark.html:164
+#: journal/templates/mark.html:158
msgid "Sure to delete mark, comment and tags for this item?"
msgstr "确认删除这条标记、短评和标签?"
@@ -3412,20 +3443,20 @@ msgstr "删除后你将无法追溯其他用户对此内容曾经作出的回应
msgid "Deletion cannot be undone, are you sure to continue?"
msgstr "删除不可撤销。确认继续吗?"
-#: journal/templates/profile.html:55
+#: journal/templates/profile.html:51
msgid "calendar"
msgstr "日历"
-#: journal/templates/profile.html:58 journal/templates/wrapped.html:14
+#: journal/templates/profile.html:54 journal/templates/wrapped.html:14
#: journal/templates/wrapped.html:53
msgid "annual summary"
msgstr "年度小结"
-#: journal/templates/profile.html:131 journal/views/collection.py:165
+#: journal/templates/profile.html:119 journal/views/collection.py:166
msgid "collection"
msgstr "收藏单"
-#: journal/templates/profile.html:171
+#: journal/templates/profile.html:155
msgid "liked collection"
msgstr "喜欢的收藏单"
@@ -3449,6 +3480,10 @@ msgstr "保存时将行首空格替换为全角"
msgid "change review date"
msgstr "指定评论日期"
+#: journal/templates/search_journal.html:25
+msgid "No items matching the search query."
+msgstr "暂无匹配条目。"
+
#: journal/templates/tag_edit.html:32
msgid "Pin"
msgstr "置顶"
@@ -3551,25 +3586,25 @@ msgid_plural "%(count)d items"
msgstr[0] "%(count)d 个条目"
msgstr[1] "%(count)d 个条目"
-#: journal/views/collection.py:36
+#: journal/views/collection.py:37
#, python-brace-format
msgid "Collection by {0}"
msgstr "{0} 的收藏单"
-#: journal/views/collection.py:170
+#: journal/views/collection.py:171
msgid "shared my collection"
msgstr "分享我的收藏单"
-#: journal/views/collection.py:173
+#: journal/views/collection.py:174
#, python-brace-format
msgid "shared {username}'s collection"
msgstr "分享 {username} 的收藏单"
-#: journal/views/collection.py:224
+#: journal/views/collection.py:225
msgid "Unable to find the item, please use item url from this site."
msgstr "找不到条目,请使用本站条目网址。"
-#: journal/views/collection.py:337 journal/views/collection.py:358
+#: journal/views/collection.py:338 journal/views/collection.py:359
#: journal/views/review.py:124
msgid "Login required"
msgstr "登录后访问"
@@ -3653,12 +3688,12 @@ msgstr "重复标签"
msgid "Tag updated."
msgstr "标签已更新"
-#: journal/views/wrapped.py:145
+#: journal/views/wrapped.py:146
msgid "Summary posted to timeline."
msgstr "总结已发布到时间轴"
#: mastodon/models/common.py:14 users/templates/users/account.html:44
-#: users/templates/users/login.html:57
+#: users/templates/users/login.html:60
msgid "Email"
msgstr "电子邮件"
@@ -3666,7 +3701,7 @@ msgstr "电子邮件"
msgid "Mastodon"
msgstr "Mastodon"
-#: mastodon/models/common.py:16 users/templates/users/login.html:76
+#: mastodon/models/common.py:16 users/templates/users/login.html:85
msgid "Threads"
msgstr "Threads"
@@ -3684,6 +3719,10 @@ msgstr ""
"\n"
"如果你没有打算用此电子邮件地址注册或登录本站,请忽略此邮件;如果你确信账号存在安全风险,请更改注册邮件地址或与我们联系。"
+#: mastodon/models/email.py:60 mastodon/models/email.py:65
+msgid "Verification Code"
+msgstr "验证码"
+
#: mastodon/models/email.py:62
#, python-brace-format
msgid ""
@@ -3708,6 +3747,11 @@ msgstr ""
"\n"
"{code}"
+#: mastodon/models/email.py:70 users/templates/users/login.html:16
+#: users/templates/users/register.html:8 users/templates/users/welcome.html:8
+msgid "Register"
+msgstr "注册"
+
#: mastodon/models/email.py:72
#, python-brace-format
msgid ""
@@ -3772,7 +3816,7 @@ msgstr "新帖文"
#: mastodon/views/common.py:30 mastodon/views/mastodon.py:37
#: mastodon/views/mastodon.py:44 mastodon/views/mastodon.py:54
#: mastodon/views/mastodon.py:61 mastodon/views/threads.py:41
-#: mastodon/views/threads.py:47 users/views/account.py:104
+#: mastodon/views/threads.py:47 users/views/account.py:105
msgid "Authentication failed"
msgstr "认证失败"
@@ -4064,7 +4108,7 @@ msgstr ""
"回应了你对 %(item_title)s 的标记\n"
#: social/templates/feed.html:11 social/templates/feed.html:23
-#: social/templates/notification.html:23
+#: social/templates/notification.html:23 social/templates/search_feed.html:11
msgid "Activities from those you follow"
msgstr "好友动态"
@@ -4096,7 +4140,11 @@ msgstr "标记"
msgid "wrote a note"
msgstr "写了笔记"
-#: social/templates/feed_events.html:140
+#: social/templates/feed_events.html:139
+msgid "no matching activities."
+msgstr "没有符合条件的动态。"
+
+#: social/templates/feed_events.html:142
#, 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的用户,这里就会显示你和她们的近期动态。"
@@ -4137,23 +4185,19 @@ msgstr "头像"
msgid "Header picture"
msgstr "背景图片"
-#: takahe/utils.py:565
-msgid "created collection"
-msgstr "创建了收藏单"
-
-#: users/models/task.py:17
+#: users/models/task.py:19
msgid "Pending"
msgstr "等待"
-#: users/models/task.py:18
+#: users/models/task.py:20
msgid "Started"
msgstr "已开始"
-#: users/models/task.py:19
+#: users/models/task.py:21
msgid "Complete"
msgstr "完成"
-#: users/models/task.py:20
+#: users/models/task.py:22
msgid "Failed"
msgstr "失败"
@@ -4189,20 +4233,20 @@ msgstr "在这里更新个人资料会停止从关联实例自动同步昵称等
msgid "Username"
msgstr "用户名"
-#: users/templates/users/account.html:50 users/templates/users/register.html:30
+#: users/templates/users/account.html:50 users/templates/users/register.html:37
msgid "Email address"
msgstr "电子邮件地址"
-#: users/templates/users/account.html:59 users/templates/users/register.html:39
+#: users/templates/users/account.html:59 users/templates/users/register.html:46
#, python-format
msgid "Please click the confirmation link in the email sent to %(pending_email)s; if you haven't received it for more than a few minutes, please input and save again."
msgstr "当前待确认的电子邮件地址为%(pending_email)s,请查收邮件并点击确认链接;如长时间未收到可重新输入并保存。"
-#: users/templates/users/account.html:61 users/templates/users/register.html:42
+#: users/templates/users/account.html:61 users/templates/users/register.html:49
msgid "Email is recommended as a backup login method, if you log in via a Fediverse instance"
msgstr "推荐输入电子邮件地址作为备用登录方式。"
-#: users/templates/users/account.html:73 users/templates/users/login.html:63
+#: users/templates/users/account.html:73 users/templates/users/login.html:69
msgid "Fediverse (Mastodon)"
msgstr "联邦宇宙(有时也被称为长毛象)"
@@ -4270,7 +4314,7 @@ msgstr "关联一个threads.net账号"
msgid "Disconnect with Threads"
msgstr "取消关联"
-#: users/templates/users/account.html:173 users/templates/users/login.html:83
+#: users/templates/users/account.html:173 users/templates/users/login.html:95
msgid "Bluesky (ATProto)"
msgstr "Bluesky (ATProto)"
@@ -4282,7 +4326,7 @@ msgstr "已验证的ATProto身份"
msgid "Bluesky Login ID"
msgstr "Bluesky 登录名"
-#: users/templates/users/account.html:202 users/templates/users/login.html:159
+#: users/templates/users/account.html:202 users/templates/users/login.html:171
msgid "Bluesky app password"
msgstr "Bluesky 应用密码"
@@ -4294,7 +4338,7 @@ msgstr "关联另一个ATProto身份"
msgid "Link with an ATProto identity"
msgstr "关联ATProto身份"
-#: users/templates/users/account.html:209 users/templates/users/login.html:164
+#: users/templates/users/account.html:209 users/templates/users/login.html:176
msgid "App password can be created on bsky.app."
msgstr "应用密码可在 bsky.app 创建管理。"
@@ -4366,11 +4410,11 @@ msgstr "输入完整的登录用 用户名@实例名
或 电
msgid "Once deleted, account data cannot be recovered."
msgstr "账号数据一旦删除后将无法恢复"
-#: users/templates/users/account.html:321
+#: users/templates/users/account.html:322
msgid "Importing in progress, can't delete now."
msgstr "暂时无法删除,因为有导入任务正在进行"
-#: users/templates/users/account.html:324
+#: users/templates/users/account.html:326
msgid "Permanently Delete"
msgstr "永久删除"
@@ -4386,7 +4430,7 @@ msgstr "导入豆瓣标记和评论"
msgid "Select .xlsx
exported from Doufen"
msgstr "在豆伴(豆坟)导出时勾选书影音游剧和评论。
选择从豆伴(豆坟)导出的.xlsx
文件"
-#: users/templates/users/data.html:27 users/templates/users/data.html:185
+#: users/templates/users/data.html:27 users/templates/users/data.html:194
msgid "Import Method"
msgstr "导入方式"
@@ -4407,7 +4451,7 @@ msgid "Import in progress, please wait"
msgstr "备份文件已上传,请等待导入完成或刷新页面查看最新进度"
#: users/templates/users/data.html:67 users/templates/users/data.html:86
-#: users/templates/users/data.html:158 users/templates/users/data.html:201
+#: users/templates/users/data.html:167 users/templates/users/data.html:210
msgid "Import"
msgstr "导入"
@@ -4419,74 +4463,81 @@ msgstr "导入Goodreads书架或书单"
msgid "Link to Goodreads Profile / Shelf / List"
msgstr "Goodreads个人主页、书架或书单链接"
-#: users/templates/users/data.html:91
+#: users/templates/users/data.html:90 users/templates/users/data.html:172
+#: users/templates/users/data_import_status.html:2
+msgid "Last import started"
+msgstr "最近导入时间"
+
+#: users/templates/users/data.html:91 users/templates/users/data.html:173
+#: users/templates/users/data.html:226
+#: users/templates/users/data_import_status.html:3
+msgid "Status"
+msgstr "状态"
+
+#: users/templates/users/data.html:100
msgid "want-to-read / currently-reading / read books and their reviews will be imported."
msgstr "提交Goodreads用户主页链接将导入想读、在读、已读列表,每本书的评论导入为本站短评。"
-#: users/templates/users/data.html:95
+#: users/templates/users/data.html:104
msgid "Shelf will be imported as a new collection."
msgstr "Goodreads书架将被导入为收藏单,每本书的评论导入为收藏单条目备注。"
-#: users/templates/users/data.html:99
+#: users/templates/users/data.html:108
msgid "List will be imported as a new collection."
msgstr "Goodreads书单将被导入为收藏单,每本书的评论导入为收藏单条目备注。"
-#: users/templates/users/data.html:110
+#: users/templates/users/data.html:119
msgid "Import from Letterboxd"
msgstr "导入Letterboxd标记"
-#: users/templates/users/data.html:160
+#: users/templates/users/data.html:169
msgid "Only forward changes(none->to-watch->watched) will be imported."
msgstr "导入时仅更新正向变化(未标->想看->已看)标记;不足360字符的评论会作为短评添加。"
-#: users/templates/users/data.html:163
-msgid "Last import started"
-msgstr "最近导入时间"
-
-#: users/templates/users/data.html:164
-msgid "Status"
-msgstr "状态"
-
-#: users/templates/users/data.html:168
+#: users/templates/users/data.html:177
msgid "Failed links, likely due to Letterboxd error, you may have to mark them manually"
msgstr "导入失败的链接(通常由于Letterboxd的信息错误,请手工添加标记)"
-#: users/templates/users/data.html:179
+#: users/templates/users/data.html:188
msgid "Import Podcast Subscriptions"
msgstr "导入播客订阅列表 (OPML)"
-#: users/templates/users/data.html:192
+#: users/templates/users/data.html:201
msgid "Mark as listening"
msgstr "标记为在听"
-#: users/templates/users/data.html:196
+#: users/templates/users/data.html:205
msgid "Import as a new collection"
msgstr "导入为新收藏单"
-#: users/templates/users/data.html:199
+#: users/templates/users/data.html:208
msgid "Select OPML file"
msgstr "选择OPML文件"
-#: users/templates/users/data.html:208
+#: users/templates/users/data.html:217
msgid "Export Data"
msgstr "导出数据"
-#: users/templates/users/data.html:214
-msgid "Export in progress"
-msgstr "正在导出"
-
-#: users/templates/users/data.html:214
+#: users/templates/users/data.html:222
msgid "Export marks and reviews"
msgstr "导出标记、短评和评论"
-#: users/templates/users/data.html:216
+#: users/templates/users/data.html:225
+msgid "Last export"
+msgstr "最近导出"
+
+#: users/templates/users/data.html:230
msgid "Download"
msgstr "下载"
-#: users/templates/users/data.html:223
+#: users/templates/users/data.html:238
msgid "View Annual Summary"
msgstr "查看年度小结"
+#: users/templates/users/data_import_status.html:11
+msgid "Failed links, you may have to mark them manually"
+msgstr "导入失败的链接(请手工添加标记)"
+
#: users/templates/users/fetch_identity_failed.html:4
msgid "Unable to find the user, please check your spelling; or the server may be busy, please try again later."
msgstr "无法找到用户,请确认拼写正确;也可能服务器正忙,请稍后再尝试。"
@@ -4496,11 +4547,6 @@ msgstr "无法找到用户,请确认拼写正确;也可能服务器正忙,
msgid "Searching the fediverse"
msgstr "正在搜索联邦宇宙"
-#: users/templates/users/login.html:16 users/templates/users/register.html:8
-#: users/templates/users/welcome.html:8
-msgid "Register"
-msgstr "注册"
-
#: users/templates/users/login.html:16
msgid "Login"
msgstr "登录"
@@ -4510,72 +4556,72 @@ msgstr "登录"
msgid "back to your home page."
msgstr "返回首页"
-#: users/templates/users/login.html:99
+#: users/templates/users/login.html:111
msgid "Enter your email address"
msgstr "输入电子邮件地址"
-#: users/templates/users/login.html:101
+#: users/templates/users/login.html:113
msgid "Send verification code"
msgstr "发送验证码"
-#: users/templates/users/login.html:116
+#: users/templates/users/login.html:128
msgid "Domain of your instance, e.g. mastodon.social"
msgstr "实例域名(不含@和@之前的部分),如mastodon.social"
-#: users/templates/users/login.html:122
+#: users/templates/users/login.html:134
msgid "Please enter domain of your instance; e.g. if your id is @neodb@mastodon.social, only enter mastodon.social."
msgstr "请输入你的实例域名(不含@和@之前的部分);如果你的联邦账号是@neodb@mastodon.social,只需要在此输入mastodon.social。"
-#: users/templates/users/login.html:125 users/templates/users/login.html:178
+#: users/templates/users/login.html:137 users/templates/users/login.html:190
msgid "Authorize via Fediverse instance"
msgstr "去联邦实例授权注册或登录"
-#: users/templates/users/login.html:127
+#: users/templates/users/login.html:139
msgid "If you don't have a Fediverse (Mastodon) account yet, you may register or login with Email first, and link it with Fediverse (Mastodon) later in account settings."
msgstr "如果你还没有或不便注册联邦实例账号,也可先通过电子邮件或其它平台注册登录,未来再作关联。"
-#: users/templates/users/login.html:137
+#: users/templates/users/login.html:149
msgid "Authorize via Threads"
msgstr "去Threads授权注册或登录"
-#: users/templates/users/login.html:150
+#: users/templates/users/login.html:162
msgid "ATProto handle"
msgstr "ATProto 用户标识"
-#: users/templates/users/login.html:155
+#: users/templates/users/login.html:167
msgid "Please input your ATProto handle (e.g. neodb.bsky.social, without the leading @), do not use email. If you changed handle recently, just use the latest one."
msgstr "请输入你的ATProto用户标识(例如neodb.bsky.social,不包含开头的@),不要输入电子邮件地址。如果你最近更改过标识,请使用最新的那一个。"
-#: users/templates/users/login.html:165
+#: users/templates/users/login.html:177
msgid "Authorize via bsky.app"
msgstr "使用Bluesky账号信息注册或登录"
-#: users/templates/users/login.html:169
+#: users/templates/users/login.html:181
#, python-format
msgid "Please choose one to register or login %(site_name)s. Have more than one of these identities? Don't worry, you may link them in account settings once logged in."
msgstr "请选择一种方式注册或登录 %(site_name)s。如果你有多个社交身份,登录后可在账号设置中添加绑定。"
-#: users/templates/users/login.html:185
+#: users/templates/users/login.html:197
msgid "Valid invitation code, please login or register."
msgstr "邀请链接有效,可注册新用户"
-#: users/templates/users/login.html:187
+#: users/templates/users/login.html:199
msgid "Please use invitation link to register a new account; existing user may login."
msgstr "本站目前为邀请注册,已有账户可直接登入,新用户请使用有效邀请链接注册"
-#: users/templates/users/login.html:189
+#: users/templates/users/login.html:201
msgid "Invitation code invalid or expired."
msgstr "邀请链接无效,已有账户可直接登入,新用户请使用有效邀请链接注册"
-#: users/templates/users/login.html:197
+#: users/templates/users/login.html:209
msgid "Loading timed out, please check your network (VPN) settings."
msgstr "部分模块加载超时,请检查网络(翻墙)设置。"
-#: users/templates/users/login.html:203
+#: users/templates/users/login.html:215
msgid "Continue using this site implies consent to our rules and terms, including using cookies to provide necessary functionality."
msgstr "继续访问或注册视为同意站规与协议,及使用cookie提供必要功能"
-#: users/templates/users/login.html:209
+#: users/templates/users/login.html:221
msgid "Domain of your instance (excl. @)"
msgstr "实例域名(不含@和@之前的部分)"
@@ -4800,27 +4846,27 @@ msgstr "确定屏蔽该用户吗?"
msgid "Your username on %(site_name)s"
msgstr "你在%(site_name)s使用的用户名"
-#: users/templates/users/register.html:26
+#: users/templates/users/register.html:27
msgid "2-30 alphabets, numbers or underscore, can't be changed once saved"
msgstr "2-30个字符,限英文字母数字下划线,保存后不可更改"
-#: users/templates/users/register.html:60
+#: users/templates/users/register.html:67
msgid "Turn on crosspost to other social networks by default"
msgstr "发表时默认转发到社交网络时间轴"
-#: users/templates/users/register.html:64
+#: users/templates/users/register.html:71
msgid "Use display name, bio and avatar from the social network you authenticated with"
msgstr "自动同步用户昵称等基本信息"
-#: users/templates/users/register.html:72
+#: users/templates/users/register.html:79
msgid "Add follow, mute and block list from the social network you authenticated with"
msgstr "自动导入新增的关注、屏蔽和隐藏列表"
-#: users/templates/users/register.html:77
+#: users/templates/users/register.html:84
msgid "Confirm and save"
msgstr "确认并保存"
-#: users/templates/users/register.html:81 users/templates/users/welcome.html:27
+#: users/templates/users/register.html:88 users/templates/users/welcome.html:27
msgid "Cut the sh*t and get me in!"
msgstr ""
@@ -4863,66 +4909,70 @@ msgstr ""
"\n"
"%(site_name)s还在不断完善中。 丰富的内容需要大家共同创造,试图添加垃圾数据(如添加信息混乱或缺失的书籍、以推广为主要目的的评论)将会受到严肃处理。 本站为非盈利站点,cookie和其它数据保管使用原则请参阅站内公告。 本站提供API和导出功能,请妥善备份您的数据,使用过程中遇到的问题或者错误欢迎向维护者提出。感谢理解和支持!"
-#: users/views/account.py:78
+#: users/views/account.py:79
msgid "This username is already in use."
msgstr "用户名已被使用"
-#: users/views/account.py:89
+#: users/views/account.py:90
msgid "This email address is already in use."
msgstr "此电子邮件地址已被使用"
-#: users/views/account.py:105
+#: users/views/account.py:106
msgid "Registration is for invitation only"
msgstr "本站仅限邀请注册"
-#: users/views/account.py:175
+#: users/views/account.py:176
msgid "Valid username required"
msgstr "请输入有效的用户名"
-#: users/views/account.py:177
+#: users/views/account.py:178
msgid "Username in use"
msgstr "用户名已被使用"
-#: users/views/account.py:247
+#: users/views/account.py:250
msgid "Account is being deleted."
msgstr "账户删除进行中。"
-#: users/views/account.py:250
+#: users/views/account.py:253
msgid "Account mismatch."
msgstr "账号信息不匹配。"
-#: users/views/data.py:128
+#: users/views/data.py:129
msgid "Generating exports."
msgstr "正在生成导出文件。"
-#: users/views/data.py:140
+#: users/views/data.py:135
+msgid "Export file not available."
+msgstr "导出文件不可用。"
+
+#: users/views/data.py:147
msgid "Export file expired. Please export again."
msgstr "导出文件已失效,请重新导出"
-#: users/views/data.py:149
+#: users/views/data.py:156
msgid "Sync in progress."
msgstr "正在同步。"
-#: users/views/data.py:163
+#: users/views/data.py:170
msgid "Settings saved."
msgstr "设置已保存"
-#: users/views/data.py:174
+#: users/views/data.py:181
msgid "Reset completed."
msgstr "重置已完成。"
-#: users/views/data.py:183
+#: users/views/data.py:195
msgid "Import in progress."
msgstr "正在导出"
-#: users/views/data.py:185
+#: users/views/data.py:197
msgid "Invalid URL."
msgstr "无效网址。"
-#: users/views/data.py:199 users/views/data.py:224 users/views/data.py:239
-msgid "File is uploaded and will be imported soon."
-msgstr "文件已上传,等待后台导入。"
-
-#: users/views/data.py:202 users/views/data.py:242
+#: users/views/data.py:215 users/views/data.py:265
msgid "Invalid file."
msgstr "无效文件。"
+
+#: users/views/data.py:224 users/views/data.py:247 users/views/data.py:262
+msgid "File is uploaded and will be imported soon."
+msgstr "文件已上传,等待后台导入。"
diff --git a/locale/zh_Hant/LC_MESSAGES/django.po b/locale/zh_Hant/LC_MESSAGES/django.po
index 1da3dbf7..84a6396c 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-12-01 16:06-0500\n"
+"POT-Creation-Date: 2024-12-30 01:47-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -15,29 +15,29 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: boofilsic/settings.py:415 common/models/lang.py:216
+#: boofilsic/settings.py:414 common/models/lang.py:216
msgid "English"
msgstr "英語"
-#: boofilsic/settings.py:416
+#: boofilsic/settings.py:415
msgid "Simplified Chinese"
msgstr "簡體中文"
-#: boofilsic/settings.py:417
+#: boofilsic/settings.py:416
msgid "Traditional Chinese"
msgstr "繁體中文"
-#: boofilsic/settings.py:418 common/models/lang.py:63
+#: boofilsic/settings.py:417 common/models/lang.py:63
msgid "Danish"
msgstr "丹麥語"
#: catalog/book/models.py:78 catalog/book/models.py:97
-#: catalog/common/models.py:303 catalog/common/models.py:321
+#: catalog/common/models.py:307 catalog/common/models.py:325
msgid "locale"
msgstr "區域語言"
#: catalog/book/models.py:81 catalog/book/models.py:100
-#: catalog/common/models.py:306 catalog/common/models.py:326
+#: catalog/common/models.py:310 catalog/common/models.py:330
msgid "text content"
msgstr "文本內容"
@@ -71,11 +71,11 @@ msgstr "副標題"
#: catalog/book/models.py:167 catalog/movie/models.py:68
#: catalog/performance/models.py:257 catalog/tv/models.py:138
-#: catalog/tv/models.py:296
+#: catalog/tv/models.py:301
msgid "original title"
msgstr "原名"
-#: catalog/book/models.py:170 catalog/book/models.py:340
+#: catalog/book/models.py:170 catalog/book/models.py:347
msgid "author"
msgstr "作者"
@@ -131,11 +131,11 @@ msgstr "未知"
msgid "Douban"
msgstr "豆瓣"
-#: catalog/common/models.py:37 catalog/common/models.py:77
+#: catalog/common/models.py:37 catalog/common/models.py:79
msgid "Goodreads"
msgstr "Goodreads"
-#: catalog/common/models.py:38 catalog/common/models.py:81
+#: catalog/common/models.py:38 catalog/common/models.py:83
msgid "Google Books"
msgstr "谷歌圖書"
@@ -143,7 +143,7 @@ msgstr "谷歌圖書"
msgid "BooksTW"
msgstr "博客來"
-#: catalog/common/models.py:40 catalog/common/models.py:70
+#: catalog/common/models.py:40 catalog/common/models.py:72
#: catalog/templates/movie.html:51 catalog/templates/tvseason.html:68
#: catalog/templates/tvshow.html:63
msgid "IMDb"
@@ -153,7 +153,7 @@ msgstr "IMDb"
msgid "TMDB"
msgstr "TMDB"
-#: catalog/common/models.py:42 catalog/common/models.py:94
+#: catalog/common/models.py:42 catalog/common/models.py:96
msgid "Bandcamp"
msgstr "Bandcamp"
@@ -169,7 +169,7 @@ msgstr "IGDB"
msgid "Steam"
msgstr "Steam"
-#: catalog/common/models.py:46 catalog/common/models.py:112
+#: catalog/common/models.py:46 catalog/common/models.py:114
msgid "Bangumi"
msgstr "Bangumi"
@@ -185,286 +185,294 @@ msgstr "RSS"
msgid "Discogs"
msgstr "Discogs"
-#: catalog/common/models.py:51 catalog/common/models.py:114
+#: catalog/common/models.py:51 catalog/common/models.py:116
msgid "Apple Music"
msgstr "蘋果音樂"
-#: catalog/common/models.py:52 catalog/common/models.py:115
+#: catalog/common/models.py:52 catalog/common/models.py:117
msgid "Fediverse"
msgstr "聯邦宇宙"
-#: catalog/common/models.py:53 catalog/common/models.py:116
+#: catalog/common/models.py:53 catalog/common/models.py:118
msgid "Qidian"
msgstr "起點"
-#: catalog/common/models.py:54 catalog/common/models.py:117
+#: catalog/common/models.py:54 catalog/common/models.py:119
msgid "Ypshuo"
msgstr "閱評說"
-#: catalog/common/models.py:58
+#: catalog/common/models.py:55 catalog/common/models.py:120
+msgid "Archive of Our Own"
+msgstr "AO3"
+
+#: catalog/common/models.py:56 catalog/common/models.py:121
+msgid "JinJiang"
+msgstr "晉江文學"
+
+#: catalog/common/models.py:60
msgid "WikiData"
msgstr "維基數據"
-#: catalog/common/models.py:59
+#: catalog/common/models.py:61
msgid "ISBN10"
msgstr "ISBN10"
-#: catalog/common/models.py:60 catalog/templates/edition.html:19
+#: catalog/common/models.py:62 catalog/templates/edition.html:19
msgid "ISBN"
msgstr "ISBN"
-#: catalog/common/models.py:61
+#: catalog/common/models.py:63
msgid "ASIN"
msgstr "ASIN"
-#: catalog/common/models.py:62
+#: catalog/common/models.py:64
msgid "ISSN"
msgstr "ISSN"
-#: catalog/common/models.py:63
+#: catalog/common/models.py:65
msgid "CUBN"
msgstr "統一書號"
-#: catalog/common/models.py:64
+#: catalog/common/models.py:66
msgid "ISRC"
msgstr "ISRC"
-#: catalog/common/models.py:67
+#: catalog/common/models.py:69
msgid "GTIN UPC EAN"
msgstr "條形碼"
-#: catalog/common/models.py:69
+#: catalog/common/models.py:71
msgid "RSS Feed URL"
msgstr "RSS網址"
-#: catalog/common/models.py:71
+#: catalog/common/models.py:73
msgid "TMDB TV Serie"
msgstr "TMDB電視劇集"
-#: catalog/common/models.py:72
+#: catalog/common/models.py:74
msgid "TMDB TV Season"
msgstr "TMDB電視分季"
-#: catalog/common/models.py:74
+#: catalog/common/models.py:76
msgid "TMDB TV Episode"
msgstr "TMDB電視單集"
-#: catalog/common/models.py:76
+#: catalog/common/models.py:78
msgid "TMDB Movie"
msgstr "TMDB電影"
-#: catalog/common/models.py:79
+#: catalog/common/models.py:81
msgid "Goodreads Work"
msgstr "Goodreads著作"
-#: catalog/common/models.py:82
+#: catalog/common/models.py:84
msgid "Douban Book"
msgstr "豆瓣圖書"
-#: catalog/common/models.py:84
+#: catalog/common/models.py:86
msgid "Douban Book Work"
msgstr "豆瓣圖書著作"
-#: catalog/common/models.py:86
+#: catalog/common/models.py:88
msgid "Douban Movie"
msgstr "豆瓣電影"
-#: catalog/common/models.py:87
+#: catalog/common/models.py:89
msgid "Douban Music"
msgstr "豆瓣音樂"
-#: catalog/common/models.py:88
+#: catalog/common/models.py:90
msgid "Douban Game"
msgstr "豆瓣遊戲"
-#: catalog/common/models.py:89
+#: catalog/common/models.py:91
msgid "Douban Drama"
msgstr "豆瓣舞臺劇"
-#: catalog/common/models.py:91
+#: catalog/common/models.py:93
msgid "Douban Drama Version"
msgstr "豆瓣舞臺劇版本"
-#: catalog/common/models.py:93
+#: catalog/common/models.py:95
msgid "BooksTW Book"
msgstr "博客來圖書"
-#: catalog/common/models.py:95
+#: catalog/common/models.py:97
msgid "Spotify Album"
msgstr "Spotify專輯"
-#: catalog/common/models.py:96
+#: catalog/common/models.py:98
msgid "Spotify Podcast"
msgstr "Spotify播客"
-#: catalog/common/models.py:98
+#: catalog/common/models.py:100
msgid "Discogs Release"
msgstr "Discogs發行"
-#: catalog/common/models.py:101
+#: catalog/common/models.py:103
msgid "Discogs Master"
msgstr "Discogs作品"
-#: catalog/common/models.py:103
+#: catalog/common/models.py:105
msgid "MusicBrainz ID"
msgstr "MusicBrainz ID"
-#: catalog/common/models.py:109
+#: catalog/common/models.py:111
msgid "IGDB Game"
msgstr "IGDB遊戲"
-#: catalog/common/models.py:110
+#: catalog/common/models.py:112
msgid "BGG Boardgame"
msgstr "BGG桌遊"
-#: catalog/common/models.py:111
+#: catalog/common/models.py:113
msgid "Steam Game"
msgstr "Steam遊戲"
-#: catalog/common/models.py:113
+#: catalog/common/models.py:115
msgid "Apple Podcast"
msgstr "蘋果播客"
-#: catalog/common/models.py:133 catalog/common/models.py:154
-#: catalog/common/models.py:167 common/templates/_header.html:25
+#: catalog/common/models.py:137 catalog/common/models.py:158
+#: catalog/common/models.py:171 common/templates/_header.html:25
#: journal/templates/_sidebar_user_mark_list.html:31
msgid "Book"
msgstr "圖書"
-#: catalog/common/models.py:134
+#: catalog/common/models.py:138
msgid "TV Serie"
msgstr "電視劇集"
-#: catalog/common/models.py:135 catalog/templates/_sidebar_edit.html:140
+#: catalog/common/models.py:139 catalog/templates/_sidebar_edit.html:140
msgid "TV Season"
msgstr "電視分季"
-#: catalog/common/models.py:136
+#: catalog/common/models.py:140
msgid "TV Episode"
msgstr "電視單集"
-#: catalog/common/models.py:137 catalog/common/models.py:155
-#: catalog/common/models.py:168 catalog/templates/_sidebar_edit.html:133
+#: catalog/common/models.py:141 catalog/common/models.py:159
+#: catalog/common/models.py:172 catalog/templates/_sidebar_edit.html:133
#: journal/templates/_sidebar_user_mark_list.html:34
msgid "Movie"
msgstr "電影"
-#: catalog/common/models.py:138
+#: catalog/common/models.py:142
msgid "Album"
msgstr "專輯"
-#: catalog/common/models.py:139 catalog/common/models.py:158
-#: catalog/common/models.py:171 common/templates/_header.html:41
+#: catalog/common/models.py:143 catalog/common/models.py:162
+#: catalog/common/models.py:175 common/templates/_header.html:41
#: journal/templates/_sidebar_user_mark_list.html:47
msgid "Game"
msgstr "遊戲"
-#: catalog/common/models.py:140
+#: catalog/common/models.py:144
msgid "Podcast Program"
msgstr "播客節目"
-#: catalog/common/models.py:142
+#: catalog/common/models.py:146
msgid "Podcast Episode"
msgstr "播客單集"
-#: catalog/common/models.py:144 catalog/common/models.py:160
-#: catalog/common/models.py:173 common/templates/_header.html:45
+#: catalog/common/models.py:148 catalog/common/models.py:164
+#: catalog/common/models.py:177 common/templates/_header.html:45
#: journal/templates/_sidebar_user_mark_list.html:51
msgid "Performance"
msgstr "演出"
-#: catalog/common/models.py:146
+#: catalog/common/models.py:150
msgid "Production"
msgstr "上演"
-#: catalog/common/models.py:148
+#: catalog/common/models.py:152
msgid "Fanfic"
msgstr "網文"
-#: catalog/common/models.py:149 catalog/common/models.py:162
+#: catalog/common/models.py:153 catalog/common/models.py:166
msgid "Exhibition"
msgstr "展覽"
-#: catalog/common/models.py:150 catalog/common/models.py:163
+#: catalog/common/models.py:154 catalog/common/models.py:167
#: journal/templates/collection.html:15 journal/templates/collection.html:25
#: journal/templates/collection_edit.html:9
#: journal/templates/collection_share.html:12
msgid "Collection"
msgstr "收藏單"
-#: catalog/common/models.py:156 catalog/common/models.py:169
+#: catalog/common/models.py:160 catalog/common/models.py:173
#: journal/templates/_sidebar_user_mark_list.html:37
msgid "TV"
msgstr "劇集"
-#: catalog/common/models.py:157 catalog/common/models.py:170
+#: catalog/common/models.py:161 catalog/common/models.py:174
#: common/templates/_header.html:37
#: journal/templates/_sidebar_user_mark_list.html:44
msgid "Music"
msgstr "音樂"
-#: catalog/common/models.py:159 catalog/common/models.py:172
+#: catalog/common/models.py:163 catalog/common/models.py:176
#: catalog/templates/_sidebar_edit.html:152 common/templates/_header.html:33
#: journal/templates/_sidebar_user_mark_list.html:41
msgid "Podcast"
msgstr "播客"
-#: catalog/common/models.py:161
+#: catalog/common/models.py:165
msgid "FanFic"
msgstr "網文"
-#: catalog/common/models.py:345 catalog/tv/models.py:376
+#: catalog/common/models.py:349 catalog/tv/models.py:381
#: users/models/user.py:115
msgid "language"
msgstr "語言"
-#: catalog/common/models.py:368 catalog/common/models.py:399
-#: journal/models/collection.py:53
+#: catalog/common/models.py:372 catalog/common/models.py:403
+#: journal/models/collection.py:56
msgid "title"
msgstr "標題"
-#: catalog/common/models.py:369 catalog/common/models.py:407
-#: journal/models/collection.py:54
+#: catalog/common/models.py:373 catalog/common/models.py:411
+#: journal/models/collection.py:57
msgid "description"
msgstr "描述"
-#: catalog/common/models.py:371 catalog/forms.py:27
+#: catalog/common/models.py:375 catalog/forms.py:27
msgid "Primary ID Type"
msgstr "主要標識類型"
-#: catalog/common/models.py:374 catalog/forms.py:32
+#: catalog/common/models.py:378 catalog/forms.py:32
msgid "Primary ID Value"
msgstr "主要標識數據"
-#: catalog/common/models.py:380
+#: catalog/common/models.py:384
msgid "metadata"
msgstr "元數據"
-#: catalog/common/models.py:382
+#: catalog/common/models.py:386
msgid "cover"
msgstr "封面"
-#: catalog/common/models.py:796
+#: catalog/common/models.py:816
msgid "source site"
msgstr "來源站點"
-#: catalog/common/models.py:798
+#: catalog/common/models.py:818
msgid "ID on source site"
msgstr "來源站點標識"
-#: catalog/common/models.py:800
+#: catalog/common/models.py:820
msgid "source url"
msgstr "來源站點網址"
-#: catalog/common/models.py:816
+#: catalog/common/models.py:836
msgid "IdType of the source site"
msgstr "來源站點的主要標識類型"
-#: catalog/common/models.py:822
+#: catalog/common/models.py:842
msgid "Primary Id on the source site"
msgstr "來源站點的主要標識數據"
-#: catalog/common/models.py:825
+#: catalog/common/models.py:845
msgid "url to the resource"
msgstr "指向外部資源的網址"
@@ -503,7 +511,7 @@ msgstr "特別版"
#: catalog/game/models.py:76 catalog/movie/models.py:71
#: catalog/music/models.py:91 catalog/performance/models.py:115
#: catalog/performance/models.py:260 catalog/tv/models.py:142
-#: catalog/tv/models.py:299
+#: catalog/tv/models.py:304
msgid "other title"
msgstr "其它標題"
@@ -542,7 +550,7 @@ msgstr "發佈類型"
#: catalog/game/models.py:135 catalog/movie/models.py:99
#: catalog/performance/models.py:122 catalog/podcast/models.py:45
-#: catalog/tv/models.py:169 catalog/tv/models.py:327
+#: catalog/tv/models.py:169 catalog/tv/models.py:332
msgid "genre"
msgstr "類型"
@@ -557,25 +565,25 @@ msgstr "平臺"
#: 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:362
+#: catalog/tv/models.py:367
msgid "website"
msgstr "網站"
#: catalog/movie/models.py:78 catalog/performance/models.py:130
#: catalog/performance/models.py:268 catalog/tv/models.py:148
-#: catalog/tv/models.py:306
+#: catalog/tv/models.py:311
msgid "director"
msgstr "導演"
#: catalog/movie/models.py:85 catalog/performance/models.py:137
#: catalog/performance/models.py:275 catalog/tv/models.py:155
-#: catalog/tv/models.py:313
+#: catalog/tv/models.py:318
msgid "playwright"
msgstr "編劇"
#: catalog/movie/models.py:92 catalog/performance/models.py:165
#: catalog/performance/models.py:303 catalog/tv/models.py:162
-#: catalog/tv/models.py:320
+#: catalog/tv/models.py:325
msgid "actor"
msgstr "演員"
@@ -587,32 +595,32 @@ msgstr "演員"
msgid "release date"
msgstr "發佈日期"
-#: catalog/movie/models.py:118 catalog/tv/models.py:346
+#: catalog/movie/models.py:118 catalog/tv/models.py:351
#: 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:347
+#: catalog/tv/models.py:352
msgid "required"
msgstr "必填"
-#: catalog/movie/models.py:123 catalog/tv/models.py:351
+#: catalog/movie/models.py:123 catalog/tv/models.py:356
msgid "region or event"
msgstr "地區或類型"
#: catalog/movie/models.py:125 catalog/tv/models.py:195
-#: catalog/tv/models.py:353
+#: catalog/tv/models.py:358
msgid "Germany or Toronto International Film Festival"
msgstr "德國或多倫多國際電影節"
#: catalog/movie/models.py:135 catalog/tv/models.py:205
-#: catalog/tv/models.py:365
+#: catalog/tv/models.py:370
msgid "region"
msgstr "地區"
#: catalog/movie/models.py:146 catalog/tv/models.py:217
-#: catalog/tv/models.py:386
+#: catalog/tv/models.py:391
msgid "year"
msgstr "年份"
@@ -705,7 +713,7 @@ msgstr "結束日期"
msgid "host"
msgstr "主播"
-#: catalog/search/views.py:55 catalog/search/views.py:175
+#: catalog/search/views.py:58 catalog/search/views.py:177
msgid "Invalid URL"
msgstr "無效網址"
@@ -714,6 +722,7 @@ msgid "Unable to fetch from the link, please check again. Some sites may require
msgstr "無法加載條目,請確認連結正確。部分網站可能刪除條目或隱藏條目爲僅登入可見,歡迎在本站手工添加這些條目。"
#: catalog/templates/_item_card_metadata_album.html:7
+#: catalog/templates/_item_card_metadata_collection.html:7
#: catalog/templates/_item_card_metadata_edition.html:7
#: catalog/templates/_item_card_metadata_game.html:7
#: catalog/templates/_item_card_metadata_movie.html:7
@@ -734,8 +743,8 @@ msgstr "所屬"
#: catalog/templates/_item_comments.html:10
#: catalog/templates/_item_comments_by_episode.html:13
-#: catalog/templates/search_results.html:28
-#: catalog/templates/search_results.html:30
+#: catalog/templates/search_header.html:13
+#: catalog/templates/search_header.html:15
#: journal/templates/_sidebar_user_mark_list.html:55
#: social/templates/notification.html:27
msgid "all"
@@ -760,7 +769,7 @@ msgstr "顯示更多"
#: 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:136
+#: social/templates/events.html:43 social/templates/feed_events.html:137
msgid "nothing more."
msgstr "沒有更多內容了。"
@@ -819,7 +828,7 @@ msgstr "編輯"
#: catalog/templates/_sidebar_edit.html:11
#: catalog/templates/catalog_history.html:9
-#: catalog/templates/catalog_history.html:30
+#: catalog/templates/catalog_history.html:57
msgid "revision history"
msgstr "編輯歷史"
@@ -965,7 +974,7 @@ msgstr "合併到另一條目"
#: catalog/templates/_sidebar_edit.html:206
#: catalog/templates/_sidebar_edit.html:210
#: catalog/templates/catalog_delete.html:11
-#: journal/templates/collection.html:138 journal/templates/mark.html:165
+#: journal/templates/collection.html:138 journal/templates/mark.html:159
#: journal/templates/piece_delete.html:9 journal/templates/piece_delete.html:33
#: journal/templates/review.html:84
msgid "Delete"
@@ -1111,7 +1120,7 @@ msgstr "創建"
#: catalog/templates/catalog_edit.html:50
#: journal/templates/add_to_collection.html:35
#: journal/templates/collection_edit.html:38 journal/templates/comment.html:69
-#: journal/templates/mark.html:150 journal/templates/note.html:39
+#: journal/templates/mark.html:144 journal/templates/note.html:39
#: journal/templates/review_edit.html:39 journal/templates/tag_edit.html:51
#: users/templates/users/account.html:37 users/templates/users/account.html:67
#: users/templates/users/preferences.html:188
@@ -1145,53 +1154,53 @@ msgstr "本操作不可撤銷。確認合併嗎?"
msgid "Discover"
msgstr "發現"
-#: catalog/templates/discover.html:84
+#: catalog/templates/discover.html:76
#: journal/templates/user_collection_list.html:17
#: journal/templates/user_collection_list.html:31
msgid "Collections"
msgstr "收藏單"
-#: catalog/templates/discover.html:102 journal/templates/profile.html:195
+#: catalog/templates/discover.html:94 journal/templates/profile.html:179
msgid "edit layout"
msgstr "編輯佈局"
-#: catalog/templates/discover.html:105 journal/templates/profile.html:198
+#: catalog/templates/discover.html:97 journal/templates/profile.html:182
msgid "save"
msgstr "保存"
-#: catalog/templates/discover.html:116 journal/templates/profile.html:209
+#: catalog/templates/discover.html:108 journal/templates/profile.html:193
msgid "cancel"
msgstr "取消"
-#: catalog/templates/discover.html:122 journal/templates/profile.html:215
+#: catalog/templates/discover.html:114 journal/templates/profile.html:199
msgid "show"
msgstr "顯示"
-#: catalog/templates/discover.html:123 journal/templates/profile.html:216
+#: catalog/templates/discover.html:115 journal/templates/profile.html:200
msgid "hide"
msgstr "隱藏"
-#: catalog/templates/discover.html:155 common/templates/_sidebar.html:14
+#: catalog/templates/discover.html:147 common/templates/_sidebar.html:14
msgid "Unread Announcements"
msgstr "未讀公告"
-#: catalog/templates/discover.html:161 common/templates/_sidebar.html:20
+#: catalog/templates/discover.html:153 common/templates/_sidebar.html:20
msgid "mark all as read"
msgstr "全部標爲已讀"
-#: catalog/templates/discover.html:170
+#: catalog/templates/discover.html:162
#: common/templates/_sidebar_anonymous.html:51
msgid "Popular Tags"
msgstr "熱門標籤"
-#: catalog/templates/discover.html:177 catalog/templates/item_base.html:239
+#: catalog/templates/discover.html:169 catalog/templates/item_base.html:239
#: 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
#: journal/templates/collection_items.html:8 journal/templates/posts.html:50
-#: journal/templates/profile.html:109 journal/templates/profile.html:151
-#: journal/templates/profile.html:187
+#: journal/templates/profile.html:101 journal/templates/profile.html:139
+#: journal/templates/profile.html:171
#: journal/templates/user_collection_list.html:51
#: journal/templates/user_item_list_base.html:25
#: social/templates/events.html:45 users/templates/users/announcements.html:54
@@ -1199,7 +1208,7 @@ msgstr "熱門標籤"
msgid "nothing so far."
msgstr "暫無內容。"
-#: catalog/templates/discover.html:186 common/templates/_sidebar.html:212
+#: catalog/templates/discover.html:178 common/templates/_sidebar.html:212
msgid "Recent Posts"
msgstr "近期帖文"
@@ -1211,11 +1220,11 @@ msgstr "發行時間"
msgid "number of pages"
msgstr "頁數"
-#: catalog/templates/edition.html:92
+#: catalog/templates/edition.html:88
msgid "other editions"
msgstr "其它版本"
-#: catalog/templates/edition.html:129
+#: catalog/templates/edition.html:125
msgid "Borrow or Buy"
msgstr "借閱或購買"
@@ -1337,66 +1346,77 @@ msgstr "用播客應用訂閱"
msgid "original website"
msgstr "原始網站"
-#: catalog/templates/search_results.html:13
-msgid "Search Results"
-msgstr "搜索結果"
-
-#: catalog/templates/search_results.html:35
-#: catalog/templates/search_results.html:37
+#: catalog/templates/search_header.html:20
+#: catalog/templates/search_header.html:22
msgid "books"
msgstr "書籍"
-#: catalog/templates/search_results.html:43
-#: catalog/templates/search_results.html:45
+#: catalog/templates/search_header.html:28
+#: catalog/templates/search_header.html:30
msgid "movie & tv"
msgstr "影視"
-#: catalog/templates/search_results.html:51
-#: catalog/templates/search_results.html:53
+#: catalog/templates/search_header.html:36
+#: catalog/templates/search_header.html:38
msgid "podcasts"
msgstr "播客"
-#: catalog/templates/search_results.html:59
-#: catalog/templates/search_results.html:61
+#: catalog/templates/search_header.html:44
+#: catalog/templates/search_header.html:46
msgid "music"
msgstr "音樂"
-#: catalog/templates/search_results.html:67
-#: catalog/templates/search_results.html:69
+#: catalog/templates/search_header.html:52
+#: catalog/templates/search_header.html:54
msgid "games"
msgstr "遊戲"
-#: catalog/templates/search_results.html:75
-#: catalog/templates/search_results.html:77
+#: catalog/templates/search_header.html:60
+#: catalog/templates/search_header.html:62
msgid "performances"
msgstr "演出"
-#: catalog/templates/search_results.html:84
+#: catalog/templates/search_header.html:68
+#: catalog/templates/search_header.html:70
+msgid "your journal"
+msgstr "你的記錄"
+
+#: catalog/templates/search_header.html:74
+#: catalog/templates/search_header.html:76
+msgid "your timeline"
+msgstr "你的貼文"
+
+#: catalog/templates/search_results.html:13
+#: journal/templates/search_journal.html:13
+msgid "Search Results"
+msgstr "搜索結果"
+
+#: catalog/templates/search_results.html:26
msgid "tag"
msgstr "標籤"
-#: catalog/templates/search_results.html:91
+#: catalog/templates/search_results.html:33
msgid "No items matching your search query."
msgstr "無站內條目匹配。"
-#: catalog/templates/search_results.html:93
+#: catalog/templates/search_results.html:35
msgid "System will search other websites and instances, click title of the item to save them locally. "
msgstr "系統會嘗試搜索其它網站的條目,點擊標題可添加到本站。"
-#: catalog/templates/search_results.html:97
+#: catalog/templates/search_results.html:39
msgid "If you have URL from one of these sites, please put the full URL (e.g. https://www.imdb.com/title/tt2513074/
) to the search box and press Enter."
msgstr "如果你在以下網站找到了相關條目,也可以把連結(如 https://movie.douban.com/subject/1309046/
)輸入到搜索欄中提交保存到本站。"
-#: catalog/templates/search_results.html:107
+#: catalog/templates/search_results.html:49
#, python-format
msgid " %(dups)s items are from the same work or have the same identifier, they are hidden from the search results, click here to show them. "
msgstr "已從結果中略去了來自同一作品或有相同標識號的%(dups)s個條目,點擊這裏可重新顯示"
-#: catalog/templates/search_results.html:121
+#: catalog/templates/search_results.html:63
msgid "Searching from other sites"
msgstr "正在搜索站外條目"
-#: catalog/templates/search_results.html:124
+#: catalog/templates/search_results.html:66
msgid "Logged in user may see search results from other sites."
msgstr "登入用戶可看到來自其它網站的搜索結果。"
@@ -1404,7 +1424,7 @@ msgstr "登入用戶可看到來自其它網站的搜索結果。"
msgid "all seasons"
msgstr "本劇所有季"
-#: catalog/templates/tvseason.html:32 catalog/tv/models.py:268
+#: catalog/templates/tvseason.html:32 catalog/tv/models.py:273
msgid "season number"
msgstr "本季序號"
@@ -1414,7 +1434,7 @@ msgid "number of seasons"
msgstr "季數"
#: catalog/templates/tvseason.html:42 catalog/templates/tvshow.html:37
-#: catalog/tv/models.py:113 catalog/tv/models.py:271
+#: catalog/tv/models.py:113 catalog/tv/models.py:276
msgid "number of episodes"
msgstr "集數"
@@ -1422,7 +1442,7 @@ msgstr "集數"
msgid "Editions"
msgstr "版本"
-#: catalog/tv/models.py:176 catalog/tv/models.py:334
+#: catalog/tv/models.py:176 catalog/tv/models.py:339
msgid "show time"
msgstr "上映時間"
@@ -1434,16 +1454,16 @@ msgstr "日期"
msgid "Region or Event"
msgstr "地區或場合"
-#: catalog/tv/models.py:219 catalog/tv/models.py:388
+#: catalog/tv/models.py:219 catalog/tv/models.py:393
msgid "episode length"
msgstr "單集長度"
-#: catalog/tv/models.py:419
+#: catalog/tv/models.py:424
#, python-brace-format
msgid "{show_title} Season {season_number}"
msgstr "{show_title} 第{season_number}季"
-#: catalog/tv/models.py:483
+#: catalog/tv/models.py:494
#, python-brace-format
msgid "{season_title} E{episode_number}"
msgstr "{season_title} 第{episode_number}集"
@@ -1466,23 +1486,23 @@ msgstr "條目不可被刪除。"
#: catalog/views_edit.py:147 catalog/views_edit.py:199
#: catalog/views_edit.py:275 catalog/views_edit.py:354
-#: journal/views/collection.py:50 journal/views/collection.py:100
-#: journal/views/collection.py:112 journal/views/collection.py:129
-#: journal/views/collection.py:195 journal/views/collection.py:214
-#: journal/views/collection.py:234 journal/views/collection.py:246
-#: journal/views/collection.py:260 journal/views/collection.py:274
-#: journal/views/collection.py:277 journal/views/collection.py:301
+#: journal/views/collection.py:51 journal/views/collection.py:101
+#: journal/views/collection.py:113 journal/views/collection.py:130
+#: journal/views/collection.py:196 journal/views/collection.py:215
+#: journal/views/collection.py:235 journal/views/collection.py:247
+#: journal/views/collection.py:261 journal/views/collection.py:275
+#: journal/views/collection.py:278 journal/views/collection.py:302
#: journal/views/common.py:136 journal/views/post.py:20
#: journal/views/post.py:42 journal/views/review.py:32
#: journal/views/review.py:46
msgid "Insufficient permission"
msgstr "權限不足"
-#: catalog/views_edit.py:202 journal/views/collection.py:263
-#: journal/views/collection.py:330 journal/views/common.py:83
+#: catalog/views_edit.py:202 journal/views/collection.py:264
+#: journal/views/collection.py:331 journal/views/common.py:83
#: journal/views/mark.py:146 journal/views/post.py:56 journal/views/post.py:70
#: journal/views/review.py:93 journal/views/review.py:96
-#: users/views/actions.py:168
+#: users/views/actions.py:169
msgid "Invalid parameter"
msgstr "無效參數"
@@ -2341,7 +2361,7 @@ msgstr "開發者"
msgid "Source Code"
msgstr "源代碼"
-#: common/templates/_footer.html:16 users/templates/users/login.html:195
+#: common/templates/_footer.html:16 users/templates/users/login.html:207
#, python-format
msgid "You are visiting an alternative domain for %(site_name)s, please always use original version if possible."
msgstr "這是%(site_name)s的臨時鏡像,請儘可能使用原始站點。"
@@ -2351,61 +2371,69 @@ msgid "title, creator, ISBN, item url, @user, @user@instance"
msgstr "標題、創作者、ISBN、站外條目連結、@用戶名、@用戶名@實例"
#: common/templates/_header.html:22
-msgid "Everything"
-msgstr "全部"
+msgid "All Items"
+msgstr "所有條目"
#: common/templates/_header.html:29
msgid "Movie & TV"
msgstr "影視"
-#: common/templates/_header.html:68
+#: common/templates/_header.html:49
+msgid "Journal"
+msgstr "記錄"
+
+#: common/templates/_header.html:51
+msgid "Posts"
+msgstr "帖文"
+
+#: common/templates/_header.html:74
msgid "Explore"
msgstr "發現"
-#: common/templates/_header.html:71
+#: common/templates/_header.html:77
msgid "Feed"
msgstr "動態"
-#: common/templates/_header.html:74 journal/templates/profile.html:11
+#: common/templates/_header.html:80 journal/templates/profile.html:11
#: users/templates/users/preferences.html:45
msgid "Home"
msgstr "主頁"
-#: common/templates/_header.html:89 social/templates/notification.html:11
+#: common/templates/_header.html:96 social/templates/notification.html:11
#: social/templates/notification.html:24
msgid "Notification"
msgstr "通知"
-#: common/templates/_header.html:92
+#: common/templates/_header.html:99
msgid "Data"
msgstr "數據"
-#: common/templates/_header.html:95 users/templates/users/preferences.html:11
+#: common/templates/_header.html:102 users/templates/users/preferences.html:11
#: users/templates/users/preferences.html:22
msgid "Preferences"
msgstr "設定"
-#: common/templates/_header.html:98
+#: common/templates/_header.html:105
msgid "Account"
msgstr "帳號"
-#: common/templates/_header.html:101
+#: common/templates/_header.html:108
msgid "Logout"
msgstr "登出"
-#: common/templates/_header.html:105
+#: common/templates/_header.html:112
msgid "Database"
msgstr "數據庫"
-#: common/templates/_header.html:108
+#: common/templates/_header.html:115
msgid "Manage"
msgstr "管理"
-#: common/templates/_header.html:113
+#: common/templates/_header.html:120
msgid "Sign up or Login"
msgstr "註冊或登入"
-#: common/templates/_header.html:127
+#: common/templates/_header.html:134
msgid "Open"
msgstr "打開"
@@ -2518,16 +2546,16 @@ msgstr "已關注"
msgid "following you"
msgstr "關注了你"
-#: common/utils.py:63 common/utils.py:93 users/views/actions.py:34
-#: users/views/actions.py:120
+#: common/utils.py:64 common/utils.py:94 users/views/actions.py:35
+#: users/views/actions.py:121
msgid "User not found"
msgstr "用戶不存在"
-#: common/utils.py:67 common/utils.py:97 users/views/actions.py:123
+#: common/utils.py:68 common/utils.py:98 users/views/actions.py:124
msgid "User no longer exists"
msgstr "用戶不存在了"
-#: common/utils.py:75 common/utils.py:105
+#: common/utils.py:76 common/utils.py:106
msgid "Access denied"
msgstr "訪問被拒絕"
@@ -2540,14 +2568,14 @@ msgid "Content (Markdown)"
msgstr "內容 (Markdown格式)"
#: journal/forms.py:21 journal/templates/comment.html:62
-#: journal/templates/mark.html:123 journal/views/note.py:26
+#: journal/templates/mark.html:117 journal/views/note.py:26
msgid "Crosspost to timeline"
msgstr "轉發到時間軸"
#: journal/forms.py:25 journal/forms.py:45
#: journal/templates/collection_share.html:24
#: journal/templates/wrapped_share.html:36 users/templates/users/data.html:38
-#: users/templates/users/data.html:130
+#: users/templates/users/data.html:139
msgid "Visibility"
msgstr "可見性"
@@ -2563,7 +2591,7 @@ msgstr "創建者和他們的互相關注"
msgid "Collaborative editing"
msgstr "協作編輯"
-#: journal/importers/letterboxd.py:108
+#: journal/importers/letterboxd.py:107
#, python-brace-format
msgid "a review of {item_title}"
msgstr "關於 {item_title} 的評論"
@@ -2580,42 +2608,46 @@ msgstr "{username} 的播客訂閱"
msgid "note"
msgstr "備註"
-#: journal/models/common.py:37 journal/templates/action_open_post.html:8
+#: journal/models/collection.py:143
+msgid "created collection"
+msgstr "創建了收藏單"
+
+#: journal/models/common.py:38 journal/templates/action_open_post.html:8
#: journal/templates/action_open_post.html:14
#: journal/templates/action_open_post.html:16
#: journal/templates/collection_share.html:35 journal/templates/comment.html:35
-#: journal/templates/mark.html:96 journal/templates/tag_edit.html:42
+#: journal/templates/mark.html:90 journal/templates/tag_edit.html:42
#: journal/templates/wrapped_share.html:43 users/templates/users/data.html:47
-#: users/templates/users/data.html:139
+#: users/templates/users/data.html:148
#: users/templates/users/preferences.html:55
msgid "Public"
msgstr "公開"
-#: journal/models/common.py:38 journal/templates/action_open_post.html:10
+#: journal/models/common.py:39 journal/templates/action_open_post.html:10
#: journal/templates/collection_share.html:46 journal/templates/comment.html:42
-#: journal/templates/mark.html:103 journal/templates/wrapped_share.html:49
-#: users/templates/users/data.html:55 users/templates/users/data.html:147
+#: journal/templates/mark.html:97 journal/templates/wrapped_share.html:49
+#: users/templates/users/data.html:55 users/templates/users/data.html:156
#: users/templates/users/preferences.html:62
msgid "Followers Only"
msgstr "僅關注者"
-#: journal/models/common.py:39 journal/templates/action_open_post.html:12
+#: journal/models/common.py:40 journal/templates/action_open_post.html:12
#: journal/templates/collection_share.html:57 journal/templates/comment.html:49
-#: journal/templates/mark.html:110 journal/templates/wrapped_share.html:55
-#: users/templates/users/data.html:63 users/templates/users/data.html:155
+#: journal/templates/mark.html:104 journal/templates/wrapped_share.html:55
+#: users/templates/users/data.html:63 users/templates/users/data.html:164
#: users/templates/users/preferences.html:69
msgid "Mentioned Only"
msgstr "自己和提到的人"
-#: journal/models/common.py:368
+#: journal/models/common.py:370
msgid "A recent post was not posted to Threads."
msgstr "帖文未能發佈到Threads。"
-#: journal/models/common.py:402
+#: journal/models/common.py:404
msgid "A recent post was not posted to Mastodon, please re-authorize."
msgstr "帖文未能發佈到聯邦實例,請重新驗證登入。"
-#: journal/models/common.py:409
+#: journal/models/common.py:411
msgid "A recent post was not posted to Mastodon."
msgstr "帖文未能發佈到聯邦實例。"
@@ -3093,7 +3125,7 @@ msgstr "不看了"
msgid "performances reviewed"
msgstr "評論過的演出"
-#: journal/models/shelf.py:534
+#: journal/models/shelf.py:562
msgid "removed mark"
msgstr "移除標記"
@@ -3268,7 +3300,7 @@ msgstr "更新"
msgid "Comment"
msgstr "寫短評"
-#: journal/templates/comment.html:24 journal/templates/mark.html:74
+#: journal/templates/comment.html:24 journal/templates/mark.html:68
msgid "Tips: use >!text!< for spoilers; some instances may not be able to show posts longer than 360 charactors."
msgstr "提示: 善用 >!文字!< 標記可隱藏劇透; 超過360字可能無法分享到聯邦宇宙實例時間軸。"
@@ -3280,20 +3312,19 @@ msgstr "分享播放位置"
msgid "Mark"
msgstr "標記"
-#: journal/templates/mark.html:51 journal/templates/mark.html:55
-#: journal/templates/mark.html:59
+#: journal/templates/mark.html:51
msgid "not rated"
msgstr "未評分"
-#: journal/templates/mark.html:82
+#: journal/templates/mark.html:76
msgid "add a tag and press Enter"
msgstr "回車增加標籤"
-#: journal/templates/mark.html:138
+#: journal/templates/mark.html:132
msgid "change mark date"
msgstr "指定標記日期"
-#: journal/templates/mark.html:164
+#: journal/templates/mark.html:158
msgid "Sure to delete mark, comment and tags for this item?"
msgstr "確認刪除這條標記、短評和標籤?"
@@ -3412,20 +3443,20 @@ msgstr "刪除後你將無法追溯其他用戶對此內容曾經作出的回應
msgid "Deletion cannot be undone, are you sure to continue?"
msgstr "刪除不可撤銷。確認繼續嗎?"
-#: journal/templates/profile.html:55
+#: journal/templates/profile.html:51
msgid "calendar"
msgstr "日曆"
-#: journal/templates/profile.html:58 journal/templates/wrapped.html:14
+#: journal/templates/profile.html:54 journal/templates/wrapped.html:14
#: journal/templates/wrapped.html:53
msgid "annual summary"
msgstr "年度小結"
-#: journal/templates/profile.html:131 journal/views/collection.py:165
+#: journal/templates/profile.html:119 journal/views/collection.py:166
msgid "collection"
msgstr "收藏單"
-#: journal/templates/profile.html:171
+#: journal/templates/profile.html:155
msgid "liked collection"
msgstr "喜歡的收藏單"
@@ -3449,6 +3480,10 @@ msgstr "保存時將行首空格替換爲全角"
msgid "change review date"
msgstr "指定評論日期"
+#: journal/templates/search_journal.html:25
+msgid "No items matching the search query."
+msgstr "無匹配條目。"
+
#: journal/templates/tag_edit.html:32
msgid "Pin"
msgstr "置頂"
@@ -3551,25 +3586,25 @@ msgid_plural "%(count)d items"
msgstr[0] "%(count)d 個條目"
msgstr[1] "%(count)d 個條目"
-#: journal/views/collection.py:36
+#: journal/views/collection.py:37
#, python-brace-format
msgid "Collection by {0}"
msgstr "{0} 的收藏單"
-#: journal/views/collection.py:170
+#: journal/views/collection.py:171
msgid "shared my collection"
msgstr "分享我的收藏單"
-#: journal/views/collection.py:173
+#: journal/views/collection.py:174
#, python-brace-format
msgid "shared {username}'s collection"
msgstr "分享 {username} 的收藏單"
-#: journal/views/collection.py:224
+#: journal/views/collection.py:225
msgid "Unable to find the item, please use item url from this site."
msgstr "找不到條目,請使用本站條目網址。"
-#: journal/views/collection.py:337 journal/views/collection.py:358
+#: journal/views/collection.py:338 journal/views/collection.py:359
#: journal/views/review.py:124
msgid "Login required"
msgstr "登入後訪問"
@@ -3653,12 +3688,12 @@ msgstr "重複標籤"
msgid "Tag updated."
msgstr "標籤已更新"
-#: journal/views/wrapped.py:145
+#: journal/views/wrapped.py:146
msgid "Summary posted to timeline."
msgstr "總結已發佈到時間軸"
#: mastodon/models/common.py:14 users/templates/users/account.html:44
-#: users/templates/users/login.html:57
+#: users/templates/users/login.html:60
msgid "Email"
msgstr "電子郵件"
@@ -3666,7 +3701,7 @@ msgstr "電子郵件"
msgid "Mastodon"
msgstr "Mastodon"
-#: mastodon/models/common.py:16 users/templates/users/login.html:76
+#: mastodon/models/common.py:16 users/templates/users/login.html:85
msgid "Threads"
msgstr "Threads"
@@ -3684,6 +3719,10 @@ msgstr ""
"\n"
"如果你沒有打算用此電子郵件地址註冊或登入本站,請忽略此郵件;如果你確信帳號存在安全風險,請更改註冊郵件地址或與我們聯繫。"
+#: mastodon/models/email.py:60 mastodon/models/email.py:65
+msgid "Verification Code"
+msgstr "驗證碼"
+
#: mastodon/models/email.py:62
#, python-brace-format
msgid ""
@@ -3708,6 +3747,11 @@ msgstr ""
"\n"
"{code}"
+#: mastodon/models/email.py:70 users/templates/users/login.html:16
+#: users/templates/users/register.html:8 users/templates/users/welcome.html:8
+msgid "Register"
+msgstr "註冊"
+
#: mastodon/models/email.py:72
#, python-brace-format
msgid ""
@@ -3772,7 +3816,7 @@ msgstr "新帖文"
#: mastodon/views/common.py:30 mastodon/views/mastodon.py:37
#: mastodon/views/mastodon.py:44 mastodon/views/mastodon.py:54
#: mastodon/views/mastodon.py:61 mastodon/views/threads.py:41
-#: mastodon/views/threads.py:47 users/views/account.py:104
+#: mastodon/views/threads.py:47 users/views/account.py:105
msgid "Authentication failed"
msgstr "認證失敗"
@@ -4064,7 +4108,7 @@ msgstr ""
"回應了你對 %(item_title)s 的標記\n"
#: social/templates/feed.html:11 social/templates/feed.html:23
-#: social/templates/notification.html:23
+#: social/templates/notification.html:23 social/templates/search_feed.html:11
msgid "Activities from those you follow"
msgstr "好友動態"
@@ -4096,7 +4140,11 @@ msgstr "標記"
msgid "wrote a note"
msgstr "寫了筆記"
-#: social/templates/feed_events.html:140
+#: social/templates/feed_events.html:139
+msgid "no matching activities."
+msgstr "無匹配動態。"
+
+#: social/templates/feed_events.html:142
#, 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的用戶,這裏就會顯示你和她們的近期動態。"
@@ -4137,23 +4185,19 @@ msgstr "頭像"
msgid "Header picture"
msgstr "背景圖片"
-#: takahe/utils.py:565
-msgid "created collection"
-msgstr "創建了收藏單"
-
-#: users/models/task.py:17
+#: users/models/task.py:19
msgid "Pending"
msgstr "等待"
-#: users/models/task.py:18
+#: users/models/task.py:20
msgid "Started"
msgstr "已開始"
-#: users/models/task.py:19
+#: users/models/task.py:21
msgid "Complete"
msgstr "完成"
-#: users/models/task.py:20
+#: users/models/task.py:22
msgid "Failed"
msgstr "失敗"
@@ -4189,20 +4233,20 @@ msgstr "在這裏更新個人資料會停止從關聯實例自動同步暱稱等
msgid "Username"
msgstr "用戶名"
-#: users/templates/users/account.html:50 users/templates/users/register.html:30
+#: users/templates/users/account.html:50 users/templates/users/register.html:37
msgid "Email address"
msgstr "電子郵件地址"
-#: users/templates/users/account.html:59 users/templates/users/register.html:39
+#: users/templates/users/account.html:59 users/templates/users/register.html:46
#, python-format
msgid "Please click the confirmation link in the email sent to %(pending_email)s; if you haven't received it for more than a few minutes, please input and save again."
msgstr "當前待確認的電子郵件地址爲%(pending_email)s,請查收郵件並點擊確認連結;如長時間未收到可重新輸入並保存。"
-#: users/templates/users/account.html:61 users/templates/users/register.html:42
+#: users/templates/users/account.html:61 users/templates/users/register.html:49
msgid "Email is recommended as a backup login method, if you log in via a Fediverse instance"
msgstr "推薦輸入電子郵件地址作爲備用登入方式。"
-#: users/templates/users/account.html:73 users/templates/users/login.html:63
+#: users/templates/users/account.html:73 users/templates/users/login.html:69
msgid "Fediverse (Mastodon)"
msgstr "聯邦宇宙(有時也被稱爲長毛象)"
@@ -4270,7 +4314,7 @@ msgstr "關聯一個threads.net帳號"
msgid "Disconnect with Threads"
msgstr "取消關聯"
-#: users/templates/users/account.html:173 users/templates/users/login.html:83
+#: users/templates/users/account.html:173 users/templates/users/login.html:95
msgid "Bluesky (ATProto)"
msgstr "Bluesky (ATProto)"
@@ -4282,7 +4326,7 @@ msgstr "已驗證的ATProto身份"
msgid "Bluesky Login ID"
msgstr "Bluesky 登入名"
-#: users/templates/users/account.html:202 users/templates/users/login.html:159
+#: users/templates/users/account.html:202 users/templates/users/login.html:171
msgid "Bluesky app password"
msgstr "Bluesky 應用密碼"
@@ -4294,7 +4338,7 @@ msgstr "關聯另一個ATProto身份"
msgid "Link with an ATProto identity"
msgstr "關聯ATProto身份"
-#: users/templates/users/account.html:209 users/templates/users/login.html:164
+#: users/templates/users/account.html:209 users/templates/users/login.html:176
msgid "App password can be created on bsky.app."
msgstr "應用密碼可在 bsky.app 創建管理。"
@@ -4366,11 +4410,11 @@ msgstr "輸入完整的登入用 用戶名@實例名
或 電
msgid "Once deleted, account data cannot be recovered."
msgstr "帳號數據一旦刪除後將無法恢復"
-#: users/templates/users/account.html:321
+#: users/templates/users/account.html:322
msgid "Importing in progress, can't delete now."
msgstr "暫時無法刪除,因爲有匯入任務正在進行"
-#: users/templates/users/account.html:324
+#: users/templates/users/account.html:326
msgid "Permanently Delete"
msgstr "永久刪除"
@@ -4386,7 +4430,7 @@ msgstr "匯入豆瓣標記和評論"
msgid "Select .xlsx
exported from Doufen"
msgstr "在豆伴(豆墳)導出時勾選書影音遊劇和評論。
選擇從豆伴(豆墳)導出的.xlsx
文件"
-#: users/templates/users/data.html:27 users/templates/users/data.html:185
+#: users/templates/users/data.html:27 users/templates/users/data.html:194
msgid "Import Method"
msgstr "匯入方式"
@@ -4407,7 +4451,7 @@ msgid "Import in progress, please wait"
msgstr "備份文件已上傳,請等待匯入完成或刷新頁面查看最新進度"
#: users/templates/users/data.html:67 users/templates/users/data.html:86
-#: users/templates/users/data.html:158 users/templates/users/data.html:201
+#: users/templates/users/data.html:167 users/templates/users/data.html:210
msgid "Import"
msgstr "匯入"
@@ -4419,74 +4463,81 @@ msgstr "匯入Goodreads書架或書單"
msgid "Link to Goodreads Profile / Shelf / List"
msgstr "Goodreads個人主頁、書架或書單連結"
-#: users/templates/users/data.html:91
+#: users/templates/users/data.html:90 users/templates/users/data.html:172
+#: users/templates/users/data_import_status.html:2
+msgid "Last import started"
+msgstr "最近匯入時間"
+
+#: users/templates/users/data.html:91 users/templates/users/data.html:173
+#: users/templates/users/data.html:226
+#: users/templates/users/data_import_status.html:3
+msgid "Status"
+msgstr "狀態"
+
+#: users/templates/users/data.html:100
msgid "want-to-read / currently-reading / read books and their reviews will be imported."
msgstr "提交Goodreads用戶主頁連結將匯入想讀、在讀、已讀列表,每本書的評論匯入爲本站短評。"
-#: users/templates/users/data.html:95
+#: users/templates/users/data.html:104
msgid "Shelf will be imported as a new collection."
msgstr "Goodreads書架將被匯入爲收藏單,每本書的評論匯入爲收藏單條目備註。"
-#: users/templates/users/data.html:99
+#: users/templates/users/data.html:108
msgid "List will be imported as a new collection."
msgstr "Goodreads書單將被匯入爲收藏單,每本書的評論匯入爲收藏單條目備註。"
-#: users/templates/users/data.html:110
+#: users/templates/users/data.html:119
msgid "Import from Letterboxd"
msgstr "匯入Letterboxd標記"
-#: users/templates/users/data.html:160
+#: users/templates/users/data.html:169
msgid "Only forward changes(none->to-watch->watched) will be imported."
msgstr "匯入時僅更新正向變化(未標->想看->已看)標記;不足360字符的評論會作爲短評添加。"
-#: users/templates/users/data.html:163
-msgid "Last import started"
-msgstr "最近匯入時間"
-
-#: users/templates/users/data.html:164
-msgid "Status"
-msgstr "狀態"
-
-#: users/templates/users/data.html:168
+#: users/templates/users/data.html:177
msgid "Failed links, likely due to Letterboxd error, you may have to mark them manually"
msgstr "匯入失敗的連結(通常由於Letterboxd的信息錯誤,請手工添加標記)"
-#: users/templates/users/data.html:179
+#: users/templates/users/data.html:188
msgid "Import Podcast Subscriptions"
msgstr "匯入播客訂閱列表 (OPML)"
-#: users/templates/users/data.html:192
+#: users/templates/users/data.html:201
msgid "Mark as listening"
msgstr "標記爲在聽"
-#: users/templates/users/data.html:196
+#: users/templates/users/data.html:205
msgid "Import as a new collection"
msgstr "匯入爲新收藏單"
-#: users/templates/users/data.html:199
+#: users/templates/users/data.html:208
msgid "Select OPML file"
msgstr "選擇OPML文件"
-#: users/templates/users/data.html:208
+#: users/templates/users/data.html:217
msgid "Export Data"
msgstr "匯出資料"
-#: users/templates/users/data.html:214
-msgid "Export in progress"
-msgstr "正在匯出"
-
-#: users/templates/users/data.html:214
+#: users/templates/users/data.html:222
msgid "Export marks and reviews"
msgstr "匯出標記、短評和評論"
-#: users/templates/users/data.html:216
+#: users/templates/users/data.html:225
+msgid "Last export"
+msgstr "最近匯出"
+
+#: users/templates/users/data.html:230
msgid "Download"
msgstr "下載"
-#: users/templates/users/data.html:223
+#: users/templates/users/data.html:238
msgid "View Annual Summary"
msgstr "查看年度小結"
+#: users/templates/users/data_import_status.html:11
+msgid "Failed links, you may have to mark them manually"
+msgstr "匯入失敗的連結(請手工添加標記)"
+
#: users/templates/users/fetch_identity_failed.html:4
msgid "Unable to find the user, please check your spelling; or the server may be busy, please try again later."
msgstr "無法找到用戶,請確認拼寫正確;也可能伺服器正忙,請稍後再嘗試。"
@@ -4496,11 +4547,6 @@ msgstr "無法找到用戶,請確認拼寫正確;也可能伺服器正忙,
msgid "Searching the fediverse"
msgstr "正在搜尋聯邦宇宙"
-#: users/templates/users/login.html:16 users/templates/users/register.html:8
-#: users/templates/users/welcome.html:8
-msgid "Register"
-msgstr "註冊"
-
#: users/templates/users/login.html:16
msgid "Login"
msgstr "登入"
@@ -4510,72 +4556,72 @@ msgstr "登入"
msgid "back to your home page."
msgstr "返回首頁"
-#: users/templates/users/login.html:99
+#: users/templates/users/login.html:111
msgid "Enter your email address"
msgstr "輸入電子郵件地址"
-#: users/templates/users/login.html:101
+#: users/templates/users/login.html:113
msgid "Send verification code"
msgstr "發送驗證碼"
-#: users/templates/users/login.html:116
+#: users/templates/users/login.html:128
msgid "Domain of your instance, e.g. mastodon.social"
msgstr "實例域名(不含@和@之前的部分),如mastodon.social"
-#: users/templates/users/login.html:122
+#: users/templates/users/login.html:134
msgid "Please enter domain of your instance; e.g. if your id is @neodb@mastodon.social, only enter mastodon.social."
msgstr "請輸入你的實例域名(不含@和@之前的部分);如果你的聯邦帳號是@neodb@mastodon.social,只需要在此輸入mastodon.social。"
-#: users/templates/users/login.html:125 users/templates/users/login.html:178
+#: users/templates/users/login.html:137 users/templates/users/login.html:190
msgid "Authorize via Fediverse instance"
msgstr "去聯邦實例授權註冊或登入"
-#: users/templates/users/login.html:127
+#: users/templates/users/login.html:139
msgid "If you don't have a Fediverse (Mastodon) account yet, you may register or login with Email first, and link it with Fediverse (Mastodon) later in account settings."
msgstr "如果你還沒有或不便註冊聯邦實例帳號,也可先通過電子郵件或其它平臺註冊登入,未來再作關聯。"
-#: users/templates/users/login.html:137
+#: users/templates/users/login.html:149
msgid "Authorize via Threads"
msgstr "去Threads授權註冊或登入"
-#: users/templates/users/login.html:150
+#: users/templates/users/login.html:162
msgid "ATProto handle"
msgstr "ATProto 用戶標識"
-#: users/templates/users/login.html:155
+#: users/templates/users/login.html:167
msgid "Please input your ATProto handle (e.g. neodb.bsky.social, without the leading @), do not use email. If you changed handle recently, just use the latest one."
msgstr "請輸入你的ATProto用戶標識(例如neodb.bsky.social,不包含開頭的@),不要輸入電子郵件地址。如果你最近更改過標識,請使用最新的那一個。"
-#: users/templates/users/login.html:165
+#: users/templates/users/login.html:177
msgid "Authorize via bsky.app"
msgstr "使用Bluesky帳號資料註冊或登入"
-#: users/templates/users/login.html:169
+#: users/templates/users/login.html:181
#, python-format
msgid "Please choose one to register or login %(site_name)s. Have more than one of these identities? Don't worry, you may link them in account settings once logged in."
msgstr "請選擇一種方式註冊或登入 %(site_name)s。如果你有多個社交身份,登入後可在帳號設定中添加綁定。"
-#: users/templates/users/login.html:185
+#: users/templates/users/login.html:197
msgid "Valid invitation code, please login or register."
msgstr "邀請連結有效,可註冊新用戶"
-#: users/templates/users/login.html:187
+#: users/templates/users/login.html:199
msgid "Please use invitation link to register a new account; existing user may login."
msgstr "本站目前爲邀請註冊,已有帳號可直接登入,新用戶請使用有效邀請連結註冊"
-#: users/templates/users/login.html:189
+#: users/templates/users/login.html:201
msgid "Invitation code invalid or expired."
msgstr "邀請連結無效,已有賬戶可直接登入,新用戶請使用有效邀請連結註冊"
-#: users/templates/users/login.html:197
+#: users/templates/users/login.html:209
msgid "Loading timed out, please check your network (VPN) settings."
msgstr "部分模塊加載超時,請檢查網絡(翻牆)設定。"
-#: users/templates/users/login.html:203
+#: users/templates/users/login.html:215
msgid "Continue using this site implies consent to our rules and terms, including using cookies to provide necessary functionality."
msgstr "繼續訪問或註冊視爲同意站規與協議,及使用cookie提供必要功能"
-#: users/templates/users/login.html:209
+#: users/templates/users/login.html:221
msgid "Domain of your instance (excl. @)"
msgstr "實例域名(不含@和@之前的部分)"
@@ -4800,27 +4846,27 @@ msgstr "確定屏蔽該用戶嗎?"
msgid "Your username on %(site_name)s"
msgstr "你在%(site_name)s使用的用戶名"
-#: users/templates/users/register.html:26
+#: users/templates/users/register.html:27
msgid "2-30 alphabets, numbers or underscore, can't be changed once saved"
msgstr "2-30個字符,限英文字母數字下劃線,儲存後不可更改"
-#: users/templates/users/register.html:60
+#: users/templates/users/register.html:67
msgid "Turn on crosspost to other social networks by default"
msgstr "發表時預設轉發到社交網絡時間軸"
-#: users/templates/users/register.html:64
+#: users/templates/users/register.html:71
msgid "Use display name, bio and avatar from the social network you authenticated with"
msgstr "自動同步用戶暱稱等基本資訊"
-#: users/templates/users/register.html:72
+#: users/templates/users/register.html:79
msgid "Add follow, mute and block list from the social network you authenticated with"
msgstr "自動匯入新增的關注、屏蔽和隱藏列表"
-#: users/templates/users/register.html:77
+#: users/templates/users/register.html:84
msgid "Confirm and save"
msgstr "確認並儲存"
-#: users/templates/users/register.html:81 users/templates/users/welcome.html:27
+#: users/templates/users/register.html:88 users/templates/users/welcome.html:27
msgid "Cut the sh*t and get me in!"
msgstr ""
@@ -4863,66 +4909,70 @@ msgstr ""
"\n"
"%(site_name)s還在不斷完善中。 豐富的內容需要大家共同創造,試圖添加垃圾資料(如添加信息混亂或缺失的書籍、以推廣爲主要目的的評論)將會受到嚴肅處理。 本站爲非盈利站點,cookie和其它資料保管使用原則請參閱站內公告。 本站提供API和導出功能,請妥善備份您的數據,使用過程中遇到的問題或者錯誤歡迎向維護者提出。感謝理解和支持!"
-#: users/views/account.py:78
+#: users/views/account.py:79
msgid "This username is already in use."
msgstr "用戶名已被使用"
-#: users/views/account.py:89
+#: users/views/account.py:90
msgid "This email address is already in use."
msgstr "此電子郵件地址已被使用"
-#: users/views/account.py:105
+#: users/views/account.py:106
msgid "Registration is for invitation only"
msgstr "本站僅限邀請註冊"
-#: users/views/account.py:175
+#: users/views/account.py:176
msgid "Valid username required"
msgstr "請輸入有效的用戶名"
-#: users/views/account.py:177
+#: users/views/account.py:178
msgid "Username in use"
msgstr "用戶名已被使用"
-#: users/views/account.py:247
+#: users/views/account.py:250
msgid "Account is being deleted."
msgstr "帳號刪除進行中。"
-#: users/views/account.py:250
+#: users/views/account.py:253
msgid "Account mismatch."
msgstr "帳號資訊不符合。"
-#: users/views/data.py:128
+#: users/views/data.py:129
msgid "Generating exports."
msgstr "正在產生匯出檔案文件。"
-#: users/views/data.py:140
+#: users/views/data.py:135
+msgid "Export file not available."
+msgstr "匯出檔案不可用"
+
+#: users/views/data.py:147
msgid "Export file expired. Please export again."
msgstr "匯出文件已失效,請重新匯出"
-#: users/views/data.py:149
+#: users/views/data.py:156
msgid "Sync in progress."
msgstr "正在同步。"
-#: users/views/data.py:163
+#: users/views/data.py:170
msgid "Settings saved."
msgstr "設定已儲存"
-#: users/views/data.py:174
+#: users/views/data.py:181
msgid "Reset completed."
msgstr "重置已完成。"
-#: users/views/data.py:183
+#: users/views/data.py:195
msgid "Import in progress."
msgstr "正在匯入"
-#: users/views/data.py:185
+#: users/views/data.py:197
msgid "Invalid URL."
msgstr "無效網址。"
-#: users/views/data.py:199 users/views/data.py:224 users/views/data.py:239
-msgid "File is uploaded and will be imported soon."
-msgstr "檔案已上傳,等待後臺匯入。"
-
-#: users/views/data.py:202 users/views/data.py:242
+#: users/views/data.py:215 users/views/data.py:265
msgid "Invalid file."
msgstr "無效檔案。"
+
+#: users/views/data.py:224 users/views/data.py:247 users/views/data.py:262
+msgid "File is uploaded and will be imported soon."
+msgstr "檔案已上傳,等待後臺匯入。"
diff --git a/requirements-dev.lock b/requirements-dev.lock
index 527c7043..5ba76534 100644
--- a/requirements-dev.lock
+++ b/requirements-dev.lock
@@ -130,7 +130,7 @@ httpcore==1.0.7
# via httpx
httpx==0.27.2
# via atproto
-identify==2.6.3
+identify==2.6.4
# via pre-commit
idna==3.10
# via anyio
@@ -167,7 +167,7 @@ markupsafe==3.0.2
mergedeep==1.3.4
# via mkdocs
# via mkdocs-get-deps
-mistune==3.0.2
+mistune==3.1.0
mkdocs==1.6.1
# via mkdocs-material
mkdocs-get-deps==0.2.0
@@ -281,7 +281,7 @@ tinycss2==1.1.1
# via bleach
tqdm==4.67.1
# via djlint
-types-pyyaml==6.0.12.20241221
+types-pyyaml==6.0.12.20241230
# via django-stubs
typesense==0.21.0
typing-extensions==4.12.2
diff --git a/requirements.lock b/requirements.lock
index 6b0a6264..b843c27e 100644
--- a/requirements.lock
+++ b/requirements.lock
@@ -117,7 +117,7 @@ lxml==5.3.0
markdown==3.7
# via django-markdownx
markdownify==0.14.1
-mistune==3.0.2
+mistune==3.1.0
multidict==6.1.0
# via aiohttp
# via yarl
diff --git a/social/templates/feed.html b/social/templates/feed.html
index 77cb6e3b..6a135490 100644
--- a/social/templates/feed.html
+++ b/social/templates/feed.html
@@ -31,7 +31,7 @@
-
diff --git a/social/templates/feed_events.html b/social/templates/feed_events.html
index 0f202598..24ba272b 100644
--- a/social/templates/feed_events.html
+++ b/social/templates/feed_events.html
@@ -125,19 +125,21 @@
{% if forloop.last %}
{% endif %}
{% empty %}
- {% if request.GET.last %}
- {% trans 'nothing more.' %}
- {% else %}
-
+
+ {% if request.GET.last or request.GET.nextpage %}
+ {% trans 'nothing more.' %}
+ {% elif request.GET.q %}
+ {% trans 'no matching activities.' %}
+ {% else %}
{% url 'users:data' as import_url %}
{% blocktrans %}Find and mark some books/movies/podcasts/games, import your data from Goodreads/Letterboxd/Douban, follow some fellow {{ site_name }} users on the fediverse, so their recent activities and yours will show up here.{% endblocktrans %}
-
- {% endif %}
+ {% endif %}
+
{% endfor %}
diff --git a/social/templates/search_feed.html b/social/templates/search_feed.html
new file mode 100644
index 00000000..51077acf
--- /dev/null
+++ b/social/templates/search_feed.html
@@ -0,0 +1,35 @@
+{% load static %}
+{% load i18n %}
+{% load l10n %}
+{% load mastodon %}
+{% load thumb %}
+
+
+
+
+
+ {{ site_name }} - {% trans 'Activities from those you follow' %}
+ {% include "common_libs.html" %}
+
+
+
+
+
+ {% include "_header.html" %}
+
+
+ {% include 'search_header.html' %}
+
+
+
+
+
+
+ {% include "_sidebar.html" with show_progress=1 identity=request.user.identity %}
+
+ {% include "_footer.html" %}
+
+
diff --git a/social/views.py b/social/views.py
index 79b7f397..660ea3f5 100644
--- a/social/views.py
+++ b/social/views.py
@@ -3,22 +3,17 @@
from django.urls import reverse
from django.views.decorators.http import require_http_methods
-from catalog.models import *
-from journal.models import *
-from takahe.models import PostInteraction, TimelineEvent
+from catalog.models import Edition, Item, ItemCategory, PodcastEpisode
+from common.models.misc import int_
+from journal.models import JournalIndex, Piece, QueryParser, ShelfType
+from takahe.models import Post, PostInteraction, TimelineEvent
from takahe.utils import Takahe
-
-from .models import *
+from users.models import APIdentity
PAGE_SIZE = 10
-@require_http_methods(["GET"])
-@login_required
-def feed(request, typ=0):
- if not request.user.registration_complete:
- return redirect(reverse("users:register"))
- user = request.user
+def _sidebar_context(user):
podcast_ids = [
p.item_id
for p in user.shelf_manager.get_latest_members(
@@ -44,59 +39,97 @@ def feed(request, typ=0):
)[:10]
]
)
- return render(
- request,
- "feed.html",
- {
- "feed_type": typ,
- "recent_podcast_episodes": recent_podcast_episodes,
- "books_in_progress": books_in_progress,
- "tvshows_in_progress": tvshows_in_progress,
- },
- )
+ return {
+ "recent_podcast_episodes": recent_podcast_episodes,
+ "books_in_progress": books_in_progress,
+ "tvshows_in_progress": tvshows_in_progress,
+ }
+
+
+@require_http_methods(["GET"])
+@login_required
+def feed(request, typ=0):
+ if not request.user.registration_complete:
+ return redirect(reverse("users:register"))
+ user = request.user
+ data = _sidebar_context(user)
+ data["feed_type"] = typ
+ return render(request, "feed.html", data)
def focus(request):
return feed(request, typ=1)
+@require_http_methods(["GET"])
+@login_required
+def search(request):
+ if not request.user.registration_complete:
+ return redirect(reverse("users:register"))
+ user = request.user
+ data = _sidebar_context(user)
+ return render(request, "search_feed.html", data)
+
+
@login_required
@require_http_methods(["GET"])
def data(request):
- since_id = int(request.GET.get("last", 0))
- typ = int(request.GET.get("typ", 0))
+ since_id = int_(request.GET.get("last", 0))
+ typ = int_(request.GET.get("typ", 0))
+ q = request.GET.get("q")
identity_id = request.user.identity.pk
- events = TimelineEvent.objects.filter(
- identity_id=identity_id,
- type__in=[TimelineEvent.Types.post, TimelineEvent.Types.boost],
- )
- match typ:
- case 1:
- events = events.filter(
- subject_post__type_data__object__has_key="relatedWith"
- )
- case _: # default: no replies
- events = events.filter(subject_post__in_reply_to__isnull=True)
- if since_id:
- events = events.filter(id__lt=since_id)
- events = list(
- events.select_related(
- "subject_post",
- "subject_post__author",
- # "subject_post__author__domain",
- "subject_identity",
- # "subject_identity__domain",
- "subject_post_interaction",
- "subject_post_interaction__identity",
- # "subject_post_interaction__identity__domain",
+ page = int_(request.GET.get("page", 1))
+ if q:
+ q = QueryParser(request.GET.get("q", default=""))
+ index = JournalIndex.instance()
+ q.filter_by["owner_id"] = [identity_id]
+ q.filter_by["post_id"] = [">0"]
+ r = index.search(
+ q.q,
+ filter_by=q.filter_by,
+ query_by=q.query_by,
+ sort_by="created:desc",
+ page=page,
+ page_size=PAGE_SIZE,
+ )
+ events = [
+ SearchResultEvent(p)
+ for p in r.posts.select_related("author")
+ .prefetch_related("attachments")
+ .order_by("-id")
+ ]
+ else:
+ events = TimelineEvent.objects.filter(
+ identity_id=identity_id,
+ type__in=[TimelineEvent.Types.post, TimelineEvent.Types.boost],
)
- .prefetch_related(
- "subject_post__attachments",
- # "subject_post__mentions",
- # "subject_post__emojis",
+ match typ:
+ case 1:
+ events = events.filter(
+ subject_post__type_data__object__has_key="relatedWith"
+ )
+ case _: # default: no replies
+ events = events.filter(subject_post__in_reply_to__isnull=True)
+ if since_id:
+ events = events.filter(id__lt=since_id)
+ events = list(
+ events.select_related(
+ "subject_post",
+ "subject_post__author",
+ # "subject_post__author__domain",
+ "subject_identity",
+ # "subject_identity__domain",
+ "subject_post_interaction",
+ "subject_post_interaction__identity",
+ # "subject_post_interaction__identity__domain",
+ )
+ .prefetch_related(
+ "subject_post__attachments",
+ # "subject_post__mentions",
+ # "subject_post__emojis",
+ )
+ .order_by("-id")[:PAGE_SIZE]
)
- .order_by("-id")[:PAGE_SIZE]
- )
interactions = PostInteraction.objects.filter(
identity_id=identity_id,
post_id__in=[event.subject_post_id for event in events],
@@ -105,15 +138,19 @@ def data(request):
).values_list("post_id", "type")
for event in events:
if event.subject_post_id:
- event.subject_post.liked_by_current_user = (
+ event.subject_post.liked_by_current_user = ( # type: ignore
event.subject_post_id,
"like",
) in interactions
- event.subject_post.boosted_by_current_user = (
- event.subject_post_id,
- "boost",
- ) in interactions
- return render(request, "feed_events.html", {"feed_type": typ, "events": events})
+ event.subject_post.boosted_by_current_user = ( # type: ignore
+ event.subject_post_id,
+ "boost",
+ ) in interactions
+ return render(
+ request,
+ "feed_events.html",
+ {"feed_type": typ, "events": events, "nextpage": page + 1},
+ )
@require_http_methods(["GET"])
@@ -182,6 +219,16 @@ def __init__(self, tle) -> None:
self.template += "_" + cls
+class SearchResultEvent:
+ def __init__(self, post: Post):
+ self.type = "post"
+ self.subject_post = post
+ self.subject_post_id = post.id
+ self.created = post.created
+ self.published = post.published
+ self.identity = post.author
+
+
@login_required
@require_http_methods(["GET"])
def events(request):
diff --git a/takahe/utils.py b/takahe/utils.py
index e27afd50..e02c2b7d 100644
--- a/takahe/utils.py
+++ b/takahe/utils.py
@@ -68,57 +68,57 @@ def init_identity_for_local_user(u: "NeoUser"):
if not u.username:
logger.warning(f"User {u} has no username")
return None
- user = User.objects.filter(pk=u.pk).first()
- handler = "@" + u.username
- if not user:
- logger.info(f"Creating takahe user {u}")
- user = User.objects.create(pk=u.pk, email=handler, password=u.password)
- else:
- if user.email != handler:
- logger.warning(f"Updating takahe user {u} email to {handler}")
- user.email = handler
- user.save()
- domain = Domain.objects.get(domain=settings.SITE_INFO["site_domain"])
- # TODO add transaction protection here
- identity = Identity.objects.filter(username=u.username, local=True).first()
- if not identity:
- logger.info(f"Creating takahe identity {u}@{domain}")
- identity = Identity.objects.create(
- actor_uri=f"https://{domain.uri_domain}/@{u.username}@{domain.domain}/",
- profile_uri=u.absolute_url,
- username=u.username,
- domain=domain,
- name=u.username,
- local=True,
- discoverable=True,
- )
- if not identity.private_key and not identity.public_key:
- identity.generate_keypair()
- identity.ensure_uris()
- if not user.identities.filter(pk=identity.pk).exists():
- user.identities.add(identity)
- apidentity = APIdentity.objects.filter(pk=identity.pk).first()
- if not apidentity:
- logger.info(f"Creating APIdentity for {identity}")
- apidentity = APIdentity.objects.create(
- user=u,
- id=identity.pk,
- local=True,
- username=u.username,
- domain_name=domain.domain,
- deleted=identity.deleted,
- )
- elif apidentity.username != identity.username:
- logger.warning(
- f"Updating APIdentity {apidentity} username to {identity.username}"
- )
- apidentity.username = identity.username
- apidentity.save()
- if u.identity != apidentity:
- logger.warning(f"Linking user {u} identity to {apidentity}")
- u.identity = apidentity
- u.save(update_fields=["identity"])
- return apidentity
+ with transaction.atomic(using="takahe"):
+ user = User.objects.filter(pk=u.pk).first()
+ handler = "@" + u.username
+ if not user:
+ logger.info(f"Creating takahe user {u}")
+ user = User.objects.create(pk=u.pk, email=handler, password=u.password)
+ else:
+ if user.email != handler:
+ logger.warning(f"Updating takahe user {u} email to {handler}")
+ user.email = handler
+ user.save()
+ domain = Domain.objects.get(domain=settings.SITE_INFO["site_domain"])
+ identity = Identity.objects.filter(username=u.username, local=True).first()
+ if not identity:
+ logger.info(f"Creating takahe identity {u}@{domain}")
+ identity = Identity.objects.create(
+ actor_uri=f"https://{domain.uri_domain}/@{u.username}@{domain.domain}/",
+ profile_uri=u.absolute_url,
+ username=u.username,
+ domain=domain,
+ name=u.username,
+ local=True,
+ discoverable=True,
+ )
+ if not identity.private_key and not identity.public_key:
+ identity.generate_keypair()
+ identity.ensure_uris()
+ if not user.identities.filter(pk=identity.pk).exists():
+ user.identities.add(identity)
+ apidentity = APIdentity.objects.filter(pk=identity.pk).first()
+ if not apidentity:
+ logger.info(f"Creating APIdentity for {identity}")
+ apidentity = APIdentity.objects.create(
+ user=u,
+ id=identity.pk,
+ local=True,
+ username=u.username,
+ domain_name=domain.domain,
+ deleted=identity.deleted,
+ )
+ elif apidentity.username != identity.username:
+ logger.warning(
+ f"Updating APIdentity {apidentity} username to {identity.username}"
+ )
+ apidentity.username = identity.username
+ apidentity.save()
+ if u.identity != apidentity:
+ logger.warning(f"Linking user {u} identity to {apidentity}")
+ u.identity = apidentity
+ u.save(update_fields=["identity"])
+ return apidentity
@staticmethod
def get_identity_by_handler(username: str, domain: str) -> Identity | None:
@@ -541,56 +541,6 @@ def visibility_t2n(visibility: int) -> int:
case _:
return 0
- @staticmethod
- def post_collection(collection: "Collection"):
- existing_post = collection.latest_post
- owner: APIdentity = collection.owner
- user = owner.user
- if not user:
- raise ValueError(f"Cannot find user for collection {collection}")
- visibility = Takahe.visibility_n2t(
- collection.visibility, user.preference.post_public_mode
- )
- if existing_post and visibility != existing_post.visibility:
- Takahe.delete_posts([existing_post.pk])
- existing_post = None
- data = {
- "object": {
- # "tag": [item.ap_object_ref for item in collection.items],
- "relatedWith": [collection.ap_object],
- }
- }
- if existing_post and existing_post.type_data == data:
- return existing_post
- action = _("created collection")
- item_link = collection.absolute_url
- prepend_content = f'{action} {collection.title}
'
- content = collection.plain_content
- if len(content) > 360:
- content = content[:357] + "..."
- data = {
- "object": {
- # "tag": [item.ap_object_ref for item in collection.items],
- "relatedWith": [collection.ap_object],
- }
- }
- post = Takahe.post(
- collection.owner.pk,
- content,
- visibility,
- prepend_content,
- "",
- None,
- False,
- data,
- existing_post.pk if existing_post else None,
- collection.created_time,
- )
- if not post:
- return
- collection.link_post_id(post.pk)
- return post
-
@staticmethod
def interact_post(post_pk: int, identity_pk: int, type: str, flip=False):
post = Post.objects.filter(pk=post_pk).first()
diff --git a/users/management/commands/user.py b/users/management/commands/user.py
index a49d92c1..e4a05623 100644
--- a/users/management/commands/user.py
+++ b/users/management/commands/user.py
@@ -47,7 +47,7 @@ def list(self, users):
self.stdout.write(
user.username.ljust(20)
+ str(user.date_joined.date()).ljust(12)
- + str(user.last_login.date()).ljust(12)
+ + str(user.last_login.date() if user.last_login else "").ljust(12)
+ str(list(user.social_accounts.all())),
)
diff --git a/users/views/account.py b/users/views/account.py
index 3e87b247..a0da2d89 100644
--- a/users/views/account.py
+++ b/users/views/account.py
@@ -15,6 +15,7 @@
from common.utils import AuthedHttpRequest
from journal.models import remove_data_by_user
+from journal.models.index import JournalIndex
from mastodon.models import Email, Mastodon
from mastodon.models.common import Platform, SocialAccount
from mastodon.models.email import EmailAccount
@@ -228,6 +229,8 @@ def clear_data_task(user_id):
remove_data_by_user(user.identity)
Takahe.delete_identity(user.identity.pk)
user.clear()
+ index = JournalIndex(user)
+ index.delete_by_owner(user.identity.pk)
logger.warning(f"User {user_str} data cleared.")
diff --git a/users/views/actions.py b/users/views/actions.py
index 32dfd09f..e1b7b0df 100644
--- a/users/views/actions.py
+++ b/users/views/actions.py
@@ -8,6 +8,7 @@
from django.utils.translation import gettext as _
from common.config import *
+from common.models import int_
from common.utils import (
AuthedHttpRequest,
HTTPResponseHXRedirect,
@@ -40,7 +41,7 @@ def fetch_refresh(request):
i = APIdentity.get_by_handle(handle)
return HTTPResponseHXRedirect(i.url)
except Exception:
- retry = int(request.GET.get("retry", 0)) + 1
+ retry = int_(request.GET.get("retry")) + 1
if retry > 10:
return render(request, "users/fetch_identity_failed.html")
else: