Add the prev build in branch for ref

Signed-off-by: Pratyush Desai <pratyush.desai@liberta.casa>
This commit is contained in:
Pratyush Desai 2024-06-16 23:47:49 +05:30
parent cc15b8fc9b
commit 6fd6420899
Signed by: pratyush
GPG Key ID: DBA5BB7505946FAD
4 changed files with 342 additions and 23 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
venv/
.vscode
notes.txt

View File

@ -1 +1,7 @@
Log and annotate your doses
# IRC DOSE MONITORING and MANAGEMENT UTILITY
Built around the Limnoria Bot Framework.
It's a tool to log and retrieve doses.

View File

@ -1,5 +1,5 @@
###
# Copyright (c) 2021, Pratyush Desai
# Copyright (c) 2020, mogad0n
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@ -29,9 +29,11 @@
###
from supybot import conf, registry
try:
from supybot.i18n import PluginInternationalization
_ = PluginInternationalization('DoseLogs')
_ = PluginInternationalization("Tripsit")
except:
# Placeholder that allows to run the plugin on a bot
# without the i18n module
@ -44,12 +46,13 @@ def configure(advanced):
# user or not. You should effect your configuration by manipulating the
# registry as appropriate.
from supybot.questions import expect, anything, something, yn
conf.registerPlugin('DoseLogs', True)
conf.registerPlugin("Tripsit", True)
DoseLogs = conf.registerPlugin('DoseLogs')
Tripsit = conf.registerPlugin("Tripsit")
# This is where your configuration variables (if any) should go. For example:
# conf.registerGlobalValue(DoseLogs, 'someConfigVariableName',
# conf.registerGlobalValue(Tripsit, 'someConfigVariableName',
# registry.Boolean(False, _("""Help for someConfigVariableName.""")))

342
plugin.py
View File

@ -1,8 +1,8 @@
###
# Copyright (c) 2021, Pratyush Desai
# Copyright (c) 2020, mogad0n
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# Redistribution and use in source and binary forms, with or wthout
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
@ -28,17 +28,25 @@
###
# My Libs
import pickle
from supybot import utils, plugins, ircutils, callbacks
from supybot import conf
from humanize import ordinal
from supybot import utils, plugins, ircutils, callbacks, world, conf, log
from supybot.commands import *
from num2words import num2words
import dateutil.parser
import json
import requests
import pickle
import sys
import datetime
import time
import pytz
try:
from supybot.i18n import PluginInternationalization
_ = PluginInternationalization('DoseLogs')
_ = PluginInternationalization("DoseLogs")
except ImportError:
# Placeholder that allows to run the plugin on a bot
# without the i18n module
@ -46,18 +54,318 @@ except ImportError:
filename = conf.supybot.directories.data.dirize("DoseLogs.db")
# Routes of Administration
ROA = {
}
class DoseLogs(callbacks.Plugin):
"""Log and annotate your doses"""
"""Tools for tracking and controlling substance use"""
threaded = True
def __init__(self, irc):
self.__parent = super(DoseLogs, self)
self.__parent.__init__(irc)
self.db = {}
self._loadDb()
world.flushers.append(self._flushDb)
Class = DoseLogs
def _loadDb(self):
"""Loads the (flatfile) database mapping nicks to doses."""
try:
with open(filename, "rb") as f:
self.db = pickle.load(f)
except Exception as e:
self.log.debug("DoseLogs: Unable to load pickled database: %s", e)
def _flushDb(self):
"""Flushes the (flatfile) database mapping nicks to doses."""
try:
with open(filename, "wb") as f:
pickle.dump(self.db, f, 2)
except Exception as e:
self.log.warning("DoseLogs: Unable to write pickled database: %s", e)
def die(self):
self._flushDb()
world.flushers.remove(self._flushDb)
self.__parent.die()
def set(self, irc, msg, args, timezone):
"""<timezone>
Sets location for your current nick to <timezone>
for eg. America/Chicago
"""
nick = msg.nick
try:
timezone = pytz.timezone(timezone)
if nick in self.db:
self.db[nick]["timezone"] = timezone
else:
self.db[nick] = {"timezone": timezone}
irc.replySuccess()
except pytz.UnknownTimeZoneError:
irc.error(_("Unknown timezone"), Raise=True)
set = wrap(set, ["something"])
@wrap(
[getopts({"ago": "something"}), "something", "something", optional("something")]
)
def idose(self, irc, msg, args, opts, dose, name, method):
"""[--ago <HHMM>] <amount> <drug> [<method/ROA>]
Logs a dose for your nick, Ex. @idose --ago 0100 20mg mph oral
would log that dose as if it was taken an hour ago.
[--ago] and [ROA] fields are optional
"""
opts = dict(opts)
found_method = False
onset = None
methods = []
if method:
methods = [method.lower()]
methods = METHODS.get(methods[0], methods)
drug_and_method = name
if method:
if not found_method:
method = method.title()
drug_and_method = "%s via %s" % (drug_and_method, method)
else:
method = "Undefined"
nick = msg.nick
if nick in self.db:
timezone = self.db[nick].get("timezone", "UTC")
tz = pytz.timezone(str(timezone))
time = datetime.datetime.now(tz=tz)
dose_td = 0
if "ago" in opts and len(opts["ago"]) == 4:
ago = opts["ago"]
dose_td = datetime.timedelta(hours=int(ago[0:2]), minutes=int(ago[2:4]))
dose_td_s = dose_td.total_seconds()
time = time - dose_td
doseLog = {"time": time, "dose": dose, "drug": name, "method": method}
doses = self.db[nick].get("doses")
if doses:
doses.append(doseLog)
else:
doses = [doseLog]
self.db[nick]["doses"] = doses
else:
timezone = "UTC"
tz = pytz.timezone(timezone)
time = datetime.datetime.now(tz=tz)
dose_td = 0
if "ago" in opts and len(opts["ago"]) == 4:
ago = opts["ago"]
dose_td = datetime.timedelta(hours=int(ago[0:2]), minutes=int(ago[2:4]))
dose_td_s = dose_td.total_seconds()
time = time - dose_td
doseLog = {"time": time, "dose": dose, "drug": name, "method": method}
doses = [doseLog]
self.db[nick] = {"timezone": timezone, "doses": doses}
if dose_td == 0:
re = utils.str.format(
"You dosed %s of %s at %s, %s",
dose,
drug_and_method,
time.strftime("%c"),
timezone,
)
if onset is not None:
re += utils.str.format(
". You should start feeling effects %s from now", onset
)
else:
re = utils.str.format(
"You dosed %s of %s at %s, %s ; %T ago",
dose,
drug_and_method,
time.strftime("%c"),
timezone,
dose_td.total_seconds(),
)
if onset is not None:
re += utils.str.format(
". You should have/will start feeling effects %s from/after dosing",
onset,
)
# re=":-( This is currently not available, sorry. Exception ID T0T4LLYFCK3D."
irc.reply(re)
@wrap([optional("positiveInt")])
def undose(self, irc, msg, args, entry):
"""<n>
removes your last dose entry, if <n> is provided then
deletes the nth last dose
"""
nick = msg.nick
if nick in self.db:
nick_dose_log = self.db[nick]["doses"]
if entry:
try:
del nick_dose_log[-int(entry)]
entry = num2words(entry, to="ordinal")
irc.replySuccess(
f"Deleted the {entry} last dose logged for {nick} "
)
except IndexError:
irc.error("The dose entry doesn't exist")
return
else:
del nick_dose_log[-1]
irc.replySuccess(f"Deleted the last dose logged for {nick} ")
else:
irc.error(f"No doses saved for {nick}")
def doseslogged(self, irc, msg, args):
"""
This command takes no arguments.
Retrieves the number of doses logged for a given nick
"""
nick = msg.nick
if nick in self.db:
try:
nick_dose_log_count = len(self.db[nick]["doses"])
nick_dose_log_since = self.db[nick]["doses"][0]["time"]
nick_dose_log_since_string = nick_dose_log_since.strftime("%c")
irc.reply(
f"{nick} has logged {nick_dose_log_count} doses since {nick_dose_log_since_string}"
)
except IndexError:
irc.error("Can't seem to do math, check logs")
else:
irc.error(f"No doses saved for {nick}")
doseslogged = wrap(doseslogged)
@wrap([optional("positiveInt")])
def lastdose(self, irc, msg, args, history):
"""<n>
retrieves your <n>th last logged dose
"""
nick = msg.nick
if nick in self.db:
if history:
try:
lastdose = self.db[nick]["doses"][-int(history)]
except IndexError:
irc.error("You haven't logged that many doses")
return
else:
lastdose = self.db[nick]["doses"][-1]
dose = lastdose["dose"]
drug = lastdose["drug"]
method = lastdose["method"]
dose_time = lastdose["time"]
timezone = self.db[nick]["timezone"]
tz = pytz.timezone(str(timezone))
time = datetime.datetime.now(tz=tz)
since_dose = time - dose_time
since_dose_seconds = since_dose.total_seconds()
if history:
history = num2words(history, to="ordinal")
re = utils.str.format(
"Your %i last dose was %s of %s via %s at %s %s, %T ago",
history,
dose,
drug,
method,
dose_time.strftime("%c"),
timezone,
since_dose_seconds,
)
else:
re = utils.str.format(
"You last dosed %s of %s via %s at %s %s, %T ago",
dose,
drug,
method,
dose_time.strftime("%c"),
timezone,
since_dose_seconds,
)
irc.reply(re)
else:
irc.error(f"No doses saved for {nick}")
@wrap(["positiveInt"])
def listdose(self, irc, msg, args, history):
"""<n>
retrieves your <n> last logged doses
"""
if history > 20:
irc.error("you can't retrieve more than 20 doses")
return
nick = msg.nick
if nick in self.db:
try:
rangecheck = self.db[nick]["doses"][-int(history)]
irc.reply(f"Your last {history} doses logged are:", private=True)
for number in range(history, 0, -1):
lastdose = self.db[nick]["doses"][-int(number)]
dose = lastdose["dose"]
drug = lastdose["drug"]
method = lastdose["method"]
dose_time = lastdose["time"]
timezone = self.db[nick]["timezone"]
tz = pytz.timezone(str(timezone))
time = datetime.datetime.now(tz=tz)
since_dose = time - dose_time
since_dose_seconds = since_dose.total_seconds()
if number == 1:
number = "The"
else:
number = num2words(number, to="ordinal")
re = utils.str.format(
"::> %i last dose: Amount: %s of \x02%s\x0F via %s | datetime: %s %s | timedelta %T ",
number,
dose,
drug,
method,
dose_time.strftime("%c"),
timezone,
since_dose_seconds,
)
irc.reply(re, private=True)
except IndexError:
irc.error("You haven't logged that many doses")
return
else:
irc.error(f"No doses saved for {nick}")
@wrap(["something"])
def amountdosed(self, irc, msg, args, drug):
"""<drug>
shows Aggregate amount in "mg" for <drug> ever logged
"""
num = 0
unit = ""
nick = msg.nick
if nick in self.db:
doselogs = self.db[nick]["doses"]
for doselog in doselogs:
if doselog["drug"] == drug:
for i, c in enumerate(doselog["dose"]):
if not c.isdigit():
break
num += int(doselog["dose"][:i])
unit = doselog["dose"][i:].lstrip()
irc.reply(f"You have dosed a total of {num}{unit} amount of {drug}")
else:
irc.error(f"No doses saved for {nick}")
Class = Tripsit
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: