Compare commits
No commits in common. "e30d85065ddb234f74cb4491c9de75483cc46b1e" and "70c900fc678fdccd27d6f18144851a113f7b8bed" have entirely different histories.
e30d85065d
...
70c900fc67
@ -1,5 +1,5 @@
|
|||||||
[tool.bumpversion]
|
[tool.bumpversion]
|
||||||
current_version = "1.3.42"
|
current_version = "1.3.41"
|
||||||
commit = true
|
commit = true
|
||||||
tag = true
|
tag = true
|
||||||
tag_name = "{new_version}"
|
tag_name = "{new_version}"
|
||||||
|
37
app.py
37
app.py
@ -17,6 +17,13 @@ from lib.reqs import (get_urls, get_user_accounts, add_user_account,
|
|||||||
delete_user_account, get_stream_names)
|
delete_user_account, get_stream_names)
|
||||||
from config import DevelopmentConfig, ProductionConfig
|
from config import DevelopmentConfig, ProductionConfig
|
||||||
|
|
||||||
|
try:
|
||||||
|
from paddleocr import PaddleOCR
|
||||||
|
from PIL import Image
|
||||||
|
import numpy as np
|
||||||
|
OCR_AVAILABLE = True
|
||||||
|
except ImportError:
|
||||||
|
OCR_AVAILABLE = False
|
||||||
|
|
||||||
os.environ["OMP_NUM_THREADS"] = "1"
|
os.environ["OMP_NUM_THREADS"] = "1"
|
||||||
os.environ["MKL_NUM_THREADS"] = "1"
|
os.environ["MKL_NUM_THREADS"] = "1"
|
||||||
@ -45,6 +52,9 @@ except redis.exceptions.ConnectionError as e:
|
|||||||
|
|
||||||
cache = Cache(app, config=cache_config)
|
cache = Cache(app, config=cache_config)
|
||||||
|
|
||||||
|
if app.config.get("OCR_ENABLED") and OCR_AVAILABLE:
|
||||||
|
ocr = PaddleOCR(use_angle_cls=True, lang='en')
|
||||||
|
else:
|
||||||
app.config["OCR_ENABLED"] = False
|
app.config["OCR_ENABLED"] = False
|
||||||
|
|
||||||
app.config["SESSION_COOKIE_SECURE"] = not app.config["DEBUG"]
|
app.config["SESSION_COOKIE_SECURE"] = not app.config["DEBUG"]
|
||||||
@ -203,6 +213,7 @@ def home() -> str:
|
|||||||
accounts=len(all_accounts),
|
accounts=len(all_accounts),
|
||||||
current_month_accounts=filter_accounts_next_30_days(all_accounts),
|
current_month_accounts=filter_accounts_next_30_days(all_accounts),
|
||||||
expired_accounts=filter_accounts_expired(all_accounts),
|
expired_accounts=filter_accounts_expired(all_accounts),
|
||||||
|
ocr_enabled=app.config.get("OCR_ENABLED"),
|
||||||
)
|
)
|
||||||
return render_template("index.html")
|
return render_template("index.html")
|
||||||
|
|
||||||
@ -289,6 +300,7 @@ def add_account() -> Union[Response, str]:
|
|||||||
|
|
||||||
return render_template(
|
return render_template(
|
||||||
"add_account.html",
|
"add_account.html",
|
||||||
|
ocr_enabled=app.config.get("OCR_ENABLED"),
|
||||||
text_input_enabled=app.config.get("TEXT_INPUT_ENABLED"),
|
text_input_enabled=app.config.get("TEXT_INPUT_ENABLED"),
|
||||||
shared_text=shared_text
|
shared_text=shared_text
|
||||||
)
|
)
|
||||||
@ -333,6 +345,31 @@ def stream_names() -> Union[Response, str]:
|
|||||||
base_url = app.config["BASE_URL"]
|
base_url = app.config["BASE_URL"]
|
||||||
return jsonify(get_stream_names(base_url, session["auth_credentials"]))
|
return jsonify(get_stream_names(base_url, session["auth_credentials"]))
|
||||||
|
|
||||||
|
if app.config.get("OCR_ENABLED"):
|
||||||
|
@app.route('/OCRupload', methods=['POST'])
|
||||||
|
def ocr_upload() -> Union[Response, str, Tuple[Response, int]]:
|
||||||
|
"""Handles image uploads for OCR processing."""
|
||||||
|
if 'image' not in request.files:
|
||||||
|
return jsonify({"error": "No image file found"}), 400
|
||||||
|
file = request.files['image']
|
||||||
|
try:
|
||||||
|
image = Image.open(file.stream)
|
||||||
|
image_np = np.array(image)
|
||||||
|
result = ocr.ocr(image_np)
|
||||||
|
extracted_text = [line[1][0] for line in result[0]]
|
||||||
|
# Basic validation
|
||||||
|
if len(extracted_text) >= 4:
|
||||||
|
return render_template(
|
||||||
|
"add_account.html",
|
||||||
|
username=extracted_text[2],
|
||||||
|
password=extracted_text[3],
|
||||||
|
ocr_enabled=True,
|
||||||
|
text_input_enabled=app.config.get("TEXT_INPUT_ENABLED")
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return jsonify({"error": "Could not extract required fields from image"}), 400
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app.run(
|
app.run(
|
||||||
|
@ -9,6 +9,12 @@ RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
|
|||||||
# Final stage
|
# Final stage
|
||||||
FROM python:3.11-slim-bookworm AS final
|
FROM python:3.11-slim-bookworm AS final
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
libgomp1 \
|
||||||
|
libgl1 \
|
||||||
|
libglib2.0-0 \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
@ -6,7 +6,8 @@
|
|||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.5/awesomplete.min.css" />
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.5/awesomplete.min.css" />
|
||||||
<style>
|
<style>
|
||||||
/* Hide the spinner by default */
|
/* Hide the spinner by default */
|
||||||
#loadingSpinner {
|
#loadingSpinner,
|
||||||
|
#ocrLoadingSpinner {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -49,6 +50,20 @@
|
|||||||
<span id="buttonText">Add Account</span>
|
<span id="buttonText">Add Account</span>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
{% if ocr_enabled %}
|
||||||
|
<hr>
|
||||||
|
<h2>Load Details Via OCR</h2>
|
||||||
|
<form action="/OCRupload" method="POST" enctype="multipart/form-data" onsubmit="showLoadingOCR()">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="image">Select Image</label>
|
||||||
|
<input type="file" class="form-control-file" id="image" name="image" accept="image/*" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-success" id="ocrButton">
|
||||||
|
<span class="spinner-border spinner-border-sm" id="ocrLoadingSpinner" role="status" aria-hidden="true"></span>
|
||||||
|
<span id="ocrButtonText">Load Details</span>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
{% if text_input_enabled %}
|
{% if text_input_enabled %}
|
||||||
<hr>
|
<hr>
|
||||||
<h2>Load Details Via Text</h2>
|
<h2>Load Details Via Text</h2>
|
||||||
@ -67,6 +82,11 @@
|
|||||||
document.getElementById("loadingSpinner").style.display = "inline-block";
|
document.getElementById("loadingSpinner").style.display = "inline-block";
|
||||||
document.getElementById("buttonText").textContent = "Working...";
|
document.getElementById("buttonText").textContent = "Working...";
|
||||||
}
|
}
|
||||||
|
function showLoadingOCR() {
|
||||||
|
document.getElementById("ocrButton").disabled = true;
|
||||||
|
document.getElementById("ocrLoadingSpinner").style.display = "inline-block";
|
||||||
|
document.getElementById("ocrButtonText").textContent = "Processing...";
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
var streamInput = document.getElementById("stream");
|
var streamInput = document.getElementById("stream");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user