From b7c1faff911c6943d379ce6ad3f44bba4027aedc Mon Sep 17 00:00:00 2001 From: Gregor Kikelj Date: Fri, 27 Jan 2023 16:08:18 +0100 Subject: Public cleanup --- .gitignore | 4 ++ README.md | 8 +++ helpers.py | 70 +++++++++++++++++++ server.py | 82 ++++++++++++++++++++++ static/favicon.ico | Bin 0 -> 193310 bytes templates/failure.html | 150 ++++++++++++++++++++++++++++++++++++++++ templates/index.html | 182 +++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 496 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 helpers.py create mode 100644 server.py create mode 100644 static/favicon.ico create mode 100644 templates/failure.html create mode 100644 templates/index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..428598d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__ +*.sh +*.log +*.txt \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..425e829 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +Koda za spletno stran za preverjanje e-vinjet + +## Kako uporabljati +Namestite vse potrebne pakete s `pip install` nato `python3 server.py`. +Nato morate stran nekako spraviti na internet, ena opcija je nakup domene, druga je ngrok(zeeeelo enostavno in zastonj ampak da popup ob uporabi). Ko spletno stran postavite ne bo delovala ker mora dobiti pravilne headerje, zato nam njen naslov pošljite na `brajdic.roman@gmail.com` da jih boste prejemali in da promet preusmerimo na vašo stran. + + + diff --git a/helpers.py b/helpers.py new file mode 100644 index 0000000..414cb87 --- /dev/null +++ b/helpers.py @@ -0,0 +1,70 @@ +import requests +import json +from datetime import datetime, timezone, timedelta +from functools import lru_cache + +def formatEndDate(st): + if st is None: + return (None, None) + dt = datetime.strptime(st, "%Y-%m-%dT%H:%M:%S.%f0%z") + formatted = dt.strftime("%d.%m.%Y") + + # print days from today to date + daysRemaining = (dt - datetime.now(timezone.utc)).days + + return (formatted, daysRemaining) + + +purl = "https://evinjeta.dars.si/selfcare/api/eshop/shopping-cart/validate" + +json_dump = open("payload.txt", "r").read() +payload = json.loads(json_dump) + + +def get_headers(): + hdump = [x.split(":") for x in [t for t in open("headers.txt", "r")][1:]] + headers = {h[0]: h[1].strip() for h in hdump} + return headers + +@lru_cache(maxsize=None) +def veljavnost(registrska: str): + today = datetime.now() + one_year_after = today + timedelta(days=365) + payload["registrationNumber"] = registrska + payload["registrationNumberAgain"] = registrska + payload["vignetteValidityStart"] = today.strftime("%Y-%m-%dT%H:%M:%S.%fZ") + payload["vignetteValidityEnd"] = one_year_after.strftime( + "%Y-%m-%dT%H:%M:%S.%f0%z") + r = requests.post(purl, json=payload, headers=get_headers(), verify=False) + # print("\n"+r.text+"\n------------------\n\n\n") + print(r.status_code, r.reason, r.url) + return r.json() + + +def aux(registrska): + registrska = registrska.upper().replace(" ", "").replace("-", "").strip() + if len(registrska) > 8 or len(registrska) < 5 or not registrska.isalnum(): + return None + if registrska == "FTEST": + t = 1/0 + if registrska[:3] == "XXX": + return None + jdump = veljavnost(registrska)["vignetteValidationResult"] + if "exemptedVehicles" in jdump and len(jdump["exemptedVehicles"]) > 0: + return f'Oproščeno {jdump["exemptedVehicles"][0]["exemptionReasonId"]["text"]}' + + # for k, v in jdump.items(): + # print(f"{k}: {v}") + max_date = None + for v in jdump["vignettes"]: + print(v) + date_1 = v["vignetteValidityStart"] + date_2 = v["vignetteValidityEnd"] + if max_date is None or date_2 > max_date: + max_date = date_2 + # resp.append(f"Obstaja vinjeta veljavna od {formatEndDate(date_1)[0]} do {formatEndDate(date_2)[0]}, torej je veljavna še {formatEndDate(date_2)[1]} dni") + return formatEndDate(max_date)[0] + + +if __name__ == "__main__": + pass diff --git a/server.py b/server.py new file mode 100644 index 0000000..aebf98c --- /dev/null +++ b/server.py @@ -0,0 +1,82 @@ +from flask import Flask, jsonify, render_template, request, send_from_directory +import os +from helpers import aux +from discord_webhook import DiscordWebhook +import datetime +from flask_limiter import Limiter +from flask_limiter.util import get_remote_address +import logging + +# Logs to both console and app.log file +logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s %(threadName)s : %(message)s") +formatter = logging.Formatter("%(asctime)s %(levelname)s %(name)s %(threadName)s : %(message)s") +logger = logging.getLogger('server') +handler = logging.FileHandler('app.log') +handler.setFormatter(formatter) +handler.setLevel(logging.INFO) +logger.addHandler(handler) + +def niceDateTime(): + time = datetime.datetime.now() + return time.strftime("%H:%M:%S -- %d/%m/%Y") +def niceTime(): + time = datetime.datetime.now() + return time.strftime("%H:%M:%S") + +def spamDiscord(logs = ""): + content = f"@everyone, napaka na strani ob {niceDateTime()}: \n {logs}" + webhook = DiscordWebhook(url='https://discord.com/api/webhooks/1062432166950219838/tgl04gFFIMkrASeWX2AlETdsgdTHU3CWufzE1NZQMLQ2eZGVeQyGXj4AAt0k4Dj467B'+'d', content=content) + webhook.execute() + + +def discordLog(msg): + DiscordWebhook(url="https://discord.com/api/webhooks/1062474351196262571/V6M_vfhPy9QEEbM-b1W7qxBr2k5olpyeOY1O2RoKZ178c0Fs9_vYzKqJwES3o3suLSF"+"o", content=msg).execute() + + +app = Flask(__name__, static_folder="static") +limiter = Limiter( + get_remote_address, + app=app, + default_limits=["50 per minute"], + storage_uri="memory://", +) + + +def setHeaders(request): + headers = request.form["headers"] + with open("headers.txt", "w") as f: + f.write(headers) + discordLog(f"Headers so bili spremenjeni ob {niceDateTime()}") + return "OK" + +@app.route('/favicon.ico') +@app.route('/robots.txt') +@app.route('/sitemap.xml') +def static_from_root(): + return send_from_directory(app.static_folder, request.path[1:]) + +@app.route('/', methods=['POST']) +def apcall(): + if "headers" in request.form: + setHeaders(request) + return "OK" + registrska = request.form["registrska"] + try: + ar = aux(registrska) + app.logger.info(f"Registrska \"{registrska}\" je veljavna do {ar} ob {niceTime()}") + # discordLog(f"Registrska \"{registrska}\" je veljavna do {ar} ob {niceTime()}") + return render_template('index.html', valid_until = ar, license_plate = registrska) + except Exception as e: + spamDiscord(str(e)) + app.logger.error(f"\nNapaka pri {registrska} ob {niceTime()}") + # discordLog(f"!!!!!!!!!!!!!!!!!!!!!!!!!!!\nNapaka pri {registrska} ob {niceTime()}") + return render_template('failure.html') + +@app.route('/', methods=['GET']) +def index(): + app.logger.info("Zahteva za domačo stran") + # discordLog(f"Zahteva za domačo stran ob {niceTime()}") + return render_template('index.html') + +if __name__ == '__main__': + app.run() \ No newline at end of file diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000..cac1eb8 Binary files /dev/null and b/static/favicon.ico differ diff --git a/templates/failure.html b/templates/failure.html new file mode 100644 index 0000000..7cff5eb --- /dev/null +++ b/templates/failure.html @@ -0,0 +1,150 @@ + + + + + + + + + + eVinjeta + + + + + + + + + + + + +
+

eVINJETA

+
+ Žal je s strežnikom nekaj narobe, DARS občasno ovira delovanje naše strani. Morda jim je dolgčas.
+
+ Za informacije o vinjeti pokličite na 01 51 88 350 + številka deluje 24/7, ko se klic poveže dvakrat pritisnite 1, nato pa operaterju povejte svojo registrsko številko.
+
+ Drugi način je da sledite navodilom na posnetku spodaj.
+
+ Lahko pa spletno stran ponovno pogledate kasneje, nismo še obupali! +
+
+ +
+
+ + diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..d552e94 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,182 @@ + + + + + + + + + + + + + eVinjeta: Hitro preveri veljavnost evinjete + + + + + + + + + + + + +
+

eVINJETA

+
+ Preveri veljavnost svoje eVinjete: + * Podatke dobimo iz DARS strežnikov. Nismo povezani z DARSom. +
+
+
+

Registrska tablica:

+ +
+
+ +
+
+ {% if valid_until %} +
+

Vinjeta za registrsko tablico {{ license_plate }} je veljavna vključno do: {{ valid_until }}

+
+ {% elif license_plate %} +
+

Registrska tablica "{{ license_plate }}" nima veljavne vinjete!

+
+ {% endif %} + +
+ +
+
+ + \ No newline at end of file -- cgit v1.2.3