epicyon/schedule.py

151 lines
6.1 KiB
Python
Raw Normal View History

2020-01-12 20:13:44 +00:00
__filename__ = "schedule.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.1.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@freedombone.net"
__status__ = "Production"
import os
2020-01-12 20:16:33 +00:00
import time
2020-01-12 20:13:44 +00:00
import datetime
2020-01-12 21:47:36 +00:00
from utils import loadJson
2020-01-13 10:45:02 +00:00
from outbox import postMessageToOutbox
2020-01-12 20:13:44 +00:00
def updatePostSchedule(baseDir: str,handle: str,httpd,maxScheduledPosts: int) -> None:
"""Checks if posts are due to be delivered and if so moves them to the outbox
"""
scheduleIndexFilename=baseDir+'/accounts/'+handle+'/schedule.index'
if not os.path.isfile(scheduleIndexFilename):
return
# get the current time as an int
currTime=datetime.datetime.utcnow()
daysSinceEpoch=(currTime - datetime.datetime(1970,1,1)).days
scheduleDir=baseDir+'/accounts/'+handle+'/scheduled/'
indexLines=[]
deleteSchedulePost=False
nickname=handle.split('@')[0]
with open(scheduleIndexFilename, 'r') as fp:
for line in fp:
2020-01-12 21:23:54 +00:00
print('DEBUG: schedule line='+line)
2020-01-12 20:13:44 +00:00
if ' ' not in line:
continue
dateStr=line.split(' ')[0]
if 'T' not in dateStr:
continue
postId=line.split(' ',1)[1].replace('\n','')
postFilename=scheduleDir+postId+'.json'
2020-01-12 21:23:54 +00:00
print('DEBUG: schedule postFilename '+postFilename)
2020-01-12 20:13:44 +00:00
if deleteSchedulePost:
# delete extraneous scheduled posts
if os.path.isfile(postFilename):
os.remove(postFilename)
continue
# create the new index file
indexLines.append(line)
# convert string date to int
2020-01-12 21:41:49 +00:00
print('DEBUG: schedule date='+dateStr)
2020-01-12 20:13:44 +00:00
postTime= \
2020-01-12 21:41:49 +00:00
datetime.datetime.strptime(dateStr,"%Y-%m-%dT%H:%M:%S%z").replace(tzinfo=None)
2020-01-12 20:13:44 +00:00
postDaysSinceEpoch= \
(postTime - datetime.datetime(1970,1,1)).days
2020-01-12 21:23:54 +00:00
print('DEBUG: schedule postTime hour='+str(postTime.time().hour))
print('DEBUG: schedule postTime minute='+str(postTime.time().minute))
2020-01-13 11:13:30 +00:00
print('DEBUG: schedule daysSinceEpoch='+str(daysSinceEpoch))
print('DEBUG: schedule postDaysSinceEpoch='+str(postDaysSinceEpoch))
2020-01-12 20:13:44 +00:00
if daysSinceEpoch < postDaysSinceEpoch:
2020-01-13 11:13:30 +00:00
print('DEBUG: schedule not yet date')
2020-01-12 20:13:44 +00:00
continue
2020-01-13 11:16:35 +00:00
if daysSinceEpoch == postDaysSinceEpoch:
if currTime.time().hour < postTime.time().hour:
print('DEBUG: schedule not yet hour')
continue
if currTime.time().minute < postTime.time().minute:
print('DEBUG: schedule not yet minute')
continue
2020-01-12 20:13:44 +00:00
if not os.path.isfile(postFilename):
2020-01-13 11:13:30 +00:00
print('WARN: schedule postFilename='+postFilename)
2020-01-12 20:13:44 +00:00
indexLines.remove(line)
continue
# load post
postJsonObject=loadJson(postFilename)
if not postJsonObject:
2020-01-13 11:13:30 +00:00
print('WARN: schedule json not loaded')
2020-01-12 20:13:44 +00:00
indexLines.remove(line)
continue
print('Sending scheduled post '+postId)
2020-01-13 10:45:02 +00:00
if not postMessageToOutbox(postJsonObject,nickname, \
2020-01-13 11:21:24 +00:00
httpd,baseDir, \
httpd.httpPrefix, \
httpd.domain, \
httpd.domainFull, \
httpd.port, \
httpd.recentPostsCache, \
httpd.followersThreads, \
httpd.federationList, \
httpd.sendThreads, \
httpd.postLog, \
httpd.cachedWebfingers, \
httpd.personCache, \
httpd.allowDeletion, \
httpd.useTor, \
httpd.projectVersion, \
httpd.debug):
2020-01-12 20:13:44 +00:00
indexLines.remove(line)
continue
# move to the outbox
outboxPostFilename= \
postFilename.replace('/scheduled/','/outbox/')
os.rename(postFilename,outboxPostFilename)
print('Scheduled post sent '+postId)
indexLines.remove(line)
if len(indexLines)>maxScheduledPosts:
deleteSchedulePost=True
# write the new schedule index file
scheduleIndexFile=baseDir+'/accounts/'+handle+'/schedule.index'
scheduleFile=open(scheduleIndexFile, "w+")
if scheduleFile:
for line in indexLines:
scheduleFile.write(line)
scheduleFile.close()
def runPostSchedule(baseDir: str,httpd,maxScheduledPosts: int):
"""Dispatches scheduled posts
"""
while True:
time.sleep(60)
# for each account
for subdir,dirs,files in os.walk(baseDir+'/accounts'):
for account in dirs:
if '@' not in account:
continue
# scheduled posts index for this account
scheduleIndexFilename=baseDir+'/accounts/'+account+'/schedule.index'
2020-01-12 21:15:42 +00:00
if not os.path.isfile(scheduleIndexFilename):
2020-01-12 20:13:44 +00:00
continue
updatePostSchedule(baseDir,account,httpd,maxScheduledPosts)
def runPostScheduleWatchdog(projectVersion: str,httpd) -> None:
"""This tries to keep the scheduled post thread running even if it dies
"""
print('Starting scheduled post watchdog')
postScheduleOriginal= \
httpd.thrPostSchedule.clone(runPostSchedule)
httpd.thrPostSchedule.start()
while True:
time.sleep(20)
if not httpd.thrPostSchedule.isAlive():
httpd.thrPostSchedule.kill()
httpd.thrPostSchedule= \
postScheduleOriginal.clone(runPostSchedule)
httpd.thrPostSchedule.start()
print('Restarting scheduled posts...')