git init / upload 🚀
This commit is contained in:
185
.gitignore
vendored
Normal file
185
.gitignore
vendored
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
|
### Python template
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
env/
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*,cover
|
||||||
|
.hypothesis/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Django stuff:
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# IPython Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# celery beat schedule file
|
||||||
|
celerybeat-schedule
|
||||||
|
|
||||||
|
# dotenv
|
||||||
|
.env
|
||||||
|
|
||||||
|
# virtualenv
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
### VirtualEnv template
|
||||||
|
# Virtualenv
|
||||||
|
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
|
||||||
|
[Bb]in
|
||||||
|
[Ii]nclude
|
||||||
|
[Ll]ib
|
||||||
|
[Ll]ib64
|
||||||
|
[Ll]ocal
|
||||||
|
[Ss]cripts
|
||||||
|
pyvenv.cfg
|
||||||
|
.venv
|
||||||
|
pip-selfcheck.json
|
||||||
|
|
||||||
|
### JetBrains template
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# AWS User-specific
|
||||||
|
.idea/**/aws.xml
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/artifacts
|
||||||
|
# .idea/compiler.xml
|
||||||
|
# .idea/jarRepositories.xml
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# SonarLint plugin
|
||||||
|
.idea/sonarlint/
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
# idea folder, uncomment if you don't need it
|
||||||
|
# .idea
|
||||||
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="PyInterpreterInspection" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
7
.idea/misc.xml
generated
Normal file
7
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="Python 3.13 (oe-html-viewer)" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13 (oe-html-viewer)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/oe-html-viewer.iml" filepath="$PROJECT_DIR$/.idea/oe-html-viewer.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
16
.idea/oe-html-viewer.iml
generated
Normal file
16
.idea/oe-html-viewer.iml
generated
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="Flask">
|
||||||
|
<option name="enabled" value="true" />
|
||||||
|
</component>
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="jdk" jdkName="Python 3.13 (oe-html-viewer)" jdkType="Python SDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
<component name="TemplatesService">
|
||||||
|
<option name="TEMPLATE_CONFIGURATION" value="Jinja2" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
67
README.md
Normal file
67
README.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# OE HTML viewer
|
||||||
|
|
||||||
|
Simple Python script to serve the exported HTML results file from the SportSoftware OE application on the local network.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Python 3.x
|
||||||
|
- pip
|
||||||
|
- virtualenv
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
1. Clone the repository:
|
||||||
|
```sh
|
||||||
|
git clone <repository_url>
|
||||||
|
cd <repository_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Create a virtual environment:
|
||||||
|
```sh
|
||||||
|
python -m venv .venv
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Activate the virtual environment:
|
||||||
|
|
||||||
|
- On Windows:
|
||||||
|
```sh
|
||||||
|
.venv\Scripts\activate
|
||||||
|
```
|
||||||
|
- On macOS/Linux:
|
||||||
|
```sh
|
||||||
|
source .venv/bin/activate
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Install the required packages:
|
||||||
|
```sh
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running the Application
|
||||||
|
|
||||||
|
1. Start the Flask application:
|
||||||
|
```sh
|
||||||
|
python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Open your web browser and navigate to `http://localhost:80`.
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
- `host`: Host address for the Flask application. Leave at `0.0.0.0` for avability at all network interfaces (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
|
||||||
|
|
||||||
|
This project is licensed under the MIT License - see the `LICENSE` file for details.
|
||||||
95
main.py
Normal file
95
main.py
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import os
|
||||||
|
from flask import Flask
|
||||||
|
from watchdog.observers import Observer
|
||||||
|
from watchdog.events import FileSystemEventHandler
|
||||||
|
|
||||||
|
# -------------- VARIABLES --------------
|
||||||
|
html_file_path = r'C:\<PATH>'
|
||||||
|
host = '0.0.0.0' # http://localhost OR http://<ip_address>
|
||||||
|
port = 80
|
||||||
|
is_oe11 = True # if using OE11 set it to True, for OE12 set it to False (encoding)
|
||||||
|
scroll_pixels = 100
|
||||||
|
scroll_interval = 3 # seconds
|
||||||
|
bottom_wait_time = 3 # seconds
|
||||||
|
top_wait_time = 3 # seconds
|
||||||
|
reload_interval = 35 # seconds
|
||||||
|
# -------------- END VARIABLES --------------
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
class FileChangeHandler(FileSystemEventHandler):
|
||||||
|
def __init__(self, app):
|
||||||
|
self.app = app
|
||||||
|
|
||||||
|
def on_modified(self, event):
|
||||||
|
if event.src_path == html_file_path:
|
||||||
|
with self.app.app_context():
|
||||||
|
self.app.config['TEMPLATES_AUTO_RELOAD'] = True
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def serve_html():
|
||||||
|
with open(html_file_path, 'r', encoding= ('latin-1' if is_oe11 else 'utf-8') ) as file:
|
||||||
|
content = file.read()
|
||||||
|
content += f'''
|
||||||
|
<style>
|
||||||
|
html {{
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
let scrollAmount = {scroll_pixels};
|
||||||
|
let scrollInterval = {scroll_interval} * 1000;
|
||||||
|
let bottomWaitTime = {bottom_wait_time} * 1000;
|
||||||
|
let topWaitTime = {top_wait_time} * 1000;
|
||||||
|
let reloadInterval = {reload_interval} * 1000;
|
||||||
|
let scrollPos = 0;
|
||||||
|
let scrollingDown = true;
|
||||||
|
|
||||||
|
function autoScroll() {{
|
||||||
|
if (scrollingDown) {{
|
||||||
|
window.scrollBy(0, scrollAmount);
|
||||||
|
scrollPos += scrollAmount;
|
||||||
|
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {{
|
||||||
|
scrollingDown = false;
|
||||||
|
setTimeout(reloadPage, bottomWaitTime);
|
||||||
|
return;
|
||||||
|
}}
|
||||||
|
}} else {{
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
scrollPos = 0;
|
||||||
|
scrollingDown = true;
|
||||||
|
setTimeout(autoScroll, topWaitTime);
|
||||||
|
return;
|
||||||
|
}}
|
||||||
|
setTimeout(autoScroll, scrollInterval);
|
||||||
|
}}
|
||||||
|
|
||||||
|
function reloadPage() {{
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
setTimeout(() => {{
|
||||||
|
location.reload();
|
||||||
|
}}, 100);
|
||||||
|
}}
|
||||||
|
|
||||||
|
window.onload = function() {{
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
if (document.body.scrollHeight <= window.innerHeight) {{
|
||||||
|
setTimeout(reloadPage, reloadInterval);
|
||||||
|
}} else {{
|
||||||
|
setTimeout(autoScroll, topWaitTime);
|
||||||
|
}}
|
||||||
|
}};
|
||||||
|
</script>
|
||||||
|
'''
|
||||||
|
return content
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
event_handler = FileChangeHandler(app)
|
||||||
|
observer = Observer()
|
||||||
|
observer.schedule(event_handler, path=os.path.dirname(html_file_path), recursive=False)
|
||||||
|
observer.start()
|
||||||
|
try:
|
||||||
|
app.run(host=host, port=port)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
observer.stop()
|
||||||
|
observer.join()
|
||||||
Reference in New Issue
Block a user