StimWebTracker/main.py
2025-10-10 11:44:58 -05:00

140 lines
4.8 KiB
Python

from flask import Flask, render_template, request, redirect, url_for
import sqlite3
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import io
import base64
from datetime import datetime, timedelta
import os
app = Flask(__name__)
# Pharmacokinetics parameters (in minutes)
# ln(2) / (Half-life-in-minutes)
CAFFEINE_ABSORPTION_RATE = 0.05 # per minute (half-life ~15 min)
CAFFEINE_ELIMINATION_RATE = 0.0023 # per minute (half-life ~5 hours)
AMPHETAMINE_ABSORPTION_RATE = 0.03 # per minute (half-life ~20 min)
AMPHETAMINE_ELIMINATION_RATE = 0.0013 # per minute (half-life ~9 hours)
# Initialize database
def init_db():
conn = sqlite3.connect('stimulants.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS doses
(id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp DATETIME,
type TEXT,
amount INTEGER)''')
conn.commit()
conn.close()
# Calculate stimulant amount at given time
def calculate_amount(doses, time, k_abs, k_elim):
total = 0
for dose in doses:
dose_time = datetime.strptime(dose[0], '%Y-%m-%d %H:%M:%S')
t = (time - dose_time).total_seconds() / 60 # convert to minutes
if t >= 0:
# One-compartment model with first-order absorption
total += dose[1] * (k_abs / (k_abs - k_elim)) * (
np.exp(-k_elim * t) - np.exp(-k_abs * t)
)
return total
# Generate graph for past 24 hours
def generate_graph():
# Get current time and 24 hours ago
now = datetime.now()
start_time = now - timedelta(hours=24)
# Create time points (every 10 minutes)
times = [start_time + timedelta(minutes=i*10) for i in range(144)]
# Get all doses from database
conn = sqlite3.connect('stimulants.db')
c = conn.cursor()
c.execute("SELECT timestamp, amount FROM doses WHERE type='caffeine'")
caffeine_doses = c.fetchall()
c.execute("SELECT timestamp, amount FROM doses WHERE type='amphetamine'")
amphetamine_doses = c.fetchall()
conn.close()
# Calculate amounts for each time point
caffeine_levels = [calculate_amount(caffeine_doses, t,
CAFFEINE_ABSORPTION_RATE,
CAFFEINE_ELIMINATION_RATE) for t in times]
amphetamine_levels = [calculate_amount(amphetamine_doses, t,
AMPHETAMINE_ABSORPTION_RATE,
AMPHETAMINE_ELIMINATION_RATE) for t in times]
# Create plot
plt.figure(figsize=(12, 6))
plt.plot(times, caffeine_levels, 'b-', label='Caffeine (mg)')
plt.plot(times, amphetamine_levels, 'r-', label='Amphetamine (mg)')
plt.xlabel('Time')
plt.ylabel('Estimated Amount (mg)')
plt.title('Stimulant Levels in Body (Past 24 Hours)')
plt.legend()
plt.grid(True)
# Format x-axis
ax = plt.gca()
ax.xaxis.set_major_locator(matplotlib.dates.HourLocator(interval=4))
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter('%H:%M'))
# Convert to base64 string
img = io.BytesIO()
plt.savefig(img, format='png')
img.seek(0)
graph_url = base64.b64encode(img.getvalue()).decode()
plt.close()
return graph_url
@app.route('/')
def index():
# Calculate current amounts
now = datetime.now()
conn = sqlite3.connect('stimulants.db')
c = conn.cursor()
c.execute("SELECT timestamp, amount FROM doses WHERE type='caffeine'")
caffeine_doses = c.fetchall()
c.execute("SELECT timestamp, amount FROM doses WHERE type='amphetamine'")
amphetamine_doses = c.fetchall()
conn.close()
caffeine_amount = calculate_amount(caffeine_doses, now,
CAFFEINE_ABSORPTION_RATE,
CAFFEINE_ELIMINATION_RATE)
amphetamine_amount = calculate_amount(amphetamine_doses, now,
AMPHETAMINE_ABSORPTION_RATE,
AMPHETAMINE_ELIMINATION_RATE)
# Generate graph
graph_url = generate_graph()
return render_template('index.html',
caffeine_amount=round(caffeine_amount, 2),
amphetamine_amount=round(amphetamine_amount, 2),
graph_url=graph_url)
@app.route('/add_dose', methods=['POST'])
def add_dose():
stim_type = request.form['type']
amount = 10 # Fixed 10mg amount
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
conn = sqlite3.connect('stimulants.db')
c = conn.cursor()
c.execute("INSERT INTO doses (timestamp, type, amount) VALUES (?, ?, ?)",
(timestamp, stim_type, amount))
conn.commit()
conn.close()
return redirect(url_for('index'))
if __name__ == '__main__':
init_db()
app.run(debug=True)