import os import json import threading import time import uuid from datetime import datetime, timedelta import zoneinfo from flask import Flask, render_template_string, request, jsonify from huggingface_hub import HfApi, hf_hub_download from huggingface_hub.utils import RepositoryNotFoundError app = Flask(__name__) app.secret_key = os.getenv("FLASK_SECRET_KEY", "med_tracker_secret_key") DATA_FILE = 'medications_data.json' REPO_ID = os.getenv("REPO_ID", "Kgshop/clients") HF_TOKEN_WRITE = os.getenv("HF_TOKEN") HF_TOKEN_READ = os.getenv("HF_TOKEN_READ") def load_data(): try: hf_hub_download( repo_id=REPO_ID, filename=DATA_FILE, repo_type="dataset", token=HF_TOKEN_READ, local_dir=".", local_dir_use_symlinks=False ) with open(DATA_FILE, 'r', encoding='utf-8') as f: data = json.load(f) if not isinstance(data, dict) or 'schedules' not in data: return {'schedules': []} return data except Exception: return {'schedules': []} def save_data(data): with open(DATA_FILE, 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=4) try: api = HfApi() api.upload_file( path_or_fileobj=DATA_FILE, path_in_repo=DATA_FILE, repo_id=REPO_ID, repo_type="dataset", token=HF_TOKEN_WRITE ) except Exception: pass def periodic_backup(): while True: try: data = load_data() save_data(data) except Exception: pass time.sleep(800) HTML_CONTENT = ''' MedTracker
''' @app.route('/') def index(): return render_template_string(HTML_CONTENT) @app.route('/api/data', methods=['GET']) def get_data(): return jsonify(load_data()) @app.route('/api/schedules/special', methods=['POST']) def create_special(): data_req = request.json start_date_str = data_req.get('start_date') start_date = datetime.strptime(start_date_str, "%Y-%m-%d").date() schedule = { "id": str(uuid.uuid4()), "name": "Пробиотик + Нистатин (42 дня)", "start_date": start_date_str, "days": [] } for day_idx in range(42): current_date = start_date + timedelta(days=day_idx) day_data = { "day_number": day_idx + 1, "date": current_date.strftime("%Y-%m-%d"), "doses": [] } day_data["doses"].append({ "id": str(uuid.uuid4()), "medication": "Пробиотик", "label": "Утро", "taken": False, "taken_at": None }) day_data["doses"].append({ "id": str(uuid.uuid4()), "medication": "Пробиотик", "label": "Вечер", "taken": False, "taken_at": None }) if (7 <= day_idx < 21) or (28 <= day_idx < 42): day_data["doses"].append({ "id": str(uuid.uuid4()), "medication": "Нистатин", "label": "Утро", "taken": False, "taken_at": None }) day_data["doses"].append({ "id": str(uuid.uuid4()), "medication": "Нистатин", "label": "День", "taken": False, "taken_at": None }) day_data["doses"].append({ "id": str(uuid.uuid4()), "medication": "Нистатин", "label": "Вечер", "taken": False, "taken_at": None }) schedule["days"].append(day_data) db = load_data() db['schedules'].append(schedule) save_data(db) return jsonify({"status": "ok"}) @app.route('/api/schedules/custom', methods=['POST']) def create_custom(): data_req = request.json start_date_str = data_req.get('start_date') name = data_req.get('name') duration = int(data_req.get('duration')) meds = data_req.get('meds') start_date = datetime.strptime(start_date_str, "%Y-%m-%d").date() schedule = { "id": str(uuid.uuid4()), "name": name, "start_date": start_date_str, "days": [] } for day_idx in range(duration): current_date = start_date + timedelta(days=day_idx) day_data = { "day_number": day_idx + 1, "date": current_date.strftime("%Y-%m-%d"), "doses": [] } for med in meds: times = int(med['times']) for t in range(times): day_data["doses"].append({ "id": str(uuid.uuid4()), "medication": med['name'], "label": f"Прием {t+1}", "taken": False, "taken_at": None }) schedule["days"].append(day_data) db = load_data() db['schedules'].append(schedule) save_data(db) return jsonify({"status": "ok"}) @app.route('/api/toggle', methods=['POST']) def toggle_dose(): data_req = request.json sched_id = data_req.get('schedule_id') dose_id = data_req.get('dose_id') val = data_req.get('value') db = load_data() tz = zoneinfo.ZoneInfo("Asia/Almaty") now_str = datetime.now(tz).strftime("%d.%m.%Y %H:%M") for s in db['schedules']: if s['id'] == sched_id: for d in s['days']: for dose in d['doses']: if dose['id'] == dose_id: dose['taken'] = val dose['taken_at'] = now_str if val else None save_data(db) return jsonify({"status": "ok", "taken_at": dose['taken_at']}) return jsonify({"status": "error"}), 404 @app.route('/api/schedules/delete', methods=['POST']) def delete_schedule(): data_req = request.json sched_id = data_req.get('schedule_id') db = load_data() db['schedules'] = [s for s in db['schedules'] if s['id'] != sched_id] save_data(db) return jsonify({"status": "ok"}) if __name__ == '__main__': backup_thread = threading.Thread(target=periodic_backup, daemon=True) backup_thread.start() try: load_data() except Exception: pass app.run(debug=False, host='0.0.0.0', port=7860)