2020-09-01 21:34:31 +05:30
###
# Copyright (c) 2020, mogad0n
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# 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.
###
2021-06-30 08:00:41 +05:30
from humanize import ordinal
2020-09-05 14:02:51 +05:30
from supybot import utils , plugins , ircutils , callbacks , world , conf , log
2020-09-01 21:34:31 +05:30
from supybot . commands import *
2021-01-11 01:08:06 +05:30
from num2words import num2words
2020-09-05 09:21:17 +05:30
import dateutil . parser
2020-09-01 21:34:31 +05:30
import json
import requests
2020-09-05 14:02:51 +05:30
import pickle
import sys
2020-09-17 13:15:49 +05:30
import datetime
2020-09-18 12:46:42 +05:30
import time
2020-10-12 02:27:58 +05:30
import pytz
2020-09-01 21:34:31 +05:30
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 14:02:51 +05:30
filename = conf . supybot . directories . data . dirize ( " Tripsit.db " )
2020-09-01 21:34:31 +05:30
2020-09-05 14:02:51 +05:30
url_drug = " http://tripbot.tripsit.me/api/tripsit/getDrug "
url_combo = " http://tripbot.tripsit.me/api/tripsit/getInteraction "
2021-01-03 05:08:12 +05:30
insufflated = [ " Insufflation " , " Insufflation-IR " , " Insufflation-XR " ]
2020-09-01 21:34:31 +05:30
METHODS = {
" iv " : [ " IV " ] ,
" shot " : [ " IV " ] ,
" im " : [ " IM " ] ,
" oral " : [ " Oral " , " Oral-IR " , " Oral-XR " ] ,
2020-09-05 14:02:51 +05:30
" insufflated " : insufflated ,
" snorted " : insufflated ,
2020-09-01 21:34:31 +05:30
" smoked " : [ " Smoked " ]
}
class Tripsit ( callbacks . Plugin ) :
""" Harm-Reduction tools from tripsit ' s tripbot and the tripsitwiki """
threaded = True
2020-09-05 14:02:51 +05:30
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-09-01 21:34:31 +05:30
@wrap ( [ ' something ' , optional ( ' something ' ) ] )
def drug ( self , irc , msg , args , name , category ) :
""" <drug> [<category>]
2021-01-03 05:08:12 +05:30
2020-09-01 21:34:31 +05:30
fetches data on drug from tripsit wiki
"""
category_list = [ ]
2020-09-05 14:02:51 +05:30
r = requests . get ( url_drug , params = { " name " : name } ) . json ( )
2020-09-01 21:34:31 +05:30
if not r [ ' err ' ] :
drug = r [ " data " ] [ 0 ] [ " pretty_name " ]
properties = r [ " data " ] [ 0 ] [ " properties " ]
2020-09-05 14:02:51 +05:30
for key in properties :
category_list . append ( key )
2021-01-03 05:08:12 +05:30
if category is None :
2020-09-05 14:02:51 +05:30
re = drug + " Available categories are: " + " , " . join ( category_list )
2020-09-01 21:34:31 +05:30
irc . reply ( re )
else :
if category in properties . keys ( ) :
2020-09-05 14:02:51 +05:30
re = drug + " " + properties [ category ]
2020-09-01 21:34:31 +05:30
irc . reply ( re )
else :
2020-09-05 14:02:51 +05:30
irc . error ( f " Unknown category { drug } Available categories are: " + " , " . join ( category_list ) )
2020-09-01 21:34:31 +05:30
else :
irc . error ( " unknown drug " )
def combo ( self , irc , msg , args , drugA , drugB ) :
""" <drugA> <drugB>
2021-01-03 05:08:12 +05:30
2020-09-05 14:02:51 +05:30
fetches known interactions between the substances provided .
2020-09-01 21:34:31 +05:30
"""
2020-10-31 20:41:10 +05:30
r = requests . get ( url_combo , params = { f " drugA " : drugA , f " drugB " : drugB } ) . json ( )
2020-09-01 21:34:31 +05:30
if not r [ " err " ] and r [ " data " ] [ 0 ] :
interaction = r [ " data " ] [ 0 ]
drug_a = interaction [ " interactionCategoryA " ]
drug_b = interaction [ " interactionCategoryB " ]
interaction_status = interaction [ " status " ]
2020-09-05 14:02:51 +05:30
re = f " { drug_a } and { drug_b } : { interaction_status } "
if ' note ' in interaction :
note = interaction [ " note " ]
re + = f ' . Note: { note } '
irc . reply ( re )
else :
irc . reply ( re )
2020-09-01 21:34:31 +05:30
else :
2020-09-05 14:02:51 +05:30
irc . reply ( " Unknown combo (that doesn ' t mean it ' s safe). Known combos: lsd, mushrooms, dmt, mescaline, dox, nbomes, 2c-x, 2c-t-x, amt, 5-meo-xxt, cannabis, ketamine, mxe, dxm, pcp, nitrous, amphetamines, mdma, cocaine, caffeine, alcohol, ghb/gbl, opioids, tramadol, benzodiazepines, maois, ssris. " )
2020-09-01 21:34:31 +05:30
combo = wrap ( combo , [ ( " something " ) , ( " something " ) ] )
2020-10-12 02:27:58 +05:30
def set ( self , irc , msg , args , timezone ) :
""" <timezone>
2021-01-03 05:08:12 +05:30
Sets location for your current nick to < timezone >
2020-10-12 02:27:58 +05:30
for eg . America / Chicago
"""
nick = msg . nick
2021-01-03 05:08:12 +05:30
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-12 02:27:58 +05:30
set = wrap ( set , [ " something " ] )
2021-06-30 08:00:41 +05:30
@wrap ( [ getopts ( { ' ago ' : ' something ' } ) , " something " , " something " , optional ( " something " ) ] )
2021-01-03 18:23:12 +05:30
def idose ( self , irc , msg , args , opts , dose , name , method ) :
""" [--ago <HHMM>] <amount> <drug> [<method/ROA>]
2020-10-12 02:27:58 +05:30
2021-06-30 08:00:41 +05:30
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 09:21:17 +05:30
"""
2021-01-03 05:08:12 +05:30
opts = dict ( opts )
2020-09-05 14:02:51 +05:30
r = requests . get ( url_drug , params = { " name " : name } ) . json ( )
2020-09-05 09:21:17 +05:30
found_method = False
onset = None
if not r [ ' err ' ] :
drug = r [ ' data ' ] [ 0 ]
2020-09-17 22:37:22 +05:30
drug_name = drug [ ' pretty_name ' ]
2020-09-05 09:21:17 +05:30
method_keys = [ ' value ' ]
methods = [ ]
if method :
methods = [ method . lower ( ) ]
methods = METHODS . get ( methods [ 0 ] , methods )
method_keys + = methods
if ' formatted_onset ' in drug :
match = list ( set ( method_keys ) &
set ( drug [ " formatted_onset " ] . keys ( ) ) )
if match :
onset = drug [ " formatted_onset " ] [ match [ 0 ] ]
found_method = True
if match [ 0 ] in methods :
method = ( match or [ method ] ) [ 0 ]
if onset and " _unit " in drug [ " formatted_onset " ] :
onset = " %s %s " % (
onset , drug [ " formatted_onset " ] [ " _unit " ] )
2020-09-17 22:48:05 +05:30
drug_and_method = name
2020-09-05 09:21:17 +05:30
if method :
if not found_method :
method = method . title ( )
drug_and_method = " %s via %s " % ( drug_and_method , method )
2020-09-17 22:43:55 +05:30
else :
2020-10-12 02:27:58 +05:30
method = ' Undefined '
nick = msg . nick
if nick in self . db :
timezone = self . db [ nick ] . get ( ' timezone ' , ' UTC ' )
2021-01-03 05:08:12 +05:30
tz = pytz . timezone ( str ( timezone ) )
2020-10-12 02:27:58 +05:30
time = datetime . datetime . now ( tz = tz )
dose_td = 0
2021-01-03 05:08:12 +05:30
if ' ago ' in opts and len ( opts [ ' ago ' ] ) == 4 :
ago = opts [ ' ago ' ]
2020-10-12 02:27:58 +05:30
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 20:41:10 +05:30
doseLog = { ' time ' : time , ' dose ' : dose , ' drug ' : name , ' method ' : method }
2020-10-12 02:27:58 +05:30
doses = self . db [ nick ] . get ( ' doses ' )
if doses :
doses . append ( doseLog )
else :
doses = [ doseLog ]
self . db [ nick ] [ ' doses ' ] = doses
2020-09-17 11:25:24 +05:30
else :
2020-10-12 02:27:58 +05:30
timezone = ' UTC '
2021-01-03 05:57:31 +05:30
tz = pytz . timezone ( timezone )
time = datetime . datetime . now ( tz = tz )
2020-10-12 02:27:58 +05:30
dose_td = 0
2021-01-03 05:08:12 +05:30
if ' ago ' in opts and len ( opts [ ' ago ' ] ) == 4 :
ago = opts [ ' ago ' ]
2020-10-12 02:27:58 +05:30
dose_td = datetime . timedelta ( hours = int ( ago [ 0 : 2 ] ) , minutes = int ( ago [ 2 : 4 ] ) )
2020-10-31 20:41:10 +05:30
dose_td_s = dose_td . total_seconds ( )
2020-10-12 02:27:58 +05:30
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 05:48:16 +05:30
re = utils . str . format ( " You dosed %s of %s at %s , %s " , dose , drug_and_method , time . strftime ( " %c " ) , timezone )
2020-10-12 02:27:58 +05:30
if onset is not None :
re + = utils . str . format ( " . You should start feeling effects %s from now " , onset )
else :
2021-07-14 05:48:16 +05:30
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-12 02:27:58 +05:30
if onset is not None :
re + = utils . str . format ( " . You should have/will start feeling effects %s from/after dosing " , onset )
2020-09-05 09:21:17 +05:30
irc . reply ( re )
2020-09-17 11:25:24 +05:30
2021-07-14 06:46:42 +05:30
@wrap ( [ optional ( ' positiveInt ' ) ] )
2021-06-30 08:00:41 +05:30
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 } ' )
2021-07-14 06:46:42 +05:30
def doseslogged ( self , irc , msg , args ) :
2021-06-30 08:08:49 +05:30
"""
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 05:48:16 +05:30
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 08:08:49 +05:30
except IndexError :
irc . error ( f " Can ' t seem to do math, check logs " )
else :
irc . error ( f " No doses saved for { nick } " )
2021-07-14 06:46:42 +05:30
doseslogged = wrap ( doseslogged )
2021-06-30 08:08:49 +05:30
2020-10-12 02:27:58 +05:30
@wrap ( [ optional ( ' positiveInt ' ) ] )
def lastdose ( self , irc , msg , args , history ) :
2020-10-31 20:41:10 +05:30
""" <n>
retrieves your < n > th last logged dose
2020-09-05 09:21:17 +05:30
"""
2020-10-12 02:27:58 +05:30
nick = msg . nick
if nick in self . db :
if history :
2021-01-03 05:08:12 +05:30
try :
lastdose = self . db [ nick ] [ ' doses ' ] [ - int ( history ) ]
except IndexError :
irc . error ( " You haven ' t logged that many doses " )
2021-01-03 18:23:12 +05:30
return
2020-10-12 02:27:58 +05:30
else :
lastdose = self . db [ nick ] [ ' doses ' ] [ - 1 ]
dose = lastdose [ ' dose ' ]
drug = lastdose [ ' drug ' ]
2021-01-03 05:08:12 +05:30
method = lastdose [ ' method ' ]
2020-10-12 02:27:58 +05:30
dose_time = lastdose [ ' time ' ]
timezone = self . db [ nick ] [ ' timezone ' ]
2021-01-03 05:08:12 +05:30
tz = pytz . timezone ( str ( timezone ) )
2020-10-12 02:27:58 +05:30
time = datetime . datetime . now ( tz = tz )
2020-09-05 14:02:51 +05:30
since_dose = time - dose_time
since_dose_seconds = since_dose . total_seconds ( )
2020-10-12 02:27:58 +05:30
if history :
2021-01-11 18:46:36 +05:30
history = num2words ( history , to = ' ordinal ' )
2021-07-14 06:46:42 +05:30
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-12 02:27:58 +05:30
else :
2021-07-14 06:46:42 +05:30
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 09:21:17 +05:30
irc . reply ( re )
else :
2020-10-12 02:27:58 +05:30
irc . error ( f ' No doses saved for { nick } ' )
2021-01-03 18:23:12 +05:30
2020-09-01 21:34:31 +05:30
Class = Tripsit
2021-01-11 01:08:06 +05:30
# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: