Calendario/scheduler_process.py
Murilo Scolari 573152a3f0
Some checks are pending
CI / test (push) Waiting to run
Initial commit of StudyCalendar
2026-09-16 20:00:04 -03:00

54 lines
1.9 KiB
Python

"""Processo único dedicado à sincronização periódica dos feeds."""
import fcntl
import logging
import os
from datetime import datetime, timedelta, timezone
from apscheduler.schedulers.blocking import BlockingScheduler
import database
import ics_sync
logging.basicConfig(level=os.environ.get('LOG_LEVEL', 'INFO'))
logger = logging.getLogger(__name__)
def sync_due_feeds():
now = datetime.now(timezone.utc)
for feed in database.get_all_feeds():
last_synced = feed.get('last_attempted') or feed.get('last_synced')
requested = feed.get('sync_requested_at')
try:
last = datetime.fromisoformat(last_synced) if last_synced else None
if last and last.tzinfo is None:
last = last.replace(tzinfo=timezone.utc)
due = not last or last + timedelta(minutes=feed['sync_interval_minutes']) <= now
except (TypeError, ValueError):
due = True
if requested or due:
ics_sync.sync_feed(feed['id'])
def main():
database.configure(os.environ.get(
'DATABASE_PATH', os.path.join(os.path.dirname(__file__), 'calendario.db')
))
database.init_db()
lock_path = os.environ.get('SCHEDULER_LOCK_PATH', '/tmp/studycalendar-scheduler.lock')
lock_fd = os.open(lock_path, os.O_CREAT | os.O_RDWR | os.O_NOFOLLOW, 0o600)
lock_file = os.fdopen(lock_fd, 'w', encoding='ascii')
try:
fcntl.flock(lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)
except BlockingIOError as exc:
raise RuntimeError('Outro scheduler já está ativo neste host.') from exc
scheduler = BlockingScheduler(timezone='America/Sao_Paulo')
scheduler.add_job(sync_due_feeds, 'interval', minutes=1, id='sync-feeds', max_instances=1,
coalesce=True, next_run_time=datetime.now(timezone.utc))
logger.info('Scheduler dedicado iniciado.')
scheduler.start()
if __name__ == '__main__':
main()