fix unicode site name; add isort; split journal and users models

This commit is contained in:
Your Name 2023-08-10 11:27:31 -04:00 committed by Henri Dickson
parent 4e7583d6f1
commit 22640a74ab
163 changed files with 2318 additions and 1918 deletions

View file

@ -12,8 +12,13 @@ repos:
language_version: python3.11
repos:
- repo: https://github.com/Riverside-Healthcare/djLint
rev: v1.30.2
rev: v1.32.1
hooks:
- id: djlint-reformat-django
- id: djlint-django
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
args: ["--profile=black"]

View file

@ -1,5 +1,7 @@
import os
NEODB_VERSION = "0.8"
PROJECT_ROOT = os.path.abspath(os.path.dirname(__name__))
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)

View file

@ -13,13 +13,14 @@ Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from users.views import login
from common.api import api
from django.contrib import admin
from django.urls import include, path
from django.views.generic import RedirectView
from common.api import api
from users.views import login
urlpatterns = [
path("api/", api.urls), # type: ignore
path("login/", login),

View file

@ -1,12 +1,13 @@
from django.http import Http404, HttpResponse
from django.utils.translation import gettext_lazy as _
from django.http import HttpResponse
from django.http import Http404
from ninja import Schema
from common.api import *
from .models import *
from .common import *
from .models import *
from .search.models import enqueue_fetch, get_fetch_lock, query_index
from .sites import *
from .search.models import enqueue_fetch, query_index, get_fetch_lock
class SearchResult(Schema):

View file

@ -7,11 +7,9 @@ class CatalogConfig(AppConfig):
def ready(self):
# load key modules in proper order, make sure class inject and signal works as expected
from catalog import models
from catalog import sites
from catalog import api, models, sites
from catalog.models import init_catalog_audit_log, init_catalog_search_models
from journal import models as journal_models
from catalog.models import init_catalog_search_models, init_catalog_audit_log
from catalog import api
init_catalog_search_models()
init_catalog_audit_log()

View file

@ -20,7 +20,9 @@ work data seems asymmetric (a book links to a work, but may not listed in that w
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.utils.translation import gettext_lazy as _
from catalog.common.models import *
from .utils import *

View file

@ -1,4 +1,5 @@
from django.test import TestCase
from catalog.book.models import *
from catalog.book.utils import *
from catalog.common import *

View file

@ -1,4 +1,5 @@
import re
from .models import IdType

View file

@ -1,9 +1,8 @@
from .models import *
from .sites import *
from .downloaders import *
from .scrapers import *
from . import jsondata
from .downloaders import *
from .models import *
from .scrapers import *
from .sites import *
__all__ = (
"IdType",

View file

@ -1,18 +1,18 @@
import requests
import filetype
from PIL import Image
from io import BytesIO
from requests.exceptions import RequestException
from django.conf import settings
from pathlib import Path
import json
from io import StringIO
import logging
import re
import time
import logging
from lxml import html
from io import BytesIO, StringIO
from pathlib import Path
from urllib.parse import quote
import filetype
import requests
from django.conf import settings
from lxml import html
from PIL import Image
from requests.exceptions import RequestException
_logger = logging.getLogger(__name__)

View file

@ -1,22 +1,20 @@
import copy
from datetime import date, datetime
from importlib import import_module
from functools import partialmethod
from django.utils.translation import gettext_lazy as _
from importlib import import_module
import django
from django.core.exceptions import FieldError
from django.db.models import fields
from django.utils import dateparse, timezone
# from django.contrib.postgres.fields import ArrayField as DJANGO_ArrayField
from django_jsonform.models.fields import ArrayField as DJANGO_ArrayField
from django.utils.translation import gettext_lazy as _
# from django.db.models import JSONField as DJANGO_JSONField
# from jsoneditor.fields.django3_jsonfield import JSONField as DJANGO_JSONField
# from django.contrib.postgres.fields import ArrayField as DJANGO_ArrayField
from django_jsonform.models.fields import ArrayField as DJANGO_ArrayField
from django_jsonform.models.fields import JSONField as DJANGO_JSONField
__all__ = (
"BooleanField",
"CharField",

View file

@ -1,29 +1,32 @@
from functools import cached_property
from polymorphic.models import PolymorphicModel
from django.db import models
import logging
import re
from catalog.common import jsondata
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from django.core.files.uploadedfile import SimpleUploadedFile
from django.contrib.contenttypes.models import ContentType
from django.utils.baseconv import base62
import uuid
from functools import cached_property
from typing import cast
from .utils import DEFAULT_ITEM_COVER, item_cover_path, resource_cover_path
from .mixins import SoftDeleteMixin
from django.conf import settings
from users.models import User
from django.db import connection
from ninja import Schema
from auditlog.context import disable_auditlog
from auditlog.models import LogEntry, AuditlogHistoryField
from auditlog.models import AuditlogHistoryField, LogEntry
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.files.uploadedfile import SimpleUploadedFile
from django.db import connection, models
from django.utils import timezone
from django.utils.baseconv import base62
from django.utils.translation import gettext_lazy as _
from ninja import Schema
from polymorphic.models import PolymorphicModel
from catalog.common import jsondata
from users.models import User
from .mixins import SoftDeleteMixin
from .utils import DEFAULT_ITEM_COVER, item_cover_path, resource_cover_path
_logger = logging.getLogger(__name__)
class SiteName(models.TextChoices):
Unknown = "unknown", _("未知站点")
Douban = "douban", _("豆瓣")
Goodreads = "goodreads", _("Goodreads")
GoogleBooks = "googlebooks", _("谷歌图书")
@ -482,6 +485,35 @@ class Item(SoftDeleteMixin, PolymorphicModel):
def editable(self):
return not self.is_deleted and self.merged_to_item is None
@property
def rating(self):
from journal.models import Rating
return Rating.get_rating_for_item(self)
@property
def rating_count(self):
from journal.models import Rating
return Rating.get_rating_count_for_item(self)
@property
def rating_dist(self):
from journal.models import Rating
return Rating.get_rating_distribution_for_item(self)
@property
def tags(self):
from journal.models import TagManager
return TagManager.indexable_tags_for_item(self)
def journal_exists(self):
from journal.models import journal_exists_for_item
return journal_exists_for_item(self)
class ItemLookupId(models.Model):
item = models.ForeignKey(
@ -542,12 +574,17 @@ class ExternalResource(models.Model):
self.save()
def get_site(self):
"""place holder only, this will be injected from SiteManager"""
pass
from .sites import SiteManager
return SiteManager.get_site_cls_by_id_type(self.id_type)
@property
def site_name(self):
return getattr(self.get_site(), "SITE_NAME")
try:
return self.get_site().SITE_NAME
except:
_logger.warning(f"Unknown site for {self}")
return SiteName.Unknown
def update_content(self, resource_content):
self.other_lookup_ids = resource_content.lookup_ids

View file

@ -6,14 +6,15 @@ a Site should map to a unique set of url patterns.
a Site may scrape a url and store result in ResourceContent
ResourceContent persists as an ExternalResource which may link to an Item
"""
from typing import Callable
import re
from .models import ExternalResource, IdType, IdealIdTypes, Item
from dataclasses import dataclass, field
import logging
import json
import logging
import re
from dataclasses import dataclass, field
from typing import Callable
import django_rq
from .models import ExternalResource, IdealIdTypes, IdType, Item
_logger = logging.getLogger(__name__)
@ -297,11 +298,6 @@ class SiteManager:
return SiteManager.register.values()
ExternalResource.get_site = lambda resource: SiteManager.get_site_cls_by_id_type(
resource.id_type
) # type: ignore
def crawl_related_resources_task(resource_pk):
resource = ExternalResource.objects.filter(pk=resource_pk).first()
if not resource:

View file

@ -1,7 +1,7 @@
import logging
from django.utils import timezone
import uuid
from django.utils import timezone
_logger = logging.getLogger(__name__)

View file

@ -1,9 +1,9 @@
from django import forms
from django.utils.translation import gettext_lazy as _
from catalog.models import *
from common.forms import PreviewImageInput
CatalogForms = {}

View file

@ -1,7 +1,9 @@
from datetime import date
from catalog.common.models import *
from django.utils.translation import gettext_lazy as _
from django.db import models
from django.utils.translation import gettext_lazy as _
from catalog.common.models import *
class GameInSchema(ItemInSchema):

View file

@ -1,4 +1,5 @@
from django.test import TestCase
from catalog.common import *
from catalog.models import *

View file

@ -1,5 +1,7 @@
from django.core.management.base import BaseCommand
import pprint
from django.core.management.base import BaseCommand
from catalog.common import SiteManager
from catalog.sites import *

View file

@ -1,6 +1,8 @@
import pprint
from django.core.management.base import BaseCommand
from django.db.models import Count, F
import pprint
from catalog.models import *
from journal.models import update_journal_for_merged_item

View file

@ -1,9 +1,11 @@
from django.core.management.base import BaseCommand
from catalog.common import *
import re
from urllib.parse import urljoin
from django.core.management.base import BaseCommand
from loguru import logger
from catalog.common import *
class Command(BaseCommand):
help = "Crawl content"

View file

@ -1,12 +1,14 @@
from django.core.management.base import BaseCommand
from django.core.cache import cache
from catalog.models import *
from journal.models import ShelfMember, query_item_category, ItemCategory, Comment
from datetime import timedelta
from django.utils import timezone
from django.core.cache import cache
from django.core.management.base import BaseCommand
from django.db.models import Count, F
from django.utils import timezone
from loguru import logger
from catalog.models import *
from journal.models import Comment, ItemCategory, ShelfMember, query_item_category
MAX_ITEMS_PER_PERIOD = 12
MIN_MARKS = 2
MAX_DAYS_FOR_PERIOD = 96

View file

@ -1,12 +1,14 @@
from django.core.management.base import BaseCommand
from django.conf import settings
from catalog.models import *
import pprint
from django.core.paginator import Paginator
from tqdm import tqdm
from time import sleep
from datetime import timedelta
from time import sleep
from django.conf import settings
from django.core.management.base import BaseCommand
from django.core.paginator import Paginator
from django.utils import timezone
from tqdm import tqdm
from catalog.models import *
BATCH_SIZE = 1000

View file

@ -1,15 +1,17 @@
from django.core.management.base import BaseCommand
import pprint
from datetime import timedelta
from time import sleep
from django.conf import settings
from django.core.management.base import BaseCommand
from django.core.paginator import Paginator
from django.utils import timezone
from loguru import logger
from tqdm import tqdm
from catalog.common.models import IdType
from catalog.models import *
from catalog.sites import RSS
import pprint
from django.core.paginator import Paginator
from tqdm import tqdm
from time import sleep
from datetime import timedelta
from django.utils import timezone
from loguru import logger
class Command(BaseCommand):

View file

@ -1,11 +1,13 @@
# Generated by Django 3.2.16 on 2023-01-12 01:32
import uuid
import django.db.models.deletion
import simple_history.models
from django.db import migrations, models
import catalog.common.mixins
import catalog.common.utils
from django.db import migrations, models
import django.db.models.deletion
import simple_history.models
import uuid
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 3.2.16 on 2023-01-12 01:32
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2.16 on 2023-02-02 03:47
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2.16 on 2023-02-03 21:58
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2.19 on 2023-06-05 02:31
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 4.2.3 on 2023-07-06 22:53
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,37 +1,41 @@
import logging
from auditlog.registry import auditlog
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from .book.models import Edition, EditionInSchema, EditionSchema, Series, Work
from .collection.models import Collection as CatalogCollection
from .common.models import (
ExternalResource,
Item,
ItemCategory,
ItemSchema,
item_content_types,
item_categories,
item_content_types,
)
from .book.models import Edition, Work, Series, EditionSchema, EditionInSchema
from .movie.models import Movie, MovieSchema, MovieInSchema
from .tv.models import (
TVShow,
TVSeason,
TVEpisode,
TVShowSchema,
TVShowInSchema,
TVSeasonSchema,
TVSeasonInSchema,
TVEpisodeSchema,
)
from .music.models import Album, AlbumSchema, AlbumInSchema
from .game.models import Game, GameSchema, GameInSchema
from .podcast.models import Podcast, PodcastSchema, PodcastInSchema, PodcastEpisode
from .game.models import Game, GameInSchema, GameSchema
from .movie.models import Movie, MovieInSchema, MovieSchema
from .music.models import Album, AlbumInSchema, AlbumSchema
from .performance.models import (
Performance,
PerformanceProduction,
PerformanceSchema,
PerformanceProductionSchema,
PerformanceSchema,
)
from .collection.models import Collection as CatalogCollection
from .search.models import Indexer
from django.contrib.contenttypes.models import ContentType
from django.conf import settings
import logging
from auditlog.registry import auditlog
from .podcast.models import Podcast, PodcastEpisode, PodcastInSchema, PodcastSchema
from .tv.models import (
TVEpisode,
TVEpisodeSchema,
TVSeason,
TVSeasonInSchema,
TVSeasonSchema,
TVShow,
TVShowInSchema,
TVShowSchema,
)
from .search.models import Indexer # isort:skip
_logger = logging.getLogger(__name__)

View file

@ -1,6 +1,7 @@
from catalog.common.models import *
from django.utils.translation import gettext_lazy as _
from django.db import models
from django.utils.translation import gettext_lazy as _
from catalog.common.models import *
class MovieInSchema(ItemInSchema):

View file

@ -1,4 +1,5 @@
from django.test import TestCase
from catalog.common import *

View file

@ -1,7 +1,9 @@
from datetime import date
from catalog.common.models import *
from django.utils.translation import gettext_lazy as _
from django.db import models
from django.utils.translation import gettext_lazy as _
from catalog.common.models import *
class AlbumInSchema(ItemInSchema):

View file

@ -1,4 +1,5 @@
from django.test import TestCase
from catalog.common import *
from catalog.models import *
from catalog.music.utils import *

View file

@ -1,10 +1,12 @@
from functools import cached_property
from django.utils.translation import gettext_lazy as _
from django.db import models
from django.utils.translation import gettext_lazy as _
from ninja import Schema
from catalog.common import *
from catalog.common.models import ItemSchema
from catalog.common.utils import DEFAULT_ITEM_COVER
from ninja import Schema
class CrewMemberSchema(Schema):

View file

@ -1,7 +1,8 @@
from catalog.common.models import *
from django.db import models
from django.utils.translation import gettext_lazy as _
from catalog.common.models import *
class PodcastInSchema(ItemInSchema):
genre: list[str]

View file

@ -1,7 +1,7 @@
from django.test import TestCase
from catalog.podcast.models import *
from catalog.common import *
from catalog.common import *
from catalog.podcast.models import *
# class ApplePodcastTestCase(TestCase):
# def setUp(self):

View file

@ -1,11 +1,13 @@
import logging
from urllib.parse import quote_plus
import requests
from django.conf import settings
from lxml import html
from catalog.common import *
from catalog.models import *
from catalog.sites.spotify import get_spotify_token
import requests
from lxml import html
import logging
SEARCH_PAGE_SIZE = 5 # not all apis support page size
logger = logging.getLogger(__name__)

View file

@ -1,15 +1,17 @@
import logging
from django.utils.translation import gettext_lazy as _
from catalog.common.sites import SiteManager
from ..models import TVSeason, Item
from django.conf import settings
import django_rq
from rq.job import Job
from django.core.cache import cache
import hashlib
from .typesense import Indexer as TypeSenseIndexer
import logging
import django_rq
from auditlog.context import set_actor
from django.conf import settings
from django.core.cache import cache
from django.utils.translation import gettext_lazy as _
from rq.job import Job
from catalog.common.sites import SiteManager
from ..models import Item, TVSeason
from .typesense import Indexer as TypeSenseIndexer
# from .meilisearch import Indexer as MeiliSearchIndexer

View file

@ -1,16 +1,18 @@
from datetime import timedelta
import types
import logging
import typesense
from typesense.exceptions import ObjectNotFound
from typesense.collection import Collection
from django.conf import settings
from django.db.models.signals import post_save, post_delete
from catalog.models import Item
import types
from datetime import timedelta
from pprint import pprint
import django_rq
from rq.job import Job
import typesense
from django.conf import settings
from django.db.models.signals import post_delete, post_save
from django_redis import get_redis_connection
from rq.job import Job
from typesense.collection import Collection
from typesense.exceptions import ObjectNotFound
from catalog.models import Item
INDEX_NAME = "catalog"
SEARCHABLE_ATTRIBUTES = [

View file

@ -1,22 +1,21 @@
from ..common.sites import SiteManager
from .apple_music import AppleMusic
from .bandcamp import Bandcamp
from .bangumi import Bangumi
from .bookstw import BooksTW
from .discogs import DiscogsMaster, DiscogsRelease
from .douban_book import DoubanBook
from .douban_drama import DoubanDrama
from .douban_game import DoubanGame
from .douban_movie import DoubanMovie
from .douban_music import DoubanMusic
from .goodreads import Goodreads
from .google_books import GoogleBooks
from .igdb import IGDB
from .imdb import IMDB
# from .apple_podcast import ApplePodcast
from .rss import RSS
from .douban_book import DoubanBook
from .douban_movie import DoubanMovie
from .douban_music import DoubanMusic
from .douban_game import DoubanGame
from .douban_drama import DoubanDrama
from .goodreads import Goodreads
from .google_books import GoogleBooks
from .tmdb import TMDB_Movie
from .imdb import IMDB
from .spotify import Spotify
from .igdb import IGDB
from .steam import Steam
from .bandcamp import Bandcamp
from .bangumi import Bangumi
from .discogs import DiscogsRelease
from .discogs import DiscogsMaster
from .bookstw import BooksTW
from .apple_music import AppleMusic
from .tmdb import TMDB_Movie

View file

@ -1,6 +1,8 @@
import logging
from catalog.common import *
from catalog.models import *
import logging
from .rss import RSS
_logger = logging.getLogger(__name__)

View file

@ -1,11 +1,12 @@
import json
import logging
import re
import urllib.parse
import dateparser
from catalog.common import *
from catalog.models import *
import logging
import urllib.parse
import dateparser
import re
import json
_logger = logging.getLogger(__name__)

View file

@ -1,7 +1,7 @@
from catalog.common import *
from catalog.models import *
import logging
from catalog.common import *
from catalog.models import *
_logger = logging.getLogger(__name__)

View file

@ -1,9 +1,10 @@
from catalog.common import *
from catalog.book.models import *
from catalog.book.utils import *
from .douban import *
import logging
from catalog.book.models import *
from catalog.book.utils import *
from catalog.common import *
from .douban import *
_logger = logging.getLogger(__name__)

View file

@ -1,15 +1,17 @@
"""
Discogs.
"""
import json
import logging
import requests
from django.conf import settings
from catalog.common import *
from catalog.models import *
from catalog.music.utils import upc_to_gtin_13
from .douban import *
import json
import logging
import requests
from .douban import *
_logger = logging.getLogger(__name__)

View file

@ -1,6 +1,6 @@
import re
from catalog.common import *
from catalog.common import *
RE_NUMBERS = re.compile(r"\d+\d*")
RE_WHITESPACES = re.compile(r"\s+")

View file

@ -1,12 +1,13 @@
from django.utils.timezone import make_aware
from datetime import datetime
from catalog.book.models import Edition, Work
from catalog.common import *
from catalog.book.utils import detect_isbn_asin
from lxml import html
import json
import logging
from datetime import datetime
from django.utils.timezone import make_aware
from lxml import html
from catalog.book.models import Edition, Work
from catalog.book.utils import detect_isbn_asin
from catalog.common import *
_logger = logging.getLogger(__name__)

View file

@ -1,8 +1,8 @@
import logging
import re
from catalog.common import *
from catalog.models import *
import re
import logging
_logger = logging.getLogger(__name__)

View file

@ -4,15 +4,16 @@ IGDB
use (e.g. "portal-2") as id, which is different from real id in IGDB API
"""
from catalog.common import *
from catalog.models import *
from django.conf import settings
from igdb.wrapper import IGDBWrapper
import requests
import datetime
import json
import logging
import requests
from django.conf import settings
from igdb.wrapper import IGDBWrapper
from catalog.common import *
from catalog.models import *
_logger = logging.getLogger(__name__)

View file

@ -1,10 +1,11 @@
import json
from catalog.common import *
from .tmdb import search_tmdb_by_imdb_id
from catalog.movie.models import *
from catalog.tv.models import *
import logging
from catalog.common import *
from catalog.movie.models import *
from catalog.tv.models import *
from .tmdb import search_tmdb_by_imdb_id
_logger = logging.getLogger(__name__)

View file

@ -1,21 +1,23 @@
from catalog.common import *
from catalog.models import *
import logging
import podcastparser
import pickle
import urllib.request
from django.core.cache import cache
from catalog.podcast.models import PodcastEpisode
from datetime import datetime
from django.utils.timezone import make_aware
import bleach
from django.core.validators import URLValidator
import podcastparser
from django.core.cache import cache
from django.core.exceptions import ValidationError
from django.core.validators import URLValidator
from django.utils.timezone import make_aware
from catalog.common import *
from catalog.common.downloaders import (
_local_response_path,
get_mock_file,
get_mock_mode,
_local_response_path,
)
import pickle
from catalog.models import *
from catalog.podcast.models import PodcastEpisode
_logger = logging.getLogger(__name__)

View file

@ -1,17 +1,19 @@
"""
Spotify
"""
import datetime
import logging
import time
import dateparser
import requests
from django.conf import settings
from catalog.common import *
from catalog.models import *
from catalog.music.utils import upc_to_gtin_13
from .douban import *
import time
import datetime
import requests
import dateparser
import logging
from .douban import *
_logger = logging.getLogger(__name__)

View file

@ -1,9 +1,11 @@
from catalog.common import *
from catalog.models import *
from .igdb import search_igdb_by_3p_url
import dateparser
import logging
import dateparser
from catalog.common import *
from catalog.models import *
from .igdb import search_igdb_by_3p_url
_logger = logging.getLogger(__name__)

View file

@ -2,14 +2,16 @@
The Movie Database
"""
import logging
import re
from django.conf import settings
from catalog.common import *
from .douban import *
from catalog.movie.models import *
from catalog.tv.models import *
import logging
from .douban import *
_logger = logging.getLogger(__name__)

View file

@ -1,10 +1,11 @@
from django.test import TestCase
from catalog.book.tests import *
from catalog.movie.tests import *
from catalog.tv.tests import *
from catalog.music.tests import *
from catalog.game.tests import *
from catalog.podcast.tests import *
from catalog.movie.tests import *
from catalog.music.tests import *
from catalog.performance.tests import *
from catalog.podcast.tests import *
from catalog.tv.tests import *
# imported tests with same name might be ignored silently

View file

@ -25,10 +25,12 @@ For now, we follow Douban convention, but keep an eye on it in case it breaks it
"""
from functools import cached_property
from catalog.common.models import *
from django.db import models
from django.utils.translation import gettext_lazy as _
from catalog.common.models import *
class TVShowInSchema(ItemInSchema):
season_count: int | None = None

View file

@ -1,7 +1,8 @@
from django.test import TestCase
from catalog.common import *
from catalog.tv.models import *
from catalog.sites.imdb import IMDB
from catalog.tv.models import *
class JSONFieldTestCase(TestCase):

View file

@ -1,6 +1,7 @@
from django.urls import path, re_path
from .views import *
from .models import *
from .views import *
app_name = "catalog"

View file

@ -1,24 +1,32 @@
import logging
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required, permission_required
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import BadRequest, PermissionDenied, ObjectDoesNotExist
from django.db.models import Count
from django.core.paginator import Paginator
from .models import *
from django.views.decorators.clickjacking import xframe_options_exempt
from journal.models import Mark, ShelfMember, Review, Comment, query_item_category
from journal.models import (
query_visible,
query_following,
)
from common.utils import PageLinksGenerator, get_uuid_or_404
from common.config import PAGE_LINK_NUMBER
from journal.models import ShelfTypeNames, ShelfType, ItemCategory
from .forms import *
from .search.views import *
from django.http import Http404
from django.core.cache import cache
from django.core.exceptions import BadRequest, ObjectDoesNotExist, PermissionDenied
from django.core.paginator import Paginator
from django.db.models import Count
from django.http import Http404
from django.shortcuts import get_object_or_404, redirect, render
from django.utils.translation import gettext_lazy as _
from django.views.decorators.clickjacking import xframe_options_exempt
from common.config import PAGE_LINK_NUMBER
from common.utils import PageLinksGenerator, get_uuid_or_404
from journal.models import (
Comment,
Mark,
Review,
ShelfMember,
ShelfType,
ShelfTypeNames,
query_following,
query_item_category,
query_visible,
)
from .forms import *
from .models import *
from .search.views import *
from .views_edit import *
_logger = logging.getLogger(__name__)
@ -205,7 +213,8 @@ def comments_by_episode(request, item_path, item_uuid):
raise Http404()
episode_uuid = request.GET.get("episode_uuid")
if episode_uuid:
ids = [TVEpisode.get_by_url(episode_uuid).id]
episode = TVEpisode.get_by_url(episode_uuid)
ids = [episode.pk] if episode else []
else:
ids = item.child_item_ids
queryset = Comment.objects.filter(item_id__in=ids).order_by("-created_time")
@ -250,7 +259,7 @@ def discover(request):
raise BadRequest()
user = request.user
if user.is_authenticated:
layout = user.get_preference().discover_layout
layout = user.preference.discover_layout
else:
layout = []

View file

@ -1,19 +1,22 @@
import logging
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required, permission_required
from django.utils.translation import gettext_lazy as _
from django.http import HttpResponseRedirect
from django.core.exceptions import BadRequest, PermissionDenied, ObjectDoesNotExist
from django.utils import timezone
from django.contrib import messages
from .common.models import ExternalResource, IdType, IdealIdTypes
from .sites.imdb import IMDB
from .models import *
from .forms import *
from .search.views import *
from journal.models import update_journal_for_merged_item
from common.utils import get_uuid_or_404
from auditlog.context import set_actor
from django.contrib import messages
from django.contrib.auth.decorators import login_required, permission_required
from django.core.exceptions import BadRequest, ObjectDoesNotExist, PermissionDenied
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from common.utils import get_uuid_or_404
from journal.models import update_journal_for_merged_item
from .common.models import ExternalResource, IdealIdTypes, IdType
from .forms import *
from .models import *
from .search.views import *
from .sites.imdb import IMDB
_logger = logging.getLogger(__name__)

View file

@ -1,13 +1,14 @@
from ninja import NinjaAPI, Schema
from django.conf import settings
import logging
from typing import Any, Callable, List, Optional, Tuple, Type
from ninja.pagination import PageNumberPagination as NinjaPageNumberPagination
from django.conf import settings
from django.db.models import QuerySet
from ninja import NinjaAPI, Schema
from ninja.pagination import PageNumberPagination as NinjaPageNumberPagination
from ninja.security import HttpBearer
from oauthlib.oauth2 import Server
from oauth2_provider.oauth2_backends import OAuthLibCore
from oauth2_provider.oauth2_validators import OAuth2Validator
import logging
from oauthlib.oauth2 import Server
_logger = logging.getLogger(__name__)

View file

@ -1,11 +1,12 @@
from django import forms
from markdownx.fields import MarkdownxFormField
import django.contrib.postgres.forms as postgres
from django.utils import formats
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
import json
import django.contrib.postgres.forms as postgres
from django import forms
from django.core.exceptions import ValidationError
from django.utils import formats
from django.utils.translation import gettext_lazy as _
from markdownx.fields import MarkdownxFormField
class PreviewImageInput(forms.FileInput):
template_name = "widgets/image.html"

View file

@ -1,8 +1,9 @@
from django.core.management.base import BaseCommand
import pprint
from django.core.management.base import BaseCommand
from redis import Redis
from rq.job import Job
from rq import Queue
from rq.job import Job
class Command(BaseCommand):

View file

@ -1,8 +1,9 @@
from django.core.management.base import BaseCommand
import pprint
from django.core.management.base import BaseCommand
from redis import Redis
from rq.job import Job
from rq import Queue
from rq.job import Job
class Command(BaseCommand):

View file

@ -2,7 +2,6 @@ from django import template
from django.conf import settings
from django.utils.html import format_html
register = template.Library()

View file

@ -1,7 +1,8 @@
from django import template
from django.template.defaultfilters import stringfilter
from django.utils.text import Truncator
from django.utils.safestring import mark_safe
from django.utils.text import Truncator
from catalog.common.models import ItemCategory, item_categories
from catalog.search.views import visible_categories as _visible_categories

View file

@ -1,9 +1,10 @@
from django import template
from django.utils.safestring import mark_safe
from django.template.defaultfilters import stringfilter
from opencc import OpenCC
import re
from django import template
from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe
from opencc import OpenCC
cc = OpenCC("t2s")
register = template.Library()

View file

@ -3,7 +3,6 @@ from django.conf import settings
from django.template.defaultfilters import stringfilter
from django.utils.translation import gettext_lazy as _
register = template.Library()

View file

@ -1,7 +1,6 @@
from django import template
from django.utils import timezone
register = template.Library()

View file

@ -2,7 +2,6 @@ from django import template
from django.template.defaultfilters import stringfilter
from django.utils.text import Truncator
register = template.Library()

View file

@ -1,4 +1,5 @@
from django.urls import path
from .views import *
app_name = "common"

View file

@ -1,4 +1,5 @@
import uuid
from django.http import Http404
from django.utils import timezone
from django.utils.baseconv import base62

View file

@ -1,7 +1,7 @@
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect, render
from django.urls import reverse
from django.contrib.auth.decorators import login_required
@login_required
@ -11,7 +11,7 @@ def me(request):
def home(request):
if request.user.is_authenticated:
home = request.user.get_preference().classic_homepage
home = request.user.preference.classic_homepage
if home == 1:
return redirect(request.user.url)
elif home == 2:

View file

@ -1,12 +1,12 @@
# Generated by Django 3.2.19 on 2023-06-28 05:09
from django.conf import settings
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import markdownx.models
import oauth2_provider.generators
import oauth2_provider.models
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 4.2.3 on 2023-07-06 22:53
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,9 +1,10 @@
from django.db import models
from django.core.validators import RegexValidator
from django.db import models
from django.utils.translation import gettext_lazy as _
from oauth2_provider.models import AbstractApplication
from markdownx.models import MarkdownxField
from journal.renderers import render_md
from oauth2_provider.models import AbstractApplication
from journal.models.renderers import render_md
class Application(AbstractApplication):

View file

@ -1,10 +1,10 @@
from django.urls import path, re_path, include
from django.contrib import admin
from django.contrib.auth import views as auth_views
from django.urls import include, path, re_path
from oauth2_provider import views as oauth2_views
from oauth2_provider.views import oidc as oidc_views
from .views import *
from .views import *
_urlpatterns = [
re_path(

View file

@ -1,23 +1,22 @@
from django.shortcuts import render
from loguru import logger
from dateutil.relativedelta import relativedelta
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.forms.models import modelform_factory
from django.shortcuts import render
from django.urls import reverse
from django.utils import timezone
from loguru import logger
from oauth2_provider.forms import AllowForm
from oauth2_provider.models import get_application_model
from oauth2_provider.generators import generate_client_id, generate_client_secret
from oauth2_provider.models import AccessToken, RefreshToken, get_application_model
from oauth2_provider.settings import oauth2_settings
from oauth2_provider.views import ApplicationRegistration as BaseApplicationRegistration
from oauth2_provider.views import ApplicationUpdate as BaseApplicationUpdate
from oauth2_provider.views.base import AuthorizationView as BaseAuthorizationView
from oauth2_provider.settings import oauth2_settings
from oauth2_provider.generators import generate_client_id, generate_client_secret
from common.api import api
from oauthlib.common import generate_token
from oauth2_provider.models import AccessToken
from django.utils import timezone
from dateutil.relativedelta import relativedelta
from oauth2_provider.models import RefreshToken
from django.conf import settings
from .models import Application
from django.forms.models import modelform_factory
from common.api import api
from .models import Application

View file

@ -1,15 +1,17 @@
from .models import *
from ninja import Schema
from common.api import *
from oauth2_provider.decorators import protected_resource
from ninja.security import django_auth
from django.contrib.auth.decorators import login_required
from catalog.common.models import *
from typing import List
from ninja.pagination import paginate
from ninja import Field
from datetime import datetime
from typing import List
from django.contrib.auth.decorators import login_required
from django.utils import timezone
from ninja import Field, Schema
from ninja.pagination import paginate
from ninja.security import django_auth
from oauth2_provider.decorators import protected_resource
from catalog.common.models import *
from common.api import *
from .models import *
class MarkSchema(Schema):

View file

@ -7,9 +7,10 @@ class JournalConfig(AppConfig):
def ready(self):
# load key modules in proper order, make sure class inject and signal works as expected
from . import api
from .models import Tag, Rating
from catalog.models import Indexer
from . import api
from .models import Rating, Tag
Indexer.register_list_model(Tag)
Indexer.register_piece_model(Rating)

View file

@ -1,10 +1,12 @@
from django.utils.translation import gettext_lazy as _
import os
from datetime import datetime
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from openpyxl import Workbook
from catalog.common.models import IdType
from common.utils import GenerateDateUUIDMediaFilePath
from datetime import datetime
import os
from journal.models import *

View file

@ -1,8 +1,11 @@
from django.contrib.syndication.views import Feed
from journal.renderers import render_md
import mimetypes
from .models import *
from django.conf import settings
from django.contrib.syndication.views import Feed
from journal.models.renderers import render_md
from .models import *
MAX_ITEM_PER_TYPE = 10

View file

@ -1,9 +1,11 @@
from django import forms
from markdownx.fields import MarkdownxFormField
from django.utils.translation import gettext_lazy as _
from .models import *
from markdownx.fields import MarkdownxFormField
from common.forms import PreviewImageInput
from .models import *
class ReviewForm(forms.ModelForm):
class Meta:

View file

@ -1,18 +1,21 @@
import openpyxl
import re
from markdownify import markdownify as md
from datetime import datetime
import logging
import pytz
from django.conf import settings
from user_messages import api as msg
import django_rq
from common.utils import GenerateDateUUIDMediaFilePath
import os
import re
from datetime import datetime
import django_rq
import openpyxl
import pytz
from auditlog.context import set_actor
from django.conf import settings
from markdownify import markdownify as md
from user_messages import api as msg
from catalog.common import *
from catalog.common.downloaders import *
from catalog.models import *
from catalog.sites.douban import DoubanDownloader
from common.utils import GenerateDateUUIDMediaFilePath
from journal.models import *
_logger = logging.getLogger(__name__)

View file

@ -1,14 +1,15 @@
import re
from datetime import datetime
from user_messages import api as msg
import django_rq
from django.utils.timezone import make_aware
from auditlog.context import set_actor
from django.utils.timezone import make_aware
from user_messages import api as msg
from catalog.common import *
from catalog.common.downloaders import *
from catalog.models import *
from journal.models import *
from catalog.common.downloaders import *
re_list = r"^https://www.goodreads.com/list/show/\d+"
re_shelf = r"^https://www.goodreads.com/review/list/\d+[^?]*\?shelf=[^&]+"

View file

@ -1,19 +1,21 @@
from django.core.files import uploadedfile
import listparser
from catalog.sites.rss import RSS
import openpyxl
import re
from markdownify import markdownify as md
from datetime import datetime
import logging
import os
import re
from datetime import datetime
import django_rq
import listparser
import openpyxl
import pytz
from django.conf import settings
from django.core.files import uploadedfile
from markdownify import markdownify as md
from user_messages import api as msg
import django_rq
from common.utils import GenerateDateUUIDMediaFilePath
import os
from catalog.common import *
from catalog.common.downloaders import *
from catalog.sites.rss import RSS
from common.utils import GenerateDateUUIDMediaFilePath
from journal.models import *

View file

@ -1,7 +1,9 @@
from django.core.management.base import BaseCommand
import pprint
from journal.models import *
from django.core.management.base import BaseCommand
from journal.importers.douban import DoubanImporter
from journal.models import *
from users.models import User

View file

@ -1,13 +1,15 @@
# Generated by Django 3.2.16 on 2023-01-12 01:32
import catalog.common.utils
import uuid
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import journal.mixins
import markdownx.models
import uuid
from django.db import migrations, models
import catalog.common.utils
import journal.models.mixins
class Migration(migrations.Migration):
@ -39,7 +41,7 @@ class Migration(migrations.Migration):
"abstract": False,
"base_manager_name": "objects",
},
bases=(models.Model, journal.mixins.UserOwnedObjectMixin),
bases=(models.Model, journal.models.mixins.UserOwnedObjectMixin),
),
migrations.CreateModel(
name="Collection",

View file

@ -1,8 +1,8 @@
# Generated by Django 3.2.16 on 2023-01-12 01:32
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,9 +1,10 @@
# Generated by Django 3.2.16 on 2023-01-12 21:06
import catalog.common.utils
from django.conf import settings
from django.db import migrations, models
import catalog.common.utils
class Migration(migrations.Migration):
dependencies = [

View file

@ -1,8 +1,8 @@
# Generated by Django 3.2.16 on 2023-01-14 03:34
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,8 +1,8 @@
# Generated by Django 3.2.16 on 2023-01-14 13:39
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2.16 on 2023-01-17 03:51
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2.16 on 2023-01-31 20:14
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 3.2.19 on 2023-06-05 02:31
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

View file

@ -1,7 +1,7 @@
# Generated by Django 4.2.3 on 2023-07-06 22:53
from django.db import migrations, models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,31 @@
from .collection import Collection, CollectionMember, FeaturedCollection
from .comment import Comment
from .common import (
Piece,
UserOwnedObjectMixin,
VisibilityType,
max_visiblity_to,
q_visible_to,
query_following,
query_item_category,
query_visible,
)
from .like import Like
from .mark import Mark
from .rating import Rating
from .review import Review
from .shelf import (
Shelf,
ShelfLogEntry,
ShelfManager,
ShelfMember,
ShelfType,
ShelfTypeNames,
)
from .tag import Tag, TagManager, TagMember
from .utils import (
journal_exists_for_item,
remove_data_by_user,
reset_journal_visibility_for_user,
update_journal_for_merged_item,
)

View file

@ -0,0 +1,111 @@
import re
from functools import cached_property
from django.db import connection, models
from django.utils.translation import gettext_lazy as _
from catalog.collection.models import Collection as CatalogCollection
from catalog.common import jsondata
from catalog.common.utils import DEFAULT_ITEM_COVER, piece_cover_path
from catalog.models import Item
from users.models import User
from .common import Piece
from .itemlist import List, ListMember
from .renderers import render_md
_RE_HTML_TAG = re.compile(r"<[^>]*>")
class CollectionMember(ListMember):
parent = models.ForeignKey(
"Collection", related_name="members", on_delete=models.CASCADE
)
note = jsondata.CharField(_("备注"), null=True, blank=True)
class Collection(List):
url_path = "collection"
MEMBER_CLASS = CollectionMember
catalog_item = models.OneToOneField(
CatalogCollection, on_delete=models.PROTECT, related_name="journal_item"
)
title = models.CharField(_("标题"), max_length=1000, default="")
brief = models.TextField(_("简介"), blank=True, default="")
cover = models.ImageField(
upload_to=piece_cover_path, default=DEFAULT_ITEM_COVER, blank=True
)
items = models.ManyToManyField(
Item, through="CollectionMember", related_name="collections"
)
collaborative = models.PositiveSmallIntegerField(
default=0
) # 0: Editable by owner only / 1: Editable by bi-direction followers
featured_by_users = models.ManyToManyField(
to=User, related_name="featured_collections", through="FeaturedCollection"
)
@property
def html(self):
html = render_md(self.brief)
return html
@property
def plain_description(self):
html = render_md(self.brief)
return _RE_HTML_TAG.sub(" ", html)
def featured_by_user_since(self, user):
f = FeaturedCollection.objects.filter(target=self, owner=user).first()
return f.created_time if f else None
def get_stats_for_user(self, user):
items = list(self.members.all().values_list("item_id", flat=True))
stats = {"total": len(items)}
for st, shelf in user.shelf_manager.shelf_list.items():
stats[st] = shelf.members.all().filter(item_id__in=items).count()
stats["percentage"] = (
round(stats["complete"] * 100 / stats["total"]) if stats["total"] else 0
)
return stats
def get_progress_for_user(self, user):
items = list(self.members.all().values_list("item_id", flat=True))
if len(items) == 0:
return 0
shelf = user.shelf_manager.shelf_list["complete"]
return round(
shelf.members.all().filter(item_id__in=items).count() * 100 / len(items)
)
def save(self, *args, **kwargs):
if getattr(self, "catalog_item", None) is None:
self.catalog_item = CatalogCollection()
if (
self.catalog_item.title != self.title
or self.catalog_item.brief != self.brief
):
self.catalog_item.title = self.title
self.catalog_item.brief = self.brief
self.catalog_item.cover = self.cover # type: ignore
self.catalog_item.save()
super().save(*args, **kwargs)
class FeaturedCollection(Piece):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
target = models.ForeignKey(Collection, on_delete=models.CASCADE)
created_time = models.DateTimeField(auto_now_add=True)
edited_time = models.DateTimeField(auto_now=True)
class Meta:
unique_together = [["owner", "target"]]
@property
def visibility(self):
return self.target.visibility
@cached_property
def progress(self):
return self.target.get_progress_for_user(self.owner)

Some files were not shown because too many files have changed in this diff Show more