add debris model for future features

This commit is contained in:
Your Name 2024-02-04 18:41:34 -05:00 committed by Henri Dickson
parent 602b7c8d35
commit 2435655995
7 changed files with 165 additions and 16 deletions

View file

@ -114,7 +114,12 @@ class Migration(migrations.Migration):
("cover_url", models.CharField(max_length=1000, null=True)),
("media_url", models.CharField(max_length=1000, null=True)),
("guid", models.CharField(max_length=1000, null=True)),
("pub_date", models.DateTimeField()),
(
"pub_date",
models.DateTimeField(
help_text="yyyy/mm/dd hh:mm", verbose_name="发布时间"
),
),
("duration", models.PositiveIntegerField(null=True)),
(
"program",

View file

@ -0,0 +1,61 @@
# Generated by Django 4.2.9 on 2024-02-04 22:37
import django.db.models.deletion
import django.utils.timezone
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("users", "0019_task"),
("catalog", "0011_alter_externalresource_id_type_and_more"),
("journal", "0022_letterboxdimporter"),
]
operations = [
migrations.CreateModel(
name="Debris",
fields=[
(
"piece_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="journal.piece",
),
),
("visibility", models.PositiveSmallIntegerField(default=0)),
(
"created_time",
models.DateTimeField(default=django.utils.timezone.now),
),
("edited_time", models.DateTimeField(auto_now=True)),
("metadata", models.JSONField(default=dict)),
(
"remote_id",
models.CharField(default=None, max_length=200, null=True),
),
("class_name", models.CharField(max_length=50)),
(
"item",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT, to="catalog.item"
),
),
(
"owner",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
to="users.apidentity",
),
),
],
options={
"abstract": False,
},
bases=("journal.piece",),
),
]

View file

@ -24,6 +24,20 @@ class CollectionMember(ListMember):
note = jsondata.CharField(_("备注"), null=True, blank=True)
@property
def ap_object(self):
return {
"id": self.absolute_url,
"type": "CollectionItem",
"collection": self.parent.absolute_url,
"published": self.created_time.isoformat(),
"updated": self.edited_time.isoformat(),
"attributedTo": self.owner.actor_uri,
"withRegardTo": self.item.absolute_url,
"note": self.note,
"href": self.absolute_url,
}
class Collection(List):
url_path = "collection"

View file

@ -5,7 +5,7 @@ from typing import TYPE_CHECKING
from django.conf import settings
from django.db import connection, models
from django.db.models import Avg, Count, Q
from django.db.models import Avg, CharField, Count, Q
from django.utils import timezone
from django.utils.baseconv import base62
from django.utils.translation import gettext_lazy as _
@ -264,3 +264,19 @@ class Content(Piece):
class Meta:
abstract = True
class Debris(Content):
class_name = CharField(max_length=50)
@classmethod
def create_from_piece(cls, c: Piece):
return cls.objects.create(
class_name=c.__class__.__name__,
owner=c.owner,
visibility=c.visibility,
created_time=c.created_time,
metadata=c.ap_object,
item=c.item,
remote_id=c.remote_id if hasattr(c, "remote_id") else None,
)

View file

@ -19,6 +19,19 @@ class TagMember(ListMember):
class Meta:
unique_together = [["parent", "item"]]
@property
def ap_object(self):
return {
"id": self.absolute_url,
"type": "Tag",
"tag": self.parent.title,
"published": self.created_time.isoformat(),
"updated": self.edited_time.isoformat(),
"attributedTo": self.owner.actor_uri,
"withRegardTo": self.item.absolute_url,
"href": self.absolute_url,
}
TagValidators = [RegexValidator(regex=r"\s+", inverse_match=True)]

View file

@ -1,3 +1,5 @@
from django.db import transaction
from django.db.utils import IntegrityError
from django.utils.translation import gettext_lazy as _
from loguru import logger
@ -6,7 +8,7 @@ from users.models import APIdentity
from .collection import Collection, CollectionMember, FeaturedCollection
from .comment import Comment
from .common import Content
from .common import Content, Debris
from .itemlist import ListMember
from .rating import Rating
from .review import Review
@ -42,21 +44,26 @@ def update_journal_for_merged_item(
logger.error("update_journal_for_merged_item: unable to find item")
return
new_item = legacy_item.merged_to_item
delete_q = []
for cls in list(Content.__subclasses__()) + list(ListMember.__subclasses__()):
for p in cls.objects.filter(item=legacy_item):
try:
p.item = new_item
p.save(update_fields=["item_id"])
except:
if delete_duplicated:
logger.warning(
f"deleted piece {p} when merging {cls.__name__}: {legacy_item} -> {new_item}"
)
p.delete()
else:
logger.warning(
f"skip piece {p} when merging {cls.__name__}: {legacy_item} -> {new_item}"
)
with transaction.atomic():
try:
p.item = new_item
p.save(update_fields=["item_id"])
except IntegrityError:
if delete_duplicated:
logger.warning(
f"deleted piece {p.id} when merging {cls.__name__}: {legacy_item_uuid} -> {new_item.uuid}"
)
delete_q.append(p)
else:
logger.warning(
f"skip piece {p.id} when merging {cls.__name__}: {legacy_item_uuid} -> {new_item.uuid}"
)
for p in delete_q:
Debris.create_from_piece(p)
p.delete()
def journal_exists_for_item(item: Item) -> bool:

View file

@ -3,6 +3,7 @@ import time
from django.test import TestCase
from catalog.models import *
from journal.models.common import Debris
from users.models import User
from .models import *
@ -188,3 +189,35 @@ class MarkTest(TestCase):
TagManager.tag_item(self.book1, self.user1.identity, [" Sci-Fi ", " fic "])
mark = Mark(self.user1.identity, self.book1)
self.assertEqual(mark.tags, ["Sci-Fi", "fic"])
class DebrisTest(TestCase):
databases = "__all__"
def setUp(self):
self.book1 = Edition.objects.create(title="Hyperion")
self.book2 = Edition.objects.create(title="Hyperion clone")
self.book3 = Edition.objects.create(title="Hyperion clone 2")
self.user1 = User.register(email="test@test", username="test")
def test_journal_migration(self):
TagManager.tag_item(self.book1, self.user1.identity, ["Sci-Fi", "fic"])
mark = Mark(self.user1.identity, self.book1)
mark.update(ShelfType.WISHLIST, "a gentle comment", 9, 1)
Review.update_item_review(self.book1, self.user1.identity, "Critic", "Review")
collection = Collection.objects.create(title="test", owner=self.user1.identity)
collection.append_item(self.book1)
self.book1.merge_to(self.book2)
update_journal_for_merged_item(self.book1.uuid, delete_duplicated=True)
cnt = Debris.objects.all().count()
self.assertEqual(cnt, 0)
TagManager.tag_item(self.book3, self.user1.identity, ["Sci-Fi", "fic"])
mark = Mark(self.user1.identity, self.book3)
mark.update(ShelfType.WISHLIST, "a gentle comment", 9, 1)
Review.update_item_review(self.book3, self.user1.identity, "Critic", "Review")
collection.append_item(self.book3)
self.book3.merge_to(self.book2)
update_journal_for_merged_item(self.book3.uuid, delete_duplicated=True)
cnt = Debris.objects.all().count()
self.assertEqual(cnt, 4) # Rating, Shelf, 2x TagMember