Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fanout limit #395

Merged
merged 4 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion boofilsic/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
# Slack API token, for sending exceptions to Slack, may deprecate in future
SLACK_API_TOKEN=(str, ""),
NEODB_SENTRY_DSN=(str, ""),
NEODB_FANOUT_LIMIT_DAYS=(int, 9),
)

# ====== End of user configuration variables ======
Expand Down Expand Up @@ -223,7 +224,7 @@
DOWNLOADER_RETRIES = env("NEODB_DOWNLOADER_RETRIES")

DISABLE_CRON = env("NEODB_DISABLE_CRON")

FANOUT_LIMIT_DAYS = env("NEODB_FANOUT_LIMIT_DAYS")
# ====== USER CONFIGUTRATION END ======

DATABASE_ROUTERS = ["takahe.db_routes.TakaheRouter"]
Expand Down
20 changes: 20 additions & 0 deletions journal/migrations/0020_shelflogentry_unique_shelf_log_entry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Generated by Django 4.2.7 on 2023-11-23 03:23

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("journal", "0019_alter_collection_edited_time_and_more"),
]

operations = [
migrations.AddConstraint(
model_name="shelflogentry",
constraint=models.UniqueConstraint(
fields=("owner", "item", "timestamp", "shelf_type"),
name="unique_shelf_log_entry",
),
),
]
4 changes: 2 additions & 2 deletions journal/models/shelf.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,8 @@ def get_calendar_data(self, max_visiblity: int):
[timezone_offset, shelf_id, int(max_visiblity)],
),
(
"SELECT to_char(DATE(journal_comment.created_time::timestamp AT TIME ZONE %s), 'YYYY-MM-DD') AS dat, django_content_type.model typ, COUNT(1) count FROM journal_comment, catalog_item, django_content_type WHERE journal_comment.item_id = catalog_item.id AND django_content_type.id = catalog_item.polymorphic_ctype_id AND journal_comment.created_time >= NOW() - INTERVAL '366 days' AND journal_comment.visibility <= %s GROUP BY item_id, dat, typ;",
[timezone_offset, int(max_visiblity)],
"SELECT to_char(DATE(journal_comment.created_time::timestamp AT TIME ZONE %s), 'YYYY-MM-DD') AS dat, django_content_type.model typ, COUNT(1) count FROM journal_comment, catalog_item, django_content_type WHERE journal_comment.owner_id = %s AND journal_comment.item_id = catalog_item.id AND django_content_type.id = catalog_item.polymorphic_ctype_id AND journal_comment.created_time >= NOW() - INTERVAL '366 days' AND journal_comment.visibility <= %s GROUP BY item_id, dat, typ;",
[timezone_offset, self.owner.id, int(max_visiblity)],
),
]
for sql, params in queries:
Expand Down
2 changes: 1 addition & 1 deletion journal/templates/profile.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
title="{{ site_name }} - {{ identity.handler }}的评论"
href="{{ request.build_absolute_uri }}feed/reviews/">
{% include "common_libs.html" with jquery=0 v2=1 %}
<script src="{% static 'js/calendar_yearview_blocks.js' %}?xxxxdd" defer></script>
<script src="{% static 'js/calendar_yearview_blocks.js' %}" defer></script>
<link href="{% static 'css/calendar_yearview_blocks.css' %}"
media="all"
rel="stylesheet" />
Expand Down
76 changes: 76 additions & 0 deletions takahe/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -647,4 +647,80 @@ class Migration(migrations.Migration):
"db_table": "users_invite",
},
),
migrations.CreateModel(
name="FanOut",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("state", models.CharField(default="outdated", max_length=100)),
("state_changed", models.DateTimeField(auto_now_add=True)),
(
"type",
models.CharField(
choices=[
("post", "Post"),
("post_edited", "Post Edited"),
("post_deleted", "Post Deleted"),
("interaction", "Interaction"),
("undo_interaction", "Undo Interaction"),
("identity_edited", "Identity Edited"),
("identity_deleted", "Identity Deleted"),
("identity_created", "Identity Created"),
("identity_moved", "Identity Moved"),
],
max_length=100,
),
),
("created", models.DateTimeField(auto_now_add=True)),
("updated", models.DateTimeField(auto_now=True)),
(
"identity",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="fan_outs",
to="takahe.identity",
),
),
(
"subject_identity",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="subject_fan_outs",
to="takahe.identity",
),
),
(
"subject_post",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="fan_outs",
to="takahe.post",
),
),
(
"subject_post_interaction",
models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="fan_outs",
to="takahe.postinteraction",
),
),
],
options={
"db_table": "activities_fanout",
},
),
]
74 changes: 73 additions & 1 deletion takahe/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1032,7 +1032,9 @@ def create_local(
post.emojis.set(emojis)
if published and published < timezone.now():
post.published = published
if timezone.now() - published > datetime.timedelta(days=9):
if timezone.now() - published > datetime.timedelta(
days=settings.FANOUT_LIMIT_DAYS
):
post.state = "fanned_out" # add post quietly if it's old
# if attachments:# FIXME
# post.attachments.set(attachments)
Expand All @@ -1045,6 +1047,13 @@ def create_local(
# Recalculate parent stats for replies
if reply_to:
reply_to.calculate_stats()
if post.state == "fanned_out":
FanOut.objects.create(
identity=author,
type="post",
subject_post=post,
)

return post

def edit_local(
Expand Down Expand Up @@ -1137,6 +1146,69 @@ def safe_content_local(self):
return ContentRenderer(local=True).render_post(self.content, self)


class FanOut(models.Model):
"""
An activity that needs to get to an inbox somewhere.
"""

class Meta:
# managed = False
db_table = "activities_fanout"

class Types(models.TextChoices):
post = "post"
post_edited = "post_edited"
post_deleted = "post_deleted"
interaction = "interaction"
undo_interaction = "undo_interaction"
identity_edited = "identity_edited"
identity_deleted = "identity_deleted"
identity_created = "identity_created"
identity_moved = "identity_moved"

state = models.CharField(max_length=100, default="outdated")
state_changed = models.DateTimeField(auto_now_add=True)

# The user this event is targeted at
# We always need this, but if there is a shared inbox URL on the user
# we'll deliver to that and won't have fanouts for anyone else with the
# same one.
identity = models.ForeignKey(
"takahe.Identity",
on_delete=models.CASCADE,
related_name="fan_outs",
)

# What type of activity it is
type = models.CharField(max_length=100, choices=Types.choices)

# Links to the appropriate objects
subject_post = models.ForeignKey(
"takahe.Post",
on_delete=models.CASCADE,
blank=True,
null=True,
related_name="fan_outs",
)
subject_post_interaction = models.ForeignKey(
"takahe.PostInteraction",
on_delete=models.CASCADE,
blank=True,
null=True,
related_name="fan_outs",
)
subject_identity = models.ForeignKey(
"takahe.Identity",
on_delete=models.CASCADE,
blank=True,
null=True,
related_name="subject_fan_outs",
)

created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)


class EmojiQuerySet(models.QuerySet):
def usable(self, domain: Domain | None = None):
"""
Expand Down