2020-09-01 18:04:31 +02:00
###
# Copyright (c) 2020, mogad0n
# All rights reserved.
#
2024-10-29 21:49:06 +01:00
# Redistribution and use in source and binary forms, with or wthout
2020-09-01 18:04:31 +02:00
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions, and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions, and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the author of this software nor the name of
# contributors to this software may be used to endorse or promote products
# derived from this software without specific prior written consent.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
###
2020-09-05 10:32:51 +02:00
from supybot import utils , plugins , ircutils , callbacks , world , conf , log
2020-09-01 18:04:31 +02:00
from supybot . commands import *
2021-01-10 20:38:06 +01:00
from num2words import num2words
2020-09-05 10:32:51 +02:00
import pickle
2020-09-17 09:45:49 +02:00
import datetime
2020-10-11 22:57:58 +02:00
import pytz
2020-09-01 18:04:31 +02:00
try :
from supybot . i18n import PluginInternationalization
_ = PluginInternationalization ( ' Tripsit ' )
except ImportError :
# Placeholder that allows to run the plugin on a bot
# without the i18n module
_ = lambda x : x
2020-09-05 10:32:51 +02:00
filename = conf . supybot . directories . data . dirize ( " Tripsit.db " )
2020-09-01 18:04:31 +02:00
2021-01-03 00:38:12 +01:00
insufflated = [ " Insufflation " , " Insufflation-IR " , " Insufflation-XR " ]
2020-09-01 18:04:31 +02:00
METHODS = {
" iv " : [ " IV " ] ,
" shot " : [ " IV " ] ,
" im " : [ " IM " ] ,
" oral " : [ " Oral " , " Oral-IR " , " Oral-XR " ] ,
2020-09-05 10:32:51 +02:00
" insufflated " : insufflated ,
" snorted " : insufflated ,
2020-09-01 18:04:31 +02:00
" smoked " : [ " Smoked " ]
}
2024-11-01 20:28:58 +01:00
2020-09-01 18:04:31 +02:00
class Tripsit ( callbacks . Plugin ) :
""" Harm-Reduction tools from tripsit ' s tripbot and the tripsitwiki """
threaded = True
2020-09-05 10:32:51 +02:00
def __init__ ( self , irc ) :
self . __parent = super ( Tripsit , self )
self . __parent . __init__ ( irc )
self . db = { }
self . _loadDb ( )
world . flushers . append ( self . _flushDb )
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 ( " Tripsit: 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 ( " Tripsit: Unable to write pickled database: %s " , e )
def die ( self ) :
self . _flushDb ( )
world . flushers . remove ( self . _flushDb )
self . __parent . die ( )
2020-10-11 22:57:58 +02:00
def set ( self , irc , msg , args , timezone ) :
""" <timezone>
2021-01-03 00:38:12 +01:00
Sets location for your current nick to < timezone >
2020-10-11 22:57:58 +02:00
for eg . America / Chicago
"""
nick = msg . nick
2021-01-03 00:38:12 +01:00
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 )
2020-10-11 22:57:58 +02:00
set = wrap ( set , [ " something " ] )
2021-06-30 04:30:41 +02:00
@wrap ( [ getopts ( { ' ago ' : ' something ' } ) , " something " , " something " , optional ( " something " ) ] )
2021-01-03 13:53:12 +01:00
def idose ( self , irc , msg , args , opts , dose , name , method ) :
""" [--ago <HHMM>] <amount> <drug> [<method/ROA>]
2020-10-11 22:57:58 +02:00
2021-06-30 04:30:41 +02:00
logs a dose for your < nick > , eg . @idose - - ago 0100 20 mg mph oral
would log that dose as if it was taken an hour ago
[ - - ago ] and [ ROA ] fields are optional
2020-09-05 05:51:17 +02:00
"""
2021-01-03 00:38:12 +01:00
opts = dict ( opts )
2020-09-05 05:51:17 +02:00
found_method = False
onset = None
2024-10-29 21:49:06 +01:00
methods = [ ]
if method :
methods = [ method . lower ( ) ]
methods = METHODS . get ( methods [ 0 ] , methods )
2020-09-17 19:18:05 +02:00
drug_and_method = name
2020-09-05 05:51:17 +02:00
if method :
if not found_method :
2024-10-29 21:49:06 +01:00
method = method
2020-09-05 05:51:17 +02:00
drug_and_method = " %s via %s " % ( drug_and_method , method )
2020-09-17 19:13:55 +02:00
else :
2020-10-11 22:57:58 +02:00
method = ' Undefined '
nick = msg . nick
if nick in self . db :
timezone = self . db [ nick ] . get ( ' timezone ' , ' UTC ' )
2021-01-03 00:38:12 +01:00
tz = pytz . timezone ( str ( timezone ) )
2020-10-11 22:57:58 +02:00
time = datetime . datetime . now ( tz = tz )
dose_td = 0
2021-01-03 00:38:12 +01:00
if ' ago ' in opts and len ( opts [ ' ago ' ] ) == 4 :
ago = opts [ ' ago ' ]
2020-10-11 22:57:58 +02:00
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
2020-10-31 16:11:10 +01:00
doseLog = { ' time ' : time , ' dose ' : dose , ' drug ' : name , ' method ' : method }
2020-10-11 22:57:58 +02:00
doses = self . db [ nick ] . get ( ' doses ' )
if doses :
doses . append ( doseLog )
else :
doses = [ doseLog ]
self . db [ nick ] [ ' doses ' ] = doses
2020-09-17 07:55:24 +02:00
else :
2020-10-11 22:57:58 +02:00
timezone = ' UTC '
2021-01-03 01:27:31 +01:00
tz = pytz . timezone ( timezone )
time = datetime . datetime . now ( tz = tz )
2020-10-11 22:57:58 +02:00
dose_td = 0
2021-01-03 00:38:12 +01:00
if ' ago ' in opts and len ( opts [ ' ago ' ] ) == 4 :
ago = opts [ ' ago ' ]
2020-10-11 22:57:58 +02:00
dose_td = datetime . timedelta ( hours = int ( ago [ 0 : 2 ] ) , minutes = int ( ago [ 2 : 4 ] ) )
2020-10-31 16:11:10 +01:00
dose_td_s = dose_td . total_seconds ( )
2020-10-11 22:57:58 +02:00
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 :
2021-07-14 02:18:16 +02:00
re = utils . str . format ( " You dosed %s of %s at %s , %s " , dose , drug_and_method , time . strftime ( " %c " ) , timezone )
2020-10-11 22:57:58 +02:00
if onset is not None :
re + = utils . str . format ( " . You should start feeling effects %s from now " , onset )
else :
2021-07-14 02:18:16 +02:00
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 ( ) )
2020-10-11 22:57:58 +02:00
if onset is not None :
re + = utils . str . format ( " . You should have/will start feeling effects %s from/after dosing " , onset )
2020-09-05 05:51:17 +02:00
irc . reply ( re )
2020-09-17 07:55:24 +02:00
2024-10-29 21:49:06 +01:00
@wrap ( [ optional ( ' positiveInt ' ) ] )
2021-06-30 04:30:41 +02:00
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 } ' )
2024-10-29 21:49:06 +01:00
def doseslogged ( self , irc , msg , args ) :
2021-06-30 04:38:49 +02:00
"""
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 ' ] )
2021-07-14 02:18:16 +02:00
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 } " )
2021-06-30 04:38:49 +02:00
except IndexError :
2024-10-29 21:49:06 +01:00
irc . error ( " Can ' t seem to do math, check logs " )
2021-06-30 04:38:49 +02:00
else :
irc . error ( f " No doses saved for { nick } " )
2024-10-29 21:49:06 +01:00
doseslogged = wrap ( doseslogged )
2021-06-30 04:38:49 +02:00
2020-10-11 22:57:58 +02:00
@wrap ( [ optional ( ' positiveInt ' ) ] )
def lastdose ( self , irc , msg , args , history ) :
2020-10-31 16:11:10 +01:00
""" <n>
retrieves your < n > th last logged dose
2020-09-05 05:51:17 +02:00
"""
2020-10-11 22:57:58 +02:00
nick = msg . nick
if nick in self . db :
if history :
2021-01-03 00:38:12 +01:00
try :
lastdose = self . db [ nick ] [ ' doses ' ] [ - int ( history ) ]
except IndexError :
irc . error ( " You haven ' t logged that many doses " )
2021-01-03 13:53:12 +01:00
return
2020-10-11 22:57:58 +02:00
else :
lastdose = self . db [ nick ] [ ' doses ' ] [ - 1 ]
dose = lastdose [ ' dose ' ]
drug = lastdose [ ' drug ' ]
2021-01-03 00:38:12 +01:00
method = lastdose [ ' method ' ]
2020-10-11 22:57:58 +02:00
dose_time = lastdose [ ' time ' ]
timezone = self . db [ nick ] [ ' timezone ' ]
2021-01-03 00:38:12 +01:00
tz = pytz . timezone ( str ( timezone ) )
2020-10-11 22:57:58 +02:00
time = datetime . datetime . now ( tz = tz )
2020-09-05 10:32:51 +02:00
since_dose = time - dose_time
since_dose_seconds = since_dose . total_seconds ( )
2020-10-11 22:57:58 +02:00
if history :
2021-01-11 14:16:36 +01:00
history = num2words ( history , to = ' ordinal ' )
2024-10-29 21:49:06 +01:00
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 )
2020-10-11 22:57:58 +02:00
else :
2024-10-29 21:49:06 +01:00
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 )
2020-09-05 05:51:17 +02:00
irc . reply ( re )
else :
2020-10-11 22:57:58 +02:00
irc . error ( f ' No doses saved for { nick } ' )
2021-01-03 13:53:12 +01:00
2024-10-29 21:49:06 +01:00
@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 } ' )
2024-10-29 22:42:14 +01:00
@wrap ( [ " something " ] )
def grepdose ( self , irc , msg , args , drug ) :
""" <drug>
2024-10-29 21:49:06 +01:00
2024-10-29 22:42:14 +01:00
pulls most recent dose for drug
"""
nick = msg . nick
if nick in self . db :
doselogs = self . db [ nick ] [ ' doses ' ]
found = False
for doselog in reversed ( doselogs ) :
if doselog [ ' drug ' ] == drug :
timezone = self . db [ nick ] [ ' timezone ' ]
tz = pytz . timezone ( str ( timezone ) )
now = datetime . datetime . now ( tz = tz )
since_dose = now - doselog [ ' time ' ]
re = utils . str . format ( " You last dosed %s of %s via %s at %s %s , % T ago " , doselog [ " dose " ] , doselog [ " drug " ] , doselog [ " method " ] , doselog [ " time " ] . strftime ( " %c " ) , timezone , since_dose . total_seconds ( ) )
irc . reply ( re )
found = True
break
if not found :
irc . error ( f " No doses saved for { drug } " )
else :
irc . error ( f " No doses saved for { nick } " )
2024-10-29 21:49:06 +01:00
@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 } " )
2020-09-01 18:04:31 +02:00
Class = Tripsit
2021-01-10 20:38:06 +01:00
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: