diff --git a/common/templates/partial/list_item.html b/common/templates/partial/list_item.html
deleted file mode 100644
index 9b4eb9ad..00000000
--- a/common/templates/partial/list_item.html
+++ /dev/null
@@ -1,9 +0,0 @@
-{% if item.category_name|lower == 'book' %}
-{% include "partial/list_item_book.html" with book=item %}
-{% elif item.category_name|lower == 'movie' %}
-{% include "partial/list_item_movie.html" with movie=item %}
-{% elif item.category_name|lower == 'game' %}
-{% include "partial/list_item_game.html" with game=item %}
-{% elif item.category_name|lower == 'album' or item.category_name|lower == 'song' %}
-{% include "partial/list_item_music.html" with music=item %}
-{% endif %}
\ No newline at end of file
diff --git a/common/templates/partial/list_item_book.html b/common/templates/partial/list_item_book.html
deleted file mode 100644
index 73efa7bf..00000000
--- a/common/templates/partial/list_item_book.html
+++ /dev/null
@@ -1,159 +0,0 @@
-{% load thumb %}
-{% load highlight %}
-{% load i18n %}
-{% load l10n %}
-{% load user_item %}
-{% current_user_marked_item book as marked %}
-
-
-
-
-
- {% if not marked %}
-
➕
- {% endif %}
-
-
-
- {% if editable %}
-
- {% if not forloop.first %}
-
▲
- {% endif %}
- {% if not forloop.last %}
-
▼
- {% endif %}
-
✖
-
- {% endif %}
-
-
-
- {% if book.rating %}
-
-
{{ book.rating }}
- {% else %}
-
{% trans '暂无评分' %}
- {% endif %}
-
-
- {% if book.pub_year %} /
- {{ book.pub_year }}{% trans '年' %}{% if book.pub_month %}{{book.pub_month }}{% trans '月' %}{% endif %}
- {% endif %}
-
- {% if book.author %} /
- {% for author in book.author %}
- {% if request.GET.q %}
- {{ author | highlight:request.GET.q }}
- {% else %}
- {{ author }}
- {% endif %}
- {% if not forloop.last %},{% endif %}
- {% endfor %}
- {% endif %}
-
- {% if book.translator %} /
- {% trans '翻译' %}:
- {% for translator in book.translator %}
- {% if request.GET.q %}
- {{ translator | highlight:request.GET.q }}
- {% else %}
- {{ translator }}
- {% endif %}
- {% if not forloop.last %},{% endif %}
- {% endfor %}
- {% endif %}
-
- {% if book.subtitle %} /
- {% trans '副标题' %}:
- {% if request.GET.q %}
- {{ book.subtitle | highlight:request.GET.q }}
- {% else %}
- {{ book.subtitle }}
- {% endif %}
- {% endif %}
-
- {% if book.orig_title %} /
- {% trans '原名' %}:
- {% if request.GET.q %}
- {{ book.orig_title | highlight:request.GET.q }}
- {% else %}
- {{ book.orig_title }}
- {% endif %}
- {% endif %}
-
-
- {{ book.brief }}
-
-
-
-
- {% if mark %}
-
-
-
-
- -
- {% if mark.rating %}
-
- {% endif %}
- {% if mark.visibility > 0 %}
-
- {% endif %}
-
- {% trans '于' %} {{ mark.created_time }}
- {% if status == 'reviewed' %}
- {% trans '评论' %}: {{ mark.title }}
- {% else %}
- {% trans '标记' %}
- {% endif %}
-
- {% if mark.text %}
-
{{ mark.text }}
- {% endif %}
-
-
-
- {% endif %}
-
- {% if collectionitem %}
-
-
-
- {% endif %}
-
-
\ No newline at end of file
diff --git a/common/templates/partial/list_item_game.html b/common/templates/partial/list_item_game.html
deleted file mode 100644
index 97db04c8..00000000
--- a/common/templates/partial/list_item_game.html
+++ /dev/null
@@ -1,139 +0,0 @@
-{% load thumb %}
-{% load highlight %}
-{% load i18n %}
-{% load l10n %}
-{% load user_item %}
-{% current_user_marked_item game as marked %}
-
-
-
-
-
- {% if not marked %}
-
➕
- {% endif %}
-
-
- {% if editable %}
-
- {% if not forloop.first %}
-
▲
- {% endif %}
- {% if not forloop.last %}
-
▼
- {% endif %}
-
✖
-
- {% endif %}
-
-
-
- {% if game.rating %}
-
-
{{ game.rating }}
- {% else %}
-
{% trans '暂无评分' %}
- {% endif %}
-
-
-
- {% if game.other_title %}{% trans '别名' %}:
- {% for other_title in game.other_title %}
- {{ other_title }}{% if not forloop.last %} {% endif %}
- {% endfor %}/
- {% endif %}
-
- {% if game.developer %}{% trans '开发商' %}:
- {% for developer in game.developer %}
- {{ developer }}{% if not forloop.last %} {% endif %}
- {% endfor %}/
- {% endif %}
-
- {% if game.genre %}{% trans '类型' %}:
- {% for genre in game.genre %}
- {{ genre }}{% if not forloop.last %} {% endif %}
- {% endfor %}/
- {% endif %}
-
- {% if game.platform %}{% trans '平台' %}:
- {% for platform in game.platform %}
- {{ platform }}{% if not forloop.last %} {% endif %}
- {% endfor %}
- {% endif %}
-
-
-
- {{ game.brief }}
-
-
-
-
- {% if mark %}
-
-
-
-
- -
- {% if mark.rating %}
-
- {% endif %}
- {% if mark.visibility > 0 %}
-
- {% endif %}
-
- {% trans '于' %} {{ mark.created_time }}
- {% if status == 'reviewed' %}
- {% trans '评论' %}: {{ mark.title }}
- {% else %}
- {% trans '标记' %}
- {% endif %}
-
- {% if mark.text %}
-
{{ mark.text }}
- {% endif %}
-
-
-
- {% endif %}
-
- {% if collectionitem %}
-
-
-
- {% endif %}
-
-
-
\ No newline at end of file
diff --git a/common/templates/partial/list_item_movie.html b/common/templates/partial/list_item_movie.html
deleted file mode 100644
index 6c9a2830..00000000
--- a/common/templates/partial/list_item_movie.html
+++ /dev/null
@@ -1,164 +0,0 @@
-{% load thumb %}
-{% load highlight %}
-{% load i18n %}
-{% load l10n %}
-{% load humanize %}
-{% load user_item %}
-{% current_user_marked_item movie as marked %}
-
-
-
-
-
- {% if not marked %}
-
➕
- {% endif %}
-
-
- {% if editable %}
-
- {% if not forloop.first %}
-
▲
- {% endif %}
- {% if not forloop.last %}
-
▼
- {% endif %}
-
✖
-
- {% endif %}
-
-
-
- {% if movie.rating %}
-
-
{{ movie.rating }}
- {% else %}
-
{% trans '暂无评分' %}
- {% endif %}
-
-
-
- {% if movie.director %}{% trans '导演' %}:
- {% for director in movie.director %}
- {% if request.GET.q %}
- {{ director | highlight:request.GET.q }}
- {% else %}
- {{ director }}
- {% endif %}
- {% if not forloop.last %},{% endif %}
- {% endfor %}/
- {% endif %}
-
- {% if movie.genre %}{% trans '类型' %}:
- {% for genre in movie.get_genre_display %}
- {{ genre }}{% if not forloop.last %} {% endif %}
- {% endfor %}/
- {% endif %}
-
-
-
- {% if movie.actor %}{% trans '主演' %}:
- {% for actor in movie.actor %}
- 5 %}style="display: none;" {% endif %}>
- {% if request.GET.q %}
- {{ actor | highlight:request.GET.q }}
- {% else %}
- {{ actor }}
- {% endif %}
-
- {% if forloop.counter <= 5 %}
- {% if not forloop.counter == 5 and not forloop.last %} {% endif %}
- {% endif %}
- {% endfor %}
- {% endif %}
-
-
- {{ movie.brief }}
-
-
-
- {% if mark %}
-
-
-
-
- -
- {% if mark.rating %}
-
- {% endif %}
- {% if mark.visibility > 0 %}
-
- {% endif %}
-
- {% trans '于' %} {{ mark.created_time }}
- {% if status == 'reviewed' %}
- {% trans '评论' %}: {{ mark.title }}
- {% else %}
- {% trans '标记' %}
- {% endif %}
-
- {% if mark.text %}
-
{{ mark.text }}
- {% endif %}
-
-
-
- {% endif %}
-
- {% if collectionitem %}
-
-
-
- {% endif %}
-
-
-
\ No newline at end of file
diff --git a/common/templates/partial/list_item_music.html b/common/templates/partial/list_item_music.html
deleted file mode 100644
index ab9244a1..00000000
--- a/common/templates/partial/list_item_music.html
+++ /dev/null
@@ -1,171 +0,0 @@
-{% load thumb %}
-{% load highlight %}
-{% load i18n %}
-{% load l10n %}
-{% load user_item %}
-{% current_user_marked_item music as marked %}
-
-
-
- {% if music.category_name|lower == 'album' %}
-
-
-
- {% if not marked %}
-
➕
- {% endif %}
- {% elif music.category_name|lower == 'song' %}
-
-
-
- {% if not marked %}
-
➕
- {% endif %}
- {% endif %}
-
-
- {% if editable %}
-
- {% if not forloop.first %}
-
▲
- {% endif %}
- {% if not forloop.last %}
-
▼
- {% endif %}
-
✖
-
- {% endif %}
-
-
-
- {% if music.rating %}
-
-
{{ music.rating }}
- {% else %}
-
{% trans '暂无评分' %}
- {% endif %}
-
-
- {% if music.artist %}{% trans '艺术家' %}:
- {% for artist in music.artist %}
- {{ artist }}
- {% if not forloop.last %} {% endif %}
- {% endfor %}
- {% endif %}
-
- {% if music.genre %}/ {% trans '流派' %}:
- {{ music.genre }}
- {% endif %}
-
- {% if music.release_date %}/ {% trans '发行日期' %}:
- {{ music.release_date }}
- {% endif %}
-
-
-
-
-
- {% if music.brief %}
-
- {{ music.brief }}
-
- {% elif music.category_name|lower == 'album' %}
-
- {% trans '曲目:' %}{{ music.track_list }}
-
- {% else %}
-
-
- {% trans '所属专辑:' %}{{ music.album }}
-
- {% endif %}
-
-
-
- {% if mark %}
-
-
-
-
- -
- {% if mark.rating %}
-
- {% endif %}
- {% if mark.visibility > 0 %}
-
- {% endif %}
-
- {% trans '于' %} {{ mark.created_time }}
- {% if status == 'reviewed' %}
- {% trans '评论' %}:
- {% if music.category_name|lower == 'album' %}
- {{ mark.title }}
- {% else %}
- {{ mark.title }}
- {% endif %}
- {% else %}
- {% trans '标记' %}
- {% endif %}
-
- {% if mark.text %}
-
{{ mark.text }}
- {% endif %}
-
-
-
- {% endif %}
-
- {% if collectionitem %}
-
-
-
- {% endif %}
-
-
-
-
\ No newline at end of file
diff --git a/common/templates/partial/mark_list.html b/common/templates/partial/mark_list.html
deleted file mode 100644
index 71c4102a..00000000
--- a/common/templates/partial/mark_list.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% load i18n %}
-
-
-{% for others_mark in mark_list %}
--
- {{ others_mark.owner.username }}
-
- {{ others_mark.get_status_display }}
-
- {% if others_mark.rating %}
-
- {% endif %}
-
- {% if others_mark.visibility > 0 %}
-
- {% endif %}
-
- {% if others_mark.shared_link %}
- {{ others_mark.created_time }}
- {% else %}
- {{ others_mark.created_time }}
- {% endif %}
-
- {% if current_item and others_mark.item != current_item %}
- {{ others_mark.item.get_source_site_display }}
- {% endif %}
-
- {% if others_mark.text %}
-
{{ others_mark.text }}
- {% endif %}
-
-{% empty %}
-
- {% trans '暂无标记' %}
-
-{% endfor %}
-
\ No newline at end of file
diff --git a/common/templatetags/user_item.py b/common/templatetags/user_item.py
deleted file mode 100644
index 2140b914..00000000
--- a/common/templatetags/user_item.py
+++ /dev/null
@@ -1,19 +0,0 @@
-from django import template
-from collection.models import Collection
-
-
-register = template.Library()
-
-
-@register.simple_tag(takes_context=True)
-def current_user_marked_item(context, item):
- # NOTE weird to put business logic in tags
- user = context['request'].user
- if user and user.is_authenticated:
- if isinstance(item, Collection) and item.owner == user:
- return item
- else:
- return context['request'].user.get_mark_for_item(item)
- return None
-
-
diff --git a/common/urls.py b/common/urls.py
index b803a47d..f0f36969 100644
--- a/common/urls.py
+++ b/common/urls.py
@@ -1,11 +1,5 @@
from django.urls import path
from .views import *
-app_name = 'common'
-urlpatterns = [
- path('', home),
- path('home/', home, name='home'),
- path('search/', search, name='search'),
- path('search.json/', search, name='search.json'),
- path('external_search/', external_search, name='external_search'),
-]
+app_name = "common"
+urlpatterns = [path("", home), path("home/", home, name="home")]
diff --git a/common/views.py b/common/views.py
index bd4f1bb7..6dd50b00 100644
--- a/common/views.py
+++ b/common/views.py
@@ -1,553 +1,15 @@
-import operator
import logging
-from difflib import SequenceMatcher
-from urllib.parse import urlparse
-from django.shortcuts import render, redirect, reverse
+from django.shortcuts import render, redirect
+from django.urls import reverse
from django.contrib.auth.decorators import login_required
from django.utils.translation import gettext_lazy as _
-from django.core.paginator import Paginator
-from django.core.validators import URLValidator
-from django.core.exceptions import ValidationError, ObjectDoesNotExist
-from django.db.models import Q, Count
-from django.http import HttpResponseBadRequest
-from books.models import Book
-from movies.models import Movie
-from games.models import Game
-from music.models import Album, Song, AlbumMark, SongMark
-from users.models import Report, User, Preference
-from mastodon.decorators import mastodon_request_included
-from users.views import home as user_home
-from timeline.views import timeline as user_timeline
-from common.models import MarkStatusEnum
-from common.utils import PageLinksGenerator
-from common.scraper import get_scraper_by_url, get_normalized_url
-from common.config import *
-from common.searcher import ExternalSources
-from management.models import Announcement
-from django.conf import settings
-from common.index import Indexer
-from django.http import JsonResponse
-from django.db.utils import IntegrityError
-
-logger = logging.getLogger(__name__)
+_logger = logging.getLogger(__name__)
@login_required
def home(request):
if request.user.get_preference().classic_homepage:
- return redirect(reverse("users:home", args=[request.user.mastodon_username]))
+ return redirect(reverse("journal:home", args=[request.user.mastodon_username]))
else:
- return redirect(reverse("timeline:timeline"))
-
-
-@login_required
-def external_search(request):
- category = request.GET.get("c", default="all").strip().lower()
- if category == "all":
- category = None
- keywords = request.GET.get("q", default="").strip()
- page_number = int(request.GET.get("page", default=1))
- items = ExternalSources.search(category, keywords, page_number) if keywords else []
- dedupe_urls = request.session.get("search_dedupe_urls", [])
- items = [i for i in items if i.source_url not in dedupe_urls]
-
- return render(
- request,
- "common/external_search_result.html",
- {
- "external_items": items,
- },
- )
-
-
-def search(request):
- if settings.ENABLE_NEW_MODEL:
- from catalog.views import search as new_search
-
- return new_search(request)
-
- if settings.SEARCH_BACKEND is None:
- return search2(request)
- category = request.GET.get("c", default="all").strip().lower()
- if category == "all":
- category = None
- keywords = request.GET.get("q", default="").strip()
- tag = request.GET.get("tag", default="").strip()
- p = request.GET.get("page", default="1")
- page_number = int(p) if p.isdigit() else 1
- if not (keywords or tag):
- return render(
- request,
- "common/search_result.html",
- {
- "items": None,
- },
- )
- if request.user.is_authenticated:
- url_validator = URLValidator()
- try:
- url_validator(keywords)
- # validation success
- return jump_or_scrape(request, keywords)
- except ValidationError as e:
- pass
-
- result = Indexer.search(keywords, page=page_number, category=category, tag=tag)
- keys = []
- items = []
- urls = []
- for i in result.items:
- key = (
- i.isbn
- if hasattr(i, "isbn")
- else (i.imdb_code if hasattr(i, "imdb_code") else None)
- )
- if key is None:
- items.append(i)
- elif key not in keys:
- keys.append(key)
- items.append(i)
- urls.append(i.source_url)
- i.tag_list = i.all_tag_list[:TAG_NUMBER_ON_LIST]
-
- if request.path.endswith(".json/"):
- return JsonResponse(
- {
- "num_pages": result.num_pages,
- "items": list(map(lambda i: i.get_json(), items)),
- }
- )
-
- request.session["search_dedupe_urls"] = urls
- return render(
- request,
- "common/search_result.html",
- {
- "items": items,
- "pagination": PageLinksGenerator(
- PAGE_LINK_NUMBER, page_number, result.num_pages
- ),
- "categories": ["book", "movie", "music", "game"],
- },
- )
-
-
-def search2(request):
- if request.method == "GET":
-
- # test if input serach string is empty or not excluding param ?c=
- empty_querystring_criteria = {k: v for k, v in request.GET.items() if k != "c"}
- if not len(empty_querystring_criteria):
- return HttpResponseBadRequest()
-
- # test if user input an URL, if so jump to URL handling function
- url_validator = URLValidator()
- input_string = request.GET.get("q", default="").strip()
- try:
- url_validator(input_string)
- # validation success
- return jump_or_scrape(request, input_string)
- except ValidationError as e:
- pass
-
- # category, book/movie/music etc
- category = request.GET.get("c", default="").strip().lower()
- # keywords, seperated by blank space
- # it is better not to split the keywords
- keywords = request.GET.get("q", default="").strip()
- keywords = [keywords] if keywords else ""
- # tag, when tag is provided there should be no keywords , for now
- tag = request.GET.get("tag", default="")
-
- # white space string, empty query
- if not (keywords or tag):
- return render(
- request,
- "common/search_result.html",
- {
- "items": None,
- },
- )
-
- def book_param_handler(**kwargs):
- # keywords
- keywords = kwargs.get("keywords")
- # tag
- tag = kwargs.get("tag")
-
- query_args = []
- q = Q()
-
- for keyword in keywords:
- q = q | Q(title__icontains=keyword)
- q = q | Q(subtitle__icontains=keyword)
- q = q | Q(orig_title__icontains=keyword)
- if tag:
- q = q & Q(book_tags__content__iexact=tag)
-
- query_args.append(q)
- queryset = Book.objects.filter(*query_args).distinct()
-
- def calculate_similarity(book):
- if keywords:
- # search by keywords
- similarity, n = 0, 0
- for keyword in keywords:
- similarity += (
- 1
- / 2
- * SequenceMatcher(None, keyword, book.title).quick_ratio()
- )
- +1 / 3 * SequenceMatcher(
- None, keyword, book.orig_title
- ).quick_ratio()
- +1 / 6 * SequenceMatcher(
- None, keyword, book.subtitle
- ).quick_ratio()
- n += 1
- book.similarity = similarity / n
-
- elif tag:
- # search by single tag
- book.similarity = (
- 0 if book.rating_number is None else book.rating_number
- )
- else:
- book.similarity = 0
- return book.similarity
-
- if len(queryset) > 0:
- ordered_queryset = sorted(
- queryset, key=calculate_similarity, reverse=True
- )
- else:
- ordered_queryset = list(queryset)
- return ordered_queryset
-
- def movie_param_handler(**kwargs):
- # keywords
- keywords = kwargs.get("keywords")
- # tag
- tag = kwargs.get("tag")
-
- query_args = []
- q = Q()
-
- for keyword in keywords:
- q = q | Q(title__icontains=keyword)
- q = q | Q(other_title__icontains=keyword)
- q = q | Q(orig_title__icontains=keyword)
- if tag:
- q = q & Q(movie_tags__content__iexact=tag)
-
- query_args.append(q)
- queryset = Movie.objects.filter(*query_args).distinct()
-
- def calculate_similarity(movie):
- if keywords:
- # search by name
- similarity, n = 0, 0
- for keyword in keywords:
- similarity += (
- 1
- / 2
- * SequenceMatcher(None, keyword, movie.title).quick_ratio()
- )
- +1 / 4 * SequenceMatcher(
- None, keyword, movie.orig_title
- ).quick_ratio()
- +1 / 4 * SequenceMatcher(
- None, keyword, movie.other_title
- ).quick_ratio()
- n += 1
- movie.similarity = similarity / n
- elif tag:
- # search by single tag
- movie.similarity = (
- 0 if movie.rating_number is None else movie.rating_number
- )
- else:
- movie.similarity = 0
- return movie.similarity
-
- if len(queryset) > 0:
- ordered_queryset = sorted(
- queryset, key=calculate_similarity, reverse=True
- )
- else:
- ordered_queryset = list(queryset)
- return ordered_queryset
-
- def game_param_handler(**kwargs):
- # keywords
- keywords = kwargs.get("keywords")
- # tag
- tag = kwargs.get("tag")
-
- query_args = []
- q = Q()
-
- for keyword in keywords:
- q = q | Q(title__icontains=keyword)
- q = q | Q(other_title__icontains=keyword)
- q = q | Q(developer__icontains=keyword)
- q = q | Q(publisher__icontains=keyword)
- if tag:
- q = q & Q(game_tags__content__iexact=tag)
-
- query_args.append(q)
- queryset = Game.objects.filter(*query_args).distinct()
-
- def calculate_similarity(game):
- if keywords:
- # search by name
- developer_dump = " ".join(game.developer)
- publisher_dump = " ".join(game.publisher)
- similarity, n = 0, 0
- for keyword in keywords:
- similarity += (
- 1
- / 2
- * SequenceMatcher(None, keyword, game.title).quick_ratio()
- )
- +1 / 4 * SequenceMatcher(
- None, keyword, game.other_title
- ).quick_ratio()
- +1 / 16 * SequenceMatcher(
- None, keyword, developer_dump
- ).quick_ratio()
- +1 / 16 * SequenceMatcher(
- None, keyword, publisher_dump
- ).quick_ratio()
- n += 1
- game.similarity = similarity / n
- elif tag:
- # search by single tag
- game.similarity = (
- 0 if game.rating_number is None else game.rating_number
- )
- else:
- game.similarity = 0
- return game.similarity
-
- if len(queryset) > 0:
- ordered_queryset = sorted(
- queryset, key=calculate_similarity, reverse=True
- )
- else:
- ordered_queryset = list(queryset)
- return ordered_queryset
-
- def music_param_handler(**kwargs):
- # keywords
- keywords = kwargs.get("keywords")
- # tag
- tag = kwargs.get("tag")
-
- query_args = []
- q = Q()
-
- # search albums
- for keyword in keywords:
- q = q | Q(title__icontains=keyword)
- q = q | Q(artist__icontains=keyword)
- if tag:
- q = q & Q(album_tags__content__iexact=tag)
-
- query_args.append(q)
- album_queryset = Album.objects.filter(*query_args).distinct()
-
- # extra query args for songs
- q = Q()
- for keyword in keywords:
- q = q | Q(album__title__icontains=keyword)
- q = q | Q(title__icontains=keyword)
- q = q | Q(artist__icontains=keyword)
- if tag:
- q = q & Q(song_tags__content__iexact=tag)
- query_args.clear()
- query_args.append(q)
- song_queryset = Song.objects.filter(*query_args).distinct()
- queryset = list(album_queryset) + list(song_queryset)
-
- def calculate_similarity(music):
- if keywords:
- # search by name
- similarity, n = 0, 0
- artist_dump = " ".join(music.artist)
- for keyword in keywords:
- if music.__class__ == Album:
- similarity += (
- 1
- / 2
- * SequenceMatcher(
- None, keyword, music.title
- ).quick_ratio()
- + 1
- / 2
- * SequenceMatcher(
- None, keyword, artist_dump
- ).quick_ratio()
- )
- elif music.__class__ == Song:
- similarity += (
- 1
- / 2
- * SequenceMatcher(
- None, keyword, music.title
- ).quick_ratio()
- + 1
- / 6
- * SequenceMatcher(
- None, keyword, artist_dump
- ).quick_ratio()
- + 1
- / 6
- * (
- SequenceMatcher(
- None, keyword, music.album.title
- ).quick_ratio()
- if music.album is not None
- else 0
- )
- )
- n += 1
- music.similarity = similarity / n
- elif tag:
- # search by single tag
- music.similarity = (
- 0 if music.rating_number is None else music.rating_number
- )
- else:
- music.similarity = 0
- return music.similarity
-
- if len(queryset) > 0:
- ordered_queryset = sorted(
- queryset, key=calculate_similarity, reverse=True
- )
- else:
- ordered_queryset = list(queryset)
- return ordered_queryset
-
- def all_param_handler(**kwargs):
- book_queryset = book_param_handler(**kwargs)
- movie_queryset = movie_param_handler(**kwargs)
- music_queryset = music_param_handler(**kwargs)
- game_queryset = game_param_handler(**kwargs)
- ordered_queryset = sorted(
- book_queryset + movie_queryset + music_queryset + game_queryset,
- key=operator.attrgetter("similarity"),
- reverse=True,
- )
- return ordered_queryset
-
- param_handler = {
- "book": book_param_handler,
- "movie": movie_param_handler,
- "music": music_param_handler,
- "game": game_param_handler,
- "all": all_param_handler,
- "": all_param_handler,
- }
-
- categories = [k for k in param_handler.keys() if not k in ["all", ""]]
-
- try:
- queryset = param_handler[category](keywords=keywords, tag=tag)
- except KeyError as e:
- queryset = param_handler["all"](keywords=keywords, tag=tag)
- paginator = Paginator(queryset, ITEMS_PER_PAGE)
- page_number = request.GET.get("page", default=1)
- items = paginator.get_page(page_number)
- items.pagination = PageLinksGenerator(
- PAGE_LINK_NUMBER, page_number, paginator.num_pages
- )
- for item in items:
- item.tag_list = (
- item.get_tags_manager()
- .values("content")
- .annotate(tag_frequency=Count("content"))
- .order_by("-tag_frequency")[:TAG_NUMBER_ON_LIST]
- )
-
- return render(
- request,
- "common/search_result.html",
- {
- "items": items,
- "categories": categories,
- },
- )
-
- else:
- return HttpResponseBadRequest()
-
-
-@login_required
-@mastodon_request_included
-def jump_or_scrape(request, url):
- """
- 1. match url to registered scrapers
- 2. try to find the url in the db, if exits then jump, else scrape and jump
- """
-
- # redirect to this site
- this_site = request.get_host()
- if this_site in url:
- return redirect(url)
-
- url = get_normalized_url(url)
- scraper = get_scraper_by_url(url)
- if scraper is None:
- # invalid url
- return render(request, "common/error.html", {"msg": _("链接无效,查询失败")})
- else:
- try:
- effective_url = scraper.get_effective_url(url)
- except ValueError:
- return render(request, "common/error.html", {"msg": _("链接无效,查询失败")})
- try:
- # raise ObjectDoesNotExist
- entity = scraper.data_class.objects.get(source_url=effective_url)
- # if exists then jump to detail page
- if request.path.endswith(".json/"):
- return JsonResponse({"num_pages": 1, "items": [entity.get_json()]})
- return redirect(entity)
- except ObjectDoesNotExist:
- # scrape if not exists
- try:
- scraper.scrape(url)
- form = scraper.save(request_user=request.user)
- except IntegrityError as ie: # duplicate key on source_url may be caused by user's double submission
- try:
- entity = scraper.data_class.objects.get(source_url=effective_url)
- return redirect(entity)
- except Exception as e:
- logger.error(f"Scrape Failed URL: {url}\n{e}")
- if settings.DEBUG:
- logger.error(
- "Expections during saving scraped data:", exc_info=e
- )
- return render(request, "common/error.html", {"msg": _("爬取数据失败😫")})
- except Exception as e:
- logger.error(f"Scrape Failed URL: {url}\n{e}")
- if settings.DEBUG:
- logger.error("Expections during saving scraped data:", exc_info=e)
- return render(request, "common/error.html", {"msg": _("爬取数据失败😫")})
- return redirect(form.instance)
-
-
-def go_relogin(request):
- return render(
- request,
- "common/error.html",
- {
- "url": reverse("users:connect") + "?domain=" + request.user.mastodon_site,
- "msg": _("信息已保存,但是未能分享到联邦网络"),
- "secondary_msg": _(
- "可能是你在联邦网络(Mastodon/Pleroma/...)的登录状态过期了,正在跳转到联邦网络重新登录😼"
- ),
- },
- )
+ return redirect(reverse("social:feed"))
diff --git a/users/feeds.py b/journal/feeds.py
similarity index 50%
rename from users/feeds.py
rename to journal/feeds.py
index ec325249..3d68dfae 100644
--- a/users/feeds.py
+++ b/journal/feeds.py
@@ -1,11 +1,7 @@
from django.contrib.syndication.views import Feed
-from django.urls import reverse
-from books.models import BookReview
-from .models import User
from markdown import markdown
-import operator
import mimetypes
-
+from .models import *
MAX_ITEM_PER_TYPE = 10
@@ -24,33 +20,27 @@ class ReviewFeed(Feed):
return "%s的评论合集 - NeoDB" % user.display_name
def items(self, user):
- if user is None:
+ if user is None or user.preference.no_anonymous_view:
return None
- book_reviews = list(user.user_bookreviews.filter(visibility=0)[:MAX_ITEM_PER_TYPE])
- movie_reviews = list(user.user_moviereviews.filter(visibility=0)[:MAX_ITEM_PER_TYPE])
- album_reviews = list(user.user_albumreviews.filter(visibility=0)[:MAX_ITEM_PER_TYPE])
- game_reviews = list(user.user_gamereviews.filter(visibility=0)[:MAX_ITEM_PER_TYPE])
- all_reviews = sorted(
- book_reviews + movie_reviews + album_reviews + game_reviews,
- key=operator.attrgetter('created_time'),
- reverse=True
- )
- return all_reviews
+ reviews = Review.objects.filter(owner=user, visibility=0)[:MAX_ITEM_PER_TYPE]
+ return reviews
- def item_title(self, item):
+ def item_title(self, item: Review):
return f"{item.title} - 评论《{item.item.title}》"
- def item_description(self, item):
- target_html = f'
{item.item.title}
\n'
- html = markdown(item.content)
+ def item_description(self, item: Review):
+ target_html = (
+ f'
{item.item.title}
\n'
+ )
+ html = markdown(item.body)
return target_html + html
# item_link is only needed if NewsItem has no get_absolute_url method.
- def item_link(self, item):
- return item.url
+ def item_link(self, item: Review):
+ return item.absolute_url
def item_categories(self, item):
- return [item.item.verbose_category_name]
+ return [item.item.category.label]
def item_pubdate(self, item):
return item.created_time
@@ -66,7 +56,11 @@ class ReviewFeed(Feed):
return t
def item_enclosure_length(self, item):
- return item.item.cover.file.size
+ try:
+ size = item.item.cover.file.size
+ except Exception:
+ size = None
+ return size
def item_comments(self, item):
- return item.shared_link
+ return item.absolute_url
diff --git a/journal/models.py b/journal/models.py
index 44f651ec..e73fcfba 100644
--- a/journal/models.py
+++ b/journal/models.py
@@ -39,7 +39,7 @@ def q_visible_to(viewer, owner):
return Q()
# elif viewer.is_blocked_by(owner):
# return Q(pk__in=[])
- elif viewer.is_following(owner):
+ elif viewer.is_authenticated and viewer.is_following(owner):
return Q(visibility__ne=2)
else:
return Q(visibility=0)
@@ -48,7 +48,7 @@ def q_visible_to(viewer, owner):
def query_visible(user):
return (
Q(visibility=0)
- | Q(owner_id__in=user.following, visibility=1)
+ | Q(owner_id__in=user.following if user.is_authenticated else [], visibility=1)
| Q(owner_id=user.id)
)
@@ -927,3 +927,10 @@ def reset_visibility_for_user(user: User, visibility: int):
Comment.objects.filter(owner=user).update(visibility=visibility)
Rating.objects.filter(owner=user).update(visibility=visibility)
Review.objects.filter(owner=user).update(visibility=visibility)
+
+
+def remove_data_by_user(user: User):
+ ShelfMember.objects.filter(owner=user).delete()
+ Comment.objects.filter(owner=user).delete()
+ Rating.objects.filter(owner=user).delete()
+ Review.objects.filter(owner=user).delete()
diff --git a/journal/templates/collection.html b/journal/templates/collection.html
index 40c910e0..8083d891 100644
--- a/journal/templates/collection.html
+++ b/journal/templates/collection.html
@@ -47,7 +47,7 @@
+ {% if collection %}
+
+ {% endif %}
diff --git a/journal/templates/list_item_base.html b/journal/templates/list_item_base.html
index 3bc8c2c2..336a6da3 100644
--- a/journal/templates/list_item_base.html
+++ b/journal/templates/list_item_base.html
@@ -70,7 +70,7 @@
diff --git a/journal/templates/piece_delete.html b/journal/templates/piece_delete.html
index 188bcd28..4bb1eecd 100644
--- a/journal/templates/piece_delete.html
+++ b/journal/templates/piece_delete.html
@@ -37,7 +37,7 @@
{% endif %}
diff --git a/journal/templates/review.html b/journal/templates/review.html
index 561e6ffe..a3fa4dfb 100644
--- a/journal/templates/review.html
+++ b/journal/templates/review.html
@@ -42,7 +42,7 @@
-
-
-
-{% if unread_announcements %}
-{% include "partial/_announcement.html" %}
-{% endif %}
-
-