From f04691879ed2714be602eb297a5606735ce988ea Mon Sep 17 00:00:00 2001 From: Cybernetic-Ransomware <71835339+Cybernetic-Ransomware@users.noreply.github.com> Date: Thu, 4 Jun 2026 00:55:25 +0200 Subject: [PATCH 01/17] Fix thread safety, seek bug, size message, and return type annotation --- app.py | 75 ++++++++++++++++++++------------- static/js/input_errors_modal.js | 2 +- templates/result.html | 8 ++-- utils/mixins.py | 22 ++++++---- utils/qr_generator.py | 40 +++++++++++++----- utils/result_store.py | 46 ++++++++++++++++++++ 6 files changed, 141 insertions(+), 52 deletions(-) create mode 100644 utils/result_store.py diff --git a/app.py b/app.py index b169e59..3bcf560 100644 --- a/app.py +++ b/app.py @@ -1,31 +1,19 @@ -import os +import io -from flask import Flask, render_template, request, send_file, jsonify +from flask import Flask, abort, render_template, request, send_file, jsonify from utils.logger import AppLogger from utils.qr_generator import QRCodeGenerator +from utils.result_store import ResultStore AppLogger.configure_logger() app = Flask(__name__) - - -def before_request_index(): - file_names = ('qr', 'qr_with_image') - current_dir = os.listdir() - - for filename in current_dir: - for name in file_names: - if filename.startswith(name): - try: - os.remove(filename) - except Exception as e: - AppLogger.logger.error(f"Error removing file {filename}: {e}") +store = ResultStore() @app.route('/') def index(): - before_request_index() return render_template('index.html') @@ -33,36 +21,65 @@ def index(): def generate(): text = request.form['text'] size = int(request.form['size']) - image = request.files['image'] if 'image' in request.files else None - color = request.form['color'] if 'color' in request.form else None + raw_image = request.files.get('image') + image = raw_image if (raw_image and raw_image.filename) else None + color = request.form.get('color') or None generator = QRCodeGenerator() success, errors = generator.generate_qr(text, size, image, color) - if success: - return jsonify({'success': True}) - else: + if not success: return jsonify({'success': False, 'errors': errors}) + token = store.put({ + 'qr': generator.qr_png, + 'artistic': generator.artistic_png, + 'artistic_ext': generator.artistic_ext, + }) + return jsonify({'success': True, 'id': token}) + @app.route('/result') def result(): - qr_with_image_exists = any(filename.startswith('qr_with_image') for filename in os.listdir('.')) - return render_template('result.html', qr_with_image_exists=qr_with_image_exists) + token = request.args.get('id', '') + payload = store.get(token) + if payload is None: + abort(404) + return render_template( + 'result.html', + token=token, + qr_with_image_exists=payload['artistic'] is not None, + ) @app.route('/download') def download(): - return send_file('qr.png', as_attachment=True) + token = request.args.get('id', '') + payload = store.get(token) + if payload is None: + abort(404) + return send_file( + io.BytesIO(payload['qr']), + mimetype='image/png', + as_attachment=True, + download_name='qr.png', + ) @app.route('/download_with_image') def download_with_image(): - for filename in os.listdir('.'): - if filename.startswith('qr_with_image'): - return send_file(filename, as_attachment=True) - - return "File not found", 404 + token = request.args.get('id', '') + payload = store.get(token) + if payload is None or payload['artistic'] is None: + abort(404) + ext = payload['artistic_ext'] + mimetype = 'image/gif' if ext == 'gif' else 'image/png' + return send_file( + io.BytesIO(payload['artistic']), + mimetype=mimetype, + as_attachment=True, + download_name=f'qr_with_image.{ext}', + ) if __name__ == '__main__': diff --git a/static/js/input_errors_modal.js b/static/js/input_errors_modal.js index 1e3e690..fc5196f 100644 --- a/static/js/input_errors_modal.js +++ b/static/js/input_errors_modal.js @@ -12,7 +12,7 @@ $(document).ready(function(){ contentType: false, success: function(response) { if (response.success) { - window.location.href = '/result'; + window.location.href = '/result?id=' + encodeURIComponent(response.id); } else { $('#errorModalBody').empty(); response.errors.forEach(function(error) { diff --git a/templates/result.html b/templates/result.html index a2823b4..80defac 100644 --- a/templates/result.html +++ b/templates/result.html @@ -11,12 +11,12 @@

QR Code Generated

- QR Code
- Download QR Code without Image
+ QR Code
+ Download QR Code without Image
{% if qr_with_image_exists %} -
- Download QR Code with Image
+ QR Code with background
+ Download QR Code with Image
{% endif %}
diff --git a/utils/mixins.py b/utils/mixins.py index 69c0bed..da62f6f 100644 --- a/utils/mixins.py +++ b/utils/mixins.py @@ -1,29 +1,35 @@ from werkzeug.datastructures import FileStorage +MIN_SIZE = 1 +MAX_SIZE = 30 + class NotificationMixin: @staticmethod - def validate_text(text: str) -> (bool, str): + def validate_text(text: str) -> tuple[bool, str]: if len(text) > 55: return False, "Text length should not exceed 55 characters." return True, "" @staticmethod - def validate_size(size: int) -> (bool, str): - if not 1 <= size <= 30: - return False, "Size should be between 1 and 10." + def validate_size(size: int) -> tuple[bool, str]: + if not MIN_SIZE <= size <= MAX_SIZE: + return False, f"Size should be between {MIN_SIZE} and {MAX_SIZE}." return True, "" @staticmethod - def validate_image(image: FileStorage | None) -> (bool, str): + def validate_image(image: FileStorage | None) -> tuple[bool, str]: allowed_extensions = {'png', 'jpg', 'jpeg', 'gif'} if image and image.filename.split('.')[-1].lower() not in allowed_extensions: return False, "Image should be in PNG, JPG, JPEG, or GIF format." - if image and len(image.read()) > 5 * 1024 * 1024: # 5 MB - return False, "Image size should not exceed 5 MB." + if image: + size_bytes = len(image.read()) + image.seek(0) + if size_bytes > 5 * 1024 * 1024: # 5 MB + return False, "Image size should not exceed 5 MB." return True, "" - def validate_data(self, text: str, size: int, image: FileStorage | None) -> (bool, list[str]): + def validate_data(self, text: str, size: int, image: FileStorage | None) -> tuple[bool, list[str]]: validations = [ self.validate_text(text), self.validate_size(size), diff --git a/utils/qr_generator.py b/utils/qr_generator.py index 7d5229b..3c282fa 100644 --- a/utils/qr_generator.py +++ b/utils/qr_generator.py @@ -1,3 +1,5 @@ +import io + import segno from utils.mixins import NotificationMixin @@ -5,21 +7,39 @@ class QRCodeGenerator(NotificationMixin): - def generate_qr(self, text: str, size: int, image: FileStorage | None, color: str | None = None) -> (bool, str): + def __init__(self) -> None: + self.qr_png: bytes | None = None + self.artistic_png: bytes | None = None + self.artistic_ext: str | None = None + + def generate_qr( + self, + text: str, + size: int, + image: FileStorage | None, + color: str | None = None, + ) -> tuple[bool, list[str]]: valid, errors = self.validate_data(text, size, image) - if not valid: return False, errors qr = segno.make(text) - extension = "png" if (extension := image.filename.split('.')[-1]) != "gif" else extension + buf = io.BytesIO() if color: - qr.save(f'qr.png', scale=size, dark=color, light='white') + qr.save(buf, kind='png', scale=size, dark=color, light='white') else: - qr.save(f'qr.png', scale=size) - - if image: - qr.to_artistic(background=image, target=f'qr_with_image.{extension}', scale=size) - - return True, "" + qr.save(buf, kind='png', scale=size) + buf.seek(0) + self.qr_png = buf.read() + + if image and image.filename: + ext = 'gif' if image.filename.rsplit('.', 1)[-1].lower() == 'gif' else 'png' + image.seek(0) + art_buf = io.BytesIO() + qr.to_artistic(background=image, target=art_buf, kind=ext, scale=size) + art_buf.seek(0) + self.artistic_png = art_buf.read() + self.artistic_ext = ext + + return True, [] diff --git a/utils/result_store.py b/utils/result_store.py new file mode 100644 index 0000000..801ac3c --- /dev/null +++ b/utils/result_store.py @@ -0,0 +1,46 @@ +import threading +import time +import uuid + + +class ResultStore: + """Thread-safe in-memory store for generated QR payloads, keyed by token. + + Each entry has a TTL; entries beyond max_entries are evicted FIFO. + """ + + def __init__(self, ttl: int = 600, max_entries: int = 128) -> None: + self._ttl = ttl + self._max_entries = max_entries + self._store: dict[str, tuple[float, dict]] = {} + self._lock = threading.Lock() + + def put(self, payload: dict) -> str: + """Store payload and return the generated token.""" + token = uuid.uuid4().hex + with self._lock: + self._evict() + self._store[token] = (time.monotonic(), payload) + return token + + def get(self, token: str) -> dict | None: + """Return payload for token, or None if missing or expired.""" + with self._lock: + entry = self._store.get(token) + if entry is None: + return None + timestamp, payload = entry + if time.monotonic() - timestamp > self._ttl: + del self._store[token] + return None + return payload + + def _evict(self) -> None: + """Remove expired entries; if still over cap, drop oldest.""" + now = time.monotonic() + expired = [k for k, (ts, _) in self._store.items() if now - ts > self._ttl] + for k in expired: + del self._store[k] + while len(self._store) >= self._max_entries: + oldest = next(iter(self._store)) + del self._store[oldest] From 9bbb64d5f6ddc774823f7a959388fa83cd95509a Mon Sep 17 00:00:00 2001 From: Cybernetic-Ransomware <71835339+Cybernetic-Ransomware@users.noreply.github.com> Date: Thu, 4 Jun 2026 01:03:24 +0200 Subject: [PATCH 02/17] Harden app against debug exposure, XSS, CSRF, and oversized uploads --- app.py | 20 +++++++++++++++++++- requirements.txt | Bin 376 -> 412 bytes static/js/input_errors_modal.js | 20 ++++++++++++++------ templates/index.html | 1 + 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/app.py b/app.py index 3bcf560..61c7b2d 100644 --- a/app.py +++ b/app.py @@ -1,6 +1,10 @@ import io +import os +import secrets from flask import Flask, abort, render_template, request, send_file, jsonify +from flask_wtf import CSRFProtect +from flask_wtf.csrf import CSRFError from utils.logger import AppLogger from utils.qr_generator import QRCodeGenerator from utils.result_store import ResultStore @@ -9,9 +13,22 @@ AppLogger.configure_logger() app = Flask(__name__) +app.config['SECRET_KEY'] = os.getenv('SECRET_KEY') or secrets.token_hex(32) +app.config['MAX_CONTENT_LENGTH'] = 6 * 1024 * 1024 # 5 MB image + multipart headroom +csrf = CSRFProtect(app) store = ResultStore() +@app.errorhandler(413) +def request_too_large(e): + return jsonify({'success': False, 'errors': ['File is too large. Maximum request size is 6 MB.']}), 413 + + +@app.errorhandler(CSRFError) +def handle_csrf_error(e): + return jsonify({'success': False, 'errors': ['Security token missing or expired. Please reload the page.']}), 400 + + @app.route('/') def index(): return render_template('index.html') @@ -83,4 +100,5 @@ def download_with_image(): if __name__ == '__main__': - app.run(debug=True, host='0.0.0.0', port=5000) + debug = os.getenv('FLASK_DEBUG', 'false').lower() == 'true' + app.run(debug=debug, host='0.0.0.0', port=5000) diff --git a/requirements.txt b/requirements.txt index f3a09e0e494ed0e41c3955ad756395c317d0ae73..70bb80688a0ea7caeb7f6cd9cfe83052cd3dee86 100644 GIT binary patch delta 44 wcmeytG>3UZ1*3`^Lk>eCLoq`(gDyijLkNQ#gDnsmGUzcF0kI(iF9R0?0O0`#cK`qY delta 7 OcmbQk{DWyj1tS0qJ_5r4 diff --git a/static/js/input_errors_modal.js b/static/js/input_errors_modal.js index fc5196f..997b905 100644 --- a/static/js/input_errors_modal.js +++ b/static/js/input_errors_modal.js @@ -1,4 +1,11 @@ $(document).ready(function(){ + function showErrors(errors) { + var $body = $('#errorModalBody').empty(); + (errors && errors.length ? errors : ['An unexpected error occurred.']) + .forEach(function(error) { $('

').text(error).appendTo($body); }); + $('#errorModal').modal('show'); + } + $('#generate-form').submit(function(event){ event.preventDefault(); @@ -14,15 +21,16 @@ $(document).ready(function(){ if (response.success) { window.location.href = '/result?id=' + encodeURIComponent(response.id); } else { - $('#errorModalBody').empty(); - response.errors.forEach(function(error) { - $('#errorModalBody').append('

' + error + '

'); - }); - $('#errorModal').modal('show'); + showErrors(response.errors); } }, - error: function(xhr, status, error) { + error: function(xhr) { console.error(xhr.responseText); + var errors = (xhr.responseJSON && xhr.responseJSON.errors) ? xhr.responseJSON.errors : null; + if (!errors && xhr.status === 413) { + errors = ['File is too large. Maximum request size is 6 MB.']; + } + showErrors(errors); } }); }); diff --git a/templates/index.html b/templates/index.html index 1f4d82d..d6f89d3 100644 --- a/templates/index.html +++ b/templates/index.html @@ -17,6 +17,7 @@

QR Code Generator

+

From 6af5da575f5db19488005eee5667071155447d5a Mon Sep 17 00:00:00 2001 From: Cybernetic-Ransomware <71835339+Cybernetic-Ransomware@users.noreply.github.com> Date: Thu, 4 Jun 2026 10:24:56 +0200 Subject: [PATCH 03/17] Fix root logger pollution, None logger, and form KeyError/ValueError --- app.py | 7 +++++-- utils/logger.py | 22 +++++++++++----------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/app.py b/app.py index 61c7b2d..10e2ae2 100644 --- a/app.py +++ b/app.py @@ -36,8 +36,11 @@ def index(): @app.route('/generate', methods=['POST']) def generate(): - text = request.form['text'] - size = int(request.form['size']) + text = request.form.get('text', '') + try: + size = int(request.form.get('size', '')) + except (TypeError, ValueError): + return jsonify({'success': False, 'errors': ['Size must be a valid integer.']}), 400 raw_image = request.files.get('image') image = raw_image if (raw_image and raw_image.filename) else None color = request.form.get('color') or None diff --git a/utils/logger.py b/utils/logger.py index db6443f..88ac782 100644 --- a/utils/logger.py +++ b/utils/logger.py @@ -1,19 +1,19 @@ import logging from logging.handlers import RotatingFileHandler +LOGGER_NAME = 'qrgen' + class AppLogger: - logger = None + logger = logging.getLogger(LOGGER_NAME) @staticmethod def configure_logger(log_file='app.log', log_level=logging.ERROR, max_bytes=1048576, backup_count=3): - AppLogger.logger = logging.getLogger() - AppLogger.logger.setLevel(log_level) - - handler = RotatingFileHandler(log_file, maxBytes=max_bytes, backupCount=backup_count) - handler.setLevel(log_level) - - formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') - handler.setFormatter(formatter) - - AppLogger.logger.addHandler(handler) + logger = logging.getLogger(LOGGER_NAME) + logger.setLevel(log_level) + if not logger.handlers: + handler = RotatingFileHandler(log_file, maxBytes=max_bytes, backupCount=backup_count) + handler.setLevel(log_level) + handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')) + logger.addHandler(handler) + AppLogger.logger = logger From ae0e28f53705c2a9b9090fe7eb13be19947bf8bd Mon Sep 17 00:00:00 2001 From: Cybernetic-Ransomware <71835339+Cybernetic-Ransomware@users.noreply.github.com> Date: Thu, 4 Jun 2026 10:38:31 +0200 Subject: [PATCH 04/17] Fix infrastructure and configuration issues --- .dockerignore | 5 +++++ .gitignore | 5 +++++ app.py | 4 ++-- docker-compose.yml | 2 +- ingress.yaml | 5 ++--- qrgen-deploy.yaml | 2 +- requirements.txt | Bin 412 -> 193 bytes templates/result.html | 8 ++++++-- 8 files changed, 22 insertions(+), 9 deletions(-) diff --git a/.dockerignore b/.dockerignore index d874ad6..9791a84 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,6 @@ *.tar +.venv/ +__pycache__/ +*.pyc +.idea/ +*.log diff --git a/.gitignore b/.gitignore index b5ac65f..3b0d7bc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,8 @@ image.tar *.png + +app.log +__pycache__/ +*.pyc +.venv/ diff --git a/app.py b/app.py index 10e2ae2..8a3f1de 100644 --- a/app.py +++ b/app.py @@ -81,7 +81,7 @@ def download(): return send_file( io.BytesIO(payload['qr']), mimetype='image/png', - as_attachment=True, + as_attachment=False, download_name='qr.png', ) @@ -97,7 +97,7 @@ def download_with_image(): return send_file( io.BytesIO(payload['artistic']), mimetype=mimetype, - as_attachment=True, + as_attachment=False, download_name=f'qr_with_image.{ext}', ) diff --git a/docker-compose.yml b/docker-compose.yml index 84566ca..3b518ba 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,4 +5,4 @@ services: ports: - "5000:5000" volumes: - - .:/app + - .:/app # dev-mode live reload; remove for production diff --git a/ingress.yaml b/ingress.yaml index 449f2f5..9eb94b8 100644 --- a/ingress.yaml +++ b/ingress.yaml @@ -2,9 +2,8 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-service - annotations: - nginx.ingress.kubernetes.io/ingress-class: "nginx" spec: + ingressClassName: nginx rules: - http: paths: @@ -14,4 +13,4 @@ spec: service: name: qrgen port: - number: 5000 \ No newline at end of file + number: 5000 diff --git a/qrgen-deploy.yaml b/qrgen-deploy.yaml index d553048..fc3d668 100644 --- a/qrgen-deploy.yaml +++ b/qrgen-deploy.yaml @@ -18,7 +18,7 @@ spec: containers: - name: qrgen image: qr_generator-web:latest - imagePullPolicy: Never + imagePullPolicy: IfNotPresent ports: - containerPort: 5000 protocol: TCP diff --git a/requirements.txt b/requirements.txt index 70bb80688a0ea7caeb7f6cd9cfe83052cd3dee86..da963ef29b805fe64b5c7a1f8297edee3dd7beff 100644 GIT binary patch literal 193 zcmXwzu@1s83`BSTORYAA!s4|95)(+BO&Y3@kd&kq5?_x)#b~|ry}NlEoJm9t9#|XgE9o literal 412 zcmZXQ$qK??420(__$V!1+%8^w5IiY(uC12Z<*!{3e0X(|zb+spv}7h4LOGvM^7cC zUL(`(1_L`n3C2BvIyai|LT8|=a3qE0Y}s$QVL*c&zt3d-GUm!?$S5`KO;ul$+C*~8 zm5hY9q?~q?*mI&|#+-fOz0=!F9eo*-n~^3LODbU<^qK;9z6ZMgr@#Njp?i<$L$Q|& F QR Code Generated + +
@@ -12,11 +16,11 @@

QR Code Generated

QR Code
- Download QR Code without Image
+ Download QR Code without Image
{% if qr_with_image_exists %} QR Code with background
- Download QR Code with Image
+ Download QR Code with Image
{% endif %}
From 861cc8155b03b514827fa6b45b1e2fed6d6342e5 Mon Sep 17 00:00:00 2001 From: Cybernetic-Ransomware <71835339+Cybernetic-Ransomware@users.noreply.github.com> Date: Thu, 4 Jun 2026 11:03:17 +0200 Subject: [PATCH 05/17] Upgrade to Bootstrap 5, drop jQuery, add tests, clean up repo --- .gitignore | 1 + app.log | 213 ------------------ requirements.txt | 2 + static/js/input_errors_modal.js | 55 +++-- templates/index.html | 22 +- templates/result.html | 4 +- tests/__init__.py | 0 tests/conftest.py | 43 ++++ tests/test_mixins.py | 93 ++++++++ tests/test_result_store.py | 54 +++++ tests/test_routes.py | 87 +++++++ utils/__pycache__/logger.cpython-312.pyc | Bin 1306 -> 0 bytes utils/__pycache__/mixins.cpython-312.pyc | Bin 2285 -> 0 bytes .../__pycache__/qr_generator.cpython-312.pyc | Bin 1450 -> 0 bytes 14 files changed, 316 insertions(+), 258 deletions(-) delete mode 100644 app.log create mode 100644 tests/__init__.py create mode 100644 tests/conftest.py create mode 100644 tests/test_mixins.py create mode 100644 tests/test_result_store.py create mode 100644 tests/test_routes.py delete mode 100644 utils/__pycache__/logger.cpython-312.pyc delete mode 100644 utils/__pycache__/mixins.cpython-312.pyc delete mode 100644 utils/__pycache__/qr_generator.cpython-312.pyc diff --git a/.gitignore b/.gitignore index 3b0d7bc..675e6b4 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ app.log __pycache__/ *.pyc .venv/ +.pytest_cache/ diff --git a/app.log b/app.log deleted file mode 100644 index 0680b63..0000000 --- a/app.log +++ /dev/null @@ -1,213 +0,0 @@ -2024-04-16 05:16:42,760 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. - * Running on http://127.0.0.1:5000 -2024-04-16 05:16:42,760 - INFO - Press CTRL+C to quit -2024-04-16 05:16:42,761 - INFO - * Restarting with stat -2024-04-16 05:16:42,947 - WARNING - * Debugger is active! -2024-04-16 05:16:42,953 - INFO - * Debugger PIN: 136-546-380 -2024-04-16 05:17:13,010 - ERROR - Error removing file qr_with_image.png: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.png' -2024-04-16 05:17:13,013 - INFO - 127.0.0.1 - - [16/Apr/2024 05:17:13] "GET / HTTP/1.1" 200 - -2024-04-16 05:17:13,146 - INFO - 127.0.0.1 - - [16/Apr/2024 05:17:13] "GET /static/js/form_remove_image.js HTTP/1.1" 200 - -2024-04-16 05:17:13,147 - INFO - 127.0.0.1 - - [16/Apr/2024 05:17:13] "GET /static/js/input_errors_modal.js HTTP/1.1" 200 - -2024-04-16 05:17:34,782 - INFO - 127.0.0.1 - - [16/Apr/2024 05:17:34] "GET / HTTP/1.1" 200 - -2024-04-16 05:17:34,812 - INFO - 127.0.0.1 - - [16/Apr/2024 05:17:34] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:17:34,813 - INFO - 127.0.0.1 - - [16/Apr/2024 05:17:34] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:17:37,759 - INFO - 127.0.0.1 - - [16/Apr/2024 05:17:37] "GET / HTTP/1.1" 200 - -2024-04-16 05:17:37,790 - INFO - 127.0.0.1 - - [16/Apr/2024 05:17:37] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:17:37,790 - INFO - 127.0.0.1 - - [16/Apr/2024 05:17:37] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:17:43,620 - INFO - 127.0.0.1 - - [16/Apr/2024 05:17:43] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:17:43,631 - ERROR - Error removing file qr_with_image.png: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.png' -2024-04-16 05:17:43,631 - INFO - 127.0.0.1 - - [16/Apr/2024 05:17:43] "GET /result HTTP/1.1" 200 - -2024-04-16 05:17:43,676 - INFO - 127.0.0.1 - - [16/Apr/2024 05:17:43] "GET /download HTTP/1.1" 500 - -2024-04-16 05:17:43,705 - INFO - 127.0.0.1 - - [16/Apr/2024 05:17:43] "GET /download_with_image HTTP/1.1" 500 - -2024-04-16 05:18:06,974 - INFO - 127.0.0.1 - - [16/Apr/2024 05:18:06] "GET / HTTP/1.1" 200 - -2024-04-16 05:18:09,564 - INFO - 127.0.0.1 - - [16/Apr/2024 05:18:09] "GET / HTTP/1.1" 200 - -2024-04-16 05:18:09,603 - INFO - 127.0.0.1 - - [16/Apr/2024 05:18:09] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:18:09,606 - INFO - 127.0.0.1 - - [16/Apr/2024 05:18:09] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:20:36,453 - INFO - * Detected change in 'H:\\Dev_Mentoring\\QR_generator\\app.py', reloading -2024-04-16 05:20:36,485 - INFO - * Restarting with stat -2024-04-16 05:20:36,687 - WARNING - * Debugger is active! -2024-04-16 05:20:36,691 - INFO - * Debugger PIN: 136-546-380 -2024-04-16 05:20:40,442 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:40] "GET / HTTP/1.1" 200 - -2024-04-16 05:20:40,558 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:40] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:20:40,559 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:40] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:20:46,243 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:46] "GET / HTTP/1.1" 200 - -2024-04-16 05:20:46,279 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:46] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:20:46,279 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:46] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:20:50,825 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:50] "GET / HTTP/1.1" 200 - -2024-04-16 05:20:50,862 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:50] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:20:50,863 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:50] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:20:53,352 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:53] "GET / HTTP/1.1" 200 - -2024-04-16 05:20:53,387 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:53] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:20:53,388 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:53] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:20:57,894 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:57] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:20:57,905 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:57] "GET /result HTTP/1.1" 200 - -2024-04-16 05:20:57,990 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:57] "GET /download HTTP/1.1" 200 - -2024-04-16 05:20:57,991 - INFO - 127.0.0.1 - - [16/Apr/2024 05:20:57] "GET /download_with_image HTTP/1.1" 200 - -2024-04-16 05:21:05,702 - ERROR - Error removing file qr_with_image.png: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.png' -2024-04-16 05:21:05,703 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:05] "GET / HTTP/1.1" 200 - -2024-04-16 05:21:08,476 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:08] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:21:08,486 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:08] "GET /result HTTP/1.1" 200 - -2024-04-16 05:21:08,542 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:08] "GET /download HTTP/1.1" 200 - -2024-04-16 05:21:08,548 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:08] "GET /download_with_image HTTP/1.1" 500 - -2024-04-16 05:21:10,445 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:10] "GET /download_with_image HTTP/1.1" 500 - -2024-04-16 05:21:10,495 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:10] "GET /download_with_image?__debugger__=yes&cmd=resource&f=style.css HTTP/1.1" 200 - -2024-04-16 05:21:10,495 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:10] "GET /download_with_image?__debugger__=yes&cmd=resource&f=debugger.js HTTP/1.1" 200 - -2024-04-16 05:21:10,530 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:10] "GET /download_with_image?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 200 - -2024-04-16 05:21:10,537 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:10] "GET /download_with_image?__debugger__=yes&cmd=resource&f=console.png HTTP/1.1" 304 - -2024-04-16 05:21:53,142 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:53] "GET /result HTTP/1.1" 200 - -2024-04-16 05:21:53,182 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:53] "GET /download_with_image HTTP/1.1" 500 - -2024-04-16 05:21:53,214 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:53] "GET /download HTTP/1.1" 304 - -2024-04-16 05:21:56,845 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:56] "GET /result HTTP/1.1" 200 - -2024-04-16 05:21:56,876 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:56] "GET /download_with_image HTTP/1.1" 500 - -2024-04-16 05:21:56,908 - INFO - 127.0.0.1 - - [16/Apr/2024 05:21:56] "GET /download HTTP/1.1" 304 - -2024-04-16 05:22:05,360 - INFO - 127.0.0.1 - - [16/Apr/2024 05:22:05] "GET /result HTTP/1.1" 200 - -2024-04-16 05:22:05,387 - INFO - 127.0.0.1 - - [16/Apr/2024 05:22:05] "GET /download_with_image HTTP/1.1" 500 - -2024-04-16 05:22:05,411 - INFO - 127.0.0.1 - - [16/Apr/2024 05:22:05] "GET /download HTTP/1.1" 304 - -2024-04-16 05:22:14,547 - INFO - 127.0.0.1 - - [16/Apr/2024 05:22:14] "GET /result HTTP/1.1" 200 - -2024-04-16 05:22:14,574 - INFO - 127.0.0.1 - - [16/Apr/2024 05:22:14] "GET /download_with_image HTTP/1.1" 500 - -2024-04-16 05:22:14,596 - INFO - 127.0.0.1 - - [16/Apr/2024 05:22:14] "GET /download HTTP/1.1" 304 - -2024-04-16 05:22:41,914 - INFO - 127.0.0.1 - - [16/Apr/2024 05:22:41] "GET /result HTTP/1.1" 200 - -2024-04-16 05:22:41,950 - INFO - 127.0.0.1 - - [16/Apr/2024 05:22:41] "GET /download_with_image HTTP/1.1" 500 - -2024-04-16 05:22:41,964 - INFO - 127.0.0.1 - - [16/Apr/2024 05:22:41] "GET /download HTTP/1.1" 304 - -2024-04-16 05:22:54,548 - INFO - 127.0.0.1 - - [16/Apr/2024 05:22:54] "GET /result HTTP/1.1" 200 - -2024-04-16 05:22:54,580 - INFO - 127.0.0.1 - - [16/Apr/2024 05:22:54] "GET /download_with_image HTTP/1.1" 500 - -2024-04-16 05:22:54,605 - INFO - 127.0.0.1 - - [16/Apr/2024 05:22:54] "GET /download HTTP/1.1" 304 - -2024-04-16 05:24:15,869 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:15] "GET /result HTTP/1.1" 200 - -2024-04-16 05:24:15,918 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:15] "GET /download HTTP/1.1" 304 - -2024-04-16 05:24:16,524 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:16] "GET /result HTTP/1.1" 200 - -2024-04-16 05:24:16,625 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:16] "GET /download HTTP/1.1" 304 - -2024-04-16 05:24:17,407 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:17] "GET / HTTP/1.1" 200 - -2024-04-16 05:24:18,420 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:18] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:24:18,432 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:18] "GET /result HTTP/1.1" 200 - -2024-04-16 05:24:18,494 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:18] "GET /download HTTP/1.1" 200 - -2024-04-16 05:24:25,556 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:25] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:24:25,572 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:25] "GET /result HTTP/1.1" 200 - -2024-04-16 05:24:25,674 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:25] "GET /download HTTP/1.1" 200 - -2024-04-16 05:24:44,722 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:44] "GET /result HTTP/1.1" 200 - -2024-04-16 05:24:44,775 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:44] "GET /download HTTP/1.1" 200 - -2024-04-16 05:24:45,443 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:45] "GET /result HTTP/1.1" 200 - -2024-04-16 05:24:45,502 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:45] "GET /download HTTP/1.1" 304 - -2024-04-16 05:24:46,730 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:46] "GET /result HTTP/1.1" 200 - -2024-04-16 05:24:46,821 - INFO - 127.0.0.1 - - [16/Apr/2024 05:24:46] "GET /download HTTP/1.1" 304 - -2024-04-16 05:26:13,901 - INFO - * Detected change in 'H:\\Dev_Mentoring\\QR_generator\\app.py', reloading -2024-04-16 05:26:13,934 - INFO - * Restarting with stat -2024-04-16 05:26:14,161 - WARNING - * Debugger is active! -2024-04-16 05:26:14,166 - INFO - * Debugger PIN: 136-546-380 -2024-04-16 05:26:23,270 - INFO - * Detected change in 'H:\\Dev_Mentoring\\QR_generator\\app.py', reloading -2024-04-16 05:26:23,304 - INFO - * Restarting with stat -2024-04-16 05:26:23,505 - WARNING - * Debugger is active! -2024-04-16 05:26:23,510 - INFO - * Debugger PIN: 136-546-380 -2024-04-16 05:26:24,505 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:24] "GET /result HTTP/1.1" 200 - -2024-04-16 05:26:24,698 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:24] "GET /download HTTP/1.1" 304 - -2024-04-16 05:26:24,700 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:24] "GET /download_with_image HTTP/1.1" 200 - -2024-04-16 05:26:24,737 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:24] "GET /favicon.ico HTTP/1.1" 404 - -2024-04-16 05:26:25,942 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:25] "GET /result HTTP/1.1" 200 - -2024-04-16 05:26:26,018 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:26] "GET /download HTTP/1.1" 304 - -2024-04-16 05:26:26,019 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:26] "GET /download_with_image HTTP/1.1" 304 - -2024-04-16 05:26:42,772 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:42] "GET /result HTTP/1.1" 200 - -2024-04-16 05:26:42,825 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:42] "GET /download HTTP/1.1" 304 - -2024-04-16 05:26:42,825 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:42] "GET /download_with_image HTTP/1.1" 304 - -2024-04-16 05:26:47,846 - ERROR - Error removing file qr_with_image.png: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.png' -2024-04-16 05:26:47,848 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:47] "GET / HTTP/1.1" 200 - -2024-04-16 05:26:47,878 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:47] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:26:47,878 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:47] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:26:52,480 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:52] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:26:52,491 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:52] "GET /result HTTP/1.1" 200 - -2024-04-16 05:26:52,562 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:52] "GET /download HTTP/1.1" 200 - -2024-04-16 05:26:54,115 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:54] "GET / HTTP/1.1" 200 - -2024-04-16 05:26:57,509 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:57] "GET / HTTP/1.1" 200 - -2024-04-16 05:26:57,534 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:57] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:26:57,535 - INFO - 127.0.0.1 - - [16/Apr/2024 05:26:57] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:28:58,363 - INFO - 127.0.0.1 - - [16/Apr/2024 05:28:58] "GET / HTTP/1.1" 200 - -2024-04-16 05:28:58,412 - INFO - 127.0.0.1 - - [16/Apr/2024 05:28:58] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:28:58,416 - INFO - 127.0.0.1 - - [16/Apr/2024 05:28:58] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:29:33,501 - INFO - 127.0.0.1 - - [16/Apr/2024 05:29:33] "GET / HTTP/1.1" 200 - -2024-04-16 05:29:33,536 - INFO - 127.0.0.1 - - [16/Apr/2024 05:29:33] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:29:33,536 - INFO - 127.0.0.1 - - [16/Apr/2024 05:29:33] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:30:06,705 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:06] "GET / HTTP/1.1" 200 - -2024-04-16 05:30:06,742 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:06] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:30:06,743 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:06] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:30:07,622 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:07] "GET / HTTP/1.1" 200 - -2024-04-16 05:30:07,691 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:07] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:30:07,693 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:07] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:30:30,254 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:30] "GET / HTTP/1.1" 200 - -2024-04-16 05:30:30,297 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:30] "GET /static/js/input_errors_modal.js HTTP/1.1" 200 - -2024-04-16 05:30:30,300 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:30] "GET /static/js/form_remove_image.js HTTP/1.1" 200 - -2024-04-16 05:30:41,634 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:41] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:30:41,650 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:41] "GET /result HTTP/1.1" 200 - -2024-04-16 05:30:41,688 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:41] "GET /download HTTP/1.1" 200 - -2024-04-16 05:30:41,689 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:41] "GET /download_with_image HTTP/1.1" 200 - -2024-04-16 05:30:44,216 - ERROR - Error removing file qr_with_image.png: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.png' -2024-04-16 05:30:44,217 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:44] "GET / HTTP/1.1" 200 - -2024-04-16 05:30:47,545 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:47] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:30:47,557 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:47] "GET /result HTTP/1.1" 200 - -2024-04-16 05:30:47,619 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:47] "GET /download HTTP/1.1" 200 - -2024-04-16 05:30:47,620 - INFO - 127.0.0.1 - - [16/Apr/2024 05:30:47] "GET /download_with_image HTTP/1.1" 200 - -2024-04-16 05:31:38,356 - INFO - * Detected change in 'H:\\Dev_Mentoring\\QR_generator\\utils\\mixins.py', reloading -2024-04-16 05:31:38,383 - INFO - * Restarting with stat -2024-04-16 05:31:38,576 - WARNING - * Debugger is active! -2024-04-16 05:31:38,581 - INFO - * Debugger PIN: 136-546-380 -2024-04-16 05:31:38,593 - ERROR - Error removing file qr_with_image.png: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.png' -2024-04-16 05:31:38,598 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:38] "GET / HTTP/1.1" 200 - -2024-04-16 05:31:38,719 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:38] "GET /static/js/input_errors_modal.js HTTP/1.1" 200 - -2024-04-16 05:31:38,720 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:38] "GET /static/js/form_remove_image.js HTTP/1.1" 200 - -2024-04-16 05:31:39,357 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:39] "GET / HTTP/1.1" 200 - -2024-04-16 05:31:39,405 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:39] "GET /static/js/input_errors_modal.js HTTP/1.1" 304 - -2024-04-16 05:31:39,409 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:39] "GET /static/js/form_remove_image.js HTTP/1.1" 304 - -2024-04-16 05:31:42,816 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:42] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:31:42,837 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:42] "GET /result HTTP/1.1" 200 - -2024-04-16 05:31:42,966 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:42] "GET /download HTTP/1.1" 200 - -2024-04-16 05:31:42,966 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:42] "GET /download_with_image HTTP/1.1" 200 - -2024-04-16 05:31:44,499 - ERROR - Error removing file qr_with_image.png: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.png' -2024-04-16 05:31:44,499 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:44] "GET / HTTP/1.1" 200 - -2024-04-16 05:31:47,171 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:47] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:31:47,192 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:47] "GET /result HTTP/1.1" 200 - -2024-04-16 05:31:47,264 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:47] "GET /download HTTP/1.1" 200 - -2024-04-16 05:31:47,264 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:47] "GET /download_with_image HTTP/1.1" 200 - -2024-04-16 05:31:50,414 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:50] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:31:50,424 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:50] "GET /result HTTP/1.1" 200 - -2024-04-16 05:31:50,488 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:50] "GET /download HTTP/1.1" 200 - -2024-04-16 05:31:50,489 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:50] "GET /download_with_image HTTP/1.1" 200 - -2024-04-16 05:31:54,267 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:54] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:31:54,277 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:54] "GET /result HTTP/1.1" 200 - -2024-04-16 05:31:54,334 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:54] "GET /download HTTP/1.1" 200 - -2024-04-16 05:31:54,335 - INFO - 127.0.0.1 - - [16/Apr/2024 05:31:54] "GET /download_with_image HTTP/1.1" 200 - -2024-04-16 05:33:28,318 - INFO - 127.0.0.1 - - [16/Apr/2024 05:33:28] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:33:28,337 - INFO - 127.0.0.1 - - [16/Apr/2024 05:33:28] "GET /result HTTP/1.1" 200 - -2024-04-16 05:33:28,444 - INFO - 127.0.0.1 - - [16/Apr/2024 05:33:28] "GET /download HTTP/1.1" 200 - -2024-04-16 05:33:28,447 - INFO - 127.0.0.1 - - [16/Apr/2024 05:33:28] "GET /download_with_image HTTP/1.1" 200 - -2024-04-16 05:37:36,052 - INFO - 127.0.0.1 - - [16/Apr/2024 05:37:36] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:37:36,065 - INFO - 127.0.0.1 - - [16/Apr/2024 05:37:36] "GET /result HTTP/1.1" 200 - -2024-04-16 05:37:36,132 - INFO - 127.0.0.1 - - [16/Apr/2024 05:37:36] "GET /download HTTP/1.1" 200 - -2024-04-16 05:37:36,133 - INFO - 127.0.0.1 - - [16/Apr/2024 05:37:36] "GET /download_with_image HTTP/1.1" 200 - -2024-04-16 05:38:00,078 - INFO - 127.0.0.1 - - [16/Apr/2024 05:38:00] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:38:00,091 - INFO - 127.0.0.1 - - [16/Apr/2024 05:38:00] "GET /result HTTP/1.1" 200 - -2024-04-16 05:38:00,152 - INFO - 127.0.0.1 - - [16/Apr/2024 05:38:00] "GET /download HTTP/1.1" 200 - -2024-04-16 05:38:00,152 - INFO - 127.0.0.1 - - [16/Apr/2024 05:38:00] "GET /download_with_image HTTP/1.1" 200 - -2024-04-16 05:38:07,088 - ERROR - Error removing file qr_with_image.png: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.png' -2024-04-16 05:38:07,088 - INFO - 127.0.0.1 - - [16/Apr/2024 05:38:07] "GET / HTTP/1.1" 200 - -2024-04-16 05:38:09,111 - INFO - 127.0.0.1 - - [16/Apr/2024 05:38:09] "POST /generate HTTP/1.1" 200 - -2024-04-16 05:38:09,125 - INFO - 127.0.0.1 - - [16/Apr/2024 05:38:09] "GET /result HTTP/1.1" 200 - -2024-04-16 05:38:09,193 - INFO - 127.0.0.1 - - [16/Apr/2024 05:38:09] "GET /download HTTP/1.1" 200 - -2024-04-16 05:39:24,775 - INFO - * Detected change in 'H:\\Dev_Mentoring\\QR_generator\\utils\\qr_generator.py', reloading -2024-04-16 05:39:24,812 - INFO - * Restarting with stat -2024-04-16 05:39:25,031 - WARNING - * Debugger is active! -2024-04-16 05:39:25,037 - INFO - * Debugger PIN: 136-546-380 -2024-04-16 05:41:26,769 - INFO - * Detected change in 'H:\\Dev_Mentoring\\QR_generator\\utils\\logger.py', reloading -2024-04-16 05:41:26,805 - INFO - * Restarting with stat -2024-04-16 05:41:27,005 - WARNING - * Debugger is active! -2024-04-16 05:41:27,010 - INFO - * Debugger PIN: 136-546-380 -2024-04-16 05:42:33,413 - INFO - * Detected change in 'H:\\Dev_Mentoring\\QR_generator\\app.py', reloading -2024-04-16 05:42:33,448 - INFO - * Restarting with stat -2024-04-16 05:55:20,539 - ERROR - Error removing file qr_with_image.png: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.png' -2024-04-16 06:11:04,905 - ERROR - Error removing file qr_with_image.gif: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.gif' -2024-04-16 06:11:19,712 - ERROR - Error removing file qr_with_image.png: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.png' -2024-04-16 06:13:39,656 - ERROR - Error removing file qr_with_image.png: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.png' -2024-04-16 06:13:55,412 - ERROR - Error removing file qr_with_image.png: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.png' -2024-04-16 06:19:41,117 - ERROR - Error removing file qr_with_image.gif: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.gif' -2024-04-16 06:26:39,508 - ERROR - Error removing file qr_with_image.gif: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.gif' -2024-04-16 06:26:45,748 - ERROR - Error removing file qr_with_image.png: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.png' -2024-04-16 06:27:20,691 - ERROR - Error removing file qr_with_image.gif: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.gif' -2024-04-16 06:34:42,506 - ERROR - Error removing file qr_with_image.gif: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.gif' -2024-04-16 06:35:34,416 - ERROR - Error removing file qr_with_image.gif: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.gif' -2024-04-16 06:37:00,955 - ERROR - Error removing file qr_with_image.gif: [WinError 2] Nie można odnaleŸć okreœlonego pliku: 'qr_with_image.gif' diff --git a/requirements.txt b/requirements.txt index da963ef..9080073 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,3 +10,5 @@ qrcode-artistic==3.0.2 segno==1.6.1 Werkzeug==3.0.2 Flask-WTF==1.2.1 +pytest +pytest-flask diff --git a/static/js/input_errors_modal.js b/static/js/input_errors_modal.js index 997b905..42e015e 100644 --- a/static/js/input_errors_modal.js +++ b/static/js/input_errors_modal.js @@ -1,37 +1,34 @@ -$(document).ready(function(){ +document.addEventListener('DOMContentLoaded', function () { + var errorModal = new bootstrap.Modal(document.getElementById('errorModal')); + function showErrors(errors) { - var $body = $('#errorModalBody').empty(); + var body = document.getElementById('errorModalBody'); + body.innerHTML = ''; (errors && errors.length ? errors : ['An unexpected error occurred.']) - .forEach(function(error) { $('

').text(error).appendTo($body); }); - $('#errorModal').modal('show'); + .forEach(function (error) { + var p = document.createElement('p'); + p.textContent = error; + body.appendChild(p); + }); + errorModal.show(); } - $('#generate-form').submit(function(event){ + document.getElementById('generate-form').addEventListener('submit', function (event) { event.preventDefault(); - var formData = new FormData($(this)[0]); - - $.ajax({ - type: 'POST', - url: '/generate', - data: formData, - processData: false, - contentType: false, - success: function(response) { - if (response.success) { - window.location.href = '/result?id=' + encodeURIComponent(response.id); - } else { - showErrors(response.errors); - } - }, - error: function(xhr) { - console.error(xhr.responseText); - var errors = (xhr.responseJSON && xhr.responseJSON.errors) ? xhr.responseJSON.errors : null; - if (!errors && xhr.status === 413) { - errors = ['File is too large. Maximum request size is 6 MB.']; - } - showErrors(errors); - } - }); + fetch('/generate', { method: 'POST', body: new FormData(this) }) + .then(function (response) { + return response.json().then(function (data) { + if (data.success) { + window.location.href = '/result?id=' + encodeURIComponent(data.id); + } else { + showErrors(data.errors); + } + }); + }) + .catch(function (err) { + console.error(err); + showErrors(null); + }); }); }); diff --git a/templates/index.html b/templates/index.html index d6f89d3..9ace205 100644 --- a/templates/index.html +++ b/templates/index.html @@ -5,8 +5,8 @@ QR Code Generator - @@ -26,7 +26,7 @@

QR Code Generator



-
+


@@ -35,14 +35,12 @@

QR Code Generator

-