mirror of https://gitlab.com/tildes/tildes.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
43 lines
1.4 KiB
43 lines
1.4 KiB
# Copyright (c) 2019 Tildes contributors <code@tildes.net>
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
"""Script to post any scheduled topics that are due."""
|
|
|
|
from typing import Optional
|
|
|
|
from sqlalchemy.orm.session import Session
|
|
|
|
from tildes.lib.database import get_session_from_config
|
|
from tildes.lib.datetime import utc_now
|
|
from tildes.models.topic import TopicSchedule
|
|
|
|
|
|
def _get_next_due_topic(db_session: Session) -> Optional[TopicSchedule]:
|
|
"""Get the next due topic (if any).
|
|
|
|
Note that this also locks the topic's row with FOR UPDATE as well as using SKIP
|
|
LOCKED. This should (hypothetically) mean that multiple instances of this script
|
|
can run concurrently safely and will not attempt to post the same topics.
|
|
"""
|
|
return (
|
|
db_session.query(TopicSchedule)
|
|
.filter(TopicSchedule.next_post_time <= utc_now()) # type: ignore
|
|
.order_by(TopicSchedule.next_post_time)
|
|
.with_for_update(skip_locked=True)
|
|
.first()
|
|
)
|
|
|
|
|
|
def post_scheduled_topics(config_path: str) -> None:
|
|
"""Post all scheduled topics that are due to be posted."""
|
|
db_session = get_session_from_config(config_path)
|
|
|
|
due_topic = _get_next_due_topic(db_session)
|
|
|
|
while due_topic:
|
|
db_session.add(due_topic.create_topic())
|
|
due_topic.advance_schedule_to_future()
|
|
db_session.add(due_topic)
|
|
db_session.commit()
|
|
|
|
due_topic = _get_next_due_topic(db_session)
|