diff --git a/common/models.py b/common/models.py
index fe317393..5098ea1f 100644
--- a/common/models.py
+++ b/common/models.py
@@ -4,7 +4,7 @@ from markdown import markdown
from django.utils.translation import gettext_lazy as _
from django.db import models, IntegrityError
from django.core.serializers.json import DjangoJSONEncoder
-from django.db.models import Q
+from django.db.models import Q, Count
from markdownx.models import MarkdownxField
from users.models import User
from mastodon.api import get_relationships, get_cross_site_id
@@ -197,8 +197,10 @@ class UserOwnedEntity(models.Model):
:param is_following: if the current user is following the owner
"""
user_owned_entities = cls.objects.filter(owner=owner)
- if not is_following:
- user_owned_entities = user_owned_entities.exclude(visibility__gt=0)
+ if is_following:
+ user_owned_entities = user_owned_entities.exclude(visibility__ne=2)
+ else:
+ user_owned_entities = user_owned_entities.filter(visibility=0)
return user_owned_entities
@@ -255,5 +257,22 @@ class Tag(models.Model):
def __str__(self):
return self.content
+ @property
+ def edited_time(self):
+ return self.mark.edited_time
+
+ @classmethod
+ def find_by_user(cls, tag, owner, is_following):
+ user_owned_entities = cls.objects.filter(content=tag, mark__owner=owner)
+ if is_following:
+ user_owned_entities = user_owned_entities.exclude(mark__visibility__ne=2)
+ else:
+ user_owned_entities = user_owned_entities.filter(mark__visibility=0)
+ return user_owned_entities
+
+ @classmethod
+ def all_by_user(cls, owner):
+ return cls.objects.filter(mark__owner=owner).values('content').annotate(total=Count('content')).order_by('-total')
+
class Meta:
abstract = True
diff --git a/users/templates/users/home.html b/users/templates/users/home.html
index b4b7d6bb..18ba2e88 100644
--- a/users/templates/users/home.html
+++ b/users/templates/users/home.html
@@ -703,6 +703,53 @@
+
+
+ {% trans '常用标签' %}
+
+
+ {% if book_tags %}
+
{% trans '书籍' %}
+ {% for v in book_tags %}
+
+ {{ v }}
+
+ {% endfor %}
+
+ {% endif %}
+
+ {% if movie_tags %}
+
{% trans '电影和剧集' %}
+ {% for v in movie_tags %}
+
+ {{ v }}
+
+ {% endfor %}
+
+ {% endif %}
+
+ {% if music_tags %}
+
{% trans '音乐' %}
+ {% for v in music_tags %}
+
+ {{ v }}
+
+ {% endfor %}
+
+ {% endif %}
+
+ {% if game_tags %}
+
{% trans '游戏' %}
+ {% for v in game_tags %}
+
+ {{ v }}
+
+ {% endfor %}
+
+ {% endif %}
+
+
+
diff --git a/users/views.py b/users/views.py
index ad3b7a35..b6597b82 100644
--- a/users/views.py
+++ b/users/views.py
@@ -354,6 +354,11 @@ def home(request, id):
**music_marks_count,
**game_marks_count,
+ 'book_tags': list(map(lambda t: t['content'], BookTag.all_by_user(user)))[:10] if user == request.user else [],
+ 'movie_tags': list(map(lambda t: t['content'], MovieTag.all_by_user(user)))[:10] if user == request.user else [],
+ 'music_tags': list(map(lambda t: t['content'], AlbumTag.all_by_user(user)))[:10] if user == request.user else [],
+ 'game_tags': list(map(lambda t: t['content'], GameTag.all_by_user(user)))[:10] if user == request.user else [],
+
'book_reviews': book_reviews.order_by("-edited_time")[:BOOKS_PER_SET],
'movie_reviews': movie_reviews.order_by("-edited_time")[:MOVIES_PER_SET],
'music_reviews': music_reviews[:MUSIC_PER_SET],
@@ -533,7 +538,7 @@ def following(request, id):
@login_required
def book_list(request, id, status):
if request.method == 'GET':
- if status.upper() not in MarkStatusEnum.names and status != 'reviewed':
+ if status.upper() not in MarkStatusEnum.names and status not in ['reviewed', 'tagged']:
return HttpResponseBadRequest()
if isinstance(id, str):
@@ -558,6 +563,7 @@ def book_list(request, id, status):
'secondary_msg': sec_msg,
}
)
+ tag = request.GET.get('t', default='')
if user != request.user:
# mastodon request
relation = get_relationship(request.user, user, request.session['oauth_token'])[0]
@@ -572,6 +578,8 @@ def book_list(request, id, status):
)
if status == 'reviewed':
queryset = BookReview.get_available_by_user(user, relation['following']).order_by("-edited_time")
+ elif status == 'tagged':
+ queryset = BookTag.find_by_user(tag, user, relation['following']).order_by("-mark__edited_time")
else:
queryset = BookMark.get_available_by_user(user, relation['following']).filter(
status=MarkStatusEnum[status.upper()]).order_by("-edited_time")
@@ -580,6 +588,8 @@ def book_list(request, id, status):
else:
if status == 'reviewed':
queryset = BookReview.objects.filter(owner=user).order_by("-edited_time")
+ elif status == 'tagged':
+ queryset = BookTag.objects.filter(content=tag, mark__owner=user).order_by("-mark__edited_time")
else:
queryset = BookMark.objects.filter(
owner=user, status=MarkStatusEnum[status.upper()]).order_by("-edited_time")
@@ -590,7 +600,12 @@ def book_list(request, id, status):
mark.book.tag_list = mark.book.get_tags_manager().values('content').annotate(
tag_frequency=Count('content')).order_by('-tag_frequency')[:TAG_NUMBER_ON_LIST]
marks.pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages)
- list_title = (str(BookMarkStatusTranslator(MarkStatusEnum[status.upper()]) if status != 'reviewed' else _("评论过"))) + str(_("的书"))
+ if status == 'reviewed':
+ list_title = str(_("评论过的书"))
+ elif status == 'tagged':
+ list_title = str(_(f"标记为「{tag}」的书"))
+ else:
+ list_title = str(BookMarkStatusTranslator(MarkStatusEnum[status.upper()])) + str(_("的书"))
return render(
request,
'users/book_list.html',
@@ -609,7 +624,7 @@ def book_list(request, id, status):
@login_required
def movie_list(request, id, status):
if request.method == 'GET':
- if status.upper() not in MarkStatusEnum.names and status != 'reviewed':
+ if status.upper() not in MarkStatusEnum.names and status not in ['reviewed', 'tagged']:
return HttpResponseBadRequest()
if isinstance(id, str):
@@ -634,6 +649,7 @@ def movie_list(request, id, status):
'secondary_msg': sec_msg,
}
)
+ tag = request.GET.get('t', default='')
if user != request.user:
# mastodon request
relation = get_relationship(request.user, user, request.session['oauth_token'])[0]
@@ -650,12 +666,16 @@ def movie_list(request, id, status):
user, request.user.mastodon_site, request.session['oauth_token'])
if status == 'reviewed':
queryset = MovieReview.get_available_by_user(user, relation['following']).order_by("-edited_time")
+ elif status == 'tagged':
+ queryset = MovieTag.find_by_user(tag, user, relation['following']).order_by("-mark__edited_time")
else:
queryset = MovieMark.get_available_by_user(user, relation['following']).filter(
status=MarkStatusEnum[status.upper()]).order_by("-edited_time")
else:
if status == 'reviewed':
queryset = MovieReview.objects.filter(owner=user).order_by("-edited_time")
+ elif status == 'tagged':
+ queryset = MovieTag.objects.filter(content=tag, mark__owner=user).order_by("-mark__edited_time")
else:
queryset = MovieMark.objects.filter(owner=user, status=MarkStatusEnum[status.upper()]).order_by("-edited_time")
paginator = Paginator(queryset, ITEMS_PER_PAGE)
@@ -665,7 +685,13 @@ def movie_list(request, id, status):
mark.movie.tag_list = mark.movie.get_tags_manager().values('content').annotate(
tag_frequency=Count('content')).order_by('-tag_frequency')[:TAG_NUMBER_ON_LIST]
marks.pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages)
- list_title = (str(MovieMarkStatusTranslator(MarkStatusEnum[status.upper()])) if status != 'reviewed' else _("评论过")) + str(_("的电影和剧集"))
+ if status == 'reviewed':
+ list_title = str(_("评论过的电影和剧集"))
+ elif status == 'tagged':
+ list_title = str(_(f"标记为「{tag}」的电影和剧集"))
+ else:
+ list_title = str(MovieMarkStatusTranslator(MarkStatusEnum[status.upper()])) + str(_("的电影和剧集"))
+
return render(
request,
'users/movie_list.html',
@@ -684,7 +710,7 @@ def movie_list(request, id, status):
@login_required
def game_list(request, id, status):
if request.method == 'GET':
- if status.upper() not in MarkStatusEnum.names and status != 'reviewed':
+ if status.upper() not in MarkStatusEnum.names and status not in ['reviewed', 'tagged']:
return HttpResponseBadRequest()
if isinstance(id, str):
@@ -709,6 +735,7 @@ def game_list(request, id, status):
'secondary_msg': sec_msg,
}
)
+ tag = request.GET.get('t', default='')
if user != request.user:
# mastodon request
relation = get_relationship(request.user, user, request.session['oauth_token'])[0]
@@ -725,12 +752,16 @@ def game_list(request, id, status):
user, request.user.mastodon_site, request.session['oauth_token'])
if status == 'reviewed':
queryset = GameReview.get_available_by_user(user, relation['following']).order_by("-edited_time")
+ elif status == 'tagged':
+ queryset = GameTag.find_by_user(tag, user, relation['following']).order_by("-mark__edited_time")
else:
queryset = GameMark.get_available_by_user(user, relation['following']).filter(
status=MarkStatusEnum[status.upper()]).order_by("-edited_time")
else:
if status == 'reviewed':
queryset = GameReview.objects.filter(owner=user).order_by("-edited_time")
+ elif status == 'tagged':
+ queryset = GameTag.objects.filter(content=tag, mark__owner=user).order_by("-mark__edited_time")
else:
queryset = GameMark.objects.filter(
owner=user, status=MarkStatusEnum[status.upper()]).order_by("-edited_time")
@@ -741,7 +772,12 @@ def game_list(request, id, status):
mark.game.tag_list = mark.game.get_tags_manager().values('content').annotate(
tag_frequency=Count('content')).order_by('-tag_frequency')[:TAG_NUMBER_ON_LIST]
marks.pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages)
- list_title = (str(GameMarkStatusTranslator(MarkStatusEnum[status.upper()])) if status != 'reviewed' else _("评论过")) + str(_("的游戏"))
+ if status == 'reviewed':
+ list_title = str(_("评论过的游戏"))
+ elif status == 'tagged':
+ list_title = str(_(f"标记为「{tag}」的游戏"))
+ else:
+ list_title = str(GameMarkStatusTranslator(MarkStatusEnum[status.upper()])) + str(_("的游戏"))
return render(
request,
'users/game_list.html',
@@ -760,7 +796,7 @@ def game_list(request, id, status):
@login_required
def music_list(request, id, status):
if request.method == 'GET':
- if status.upper() not in MarkStatusEnum.names and status != 'reviewed':
+ if status.upper() not in MarkStatusEnum.names and status not in ['reviewed', 'tagged']:
return HttpResponseBadRequest()
if isinstance(id, str):
@@ -785,6 +821,7 @@ def music_list(request, id, status):
'secondary_msg': sec_msg,
}
)
+ tag = request.GET.get('t', default='')
if not user == request.user:
# mastodon request
relation = get_relationship(request.user, user, request.session['oauth_token'])[0]
@@ -800,6 +837,8 @@ def music_list(request, id, status):
if status == 'reviewed':
queryset = list(AlbumReview.get_available_by_user(user, relation['following']).order_by("-edited_time")) + \
list(SongReview.get_available_by_user(user, relation['following']).order_by("-edited_time"))
+ elif status == 'tagged':
+ queryset = list(AlbumTag.find_by_user(tag, user, relation['following']).order_by("-mark__edited_time"))
else:
queryset = list(AlbumMark.get_available_by_user(user, relation['following']).filter(
status=MarkStatusEnum[status.upper()])) \
@@ -812,6 +851,8 @@ def music_list(request, id, status):
if status == 'reviewed':
queryset = list(AlbumReview.objects.filter(owner=user).order_by("-edited_time")) + \
list(SongReview.objects.filter(owner=user).order_by("-edited_time"))
+ elif status == 'tagged':
+ queryset = list(AlbumTag.objects.filter(content=tag, mark__owner=user).order_by("-mark__edited_time"))
else:
queryset = list(AlbumMark.objects.filter(owner=user, status=MarkStatusEnum[status.upper()])) \
+ list(SongMark.objects.filter(owner=user, status=MarkStatusEnum[status.upper()]))
@@ -820,7 +861,7 @@ def music_list(request, id, status):
page_number = request.GET.get('page', default=1)
marks = paginator.get_page(page_number)
for mark in marks:
- if mark.__class__ == AlbumMark or mark.__class__ == AlbumReview:
+ if mark.__class__ in [AlbumMark, AlbumReview, AlbumTag]:
mark.music = mark.album
mark.music.tag_list = mark.album.get_tags_manager().values('content').annotate(
tag_frequency=Count('content')).order_by('-tag_frequency')[:TAG_NUMBER_ON_LIST]
@@ -830,7 +871,12 @@ def music_list(request, id, status):
tag_frequency=Count('content')).order_by('-tag_frequency')[:TAG_NUMBER_ON_LIST]
marks.pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages)
- list_title = (str(MusicMarkStatusTranslator(MarkStatusEnum[status.upper()]) if status != 'reviewed' else _("评论过"))) + str(_("的音乐"))
+ if status == 'reviewed':
+ list_title = str(_("评论过的音乐"))
+ elif status == 'tagged':
+ list_title = str(_(f"标记为「{tag}」的音乐"))
+ else:
+ list_title = str(MusicMarkStatusTranslator(MarkStatusEnum[status.upper()])) + str(_("的音乐"))
return render(
request,
'users/music_list.html',