Orders - Refactor out posting

Use stored due_at
This commit is contained in:
Johnny Gear 2025-11-13 22:03:20 -06:00
parent 49a2403886
commit bfca81e8ac
4 changed files with 105 additions and 66 deletions

10
db.py
View file

@ -23,6 +23,7 @@ TABLE_ORDER_STATUS = '''
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
mastodon_id TEXT NOT NULL, mastodon_id TEXT NOT NULL,
created_at TIMESTAMP NOT NULL, created_at TIMESTAMP NOT NULL,
due_at TIMESTAMP NOT NULL,
text TEXT NOT NULL, text TEXT NOT NULL,
confirmed_at TIMESTAMP, confirmed_at TIMESTAMP,
punishment_id INTEGER, punishment_id INTEGER,
@ -90,16 +91,17 @@ class Database:
c.execute(sql, [date]) c.execute(sql, [date])
return c.fetchone() is not None return c.fetchone() is not None
def order_status_put(self, mastodon_id, created_at, text): def order_status_put(self, mastodon_id, created_at, due_at, text):
self.update( self.update(
''' '''
INSERT INTO order_status INSERT INTO order_status
(mastodon_id, created_at, text) (mastodon_id, created_at, due_at, text)
VALUES (?, ?, ?); VALUES (?, ?, ?, ?);
''', ''',
[ [
mastodon_id, mastodon_id,
created_at, created_at,
due_at,
text text
] ]
) )
@ -107,7 +109,7 @@ class Database:
def order_status_outstanding(self): def order_status_outstanding(self):
c = self.conn.cursor() c = self.conn.cursor()
sql = ''' sql = '''
SELECT id, mastodon_id, created_at, confirmed_at SELECT id, mastodon_id, created_at, due_at, confirmed_at
FROM order_status FROM order_status
WHERE confirmed_at IS NULL AND punishment_id IS NULL WHERE confirmed_at IS NULL AND punishment_id IS NULL
''' '''

144
orders.py
View file

@ -7,10 +7,31 @@ from db import Database
from mastodon import Mastodon from mastodon import Mastodon
from telegram import Telegram from telegram import Telegram
from settings import MASTODON_USERNAME, ORDER_TIMEOUT from settings import MASTODON_USERNAME, ORDER_TIMEOUT
from util import order_time from util import timezone
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
async def order_mastodon_post(session, orders_str, repeats, due_at):
m_post = "Here are today's orders for @%s -\n\n" % MASTODON_USERNAME
m_post += orders_str + "\n\n"
if repeats > 1:
m_post += f"These are the same orders from the last {repeats} days\n\n"
m_post += "Proof of compliance is due by " + due_at.strftime("%H:%M %p")
m = Mastodon(session)
return await m.statusPost(m_post)
async def order_telegram_post(session, orders_str, repeats, due_at, m_url):
t_post = "Here are your orders -\n\n"
t_post += orders_str + "\n\n"
if repeats > 1:
t_post += f"These are the same orders from the last {repeats} days\n\n"
t_post += "Proof of compliance is due by " + due_at.strftime("%H:%M %p") + "\n\n"
t_post += m_url
t = Telegram(session)
await t.message_send(t_post)
async def order_issue(): async def order_issue():
async with make_session() as session: async with make_session() as session:
orders_info = generate_order() orders_info = generate_order()
@ -21,46 +42,84 @@ async def order_issue():
orders_str = "\n".join(orders_info['orders']) orders_str = "\n".join(orders_info['orders'])
due_by = "Proof of compliance is due by %s" % ( created_at = datetime.datetime.now(tz=timezone())
(datetime.datetime.combine( due_at = created_at + ORDER_TIMEOUT
datetime.datetime.today(),
order_time()
) + ORDER_TIMEOUT
).strftime("%H:%M %p")
)
m_post = "Here are today's orders for @%s -\n\n" % MASTODON_USERNAME repeats_count = orders_info.get('count', 0)
if "count" in orders_info and orders_info['count'] > 1:
m_post += f"These are the same orders from the last {orders_info['count']} days\n\n"
m_post += orders_str + "\n\n"
m_post += due_by
m = Mastodon(session) m_status = await order_mastodon_post(
m_status = await m.statusPost(m_post) session,
orders_str,
repeats_count,
due_at
)
t_post = "Here are your orders -\n\n" await order_telegram_post(
t_post += orders_str + "\n\n" session,
t_post += due_by + "\n\n" orders_str,
t_post += m_status['url'] repeats_count,
due_at,
t = Telegram(session) m_status['url']
await t.message_send(t_post) )
db = Database() db = Database()
db.order_status_put( db.order_status_put(
m_status['id'], m_status['id'],
m_status['created_at'], created_at,
m_post due_at,
orders_str
) )
return due_at
async def punishment_mastodon_post(session, punishment_str, reply_id=None):
post = "@%s has failed to post proof of compliance. Here is the punishment -\n\n" % MASTODON_USERNAME
post += punishment_str
m = Mastodon(session)
return await m.statusPost(
post,
in_reply_to_id=reply_id
)
async def punishment_telegram_post(session, punishment_str, m_url):
post = "You failed to show proof of compliance. Here is your punishment -\n\n"
post += punishment_str + "\n\n"
post += m_url
t = Telegram(session)
await t.message_send(post)
async def punishment_issue(db, session, outstanding_order):
punishment = generate_punishment()
punishment_str = "\n".join(punishment)
punishment_status = await punishment_mastodon_post(
session,
punishment_str,
outstanding_order['mastodon_id'],
)
await punishment_telegram_post(
session,
punishment_str,
punishment_status['url']
)
db.punishment_status_put(
outstanding_order['id'],
punishment_status['id'],
punishment_status['created_at'],
punishment_str
)
async def order_check(): async def order_check():
async with make_session() as session: async with make_session() as session:
m = Mastodon(session)
t = Telegram(session)
db = Database() db = Database()
outstanding_orders = db.order_status_outstanding() outstanding_orders = db.order_status_outstanding()
for outstanding_order in outstanding_orders: for outstanding_order in outstanding_orders:
m = Mastodon(session)
context = await m.statusContext(outstanding_order['mastodon_id']) context = await m.statusContext(outstanding_order['mastodon_id'])
confirmed_at = None confirmed_at = None
@ -72,35 +131,14 @@ async def order_check():
): ):
confirmed_at = d['created_at'] confirmed_at = d['created_at']
db.order_status_confirm(outstanding_order['id'], confirmed_at) db.order_status_confirm(outstanding_order['id'], confirmed_at)
logger.info('Confirmed order %s' % (outstanding_order['created_at'])) logger.info('Confirmed order %s' % (outstanding_order['id']))
break break
if confirmed_at is None: if confirmed_at is None:
logger.info('Order %s remains unconfirmed' % (outstanding_order['created_at'])) logger.info('Order %s remains unconfirmed' % (outstanding_order['id']))
oo_created_at = datetime.datetime.fromisoformat(outstanding_order['created_at']) due_at = datetime.datetime.fromisoformat(outstanding_order['due_at'])
if(oo_created_at + ORDER_TIMEOUT < datetime.datetime.now(datetime.UTC)): if(due_at < datetime.datetime.now(datetime.UTC)):
logger.info('Time to issue a punishment for %s' % outstanding_order['created_at']) logger.info('Time to issue a punishment for %s' % outstanding_order['id'])
punishment = generate_punishment() await punishment_issue(db, session, outstanding_order)
punishment_str = "\n".join(punishment)
m_post = "@%s has failed to post proof of compliance. Here is the punishment -\n\n" % MASTODON_USERNAME
m_post += punishment_str
punishment_status = await m.statusPost(
m_post,
in_reply_to_id=outstanding_order['mastodon_id']
)
t_post = "You failed to show proof of compliance. Here is your punishment -\n\n"
t_post += punishment_str + "\n\n"
t_post += punishment_status['url']
await t.message_send(t_post)
db.punishment_status_put(
outstanding_order['id'],
punishment_status['id'],
punishment_status['created_at'],
m_post
)

View file

@ -4,7 +4,7 @@ import pytz
from scheduler.asyncio import Scheduler from scheduler.asyncio import Scheduler
from settings import TIMEZONE, ORDER_TIME, ORDER_TIMEOUT from settings import TIMEZONE
from orders import order_issue, order_check from orders import order_issue, order_check
from db import Database from db import Database
from util import order_time from util import order_time
@ -31,7 +31,7 @@ class OrderScheduler():
outstanding_orders = db.order_status_outstanding() outstanding_orders = db.order_status_outstanding()
for oo in outstanding_orders: for oo in outstanding_orders:
self.scheduler.once( self.scheduler.once(
datetime.datetime.fromisoformat(oo['created_at']) + ORDER_TIMEOUT + GRACE_PERIOD, datetime.datetime.fromisoformat(oo['due_at']) + GRACE_PERIOD,
self.scheduled_check self.scheduled_check
) )
@ -52,13 +52,11 @@ class OrderScheduler():
logger.info('Today is a skip day') logger.info('Today is a skip day')
return return
await order_issue() due_at = await order_issue()
# Schedule check # Schedule check
self.scheduler.once( self.scheduler.once(
datetime.datetime.now(tz=self.tz) + due_at + GRACE_PERIOD,
ORDER_TIMEOUT +
GRACE_PERIOD,
self.scheduled_check self.scheduled_check
) )

View file

@ -7,12 +7,13 @@ from settings import TIMEZONE, ORDER_TIME
def make_session(): def make_session():
return aiohttp.ClientSession() return aiohttp.ClientSession()
def order_time(): def timezone():
tz = pytz.timezone(TIMEZONE) return pytz.timezone(TIMEZONE)
def order_time():
order_time_arr = list(map(int, ORDER_TIME.split(':'))) order_time_arr = list(map(int, ORDER_TIME.split(':')))
return datetime.time( return datetime.time(
hour=order_time_arr[0], hour=order_time_arr[0],
minute=order_time_arr[1], minute=order_time_arr[1],
tzinfo=tz tzinfo=timezone()
) )