#!/usr/bin/env python3 # -*- coding: utf-8 -*- """Flask web server for the song projector application. HTML, CSS and JavaScript are now stored in separate template/static files rather than being generated inside Python code. """ import threading import os from flask import Flask, render_template, request, jsonify # create Flask app with proper folders relative to this file app = Flask(__name__, static_folder="static", template_folder="templates") # Globalna referenca na SongProjector aplikaciju _projector_app = None def set_projector_app(projector_app): """Postavi referenco na SongProjector aplikacijo""" global _projector_app _projector_app = projector_app # ---------------------------------------------------------- # Flask rute # ---------------------------------------------------------- @app.route("/", methods=["GET"]) def index(): """Prikaže glavno HTML stranko""" # predaja nadzora Jinja2, ki poišče web/templates/index.html return render_template("index.html") @app.route('/api/state', methods=['GET']) def get_state(): """Vrati trenutno stanje aplikacije""" if _projector_app is None: return jsonify({ 'current_text': 'Napaka: Aplikacija ni inicijalizirana', 'page_info': '', 'caps_mode': False, 'can_prev': False, 'can_next': False }) current_text = "" page_info = "" can_prev = False can_next = False if _projector_app.pages: current_text = _projector_app.pages[_projector_app.current_page_index] if _projector_app.all_caps_mode: current_text = current_text.upper() current_page = _projector_app.current_page_index + 1 total_pages = len(_projector_app.pages) page_info = f"{_projector_app.song_number_last} {current_page}/{total_pages}" can_prev = _projector_app.current_page_index > 0 can_next = _projector_app.current_page_index + 1 < len(_projector_app.pages) else: current_text = "Pripravljeno. Vpiši številko pesmi." return jsonify({ 'current_text': current_text, 'page_info': page_info, 'caps_mode': _projector_app.all_caps_mode, 'can_prev': can_prev, 'can_next': can_next }) @app.route('/api/load_song', methods=['POST']) def load_song(): """Naloži pesem po številki""" if _projector_app is None: return jsonify({'status': 'error', 'message': 'Aplikacija ni inicijalizirana'}) data = request.get_json() song_number = data.get('song_number', '').strip() if song_number: _projector_app.song_number = song_number _projector_app.load_song() if hasattr(_projector_app, 'show_page'): _projector_app.show_page() return jsonify({'status': 'ok'}) @app.route('/api/next_page', methods=['POST']) def next_page(): """Naslednja stran""" if _projector_app is not None: _projector_app.next_page() return jsonify({'status': 'ok'}) @app.route('/api/prev_page', methods=['POST']) def prev_page(): """Prejšnja stran""" if _projector_app is not None: _projector_app.prev_page() return jsonify({'status': 'ok'}) @app.route('/api/clear_screen', methods=['POST']) def clear_screen(): """Zatemniti ekran""" if _projector_app is not None: _projector_app.clear_screen() return jsonify({'status': 'ok'}) @app.route('/api/toggle_caps', methods=['POST']) def toggle_caps(): """Preklop med velikimi in malimi črkami""" if _projector_app is not None: _projector_app.all_caps_mode = not _projector_app.all_caps_mode _projector_app.show_page() return jsonify({'status': 'ok'}) @app.route('/api/search_songs', methods=['POST']) def search_songs(): """Iskanje pesmi po naslovu""" if _projector_app is None: return jsonify({'results': []}) data = request.get_json() query = data.get('query', '').strip() if not query: return jsonify({'results': []}) try: _projector_app.cursor.execute( "SELECT id, title FROM songs WHERE title LIKE ? COLLATE NOCASE", (f"%{query}%",) ) results = _projector_app.cursor.fetchall() return jsonify({'results': results}) except Exception as e: return jsonify({'error': str(e)}) def run_server(host='127.0.0.1', port=5000): """Zaženi Flask server""" app.run(host=host, port=port, debug=False, use_reloader=False, threaded=True) def start_server_thread(projector_app, host='127.0.0.1', port=5000): """Zaženi server v zvjenoj niti""" set_projector_app(projector_app) server_thread = threading.Thread( target=run_server, args=(host, port), daemon=True ) server_thread.start() return server_thread