Compare commits

...

5 Commits

Author SHA1 Message Date
3e73280e7a auto reload at file change 2025-04-12 20:49:48 +02:00
d99683eab9 readme fix 2025-04-02 15:32:51 +02:00
0148136180 readme fix 2025-04-02 15:24:33 +02:00
d8a8a6d16e added en/hu readme and license 2025-04-02 15:22:43 +02:00
40f0d05290 updated main.py for oe11 encoding 2025-04-02 12:42:55 +02:00
4 changed files with 186 additions and 67 deletions

7
LICENSE Normal file
View File

@@ -0,0 +1,7 @@
Copyright 2025 Norbert Jovari
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

82
README.en.md Normal file
View File

@@ -0,0 +1,82 @@
# SportSoftware OE HTML viewer
[![hu](https://img.shields.io/badge/lang-hu-blue.svg)](https://gitea.carburator.dev/carburator/oe-html-viewer/src/branch/main/README.md)
Simple Python script to serve the exported HTML results file from the SportSoftware OE application on the local network.
Use it to display the results on a TV or to serve results for the competitors.
## Features
<ul style="list-style-type: none"> ✅ Customizable auto-scroll (see Variables section) </ul>
<ul style="list-style-type: none"> ✅ Smooth scrolling </ul>
<ul style="list-style-type: none"> ✅ Auto-reload at bottom </ul>
<ul style="list-style-type: none"> ✅ Auto-reload at file change when no need for scrolling </ul>
<ul style="list-style-type: none"> ✅ Supports OE11 and OE12 exported HTML </ul>
<ul style="list-style-type: none"> ✅ File serving on localhost and LAN </ul>
### Variables
The following variables can be found at the top of the `main.py` script:
- `html_file_path`: Path to the HTML file to be served. Example: `C:\Users\<username>\Documents\example-event\results.html`
- `host`: Host address for the Flask application. Leave at `0.0.0.0` for availability at all network addresses (localhost / LAN)
- `port`: Port number for the Flask application
- `is_oe11`: Boolean flag for encoding (`True` for OE11, `False` for OE12)
- `scroll_pixels`: Number of pixels to scroll each interval
- `scroll_interval`: Time interval (in seconds) between each scroll
- `bottom_wait_time`: Time to wait (in seconds) at the bottom of the page before reloading
- `top_wait_time`: Time to wait (in seconds) at the top of the page before starting to scroll
## Getting Started
### Prerequisites
- Python 3.x
- pip
- virtualenv
### Installation
Run these commands in CMD or PowerShell.
1. Clone the repository:
```sh
git clone https://gitea.carburator.dev/carburator/oe-html-viewer.git
cd oe-html-viewer
```
2. Create a virtual environment:
```sh
python -m venv .venv
```
3. Activate the virtual environment:
```sh
.venv\Scripts\activate
```
4. Install the required packages:
```sh
pip install -r requirements.txt
```
### Running the Application
0. If you downloaded earlier and want to use the program again, first activate the venv. Check: Installation - 3.
1. Start the Flask application:
```sh
python main.py
```
2. Open your web browser and navigate to `http://localhost:80`. From other devices on LAN: `http://<host machine IP address>`
### License
This project is licensed under the MIT License - see the `LICENSE` file for details.
<hr>
<p style="text-align: center;"> Made with ❤️ and ☕ on 603 NYÍRSÉG IC </p>

View File

@@ -1,67 +1,82 @@
# SportSoftware OE HTML viewer # SportSoftware OE HTML megjelenítő
Simple Python script to serve the exported HTML results file from the SportSoftware OE application on the local network. [![en](https://img.shields.io/badge/lang-en-blue.svg)](https://gitea.carburator.dev/carburator/oe-html-viewer/src/branch/main/README.en.md)
## Getting Started Egyszerű python program, amivel a tájfutó eseményeken használt OE11 és OE12 programból exportált HTML fájlokat lehet megjeleníteni kijelzőn, vagy a helyi hálózaton.
### Prerequisites ## Funkciók
<ul style="list-style-type: none"> ✅ Személyre szabható automatikus görgetés </ul>
<ul style="list-style-type: none"> ✅ Finom görgetés </ul>
<ul style="list-style-type: none"> ✅ Automatikus újratöltés a lap alján </ul>
<ul style="list-style-type: none"> ✅ Automatikus újratöltés fájl változáskor, ha nincs szükség görgetésre </ul>
<ul style="list-style-type: none"> ✅ Támogatja az OE11 és OE12-ből exportált HTML fájlokat is </ul>
<ul style="list-style-type: none"> ✅ Megjeleníti a fájlt localhost-on és a helyi hálózaton is </ul>
### Változók
A `main.py` fájl elején található, szerkeszthető változók:
- `html_file_path`: Elérési út a HTML fájlhoz. Példa: `C:\Users\<felhasználó>\Documents\példa-verseny\eredmenyek.html`
- `host`: A webszerver IP címe. Hagyd az alapértelmezett `0.0.0.0` értéken, hogy elérhető legyen a fájl lokálisan és a lokális hálózaton is
- `port`: A webszerver portja. Alapértelmezetten `80`, ez elhagyható az URL-ből
- `is_oe11`: Változó az OE11 vagy OE12 kiválasztására. Legyen `True` ha OE11-et használsz és `False`, ha OE12-t
- `scroll_pixels`: Ennyi pixelt görget lefelé
- `scroll_interval`: Időtartam másodpercben, ennyi időnként görget
- `bottom_wait_time`: Időtartam másodpercben, ennyit vár ha a lap aljára ért újratöltés előtt
- `top_wait_time`: Időtartam másodpercben, ennyit vár a lap tetején, mielőtt elkezdődne a görgetés
## Használat
### Előfeltételek
- Python 3.x - Python 3.x
- pip - pip
- virtualenv - virtualenv
### Installation ### Telepítés
A következő parancsokat CMD-ben vagy PowerShell-ben kell kiadni.
1. Töltsd le a repository-t:
1. Clone the repository:
```sh ```sh
git clone https://gitea.carburator.dev/carburator/oe-html-viewer.git git clone https://gitea.carburator.dev/carburator/oe-html-viewer.git
cd oe-html-viewer cd oe-html-viewer
``` ```
2. Create a virtual environment: 2. Hozz létre egy virtuális környezetet:
```sh ```sh
python -m venv .venv python -m venv .venv
``` ```
3. Activate the virtual environment: 3. Aktiváld a virtuális környezetet:
- On Windows:
```sh ```sh
.venv\Scripts\activate .venv\Scripts\activate
``` ```
- On macOS/Linux:
```sh
source .venv/bin/activate
```
4. Install the required packages: 4. Telepítsd a szükséges csomagokat:
```sh ```sh
pip install -r requirements.txt pip install -r requirements.txt
``` ```
### Running the Application ### Futtatás
0. Ha már telepítetted és újra használni akarod, akkor előbb aktiváld a virtuális környezetet. Lásd: Telepítés - 3.
1. Indítsd el a programot:
1. Start the Flask application:
```sh ```sh
python main.py python main.py
``` ```
2. Open your web browser and navigate to `http://localhost:80`. 2. Nyisd meg a böngészőt és írd be a címsorba: `http://localhost`. Más eszközről a helyi hálózaton: `http://<host gép ip címe>`
### Variables ### Licensz
The following variables can be found at the top of the `main.py` script: Ez a projekt az MIT Licensz alatt van licenszelve - részletekért lásd a LICENSE fájlt.
- `html_file_path`: Path to the HTML file to be served. <hr>
- `host`: Host address for the Flask application. Leave at `0.0.0.0` for availability at all network addresses (localhost / LAN)
- `port`: Port number for the Flask application.
- `is_oe11`: Boolean flag for encoding (True for OE11, False for OE12).
- `scroll_pixels`: Number of pixels to scroll each interval.
- `scroll_interval`: Time interval (in seconds) between each scroll.
- `bottom_wait_time`: Time to wait (in seconds) at the bottom of the page before reloading.
- `top_wait_time`: Time to wait (in seconds) at the top of the page before starting to scroll.
- `reload_interval`: Time interval (in seconds) to reload the page if no scrolling is needed. Set this value minimum 1 seconds larger than the export interval in OE.
### License <p style="text-align: center;"> Készült sok ❤️-el és ☕-val a 603 NYÍRSÉG IC-n </p>
This project is licensed under the MIT License - see the `LICENSE` file for details.

55
main.py
View File

@@ -1,47 +1,56 @@
import os import os
from flask import Flask from flask import Flask, Response
from watchdog.observers import Observer import threading
from watchdog.events import FileSystemEventHandler from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer
# -------------- VARIABLES -------------- # -------------- VARIABLES --------------
html_file_path = r'PATH' html_file_path = r"PATH"
host = '0.0.0.0' host = "0.0.0.0"
port = 80 port = 80
is_oe11 = True # if using OE11 set it to True, for OE12 set it to False (encoding) is_oe11 = True # if using OE11 set it to True, for OE12 set it to False (encoding)
scroll_pixels = 100 scroll_pixels = 100
scroll_interval = 3 # seconds scroll_interval = 3 # seconds
bottom_wait_time = 3 # seconds bottom_wait_time = 3 # seconds
top_wait_time = 3 # seconds top_wait_time = 3 # seconds
reload_interval = 35 # seconds
# -------------- END VARIABLES -------------- # -------------- END VARIABLES --------------
app = Flask(__name__) app = Flask(__name__)
file_change_event = threading.Event()
class FileChangeHandler(FileSystemEventHandler): class FileChangeHandler(FileSystemEventHandler):
def __init__(self, app):
self.app = app
def on_modified(self, event): def on_modified(self, event):
if event.src_path == html_file_path: if event.src_path == html_file_path:
with self.app.app_context(): file_change_event.set()
self.app.config['TEMPLATES_AUTO_RELOAD'] = True
@app.route('/')
@app.route("/_file_change")
def file_change_stream():
def stream():
while True:
file_change_event.wait()
yield "data: reload\n\n"
file_change_event.clear()
return Response(stream(), content_type="text/event-stream")
@app.route("/")
def serve_html(): def serve_html():
with open(html_file_path, 'r', encoding= ('latin-1' if is_oe11 else 'utf-8') ) as file: with open(html_file_path, "r", encoding=("cp1252" if is_oe11 else "utf-8")) as file:
content = file.read() content = file.read()
content += f''' content += f"""
<style> <style>
html {{ html {{
scroll-behavior: smooth; scroll-behavior: smooth;
}} }}
</style> </style>
<script> <script>
let scrollAmount = {scroll_pixels}; let scrollAmount = {scroll_pixels};
let scrollInterval = {scroll_interval} * 1000; let scrollInterval = {scroll_interval} * 1000;
let bottomWaitTime = {bottom_wait_time} * 1000; let bottomWaitTime = {bottom_wait_time} * 1000;
let topWaitTime = {top_wait_time} * 1000; let topWaitTime = {top_wait_time} * 1000;
let reloadInterval = {reload_interval} * 1000;
let scrollPos = 0; let scrollPos = 0;
let scrollingDown = true; let scrollingDown = true;
@@ -74,19 +83,25 @@ def serve_html():
window.onload = function() {{ window.onload = function() {{
window.scrollTo(0, 0); window.scrollTo(0, 0);
if (document.body.scrollHeight <= window.innerHeight) {{ if (document.body.scrollHeight <= window.innerHeight) {{
setTimeout(reloadPage, reloadInterval); const eventSource = new EventSource('/_file_change');
eventSource.onmessage = function() {{
location.reload();
}};
}} else {{ }} else {{
setTimeout(autoScroll, topWaitTime); setTimeout(autoScroll, topWaitTime);
}} }}
}}; }};
</script> </script>
''' """
return content return content
if __name__ == '__main__':
event_handler = FileChangeHandler(app) if __name__ == "__main__":
event_handler = FileChangeHandler()
observer = Observer() observer = Observer()
observer.schedule(event_handler, path=os.path.dirname(html_file_path), recursive=False) observer.schedule(
event_handler, path=os.path.dirname(html_file_path), recursive=False
)
observer.start() observer.start()
try: try:
app.run(host=host, port=port) app.run(host=host, port=port)