diff --git a/app/main.py b/app/main.py index 274d509..dff4584 100644 --- a/app/main.py +++ b/app/main.py @@ -12,8 +12,7 @@ from sqlalchemy import text app = Flask(__name__) # --- Konfiguration --- -db_path = os.path.join('/app/data', 'raceplanner.db') -app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{db_path}' +app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', 'sqlite:////app/data/raceplanner.db') app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SECRET_KEY'] = 'renn-strategie-2026-final-v3' app.config['REMEMBER_COOKIE_DURATION'] = timedelta(days=31) @@ -34,7 +33,7 @@ class User(UserMixin, db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) password = db.Column(db.String(200), nullable=False) - theme = db.Column(db.String(20), default='light') + theme = db.Column(db.String(20), default='light') # 'light' oder 'dark' class RaceConfig(db.Model): id = db.Column(db.Integer, primary_key=True) @@ -64,6 +63,7 @@ def load_user(user_id): def get_calculated_schedule(car_num): config = RaceConfig.query.first() if not config: return [] + stints = Stint.query.filter_by(car_number=car_num).order_by(Stint.order).all() schedule = [] current_time = config.start_time @@ -72,10 +72,13 @@ def get_calculated_schedule(car_num): for i, stint in enumerate(stints): driver = stint.driver if not driver: continue - laps_possible = int(fuel_capacity / (driver.cons_per_lap or 1.0)) - duration_sec = laps_possible * (driver.avg_lap_time or 120.0) + + laps_possible = int(fuel_capacity / driver.cons_per_lap) + duration_sec = laps_possible * driver.avg_lap_time + start_str = current_time.strftime('%H:%M') end_time = current_time + timedelta(seconds=duration_sec) + schedule.append({ 'id': stint.id, 'number': i + 1, @@ -87,62 +90,12 @@ def get_calculated_schedule(car_num): 'laps': laps_possible, 'fuel': round(fuel_capacity, 1), 'change_tires': stint.change_tires, - 'is_finish': end_time >= (config.start_time + timedelta(hours=config.total_duration_h)) + 'is_finish': (current_time + timedelta(seconds=duration_sec)) >= (config.start_time + timedelta(hours=config.total_duration_h)) }) current_time = end_time return schedule -# --- Szenario Routen (Speichern/Laden) --- -@app.route('/save_scenario', methods=['POST']) -@login_required -def save_scenario(): - name = request.json.get('name', 'unnamed_scenario') - filename = f"{name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json" - - data = { - 'config': { - 'start_time': RaceConfig.query.first().start_time.isoformat(), - 'total_duration_h': RaceConfig.query.first().total_duration_h - }, - 'stints': [] - } - - for s in Stint.query.all(): - data['stints'].append({ - 'car_number': s.car_number, - 'driver_id': s.driver_id, - 'order': s.order, - 'change_tires': s.change_tires - }) - - with open(os.path.join(SCENARIO_DIR, filename), 'w') as f: - json.dump(data, f) - return jsonify({'status': 'ok', 'filename': filename}) - -@app.route('/list_scenarios') -@login_required -def list_scenarios(): - files = [f for f in os.listdir(SCENARIO_DIR) if f.endswith('.json')] - return jsonify(sorted(files, reverse=True)) - -@app.route('/load_scenario', methods=['POST']) -@login_required -def load_scenario(): - filename = request.json.get('filename') - path = os.path.join(SCENARIO_DIR, filename) - if not os.path.exists(path): - return jsonify({'status': 'error', 'message': 'Datei nicht gefunden'}) - - with open(path, 'r') as f: - data = json.load(f) - - Stint.query.delete() - for s_data in data['stints']: - db.session.add(Stint(**s_data)) - db.session.commit() - return jsonify({'status': 'ok'}) - -# --- Standard Routen --- +# --- Routen --- @app.route('/') @login_required def index(): @@ -168,9 +121,8 @@ def update_theme(): def update_stint_driver(): data = request.json s = db.session.get(Stint, data['stint_id']) - if s: - s.driver_id = data['driver_id'] - db.session.commit() + s.driver_id = data['driver_id'] + db.session.commit() return jsonify({'status': 'ok'}) @app.route('/reorder_stints', methods=['POST']) @@ -179,7 +131,7 @@ def reorder_stints(): order = request.json['order'] for idx, sid in enumerate(order): s = db.session.get(Stint, int(sid)) - if s: s.order = idx + s.order = idx db.session.commit() return jsonify({'status': 'ok'}) @@ -206,7 +158,7 @@ def driver_detail(id): @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': - u = User.query.filter_by(username='mscaltenbach').first() + u = User.query.filter_by(username=request.form.get('username')).first() if u and check_password_hash(u.password, request.form.get('password')): session.permanent = True login_user(u, remember=True) @@ -218,43 +170,24 @@ def logout(): logout_user() return redirect(url_for('login')) -def init_db(): +if __name__ == '__main__': with app.app_context(): db.create_all() + + # Manueller Fix: Spalte 'theme' hinzufügen, falls sie fehlt (SQLite-spezifisch) try: db.session.execute(text("ALTER TABLE user ADD COLUMN theme VARCHAR(20) DEFAULT 'light'")) db.session.commit() except Exception: + # Fehler tritt auf, wenn Spalte bereits existiert – das ist ok db.session.rollback() - target_username = 'mscaltenbach' - target_password = 'SendIt123!' - admin_user = User.query.filter_by(username=target_username).first() - if not admin_user: - hashed_pw = generate_password_hash(target_password) - db.session.add(User(username=target_username, password=hashed_pw, theme='light')) - db.session.commit() + if not User.query.filter_by(username='mscaltenbach').first(): + pw = generate_password_hash('admin123') + db.session.add(User(username='mscaltenbach', password=pw, theme='light')) if not RaceConfig.query.first(): - db.session.add(RaceConfig(start_time=datetime.now(), total_duration_h=24)) - db.session.commit() - - if not Driver.query.first(): - drivers = [ - Driver(name="Caltenbach", car_number=1, avg_lap_time=128.5, cons_per_lap=3.8), - Driver(name="Mueller", car_number=1, avg_lap_time=130.2, cons_per_lap=3.6), - Driver(name="Schmidt", car_number=2, avg_lap_time=129.1, cons_per_lap=3.7), - Driver(name="Weber", car_number=2, avg_lap_time=131.5, cons_per_lap=3.5) - ] - db.session.add_all(drivers) - db.session.commit() - d1, d2 = Driver.query.filter_by(car_number=1).first(), Driver.query.filter_by(car_number=2).first() - if d1 and d2: - for i in range(12): - db.session.add(Stint(car_number=1, driver_id=d1.id, order=i)) - db.session.add(Stint(car_number=2, driver_id=d2.id, order=i)) - db.session.commit() - -if __name__ == '__main__': - init_db() + db.session.add(RaceConfig()) + + db.session.commit() app.run(host='0.0.0.0', port=5000, debug=True) \ No newline at end of file diff --git a/app/templates/driver_detail.html b/app/templates/driver_detail.html index c9bb210..cbab630 100644 --- a/app/templates/driver_detail.html +++ b/app/templates/driver_detail.html @@ -1,83 +1,50 @@ - +
Driver Profile & Schedule
-Keine Stints geplant
-Endurance Strategy Engine
+ + +