import logging from datetime import date, timedelta from app import app # This is required to initialize the database. from data.database import Repository, LogEntry, RepositoryActionCount, db_random_func from workers.worker import Worker POLL_PERIOD_SECONDS = 10 logger = logging.getLogger(__name__) def count_repository_actions(): """ Aggregates repository actions from the LogEntry table and writes them to the RepositoryActionCount table. Returns the number of repositories for which actions were logged. Returns 0 when there is no more work. """ try: # Get a random repository to count. today = date.today() yesterday = today - timedelta(days=1) has_yesterday_actions = (RepositoryActionCount .select(RepositoryActionCount.repository) .where(RepositoryActionCount.date == yesterday)) to_count = (Repository .select() .where(~(Repository.id << (has_yesterday_actions))) .order_by(db_random_func()).get()) logger.debug('Counting: %s', to_count.id) actions = (LogEntry .select() .where(LogEntry.repository == to_count, LogEntry.datetime >= yesterday, LogEntry.datetime < today) .count()) # Create the row. try: RepositoryActionCount.create(repository=to_count, date=yesterday, count=actions) return 1 except: logger.exception('Exception when writing count') except Repository.DoesNotExist: logger.debug('No further repositories to count') return 0 class RepositoryActionCountWorker(Worker): def __init__(self): super(RepositoryActionCountWorker, self).__init__() self.add_operation(self._count_repository_actions, POLL_PERIOD_SECONDS) def _count_repository_actions(self): """ Counts actions for a random repository for the previous day. """ count_repository_actions() if __name__ == "__main__": worker = RepositoryActionCountWorker() worker.start()