i18n for 4xx 5xx pages
This commit is contained in:
parent
c74e3c5332
commit
a776dcfbb5
19 changed files with 390 additions and 374 deletions
|
@ -1,4 +1,3 @@
|
|||
import logging
|
||||
import re
|
||||
|
||||
import django_rq
|
||||
|
@ -8,11 +7,11 @@ from django.core.cache import cache
|
|||
from django.core.exceptions import BadRequest
|
||||
from django.shortcuts import redirect, render
|
||||
from django.utils.translation import gettext_lazy 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.config import PAGE_LINK_NUMBER
|
||||
from common.utils import (
|
||||
HTTPResponseHXRedirect,
|
||||
PageLinksGenerator,
|
||||
|
@ -52,7 +51,7 @@ def fetch(request, url, is_refetch: bool = False, site: AbstractSite | None = No
|
|||
if not site:
|
||||
site = SiteManager.get_site_by_url(url)
|
||||
if not site:
|
||||
raise BadRequest()
|
||||
raise BadRequest(_("Invalid URL"))
|
||||
item = site.get_item()
|
||||
if item and not is_refetch:
|
||||
return redirect(item.url)
|
||||
|
@ -172,10 +171,9 @@ def external_search(request):
|
|||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def refetch(request):
|
||||
if request.method != "POST":
|
||||
raise BadRequest()
|
||||
url = request.POST.get("url")
|
||||
if not url:
|
||||
raise BadRequest()
|
||||
raise BadRequest(_("Invalid URL"))
|
||||
return fetch(request, url, True)
|
||||
|
|
|
@ -50,11 +50,11 @@ def retrieve_redirect(request, item_path, item_uuid):
|
|||
def embed(request, item_path, item_uuid):
|
||||
item = Item.get_by_url(item_uuid)
|
||||
if item is None:
|
||||
raise Http404()
|
||||
raise Http404(_("Item not found"))
|
||||
if item.merged_to_item:
|
||||
return redirect(item.merged_to_item.url)
|
||||
if item.is_deleted:
|
||||
raise Http404()
|
||||
raise Http404(_("Item no longer exists"))
|
||||
focus_item = None
|
||||
if request.GET.get("focus"):
|
||||
focus_item = get_object_or_404(
|
||||
|
@ -73,7 +73,7 @@ def retrieve(request, item_path, item_uuid):
|
|||
# item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
item = Item.get_by_url(item_uuid)
|
||||
if item is None:
|
||||
raise Http404()
|
||||
raise Http404(_("Item not found"))
|
||||
item_url = f"/{item_path}/{item_uuid}"
|
||||
if item.url != item_url:
|
||||
return redirect(item.url)
|
||||
|
@ -81,7 +81,7 @@ def retrieve(request, item_path, item_uuid):
|
|||
if not skipcheck and item.merged_to_item:
|
||||
return redirect(item.merged_to_item.url)
|
||||
if not skipcheck and item.is_deleted:
|
||||
raise Http404()
|
||||
raise Http404(_("Item no longer exists"))
|
||||
if request.headers.get("Accept", "").endswith("json"):
|
||||
return redirect(item.api_url)
|
||||
focus_item = None
|
||||
|
@ -146,8 +146,6 @@ def episode_data(request, item_uuid):
|
|||
@login_required
|
||||
def mark_list(request, item_path, item_uuid, following_only=False):
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if not item:
|
||||
raise Http404()
|
||||
queryset = ShelfMember.objects.filter(item=item).order_by("-created_time")
|
||||
if following_only:
|
||||
queryset = queryset.filter(q_piece_in_home_feed_of_user(request.user))
|
||||
|
@ -171,8 +169,6 @@ def mark_list(request, item_path, item_uuid, following_only=False):
|
|||
|
||||
def review_list(request, item_path, item_uuid):
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if not item:
|
||||
raise Http404()
|
||||
queryset = Review.objects.filter(item=item).order_by("-created_time")
|
||||
queryset = queryset.filter(q_piece_visible_to_user(request.user))
|
||||
paginator = Paginator(queryset, NUM_REVIEWS_ON_LIST_PAGE)
|
||||
|
@ -192,8 +188,6 @@ def review_list(request, item_path, item_uuid):
|
|||
|
||||
def comments(request, item_path, item_uuid):
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if not item:
|
||||
raise Http404()
|
||||
ids = item.child_item_ids + [item.id] + item.sibling_item_ids
|
||||
queryset = Comment.objects.filter(item_id__in=ids).order_by("-created_time")
|
||||
queryset = queryset.filter(q_piece_visible_to_user(request.user))
|
||||
|
@ -212,8 +206,6 @@ def comments(request, item_path, item_uuid):
|
|||
|
||||
def comments_by_episode(request, item_path, item_uuid):
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if not item:
|
||||
raise Http404()
|
||||
episode_uuid = request.GET.get("episode_uuid")
|
||||
if episode_uuid:
|
||||
episode = TVEpisode.get_by_url(episode_uuid)
|
||||
|
@ -238,8 +230,6 @@ def comments_by_episode(request, item_path, item_uuid):
|
|||
|
||||
def reviews(request, item_path, item_uuid):
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if not item:
|
||||
raise Http404()
|
||||
ids = item.child_item_ids + [item.id] + item.sibling_item_ids
|
||||
queryset = Review.objects.filter(item_id__in=ids).order_by("-created_time")
|
||||
queryset = queryset.filter(q_piece_visible_to_user(request.user))
|
||||
|
|
|
@ -97,7 +97,7 @@ def edit(request, item_path, item_uuid):
|
|||
form.fields["primary_lookup_id_type"].disabled = True
|
||||
form.fields["primary_lookup_id_value"].disabled = True
|
||||
return render(request, "catalog_edit.html", {"form": form, "item": item})
|
||||
elif request.method == "POST":
|
||||
else:
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
form_cls = CatalogForms[item.__class__.__name__]
|
||||
form = form_cls(request.POST, request.FILES, instance=item)
|
||||
|
@ -115,8 +115,6 @@ def edit(request, item_path, item_uuid):
|
|||
return redirect(form.instance.url)
|
||||
else:
|
||||
raise BadRequest(_add_error_map_detail(form.errors))
|
||||
else:
|
||||
raise BadRequest()
|
||||
|
||||
|
||||
@require_http_methods(["POST"])
|
||||
|
@ -124,7 +122,7 @@ def edit(request, item_path, item_uuid):
|
|||
def delete(request, item_path, item_uuid):
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if not request.user.is_staff and item.journal_exists():
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
if request.POST.get("sure", 0) != "1":
|
||||
return render(request, "catalog_delete.html", {"item": item})
|
||||
else:
|
||||
|
@ -147,7 +145,7 @@ def delete(request, item_path, item_uuid):
|
|||
def undelete(request, item_path, item_uuid):
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if not request.user.is_staff:
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
item.is_deleted = False
|
||||
item.save()
|
||||
return redirect(item.url)
|
||||
|
@ -199,10 +197,10 @@ def recast(request, item_path, item_uuid):
|
|||
@login_required
|
||||
def unlink(request):
|
||||
if not request.user.is_staff:
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
res_id = request.POST.get("id")
|
||||
if not res_id:
|
||||
raise BadRequest()
|
||||
raise BadRequest(_("Invalid parameter"))
|
||||
resource = get_object_or_404(ExternalResource, id=res_id)
|
||||
resource.unlink_from_item()
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER"))
|
||||
|
@ -251,7 +249,7 @@ def remove_unused_seasons(request, item_path, item_uuid):
|
|||
def fetch_tvepisodes(request, item_path, item_uuid):
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if item.class_name != "tvseason" or not item.imdb or item.season_number is None:
|
||||
raise BadRequest()
|
||||
raise BadRequest(_("Must be a TV Season with IMDB id and season id"))
|
||||
item.log_action({"!fetch_tvepisodes": ["", ""]})
|
||||
django_rq.get_queue("crawl").enqueue(
|
||||
fetch_episodes_for_season_task, item.uuid, request.user
|
||||
|
@ -275,7 +273,7 @@ def fetch_episodes_for_season_task(item_uuid, user):
|
|||
def merge(request, item_path, item_uuid):
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if not request.user.is_staff and item.journal_exists():
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
if request.POST.get("sure", 0) != "1":
|
||||
new_item = Item.get_by_url(request.POST.get("target_item_url"))
|
||||
return render(
|
||||
|
@ -352,7 +350,7 @@ def link_edition(request, item_path, item_uuid):
|
|||
def unlink_works(request, item_path, item_uuid):
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if not request.user.is_staff and item.journal_exists():
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
item.unlink_from_all_works()
|
||||
discord_send(
|
||||
"audit",
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ site_name }} - {% trans '无效请求' %}</title>
|
||||
<title>{{ site_name }} - 400</title>
|
||||
<meta name="robots" content="noindex">
|
||||
{% include "common_libs.html" %}
|
||||
</head>
|
||||
|
@ -17,11 +17,12 @@
|
|||
<main class="container">
|
||||
<article class="error">
|
||||
<header>
|
||||
<h3>🤷🏻 无效的请求</h3>
|
||||
<h3>🤷🏻 {{ exception }}</h3>
|
||||
</header>
|
||||
您可能提交了无效的数据,或者相关内容已被作者删除。如果您确信这是我们的错误,请通过页面底部的链接联系我们。
|
||||
{% blocktrans %}You may have submitted invalid data, or the content may have been deleted by the author.{% endblocktrans %}
|
||||
<br>
|
||||
{% blocktrans %}If you believe this is our mistake, please contact us through the link at the bottom of the page.{% endblocktrans %}
|
||||
<section>
|
||||
{{ exception }}
|
||||
{% if exception.additonal_detail %}
|
||||
{% for e in exception.additonal_detail %}<p>{{ e }}</p>{% endfor %}
|
||||
{% endif %}
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
{% load mastodon %}
|
||||
{% load thumb %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ site_name }} - {% trans '权限不符' %}</title>
|
||||
<title>{{ site_name }} - 403</title>
|
||||
<meta name="robots" content="noindex">
|
||||
{% include "common_libs.html" %}
|
||||
</head>
|
||||
|
@ -17,10 +17,11 @@
|
|||
<main class="container">
|
||||
<article class="error">
|
||||
<header>
|
||||
<h3>🙅🏻 权限不符</h3>
|
||||
<h3>🙅🏻 {{ exception|default:"" }}</h3>
|
||||
</header>
|
||||
{{ exception }}
|
||||
您可能访问了错误的网址,或者相关内容已被作者删除。如果您确信这是我们的错误,请通过页面底部的链接联系我们。
|
||||
{% blocktrans %}Author may require you to log in before accessing this content, or you do not have permission to view it.{% endblocktrans %}
|
||||
<br>
|
||||
{% blocktrans %}If you believe this is our mistake, please contact us through the link at the bottom of the page.{% endblocktrans %}
|
||||
</article>
|
||||
</main>
|
||||
{% include "_footer.html" %}
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
{% load mastodon %}
|
||||
{% load thumb %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ site_name }} - {% trans '未找到' %}</title>
|
||||
<title>{{ site_name }} - 404</title>
|
||||
<meta name="robots" content="noindex">
|
||||
{% include "common_libs.html" %}
|
||||
</head>
|
||||
|
@ -17,9 +17,11 @@
|
|||
<main class="container">
|
||||
<article class="error">
|
||||
<header>
|
||||
<h3>🤷🏻 条目未找到</h3>
|
||||
<h3>🤷🏻 {{ exception|default:"" }}</h3>
|
||||
</header>
|
||||
您可能输入了一个无效的网址,或者相关内容已被作者删除。如果您确信这是我们的错误,请通过页面底部的链接联系我们。
|
||||
{% blocktrans %}You may have visited an incorrect URL, or the content you are looking for has been deleted by the author.{% endblocktrans %}
|
||||
<br>
|
||||
{% blocktrans %}If you believe this is our mistake, please contact us through the link at the bottom of the page.{% endblocktrans %}
|
||||
</article>
|
||||
</main>
|
||||
{% include "_footer.html" %}
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
{% load mastodon %}
|
||||
{% load thumb %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ site_name }} - {% trans '系统错误' %}</title>
|
||||
<title>{{ site_name }} - 500</title>
|
||||
<meta name="robots" content="noindex">
|
||||
{% include "common_libs.html" %}
|
||||
</head>
|
||||
|
@ -17,9 +17,11 @@
|
|||
<main class="container">
|
||||
<article class="error">
|
||||
<header>
|
||||
<h3>🤦🏻 系统内部错误</h3>
|
||||
<h3>🤦🏻 My Bad</h3>
|
||||
</header>
|
||||
发生了一个内部错误,如果这个错误多次出现,后台会记录并会由人工处理。如果您有紧急情况或任何疑问,请通过页面底部的链接联系我们。
|
||||
{% blocktrans %}An internal error occurred. If this error occurs repeatedly, it will be recorded and handled by a human.{% endblocktrans %}
|
||||
<br>
|
||||
{% blocktrans %}If you have an urgent situation or any questions, please contact us through the link at the bottom of the page.{% endblocktrans %}
|
||||
</article>
|
||||
</main>
|
||||
{% include "_footer.html" %}
|
||||
|
|
|
@ -4,9 +4,11 @@ from typing import TYPE_CHECKING
|
|||
|
||||
from discord import SyncWebhook
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.http import Http404, HttpRequest, HttpResponseRedirect, QueryDict
|
||||
from django.utils import timezone
|
||||
from django.utils.baseconv import base62
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from .config import PAGE_LINK_NUMBER
|
||||
|
||||
|
@ -52,16 +54,15 @@ def target_identity_required(func):
|
|||
@functools.wraps(func)
|
||||
def wrapper(request, user_name, *args, **kwargs):
|
||||
from users.models import APIdentity
|
||||
from users.views import render_user_blocked, render_user_not_found
|
||||
|
||||
try:
|
||||
target = APIdentity.get_by_handle(user_name)
|
||||
except APIdentity.DoesNotExist:
|
||||
return render_user_not_found(request)
|
||||
raise Http404(_("User not found"))
|
||||
target_user = target.user
|
||||
viewer = None
|
||||
if target_user and not target_user.is_active:
|
||||
return render_user_not_found(request)
|
||||
raise Http404(_("User no longer exists"))
|
||||
if request.user.is_authenticated:
|
||||
try:
|
||||
viewer = APIdentity.objects.get(user=request.user)
|
||||
|
@ -69,7 +70,7 @@ def target_identity_required(func):
|
|||
return HttpResponseRedirect("/account/register")
|
||||
if request.user != target_user:
|
||||
if target.is_blocking(viewer) or target.is_blocked_by(viewer):
|
||||
return render_user_blocked(request)
|
||||
raise PermissionDenied(_("Access denied"))
|
||||
else:
|
||||
viewer = None
|
||||
request.target_identity = target
|
||||
|
@ -83,16 +84,15 @@ def profile_identity_required(func):
|
|||
@functools.wraps(func)
|
||||
def wrapper(request, user_name, *args, **kwargs):
|
||||
from users.models import APIdentity
|
||||
from users.views import render_user_blocked, render_user_not_found
|
||||
|
||||
try:
|
||||
target = APIdentity.get_by_handle(user_name, match_linked=True)
|
||||
except APIdentity.DoesNotExist:
|
||||
return render_user_not_found(request)
|
||||
raise Http404(_("User not found"))
|
||||
target_user = target.user
|
||||
viewer = None
|
||||
if target_user and not target_user.is_active:
|
||||
return render_user_not_found(request)
|
||||
raise Http404(_("User no longer exists"))
|
||||
if request.user.is_authenticated:
|
||||
try:
|
||||
viewer = APIdentity.objects.get(user=request.user)
|
||||
|
@ -100,7 +100,7 @@ def profile_identity_required(func):
|
|||
return HttpResponseRedirect("/account/register")
|
||||
if request.user != target_user:
|
||||
if target.is_blocking(viewer) or target.is_blocked_by(viewer):
|
||||
return render_user_blocked(request)
|
||||
raise PermissionDenied(_("Access denied"))
|
||||
else:
|
||||
viewer = None
|
||||
request.target_identity = target
|
||||
|
|
|
@ -69,21 +69,16 @@ def nodeinfo2(request):
|
|||
|
||||
|
||||
def error_400(request, exception=None):
|
||||
return render(
|
||||
request,
|
||||
"400.html",
|
||||
{"exception": exception},
|
||||
status=400,
|
||||
)
|
||||
return render(request, "400.html", status=400, context={"exception": exception})
|
||||
|
||||
|
||||
def error_403(request, exception=None):
|
||||
return render(request, "403.html", status=403)
|
||||
return render(request, "403.html", status=403, context={"exception": exception})
|
||||
|
||||
|
||||
def error_404(request, exception=None):
|
||||
return render(request, "404.html", status=404)
|
||||
return render(request, "404.html", status=404, context={"exception": exception})
|
||||
|
||||
|
||||
def error_500(request, exception=None):
|
||||
return render(request, "500.html", status=500)
|
||||
return render(request, "500.html", status=500, context={"exception": exception})
|
||||
|
|
|
@ -6,17 +6,11 @@ from django.shortcuts import get_object_or_404, redirect, render
|
|||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.decorators.http import require_http_methods
|
||||
|
||||
from catalog.models import Item
|
||||
from common.utils import AuthedHttpRequest, get_uuid_or_404
|
||||
from mastodon.api import boost_toot_later, share_collection
|
||||
from users.models import User
|
||||
from users.models.apidentity import APIdentity
|
||||
from users.views import (
|
||||
render_user_blocked,
|
||||
render_user_noanonymous,
|
||||
render_user_not_found,
|
||||
)
|
||||
|
||||
from ..forms import *
|
||||
from ..models import *
|
||||
|
@ -55,7 +49,7 @@ def collection_retrieve_redirect(request: AuthedHttpRequest, collection_uuid):
|
|||
def collection_retrieve(request: AuthedHttpRequest, collection_uuid):
|
||||
collection = get_object_or_404(Collection, uid=get_uuid_or_404(collection_uuid))
|
||||
if not collection.is_visible_to(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
follower_count = collection.likes.all().count()
|
||||
following = (
|
||||
Like.user_liked_piece(request.user.identity, collection)
|
||||
|
@ -101,12 +95,11 @@ def collection_retrieve(request: AuthedHttpRequest, collection_uuid):
|
|||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def collection_add_featured(request: AuthedHttpRequest, collection_uuid):
|
||||
if request.method != "POST":
|
||||
raise BadRequest()
|
||||
collection = get_object_or_404(Collection, uid=get_uuid_or_404(collection_uuid))
|
||||
if not collection.is_visible_to(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
FeaturedCollection.objects.update_or_create(
|
||||
owner=request.user.identity, target=collection
|
||||
)
|
||||
|
@ -114,12 +107,11 @@ def collection_add_featured(request: AuthedHttpRequest, collection_uuid):
|
|||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def collection_remove_featured(request: AuthedHttpRequest, collection_uuid):
|
||||
if request.method != "POST":
|
||||
raise BadRequest()
|
||||
collection = get_object_or_404(Collection, uid=get_uuid_or_404(collection_uuid))
|
||||
if not collection.is_visible_to(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
fc = FeaturedCollection.objects.filter(
|
||||
owner=request.user.identity, target=collection
|
||||
).first()
|
||||
|
@ -129,15 +121,16 @@ def collection_remove_featured(request: AuthedHttpRequest, collection_uuid):
|
|||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST", "GET"])
|
||||
def collection_share(request: AuthedHttpRequest, collection_uuid):
|
||||
collection = get_object_or_404(
|
||||
Collection, uid=get_uuid_or_404(collection_uuid) if collection_uuid else None
|
||||
)
|
||||
if collection and not collection.is_visible_to(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
if request.method == "GET":
|
||||
return render(request, "collection_share.html", {"collection": collection})
|
||||
elif request.method == "POST":
|
||||
else:
|
||||
comment = request.POST.get("comment")
|
||||
# boost if possible, otherwise quote
|
||||
if (
|
||||
|
@ -158,8 +151,6 @@ def collection_share(request: AuthedHttpRequest, collection_uuid):
|
|||
):
|
||||
return render_relogin(request)
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
|
||||
else:
|
||||
raise BadRequest()
|
||||
|
||||
|
||||
def collection_retrieve_items(
|
||||
|
@ -167,7 +158,7 @@ def collection_retrieve_items(
|
|||
):
|
||||
collection = get_object_or_404(Collection, uid=get_uuid_or_404(collection_uuid))
|
||||
if not collection.is_visible_to(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
form = CollectionForm(instance=collection)
|
||||
return render(
|
||||
request,
|
||||
|
@ -182,12 +173,11 @@ def collection_retrieve_items(
|
|||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def collection_append_item(request: AuthedHttpRequest, collection_uuid):
|
||||
if request.method != "POST":
|
||||
raise BadRequest()
|
||||
collection = get_object_or_404(Collection, uid=get_uuid_or_404(collection_uuid))
|
||||
if not collection.is_editable_by(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
|
||||
url = request.POST.get("url")
|
||||
note = request.POST.get("note")
|
||||
|
@ -202,26 +192,24 @@ def collection_append_item(request: AuthedHttpRequest, collection_uuid):
|
|||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def collection_remove_item(request: AuthedHttpRequest, collection_uuid, item_uuid):
|
||||
if request.method != "POST":
|
||||
raise BadRequest()
|
||||
collection = get_object_or_404(Collection, uid=get_uuid_or_404(collection_uuid))
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if not collection.is_editable_by(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
collection.remove_item(item)
|
||||
return collection_retrieve_items(request, collection_uuid, True)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def collection_move_item(
|
||||
request: AuthedHttpRequest, direction, collection_uuid, item_uuid
|
||||
):
|
||||
if request.method != "POST":
|
||||
raise BadRequest()
|
||||
collection = get_object_or_404(Collection, uid=get_uuid_or_404(collection_uuid))
|
||||
if not collection.is_editable_by(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if direction == "up":
|
||||
collection.move_up_item(item)
|
||||
|
@ -231,45 +219,44 @@ def collection_move_item(
|
|||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def collection_update_member_order(request: AuthedHttpRequest, collection_uuid):
|
||||
if request.method != "POST":
|
||||
raise BadRequest()
|
||||
collection = get_object_or_404(Collection, uid=get_uuid_or_404(collection_uuid))
|
||||
if not collection.is_editable_by(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
ids = request.POST.get("member_ids", "").strip()
|
||||
if not ids:
|
||||
raise BadRequest()
|
||||
raise BadRequest(_("Invalid parameter"))
|
||||
ordered_member_ids = [int(i) for i in ids.split(",")]
|
||||
collection.update_member_order(ordered_member_ids)
|
||||
return collection_retrieve_items(request, collection_uuid, True)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def collection_update_item_note(request: AuthedHttpRequest, collection_uuid, item_uuid):
|
||||
collection = get_object_or_404(Collection, uid=get_uuid_or_404(collection_uuid))
|
||||
if not collection.is_editable_by(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if not collection.is_editable_by(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
if request.method == "POST":
|
||||
collection.update_item_metadata(
|
||||
item, {"note": request.POST.get("note", default="")}
|
||||
)
|
||||
return collection_retrieve_items(request, collection_uuid, True)
|
||||
elif request.method == "GET":
|
||||
else:
|
||||
member = collection.get_member_for_item(item)
|
||||
return render(
|
||||
request,
|
||||
"collection_update_item_note.html",
|
||||
{"collection": collection, "item": item, "note": member.note},
|
||||
)
|
||||
else:
|
||||
raise BadRequest()
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def collection_edit(request: AuthedHttpRequest, collection_uuid=None):
|
||||
collection = (
|
||||
get_object_or_404(Collection, uid=get_uuid_or_404(collection_uuid))
|
||||
|
@ -277,7 +264,7 @@ def collection_edit(request: AuthedHttpRequest, collection_uuid=None):
|
|||
else None
|
||||
)
|
||||
if collection and not collection.is_editable_by(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
if request.method == "GET":
|
||||
form = CollectionForm(instance=collection) if collection else CollectionForm()
|
||||
if request.GET.get("title"):
|
||||
|
@ -292,7 +279,7 @@ def collection_edit(request: AuthedHttpRequest, collection_uuid=None):
|
|||
"identity": collection.owner if collection else request.user.identity,
|
||||
},
|
||||
)
|
||||
elif request.method == "POST":
|
||||
else:
|
||||
form = (
|
||||
CollectionForm(request.POST, request.FILES, instance=collection)
|
||||
if collection
|
||||
|
@ -306,16 +293,14 @@ def collection_edit(request: AuthedHttpRequest, collection_uuid=None):
|
|||
reverse("journal:collection_retrieve", args=[form.instance.uuid])
|
||||
)
|
||||
else:
|
||||
raise BadRequest()
|
||||
else:
|
||||
raise BadRequest()
|
||||
raise BadRequest(_("Invalid parameter"))
|
||||
|
||||
|
||||
@target_identity_required
|
||||
def user_collection_list(request: AuthedHttpRequest, user_name):
|
||||
target = request.target_identity
|
||||
if not request.user.is_authenticated and not target.anonymous_viewable:
|
||||
return render_user_noanonymous(request)
|
||||
raise PermissionDenied(_("Login required"))
|
||||
collections = (
|
||||
Collection.objects.filter(owner=target)
|
||||
.filter(q_owned_piece_visible_to_user(request.user, target))
|
||||
|
@ -336,7 +321,7 @@ def user_collection_list(request: AuthedHttpRequest, user_name):
|
|||
def user_liked_collection_list(request: AuthedHttpRequest, user_name):
|
||||
target = request.target_identity
|
||||
if not request.user.is_authenticated and not target.anonymous_viewable:
|
||||
return render_user_noanonymous(request)
|
||||
raise PermissionDenied(_("Login required"))
|
||||
collections = Collection.objects.filter(
|
||||
interactions__identity=target,
|
||||
interactions__interaction_type="like",
|
||||
|
|
|
@ -7,6 +7,7 @@ from django.db.models import F, Min, OuterRef, Subquery
|
|||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.decorators.http import require_http_methods
|
||||
|
||||
from catalog.models import *
|
||||
from common.utils import (
|
||||
|
@ -77,7 +78,7 @@ def render_list(
|
|||
elif type == "review" and item_category:
|
||||
queryset = Review.objects.filter(q_item_in_category(item_category))
|
||||
else:
|
||||
raise BadRequest()
|
||||
raise BadRequest(_("Invalid parameter"))
|
||||
if sort == "rating":
|
||||
rating = Rating.objects.filter(
|
||||
owner_id=OuterRef("owner_id"), item_id=OuterRef("item_id")
|
||||
|
@ -125,17 +126,16 @@ def render_list(
|
|||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def piece_delete(request, piece_uuid):
|
||||
piece = get_object_or_404(Piece, uid=get_uuid_or_404(piece_uuid))
|
||||
return_url = request.GET.get("return_url", None) or "/"
|
||||
if not piece.is_editable_by(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
if request.method == "GET":
|
||||
return render(
|
||||
request, "piece_delete.html", {"piece": piece, "return_url": return_url}
|
||||
)
|
||||
elif request.method == "POST":
|
||||
else:
|
||||
piece.delete()
|
||||
return redirect(return_url)
|
||||
else:
|
||||
raise BadRequest()
|
||||
|
|
|
@ -9,6 +9,7 @@ from django.shortcuts import get_object_or_404, redirect, render
|
|||
from django.utils import timezone
|
||||
from django.utils.dateparse import parse_datetime
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.decorators.http import require_http_methods
|
||||
|
||||
from catalog.models import *
|
||||
from common.utils import AuthedHttpRequest, get_uuid_or_404
|
||||
|
@ -25,12 +26,9 @@ _checkmark = "✔️".encode("utf-8")
|
|||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def wish(request: AuthedHttpRequest, item_uuid):
|
||||
if request.method != "POST":
|
||||
raise BadRequest()
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if not item:
|
||||
raise Http404()
|
||||
mark = Mark(request.user.identity, item)
|
||||
if not mark.shelf_type:
|
||||
mark.update(ShelfType.WISHLIST)
|
||||
|
@ -40,6 +38,7 @@ def wish(request: AuthedHttpRequest, item_uuid):
|
|||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def mark(request: AuthedHttpRequest, item_uuid):
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
mark = Mark(request.user.identity, item)
|
||||
|
@ -59,7 +58,7 @@ def mark(request: AuthedHttpRequest, item_uuid):
|
|||
"date_today": timezone.localdate().isoformat(),
|
||||
},
|
||||
)
|
||||
elif request.method == "POST":
|
||||
else:
|
||||
if request.POST.get("delete", default=False):
|
||||
mark.delete()
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
|
||||
|
@ -120,27 +119,28 @@ def mark(request: AuthedHttpRequest, item_uuid):
|
|||
},
|
||||
)
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
|
||||
raise BadRequest()
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def mark_log(request: AuthedHttpRequest, item_uuid, log_id):
|
||||
"""
|
||||
Delete log of one item by log id.
|
||||
"""
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
mark = Mark(request.user.identity, item)
|
||||
if request.method == "POST":
|
||||
if request.GET.get("delete", default=False):
|
||||
if log_id:
|
||||
mark.delete_log(log_id)
|
||||
else:
|
||||
mark.delete_all_logs()
|
||||
return render(request, "_item_user_mark_history.html", {"mark": mark})
|
||||
raise BadRequest()
|
||||
if request.GET.get("delete", default=False):
|
||||
if log_id:
|
||||
mark.delete_log(log_id)
|
||||
else:
|
||||
mark.delete_all_logs()
|
||||
return render(request, "_item_user_mark_history.html", {"mark": mark})
|
||||
else:
|
||||
raise BadRequest(_("Invalid parameter"))
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def comment(request: AuthedHttpRequest, item_uuid):
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
if item.class_name not in ["podcastepisode", "tvepisode"]:
|
||||
|
@ -155,10 +155,10 @@ def comment(request: AuthedHttpRequest, item_uuid):
|
|||
"comment": comment,
|
||||
},
|
||||
)
|
||||
elif request.method == "POST":
|
||||
else:
|
||||
if request.POST.get("delete", default=False):
|
||||
if not comment:
|
||||
raise Http404()
|
||||
raise Http404(_("Content not found"))
|
||||
comment.delete()
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
|
||||
visibility = int(request.POST.get("visibility", default=0))
|
||||
|
@ -176,9 +176,9 @@ def comment(request: AuthedHttpRequest, item_uuid):
|
|||
d = {"text": text, "visibility": visibility}
|
||||
if position:
|
||||
d["metadata"] = {"position": position}
|
||||
comment, _ = Comment.objects.update_or_create(
|
||||
comment = Comment.objects.update_or_create(
|
||||
owner=request.user.identity, item=item, defaults=d
|
||||
)
|
||||
)[0]
|
||||
post = Takahe.post_comment(comment, False)
|
||||
share_to_mastodon = bool(request.POST.get("share_to_mastodon", default=False))
|
||||
if post and share_to_mastodon:
|
||||
|
@ -187,7 +187,6 @@ def comment(request: AuthedHttpRequest, item_uuid):
|
|||
else:
|
||||
boost_toot_later(request.user, post.url)
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER", "/"))
|
||||
raise BadRequest()
|
||||
|
||||
|
||||
def user_mark_list(request: AuthedHttpRequest, user_name, shelf_type, item_category):
|
||||
|
|
|
@ -17,7 +17,7 @@ from ..models import *
|
|||
def piece_replies(request: AuthedHttpRequest, piece_uuid: str):
|
||||
piece = get_object_or_404(Piece, uid=get_uuid_or_404(piece_uuid))
|
||||
if not piece.is_visible_to(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
replies = piece.get_replies(request.user.identity)
|
||||
return render(
|
||||
request, "replies.html", {"post": piece.latest_post, "replies": replies}
|
||||
|
@ -38,7 +38,7 @@ def post_reply(request: AuthedHttpRequest, post_id: int):
|
|||
content = request.POST.get("content", "").strip()
|
||||
visibility = Takahe.Visibilities(int(request.POST.get("visibility", -1)))
|
||||
if not content:
|
||||
raise BadRequest()
|
||||
raise BadRequest(_("Invalid parameter"))
|
||||
Takahe.reply_post(post_id, request.user.identity.pk, content, visibility)
|
||||
replies = Takahe.get_replies_for_posts([post_id], request.user.identity.pk)
|
||||
return render(
|
||||
|
@ -52,7 +52,7 @@ def post_boost(request: AuthedHttpRequest, post_id: int):
|
|||
# classic_repost = request.user.preference.mastodon_repost_mode == 1
|
||||
post = Takahe.get_post(post_id)
|
||||
if not post:
|
||||
raise BadRequest()
|
||||
raise BadRequest(_("Invalid parameter"))
|
||||
if request.user.mastodon_site:
|
||||
boost_toot_later(request.user, post.object_uri)
|
||||
else:
|
||||
|
@ -70,7 +70,5 @@ def post_like(request: AuthedHttpRequest, post_id: int):
|
|||
@require_http_methods(["POST"])
|
||||
@login_required
|
||||
def post_unlike(request: AuthedHttpRequest, post_id: int):
|
||||
if request.method != "POST":
|
||||
raise BadRequest()
|
||||
Takahe.unlike_post(post_id, request.user.identity.pk)
|
||||
return render(request, "action_like_post.html", {"post": Takahe.get_post(post_id)})
|
||||
|
|
|
@ -27,13 +27,14 @@ def review_retrieve(request, review_uuid):
|
|||
# piece = get_object_or_404(Review, uid=get_uuid_or_404(review_uuid))
|
||||
piece = Review.get_by_url(review_uuid)
|
||||
if piece is None:
|
||||
raise Http404()
|
||||
raise Http404(_("Content not found"))
|
||||
if not piece.is_visible_to(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
return render(request, "review.html", {"review": piece})
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def review_edit(request: AuthedHttpRequest, item_uuid, review_uuid=None):
|
||||
item = get_object_or_404(Item, uid=get_uuid_or_404(item_uuid))
|
||||
review = (
|
||||
|
@ -42,7 +43,7 @@ def review_edit(request: AuthedHttpRequest, item_uuid, review_uuid=None):
|
|||
else None
|
||||
)
|
||||
if review and not review.is_editable_by(request.user):
|
||||
raise PermissionDenied()
|
||||
raise PermissionDenied(_("Insufficient permission"))
|
||||
if request.method == "GET":
|
||||
form = (
|
||||
ReviewForm(instance=review)
|
||||
|
@ -63,7 +64,7 @@ def review_edit(request: AuthedHttpRequest, item_uuid, review_uuid=None):
|
|||
"date_today": timezone.localdate().isoformat(),
|
||||
},
|
||||
)
|
||||
elif request.method == "POST":
|
||||
else:
|
||||
form = (
|
||||
ReviewForm(request.POST, instance=review)
|
||||
if review
|
||||
|
@ -89,12 +90,10 @@ def review_edit(request: AuthedHttpRequest, item_uuid, review_uuid=None):
|
|||
form.cleaned_data["share_to_mastodon"],
|
||||
)
|
||||
if not review:
|
||||
raise BadRequest()
|
||||
raise BadRequest(_("Invalid parameter"))
|
||||
return redirect(reverse("journal:review_retrieve", args=[review.uuid]))
|
||||
else:
|
||||
raise BadRequest()
|
||||
else:
|
||||
raise BadRequest()
|
||||
raise BadRequest(_("Invalid parameter"))
|
||||
|
||||
|
||||
def user_review_list(request, user_name, item_category):
|
||||
|
@ -112,7 +111,7 @@ class ReviewFeed(Feed):
|
|||
return (
|
||||
_("Reviews by {0}").format(owner.display_name)
|
||||
if owner
|
||||
else _("link unavailable")
|
||||
else _("Link invalid")
|
||||
)
|
||||
|
||||
def link(self, owner):
|
||||
|
@ -120,9 +119,9 @@ class ReviewFeed(Feed):
|
|||
|
||||
def description(self, owner):
|
||||
if not owner:
|
||||
return _("link unavailable")
|
||||
return _("Link invalid")
|
||||
elif not owner.anonymous_viewable:
|
||||
return _("anonymous access disabled by owner")
|
||||
return _("Login required")
|
||||
else:
|
||||
return _("Reviews by {0}").format(owner.display_name)
|
||||
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.exceptions import BadRequest, ObjectDoesNotExist, PermissionDenied
|
||||
from django.db.models import Count
|
||||
from django.http import Http404, HttpResponse, HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from user_messages import api as msg
|
||||
|
||||
from catalog.models import *
|
||||
from users.models import User
|
||||
from users.views import render_user_blocked, render_user_not_found
|
||||
|
||||
from ..forms import *
|
||||
from ..models import *
|
||||
|
@ -38,16 +36,17 @@ def user_tag_list(request, user_name):
|
|||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def user_tag_edit(request):
|
||||
if request.method == "GET":
|
||||
tag_title = Tag.cleanup_title(request.GET.get("tag", ""), replace=False)
|
||||
if not tag_title:
|
||||
raise Http404()
|
||||
raise Http404(_("Invalid tag"))
|
||||
tag = Tag.objects.filter(owner=request.user.identity, title=tag_title).first()
|
||||
if not tag:
|
||||
raise Http404()
|
||||
raise Http404(_("Tag not found"))
|
||||
return render(request, "tag_edit.html", {"tag": tag})
|
||||
elif request.method == "POST":
|
||||
else:
|
||||
tag_title = Tag.cleanup_title(request.POST.get("title", ""), replace=False)
|
||||
tag_id = request.POST.get("id")
|
||||
tag = (
|
||||
|
@ -56,7 +55,7 @@ def user_tag_edit(request):
|
|||
else None
|
||||
)
|
||||
if not tag or not tag_title:
|
||||
msg.error(request.user, _("Invalid tag."))
|
||||
msg.error(request.user, _("Invalid tag"))
|
||||
return HttpResponseRedirect(request.META.get("HTTP_REFERER"))
|
||||
if request.POST.get("delete"):
|
||||
tag.delete()
|
||||
|
@ -83,7 +82,6 @@ def user_tag_edit(request):
|
|||
args=[request.user.username, tag.title],
|
||||
)
|
||||
)
|
||||
raise BadRequest()
|
||||
|
||||
|
||||
def user_tag_member_list(request, user_name, tag_title):
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-04-20 12:47-0400\n"
|
||||
"POT-Creation-Date: 2024-04-24 01:50-0400\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -578,6 +578,10 @@ msgstr "结束日期"
|
|||
msgid "host"
|
||||
msgstr "主播"
|
||||
|
||||
#: catalog/search/views.py:54 catalog/search/views.py:178
|
||||
msgid "Invalid URL"
|
||||
msgstr "无效网址"
|
||||
|
||||
#: catalog/templates/_item_card_metadata_edition.html:17
|
||||
#: catalog/templates/edition.html:54
|
||||
msgid "年"
|
||||
|
@ -1129,59 +1133,113 @@ msgstr ""
|
|||
msgid "season number"
|
||||
msgstr ""
|
||||
|
||||
#: catalog/views_edit.py:259
|
||||
#: catalog/views.py:53 catalog/views.py:76
|
||||
msgid "Item not found"
|
||||
msgstr ""
|
||||
|
||||
#: catalog/views.py:57 catalog/views.py:84
|
||||
msgid "Item no longer exists"
|
||||
msgstr ""
|
||||
|
||||
#: catalog/views_edit.py:125 catalog/views_edit.py:148
|
||||
#: catalog/views_edit.py:200 catalog/views_edit.py:276
|
||||
#: catalog/views_edit.py:353 journal/views/collection.py:52
|
||||
#: journal/views/collection.py:102 journal/views/collection.py:114
|
||||
#: journal/views/collection.py:130 journal/views/collection.py:161
|
||||
#: journal/views/collection.py:180 journal/views/collection.py:200
|
||||
#: journal/views/collection.py:212 journal/views/collection.py:226
|
||||
#: journal/views/collection.py:240 journal/views/collection.py:243
|
||||
#: journal/views/collection.py:267 journal/views/common.py:134
|
||||
#: journal/views/post.py:20 journal/views/review.py:32
|
||||
#: journal/views/review.py:46
|
||||
msgid "Insufficient permission"
|
||||
msgstr ""
|
||||
|
||||
#: catalog/views_edit.py:203 journal/views/collection.py:229
|
||||
#: journal/views/collection.py:296 journal/views/common.py:81
|
||||
#: journal/views/mark.py:139 journal/views/post.py:41 journal/views/post.py:55
|
||||
#: journal/views/review.py:93 journal/views/review.py:96 users/views.py:169
|
||||
msgid "Invalid parameter"
|
||||
msgstr "无效参数"
|
||||
|
||||
#: catalog/views_edit.py:252
|
||||
msgid "Must be a TV Season with IMDB id and season id"
|
||||
msgstr ""
|
||||
|
||||
#: catalog/views_edit.py:257
|
||||
msgid "Updating episodes"
|
||||
msgstr ""
|
||||
|
||||
#: catalog/views_edit.py:289
|
||||
#: catalog/views_edit.py:287
|
||||
msgid "Cannot be merged to an item already deleted or merged"
|
||||
msgstr ""
|
||||
|
||||
#: catalog/views_edit.py:292
|
||||
#: catalog/views_edit.py:290
|
||||
msgid "Cannot merge items in different categories"
|
||||
msgstr ""
|
||||
|
||||
#: catalog/views_edit.py:329
|
||||
#: catalog/views_edit.py:327
|
||||
msgid "Cannot be linked to an item already deleted or merged"
|
||||
msgstr ""
|
||||
|
||||
#: catalog/views_edit.py:331
|
||||
#: catalog/views_edit.py:329
|
||||
msgid "Cannot link items other than editions"
|
||||
msgstr ""
|
||||
|
||||
#: common/templates/400.html:11
|
||||
msgid "无效请求"
|
||||
msgstr ""
|
||||
#: common/templates/400.html:22
|
||||
msgid ""
|
||||
"You may have submitted invalid data, or the content may have been deleted by "
|
||||
"the author."
|
||||
msgstr "您可能提交了无效的数据,或者相关内容已被作者删除。"
|
||||
|
||||
#: common/templates/403.html:11
|
||||
msgid "权限不符"
|
||||
msgstr ""
|
||||
#: common/templates/400.html:24 common/templates/403.html:24
|
||||
#: common/templates/404.html:24
|
||||
msgid ""
|
||||
"If you believe this is our mistake, please contact us through the link at "
|
||||
"the bottom of the page."
|
||||
msgstr "如果您确信这是我们的错误,请通过页面底部的链接联系我们。"
|
||||
|
||||
#: common/templates/404.html:11
|
||||
msgid "未找到"
|
||||
msgstr ""
|
||||
#: common/templates/403.html:22
|
||||
msgid ""
|
||||
"Author may require you to log in before accessing this content, or you do "
|
||||
"not have permission to view it."
|
||||
msgstr "作者可能希望您登录后访问,或者您没有权限查看此内容。"
|
||||
|
||||
#: common/templates/500.html:11
|
||||
msgid "系统错误"
|
||||
msgstr ""
|
||||
#: common/templates/404.html:22
|
||||
msgid ""
|
||||
"You may have visited an incorrect URL, or the content you are looking for "
|
||||
"has been deleted by the author."
|
||||
msgstr "您可能访问了错误的网址,或者相关内容已被作者删除。"
|
||||
|
||||
#: common/templates/_footer.html:11
|
||||
#: common/templates/500.html:22
|
||||
msgid ""
|
||||
"An internal error occurred. If this error occurs repeatedly, it will be "
|
||||
"recorded and handled by a human."
|
||||
msgstr "发生了一个内部错误,如果这个错误多次出现,后台会记录并会由人工处理。"
|
||||
|
||||
#: common/templates/500.html:24
|
||||
msgid ""
|
||||
"If you have an urgent situation or any questions, please contact us through "
|
||||
"the link at the bottom of the page."
|
||||
msgstr "如果您有紧急情况或任何疑问,请通过页面底部的链接联系我们。"
|
||||
|
||||
#: common/templates/_footer.html:6
|
||||
msgid "Rules"
|
||||
msgstr "站点规则"
|
||||
|
||||
#: common/templates/_footer.html:12
|
||||
#: common/templates/_footer.html:7
|
||||
msgid "Terms"
|
||||
msgstr "服务协议"
|
||||
|
||||
#: common/templates/_footer.html:13
|
||||
#: common/templates/_footer.html:8
|
||||
msgid "Announcements"
|
||||
msgstr "公告栏"
|
||||
|
||||
#: common/templates/_footer.html:14
|
||||
#: common/templates/_footer.html:9
|
||||
msgid "Developer"
|
||||
msgstr "开发者"
|
||||
|
||||
#: common/templates/_footer.html:19
|
||||
#: common/templates/_footer.html:13
|
||||
msgid "Source Code"
|
||||
msgstr "源代码"
|
||||
|
||||
|
@ -1294,71 +1352,83 @@ msgstr "关注了你"
|
|||
msgid "just now"
|
||||
msgstr "刚刚"
|
||||
|
||||
#: common/utils.py:61 common/utils.py:91 users/views.py:35 users/views.py:121
|
||||
msgid "User not found"
|
||||
msgstr "用户不存在"
|
||||
|
||||
#: common/utils.py:65 common/utils.py:95 users/views.py:124
|
||||
msgid "User no longer exists"
|
||||
msgstr "用户不存在了"
|
||||
|
||||
#: common/utils.py:73 common/utils.py:103
|
||||
msgid "Access denied"
|
||||
msgstr "访问被拒绝"
|
||||
|
||||
#: developer/models.py:18
|
||||
msgid "minimum two characters, words and -_. only, no special characters"
|
||||
msgstr ""
|
||||
msgstr "两字符以上,无特殊字符"
|
||||
|
||||
#: developer/models.py:29
|
||||
msgid "Allowed URIs list, space separated, at least one URI is required"
|
||||
msgstr ""
|
||||
msgstr "至少一个网址,空格分隔"
|
||||
|
||||
#: developer/templates/console.html:37
|
||||
#: developer/templates/oauth2_provider/application_list.html:5
|
||||
msgid "Your applications"
|
||||
msgstr ""
|
||||
msgstr "你的应用程序"
|
||||
|
||||
#: developer/templates/oauth2_provider/application_detail.html:9
|
||||
msgid "Client ID"
|
||||
msgstr ""
|
||||
msgstr "Client ID"
|
||||
|
||||
#: developer/templates/oauth2_provider/application_detail.html:18
|
||||
msgid "URL"
|
||||
msgstr ""
|
||||
msgstr "网址"
|
||||
|
||||
#: developer/templates/oauth2_provider/application_detail.html:24
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
msgstr "描述"
|
||||
|
||||
#: developer/templates/oauth2_provider/application_detail.html:30
|
||||
msgid "Redirect Uris"
|
||||
msgstr ""
|
||||
msgstr "重定向网址"
|
||||
|
||||
#: developer/templates/oauth2_provider/application_detail.html:38
|
||||
#: developer/templates/oauth2_provider/application_form.html:33
|
||||
msgid "Go Back"
|
||||
msgstr ""
|
||||
msgstr "返回"
|
||||
|
||||
#: developer/templates/oauth2_provider/application_detail.html:40
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
msgstr "编辑"
|
||||
|
||||
#: developer/templates/oauth2_provider/application_detail.html:42
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
msgstr "删除"
|
||||
|
||||
#: developer/templates/oauth2_provider/application_form.html:8
|
||||
msgid "Edit application"
|
||||
msgstr ""
|
||||
msgstr "编辑应用程序"
|
||||
|
||||
#: developer/templates/oauth2_provider/application_form.html:35
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
msgstr "保存"
|
||||
|
||||
#: developer/templates/oauth2_provider/application_list.html:20
|
||||
msgid "New Application"
|
||||
msgstr ""
|
||||
msgstr "新建应用程序"
|
||||
|
||||
#: developer/templates/oauth2_provider/application_list.html:23
|
||||
msgid "No applications defined"
|
||||
msgstr ""
|
||||
msgstr "尚无应用程序"
|
||||
|
||||
#: developer/templates/oauth2_provider/application_list.html:23
|
||||
msgid "Click here"
|
||||
msgstr ""
|
||||
msgstr "点此"
|
||||
|
||||
#: developer/templates/oauth2_provider/application_list.html:23
|
||||
msgid "if you want to register a new one"
|
||||
msgstr ""
|
||||
msgstr "如果你希望新注册一个"
|
||||
|
||||
#: journal/forms.py:18 journal/forms.py:41
|
||||
msgid "Title"
|
||||
|
@ -1790,7 +1860,7 @@ msgstr ""
|
|||
msgid "喜欢的收藏单"
|
||||
msgstr ""
|
||||
|
||||
#: journal/templates/replies.html:39 social/templates/events.html:46
|
||||
#: journal/templates/replies.html:46 social/templates/events.html:46
|
||||
msgid "nothing so far."
|
||||
msgstr "暂无内容。"
|
||||
|
||||
|
@ -1824,83 +1894,92 @@ msgstr ""
|
|||
msgid "分享"
|
||||
msgstr ""
|
||||
|
||||
#: journal/views/collection.py:44
|
||||
#: journal/views/collection.py:38
|
||||
#, python-brace-format
|
||||
msgid "Collection by {0}"
|
||||
msgstr "{0} 的收藏单"
|
||||
|
||||
#: journal/views/collection.py:200
|
||||
#: journal/views/collection.py:190
|
||||
msgid "Unable to find the item, please use item url from this site."
|
||||
msgstr ""
|
||||
|
||||
#: journal/views/common.py:32 journal/views/mark.py:118
|
||||
#: journal/views/collection.py:303 journal/views/collection.py:324
|
||||
#: journal/views/review.py:124
|
||||
msgid "Login required"
|
||||
msgstr "登录后访问"
|
||||
|
||||
#: journal/views/common.py:33 journal/views/mark.py:117
|
||||
msgid "Data saved but unable to repost to Fediverse."
|
||||
msgstr ""
|
||||
msgstr "数据已保存但未能转发到联邦宇宙。"
|
||||
|
||||
#: journal/views/common.py:34
|
||||
#: journal/views/common.py:35
|
||||
msgid "Redirecting to your Mastodon instance now to re-authenticate."
|
||||
msgstr ""
|
||||
msgstr "正在重定向到你的Mastodon实例以重新认证。"
|
||||
|
||||
#: journal/views/common.py:41
|
||||
#: journal/views/common.py:42
|
||||
msgid "List not found."
|
||||
msgstr ""
|
||||
msgstr "列表未找到"
|
||||
|
||||
#: journal/views/mark.py:110
|
||||
#: journal/views/mark.py:109
|
||||
msgid "Content too long for your Mastodon instance."
|
||||
msgstr ""
|
||||
msgstr "内容过长,超出了你的Mastodon实例的限制。"
|
||||
|
||||
#: journal/views/review.py:113 journal/views/review.py:127
|
||||
#: journal/views/mark.py:161 journal/views/review.py:30
|
||||
msgid "Content not found"
|
||||
msgstr "内容未找到"
|
||||
|
||||
#: journal/views/review.py:112 journal/views/review.py:126
|
||||
#, python-brace-format
|
||||
msgid "Reviews by {0}"
|
||||
msgstr ""
|
||||
msgstr "{0} 的评论"
|
||||
|
||||
#: journal/views/review.py:115 journal/views/review.py:123
|
||||
msgid "link unavailable"
|
||||
msgstr ""
|
||||
#: journal/views/review.py:114 journal/views/review.py:122
|
||||
msgid "Link invalid"
|
||||
msgstr "链接无效"
|
||||
|
||||
#: journal/views/review.py:125
|
||||
msgid "anonymous access disabled by owner"
|
||||
msgstr ""
|
||||
|
||||
#: journal/views/review.py:136
|
||||
#: journal/views/review.py:135
|
||||
#, python-brace-format
|
||||
msgid "{review_title} - a review of {item_title}"
|
||||
msgstr ""
|
||||
msgstr "{review_title} - 关于 {item_title} 的评论"
|
||||
|
||||
#: journal/views/tag.py:59
|
||||
msgid "Invalid tag."
|
||||
msgstr ""
|
||||
#: journal/views/tag.py:43 journal/views/tag.py:57
|
||||
msgid "Invalid tag"
|
||||
msgstr "无效标签"
|
||||
|
||||
#: journal/views/tag.py:63
|
||||
#: journal/views/tag.py:46
|
||||
msgid "Tag not found"
|
||||
msgstr "标签不存在"
|
||||
|
||||
#: journal/views/tag.py:61
|
||||
msgid "Tag deleted."
|
||||
msgstr ""
|
||||
msgstr "标签已删除"
|
||||
|
||||
#: journal/views/tag.py:73
|
||||
#: journal/views/tag.py:71
|
||||
msgid "Duplicated tag."
|
||||
msgstr ""
|
||||
msgstr "重复标签"
|
||||
|
||||
#: journal/views/tag.py:79
|
||||
#: journal/views/tag.py:77
|
||||
msgid "Tag updated."
|
||||
msgstr ""
|
||||
msgstr "标签已更新"
|
||||
|
||||
#: journal/views/wrapped.py:141
|
||||
msgid "Summary posted to timeline."
|
||||
msgstr ""
|
||||
msgstr "总结已发布到时间轴"
|
||||
|
||||
#: mastodon/api.py:489 takahe/utils.py:514
|
||||
#, python-brace-format
|
||||
msgid "regarding {item_title}, may contain spoiler or triggering content"
|
||||
msgstr "关于 {item_title},可能包含剧透或敏感内容"
|
||||
|
||||
#: mastodon/api.py:639
|
||||
#: mastodon/api.py:646
|
||||
msgid "collection"
|
||||
msgstr "收藏单"
|
||||
|
||||
#: mastodon/api.py:644
|
||||
#: mastodon/api.py:651
|
||||
msgid "shared my collection"
|
||||
msgstr "分享我的收藏单"
|
||||
|
||||
#: mastodon/api.py:647
|
||||
#: mastodon/api.py:654
|
||||
#, python-brace-format
|
||||
msgid "shared {username}'s collection"
|
||||
msgstr "分享 {username} 的收藏单"
|
||||
|
@ -2007,14 +2086,18 @@ msgstr "转播了你的帖文"
|
|||
msgid ""
|
||||
"\n"
|
||||
"boosted your collection <a href=\"%(piece_url)s\">%(piece_title)s</a>\n"
|
||||
msgstr "\n转播了你的收藏单 <a href=\"%(piece_url)s\">%(piece_title)s</a>\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"转播了你的收藏单 <a href=\"%(piece_url)s\">%(piece_title)s</a>\n"
|
||||
|
||||
#: social/templates/event/boosted_comment.html:3
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
"boosted your comment on <a href=\"%(item_url)s\">%(item_title)s</a>\n"
|
||||
msgstr "\n转播了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的短评\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"转播了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的短评\n"
|
||||
|
||||
#: social/templates/event/boosted_review.html:2
|
||||
#, python-format
|
||||
|
@ -2023,7 +2106,8 @@ msgid ""
|
|||
"boosted your review <a href=\"%(piece_url)s\">%(piece_title)s</a> on <a "
|
||||
"href=\"%(item_url)s\">%(item_title)s</a>\n"
|
||||
msgstr ""
|
||||
"\n转播了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的评论 <a "
|
||||
"\n"
|
||||
"转播了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的评论 <a "
|
||||
"href=\"%(piece_url)s\">%(piece_title)s</a>\n"
|
||||
|
||||
#: social/templates/event/boosted_shelfmember.html:3
|
||||
|
@ -2031,7 +2115,9 @@ msgstr ""
|
|||
msgid ""
|
||||
"\n"
|
||||
"boosted your mark on <a href=\"%(item_url)s\">%(item_title)s</a>\n"
|
||||
msgstr "\n转播了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的标记\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"转播了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的标记\n"
|
||||
|
||||
#: social/templates/event/follow_requested.html:3
|
||||
msgid "requested to follow you"
|
||||
|
@ -2050,14 +2136,18 @@ msgstr "赞了你的帖文"
|
|||
msgid ""
|
||||
"\n"
|
||||
"liked your collection <a href=\"%(piece_url)s\">%(piece_title)s</a>\n"
|
||||
msgstr "\n赞了你的收藏单 <a href=\"%(piece_url)s\">%(piece_title)s</a>\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"赞了你的收藏单 <a href=\"%(piece_url)s\">%(piece_title)s</a>\n"
|
||||
|
||||
#: social/templates/event/liked_comment.html:3
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
"liked your comment on <a href=\"%(item_url)s\">%(item_title)s</a>\n"
|
||||
msgstr "\n赞了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的短评\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"赞了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的短评\n"
|
||||
|
||||
#: social/templates/event/liked_review.html:2
|
||||
#, python-format
|
||||
|
@ -2066,7 +2156,8 @@ msgid ""
|
|||
"liked your review <a href=\"%(piece_url)s\">%(piece_title)s</a> on <a "
|
||||
"href=\"%(item_url)s\">%(item_title)s</a>\n"
|
||||
msgstr ""
|
||||
"\n赞了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的评论 <a "
|
||||
"\n"
|
||||
"赞了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的评论 <a "
|
||||
"href=\"%(piece_url)s\">%(piece_title)s</a>\n"
|
||||
|
||||
#: social/templates/event/liked_shelfmember.html:3
|
||||
|
@ -2074,7 +2165,9 @@ msgstr ""
|
|||
msgid ""
|
||||
"\n"
|
||||
"liked your mark on <a href=\"%(item_url)s\">%(item_title)s</a>\n"
|
||||
msgstr "\n赞了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的标记\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"赞了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的标记\n"
|
||||
|
||||
#: social/templates/event/mentioned.html:3
|
||||
msgid "mentioned you"
|
||||
|
@ -2085,14 +2178,18 @@ msgstr "提到了你"
|
|||
msgid ""
|
||||
"\n"
|
||||
"replied to your collection <a href=\"%(piece_url)s\">%(piece_title)s</a>\n"
|
||||
msgstr "\n回应了你的收藏单 <a href=\"%(piece_url)s\">%(piece_title)s</a>\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"回应了你的收藏单 <a href=\"%(piece_url)s\">%(piece_title)s</a>\n"
|
||||
|
||||
#: social/templates/event/mentioned_comment.html:3
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
"replied to your comment on <a href=\"%(item_url)s\">%(item_title)s</a>\n"
|
||||
msgstr "\n回应了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的短评\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"回应了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的短评\n"
|
||||
|
||||
#: social/templates/event/mentioned_review.html:2
|
||||
#, python-format
|
||||
|
@ -2101,7 +2198,8 @@ msgid ""
|
|||
"replied to your review <a href=\"%(piece_url)s\">%(piece_title)s</a> on <a "
|
||||
"href=\"%(item_url)s\">%(item_title)s</a>\n"
|
||||
msgstr ""
|
||||
"\n回应了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的评论 <a "
|
||||
"\n"
|
||||
"回应了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的评论 <a "
|
||||
"href=\"%(piece_url)s\">%(piece_title)s</a>\n"
|
||||
|
||||
#: social/templates/event/mentioned_shelfmember.html:3
|
||||
|
@ -2109,7 +2207,9 @@ msgstr ""
|
|||
msgid ""
|
||||
"\n"
|
||||
"replied to your mark on <a href=\"%(item_url)s\">%(item_title)s</a>\n"
|
||||
msgstr "\n回应了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的标记\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"回应了你对 <a href=\"%(item_url)s\">%(item_title)s</a> 的标记\n"
|
||||
|
||||
#: social/templates/events.html:44
|
||||
msgid "nothing more."
|
||||
|
@ -2167,114 +2267,118 @@ msgstr ""
|
|||
msgid "created collection"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:87
|
||||
#: users/account.py:86
|
||||
msgid "无效的电子邮件地址"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:105
|
||||
#: users/account.py:104
|
||||
msgid "验证邮件已发送"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:106
|
||||
#: users/account.py:105
|
||||
msgid "请查阅收件箱"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:156 users/account.py:163 users/account.py:173
|
||||
#: users/account.py:155 users/account.py:162 users/account.py:172
|
||||
msgid "认证失败😫"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:156
|
||||
#: users/account.py:155
|
||||
msgid "Mastodon服务未能返回有效认证信息"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:163
|
||||
#: users/account.py:162
|
||||
msgid "无效会话信息"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:173
|
||||
#: users/account.py:167
|
||||
msgid "Invalid instance domain"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:172
|
||||
msgid "Mastodon服务未能返回有效认证令牌"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:190
|
||||
#: users/account.py:189
|
||||
msgid "联邦宇宙访问失败😫"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:212
|
||||
#: users/account.py:211
|
||||
msgid "注册失败😫"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:213
|
||||
#: users/account.py:212
|
||||
msgid "本站仅限邀请注册"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:279
|
||||
#: users/account.py:273
|
||||
msgid "This username is already in use."
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:290
|
||||
#: users/account.py:284
|
||||
msgid "This email address is already in use."
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:342 users/account.py:351
|
||||
#: users/account.py:336 users/account.py:345
|
||||
msgid "无效的验证码"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:370
|
||||
#: users/account.py:364
|
||||
msgid "链接无效或已过期"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:387 users/account.py:393
|
||||
#: users/account.py:381 users/account.py:387
|
||||
msgid "电子邮件地址不匹配"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:397
|
||||
#: users/account.py:391
|
||||
msgid "此电子邮件地址已被注册"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:402
|
||||
#: users/account.py:396
|
||||
msgid "无法完成验证"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:434
|
||||
#: users/account.py:428
|
||||
msgid "用户名已被使用"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:449
|
||||
#: users/account.py:443
|
||||
msgid "电子邮件地址已被使用"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:467
|
||||
#: users/account.py:461
|
||||
msgid "已发送验证邮件,请查收。"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:471
|
||||
#: users/account.py:465
|
||||
msgid "用户名已设置。"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:473
|
||||
#: users/account.py:467
|
||||
msgid "电子邮件地址已取消关联。"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:491
|
||||
#: users/account.py:485
|
||||
#, python-brace-format
|
||||
msgid "该身份 {username}@{site} 与当前账号相同。"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:499
|
||||
#: users/account.py:493
|
||||
#, python-brace-format
|
||||
msgid "该身份 {username}@{site} 已被用于其它账号。"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:523
|
||||
#: users/account.py:517
|
||||
#, python-brace-format
|
||||
msgid "账号身份已更新为 {username}@{site}。"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:526
|
||||
#: users/account.py:520
|
||||
msgid "连接联邦宇宙获取身份信息失败。"
|
||||
msgstr ""
|
||||
|
||||
#: users/account.py:575
|
||||
#: users/account.py:569
|
||||
msgid "验证信息不符。"
|
||||
msgstr ""
|
||||
|
||||
|
@ -2534,18 +2638,5 @@ msgstr ""
|
|||
msgid "验证电子邮件"
|
||||
msgstr ""
|
||||
|
||||
#: users/views.py:25
|
||||
msgid "😖哎呀,这位用户好像还没有加入本站,快去联邦宇宙呼唤TA来注册吧!"
|
||||
msgstr ""
|
||||
|
||||
#: users/views.py:26
|
||||
msgid "未找到用户"
|
||||
msgstr ""
|
||||
|
||||
#: users/views.py:38
|
||||
msgid "没有访问该用户主页的权限"
|
||||
msgstr ""
|
||||
|
||||
#: users/views.py:49
|
||||
msgid "作者已设置仅限登录用户查看"
|
||||
msgstr ""
|
||||
#~ msgid "Invalid tag."
|
||||
#~ msgstr "无效标签"
|
||||
|
|
|
@ -4,7 +4,7 @@ reportIncompatibleVariableOverride = false
|
|||
reportUnusedImport = false
|
||||
|
||||
[tool.djlint]
|
||||
ignore="T002,T003,H006,H019,H020,H021,H023,H030,H031,D018"
|
||||
ignore="T002,T003,H005,H006,H019,H020,H021,H023,H030,H031,D018"
|
||||
indent=2
|
||||
|
||||
[tool.isort]
|
||||
|
|
|
@ -32,46 +32,45 @@ from takahe.utils import Takahe
|
|||
from .models import Preference, User
|
||||
from .tasks import *
|
||||
|
||||
|
||||
# the 'login' page that user can see
|
||||
def login(request):
|
||||
if request.method == "GET":
|
||||
selected_site = request.GET.get("site", default="")
|
||||
require_http_methods(["GET"])
|
||||
|
||||
cache_key = "login_sites"
|
||||
sites = cache.get(cache_key, [])
|
||||
if not sites:
|
||||
sites = list(
|
||||
User.objects.filter(is_active=True)
|
||||
.values("mastodon_site")
|
||||
.annotate(total=Count("mastodon_site"))
|
||||
.order_by("-total")
|
||||
.values_list("mastodon_site", flat=True)
|
||||
)
|
||||
cache.set(cache_key, sites, timeout=3600 * 8)
|
||||
# store redirect url in the cookie
|
||||
if request.GET.get("next"):
|
||||
request.session["next_url"] = request.GET.get("next")
|
||||
invite_status = -1 if settings.INVITE_ONLY else 0
|
||||
if settings.INVITE_ONLY and request.GET.get("invite"):
|
||||
if Takahe.verify_invite(request.GET.get("invite")):
|
||||
invite_status = 1
|
||||
request.session["invite"] = request.GET.get("invite")
|
||||
else:
|
||||
invite_status = -2
|
||||
return render(
|
||||
request,
|
||||
"users/login.html",
|
||||
{
|
||||
"sites": sites,
|
||||
"scope": quote(settings.MASTODON_CLIENT_SCOPE),
|
||||
"selected_site": selected_site,
|
||||
"allow_any_site": settings.MASTODON_ALLOW_ANY_SITE,
|
||||
"invite_status": invite_status,
|
||||
},
|
||||
|
||||
def login(request):
|
||||
selected_site = request.GET.get("site", default="")
|
||||
|
||||
cache_key = "login_sites"
|
||||
sites = cache.get(cache_key, [])
|
||||
if not sites:
|
||||
sites = list(
|
||||
User.objects.filter(is_active=True)
|
||||
.values("mastodon_site")
|
||||
.annotate(total=Count("mastodon_site"))
|
||||
.order_by("-total")
|
||||
.values_list("mastodon_site", flat=True)
|
||||
)
|
||||
else:
|
||||
raise BadRequest()
|
||||
cache.set(cache_key, sites, timeout=3600 * 8)
|
||||
# store redirect url in the cookie
|
||||
if request.GET.get("next"):
|
||||
request.session["next_url"] = request.GET.get("next")
|
||||
invite_status = -1 if settings.INVITE_ONLY else 0
|
||||
if settings.INVITE_ONLY and request.GET.get("invite"):
|
||||
if Takahe.verify_invite(request.GET.get("invite")):
|
||||
invite_status = 1
|
||||
request.session["invite"] = request.GET.get("invite")
|
||||
else:
|
||||
invite_status = -2
|
||||
return render(
|
||||
request,
|
||||
"users/login.html",
|
||||
{
|
||||
"sites": sites,
|
||||
"scope": quote(settings.MASTODON_CLIENT_SCOPE),
|
||||
"selected_site": selected_site,
|
||||
"allow_any_site": settings.MASTODON_ALLOW_ANY_SITE,
|
||||
"invite_status": invite_status,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
# connect will send verification email or redirect to mastodon server
|
||||
|
@ -165,7 +164,7 @@ def connect_redirect_back(request):
|
|||
try:
|
||||
token, refresh_token = obtain_token(site, request, code)
|
||||
except ObjectDoesNotExist:
|
||||
raise BadRequest()
|
||||
raise BadRequest(_("Invalid instance domain"))
|
||||
if not token:
|
||||
return render(
|
||||
request,
|
||||
|
@ -239,24 +238,19 @@ def login_existing_user(request, existing_user):
|
|||
@mastodon_request_included
|
||||
@login_required
|
||||
def logout(request):
|
||||
if request.method == "GET":
|
||||
# revoke_token(request.user.mastodon_site, request.user.mastodon_token)
|
||||
return auth_logout(request)
|
||||
else:
|
||||
raise BadRequest()
|
||||
# revoke_token(request.user.mastodon_site, request.user.mastodon_token)
|
||||
return auth_logout(request)
|
||||
|
||||
|
||||
@mastodon_request_included
|
||||
@login_required
|
||||
@require_http_methods(["POST"])
|
||||
def reconnect(request):
|
||||
if request.META.get("HTTP_AUTHORIZATION"):
|
||||
raise BadRequest("Only for web login")
|
||||
if request.method == "POST":
|
||||
request.session["swap_login"] = True
|
||||
request.session["swap_domain"] = request.POST["domain"]
|
||||
return connect(request)
|
||||
else:
|
||||
raise BadRequest()
|
||||
request.session["swap_login"] = True
|
||||
request.session["swap_domain"] = request.POST["domain"]
|
||||
return connect(request)
|
||||
|
||||
|
||||
class RegistrationForm(forms.ModelForm):
|
||||
|
|
|
@ -2,7 +2,7 @@ import json
|
|||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core.exceptions import BadRequest
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.http import Http404, HttpResponseRedirect
|
||||
from django.shortcuts import redirect, render
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
@ -21,41 +21,6 @@ from .data import *
|
|||
from .models import APIdentity
|
||||
|
||||
|
||||
def render_user_not_found(request, user_name=""):
|
||||
sec_msg = _("😖哎呀,这位用户好像还没有加入本站,快去联邦宇宙呼唤TA来注册吧!")
|
||||
msg = _("未找到用户") + user_name
|
||||
return render(
|
||||
request,
|
||||
"common/error.html",
|
||||
{
|
||||
"msg": msg,
|
||||
"secondary_msg": sec_msg,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def render_user_blocked(request):
|
||||
msg = _("没有访问该用户主页的权限")
|
||||
return render(
|
||||
request,
|
||||
"common/error.html",
|
||||
{
|
||||
"msg": msg,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def render_user_noanonymous(request):
|
||||
msg = _("作者已设置仅限登录用户查看")
|
||||
return render(
|
||||
request,
|
||||
"common/error.html",
|
||||
{
|
||||
"msg": msg,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def query_identity(request, handle):
|
||||
try:
|
||||
i = APIdentity.get_by_handle(handle)
|
||||
|
@ -67,7 +32,7 @@ def query_identity(request, handle):
|
|||
request, "users/fetch_identity_pending.html", {"handle": handle}
|
||||
)
|
||||
else:
|
||||
return render_user_not_found(request, handle)
|
||||
raise Http404(_("User not found"))
|
||||
|
||||
|
||||
def fetch_refresh(request):
|
||||
|
@ -153,10 +118,10 @@ def unblock(request: AuthedHttpRequest, user_name):
|
|||
try:
|
||||
target = APIdentity.get_by_handle(user_name)
|
||||
except APIdentity.DoesNotExist:
|
||||
return render_user_not_found(request)
|
||||
raise Http404(_("User not found"))
|
||||
target_user = target.user
|
||||
if target_user and not target_user.is_active:
|
||||
return render_user_not_found(request)
|
||||
raise Http404(_("User no longer exists"))
|
||||
request.user.identity.unblock(target)
|
||||
return render(
|
||||
request,
|
||||
|
@ -201,7 +166,7 @@ def set_layout(request: AuthedHttpRequest):
|
|||
request.user.preference.discover_layout = layout
|
||||
request.user.preference.save(update_fields=["discover_layout"])
|
||||
return redirect(reverse("catalog:discover"))
|
||||
raise BadRequest()
|
||||
raise BadRequest(_("Invalid parameter"))
|
||||
|
||||
|
||||
@login_required
|
||||
|
|
Loading…
Add table
Reference in a new issue