diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ed8ebf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__ \ No newline at end of file diff --git a/README.md b/README.md index 6ce6f47..0af8478 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,13 @@ Project based on [Virtual Air Traffic Simulation Network (VATSIM) API](https://v Written in Python 3.7.10 + JS (JQuery framework) + Boostrap +## Startup +For run application on your own machine, you must install docker. Then just one command in the "src" folder with the project source code: + +```bash +docker compose up +``` + ## Contibution Any help with this project would be greatly appreciated. Fixes or some features are welcome. @@ -21,13 +28,17 @@ More information about the contributing to this project will appear there a litt ## Feature There is small TODO list I would like to make in this project: -+ Deploy to webserver with domain -+ More ATC information — add map with control area -+ More profile information — add some more info, not only date of registration. Maybe rating or something -+ Website redesign -+ Challenges, like: "fly to this country N times", or "fly to all countries around the world", etc +- [x] Create docker +- [x] Deploy to webserver with domain +- [ ] More ATC information — add map with control area +- [ ] More profile information — add some more info, not only date of registration. Maybe rating or something +- [ ] Website redesign +- [ ] Challenges, like: "fly to this country N times", or "fly to all countries around the world", etc -## Author +## Contributors +https://github.com/exituser/ + +## Author contacts Telegram: https://uw935.t.me/
Instagram: https://instagram.com/uw_935/
Discord: uw935 \ No newline at end of file diff --git a/app.py b/app.py deleted file mode 100644 index 684ca97..0000000 --- a/app.py +++ /dev/null @@ -1,29 +0,0 @@ -from flask import Flask, render_template, abort -import requests - - -app = Flask(__name__) - - -@app.route("/") -def index_page(): - return render_template("index.html") - - -@app.errorhandler(404) -def errorhandler_page(_): - return render_template("4O4.html"), 404 - - -@app.route("//") -def viewer_page(cid): - user = requests.get(f"https://api.vatsim.net/v2/members/{cid}").json() - - if "detail" in user and user["detail"] == "Not Found": - return abort(404) - - return render_template("viewer.html", data=(user, )) - - -if __name__ == "__main__": - app.run(debug=True) diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 4b70123..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -Flask==2.2.5 diff --git a/src/.dockerignore b/src/.dockerignore new file mode 100644 index 0000000..1c2b579 --- /dev/null +++ b/src/.dockerignore @@ -0,0 +1,2 @@ +media +README.md \ No newline at end of file diff --git a/src/Dockerfile b/src/Dockerfile new file mode 100644 index 0000000..dd45b5b --- /dev/null +++ b/src/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.7.10 + +WORKDIR /build/ + +COPY requirements.txt /build/ + +RUN pip install --upgrade pip +RUN pip install -r requirements.txt + +COPY . /build/ + +CMD ["python3", "-m", "flask", "run", "--host=0.0.0.0"] \ No newline at end of file diff --git a/src/app.py b/src/app.py new file mode 100644 index 0000000..9135d1e --- /dev/null +++ b/src/app.py @@ -0,0 +1,40 @@ +from flask import Flask, render_template, abort, request, jsonify +import requests + + +app = Flask(__name__) +VATSIM_API_URL = "https://api.vatsim.net/v2/" + + +@app.route("/") +def index_page(): + return render_template("index.html") + + +@app.errorhandler(404) +def errorhandler_page(_): + return render_template("4O4.html"), 404 + +# Custom wrapper to fetch VATSIM data +@app.route("/api/request") +def request_handler(): + request_string = request.args.get("request_string") + + if request_string: + return requests.get(f"{VATSIM_API_URL}{request_string}").json() + + return jsonify({"result": "not found"}) + + +@app.route("//") +def viewer_page(cid): + user = requests.get(f"{VATSIM_API_URL}members/{cid}").json() + + if "detail" in user and user["detail"] == "Not Found": + return abort(404) + + return render_template("viewer.html", data=(user, )) + + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=80) diff --git a/src/docker-compose.yml b/src/docker-compose.yml new file mode 100644 index 0000000..4c96860 --- /dev/null +++ b/src/docker-compose.yml @@ -0,0 +1,9 @@ +version: "3" + +services: + app: + build: + context: . + dockerfile: Dockerfile + ports: + - "80:5000" diff --git a/src/requirements.txt b/src/requirements.txt new file mode 100644 index 0000000..560df14 --- /dev/null +++ b/src/requirements.txt @@ -0,0 +1,3 @@ +Flask==2.2.5 +requests==2.31.0 +flake8==5.0.4 diff --git a/static/data/airports.json b/src/static/data/airports.json similarity index 100% rename from static/data/airports.json rename to src/static/data/airports.json diff --git a/static/icon.ico b/src/static/icon.ico similarity index 100% rename from static/icon.ico rename to src/static/icon.ico diff --git a/static/viewer.css b/src/static/viewer.css similarity index 100% rename from static/viewer.css rename to src/static/viewer.css diff --git a/static/viewer.js b/src/static/viewer.js similarity index 75% rename from static/viewer.js rename to src/static/viewer.js index 349977f..89ed904 100644 --- a/static/viewer.js +++ b/src/static/viewer.js @@ -1,7 +1,10 @@ // Fetching user's ATC session informations from API let userSession = {}; -fetch(ATC_API_URL, {}).then(response => response.json).then(result => { +fetch(ATC_API_URL, {}).then(response => response.json()).then(result => { + if (result && result["result"] == "not found") + return + for (let session of result["items"]) { // Separate each session by it's connection ID let session_id = session["connection_id"]["id"]; @@ -13,24 +16,48 @@ fetch(ATC_API_URL, {}).then(response => response.json).then(result => { $("#fox_atc").append(sessionElement); } - showSession(userSession[result["items"][0]["callsign"]]); + // Click event handler to left menu button + $(".fox_atc").click(function() { + if ($(this).hasClass("fox_atc_active")) return; + + $(".fox_atc_active").removeClass("fox_atc_active"); + $(this).addClass("fox_atc_active"); + + showSession(userSession[$(this).attr("id")]); + }); + + showSession(result["items"][0]); }); // Fetching user's flightplans from VATSIM API let userFlightplans = {}; -fetch(FLIGHTPLANS_API_URL, {}).then(response => response.json).then(result => { +fetch(FLIGHTPLANS_API_URL, {}).then(response => response.json()).then(result => { + if (result && result["result"] == "not found") + return + for (let flightplan of result) { // Separate each flight by it's connection ID // Like it was with ATC session's - let flightplan_id = flightplan["connection_id"] + let flightplan_id = flightplan["id"] userFlightplans[flightplan_id] = flightplan; + userFlightplans[flightplan_id]["not_filed"] = flightplan["connection_id"] === 0 // Long line again let flightplanElement = "
" + flightplan["callsign"] + "
"; $("#fox_flightplans").append(flightplanElement); } - showFlight(userFlightplans[result[0]["callsign"]]); + + $(".fox_button").click(function() { + if ($(this).hasClass("fox_active")) return; + + $(".fox_active").removeClass("fox_active"); + $(this).addClass("fox_active"); + + showFlight(userFlightplans[$(this).attr("id")]); + }); + + showFlight(result[0]); }); // Fetching airports information @@ -93,6 +120,7 @@ function showFlight(flight) { // Changing text in each class // FP before _ - means flightplan + $(".fp_is_filed").text(flight["not_filed"] ? "This flightplan was not filed" : ""); $(".fp_callsign").text(flight["callsign"]); $(".fp_depa_city").text(airports[flight["dep"]]["city"]); $(".fp_arra_city").text(airports[flight["arr"]]["city"]); @@ -117,30 +145,11 @@ function showSession(session) { if (!session) return; $(".atc_callsign").text(session["connection_id"]["callsign"]); - $(".atc_start_time").text(session["connection_id"]["start"]); - $(".atc_end_time").text(session["connection_id"]["end"]); + $(".atc_start_time").text(session["connection_id"]["start"].replace("T", " ")); + $(".atc_end_time").text(session["connection_id"]["end"].replace("T", " ")); $(".atc_trackedair").text(session["aircrafttracked"]); $(".atc_seenair").text(session["aircraftseen"]); $(".atc_squawks").text(session["squawksassigned"]); $(".atc_transfers").text(session["handoffsinitiated"]); $(".atc_received").text(session["handoffsreceived"]); } - -// Click event handler to left menu button -$(".fox_atc").click(function() { - if ($(this).hasClass("fox_atc_active")) return; - - $(".fox_atc_active").removeClass("fox_atc_active"); - $(this).addClass("fox_atc_active"); - - showSession(userSession[$(this).attr("id")]); -}) - -$(".fox_button").click(function() { - if ($(this).hasClass("fox_active")) return; - - $(".fox_active").removeClass("fox_active"); - $(this).addClass("fox_active"); - - showFlight(userFlightplans[$(this).attr("id")]); -}); diff --git a/templates/4O4.html b/src/templates/4O4.html similarity index 100% rename from templates/4O4.html rename to src/templates/4O4.html diff --git a/templates/include/template.html b/src/templates/include/template.html similarity index 100% rename from templates/include/template.html rename to src/templates/include/template.html diff --git a/templates/index.html b/src/templates/index.html similarity index 67% rename from templates/index.html rename to src/templates/index.html index 1482061..5194eda 100644 --- a/templates/index.html +++ b/src/templates/index.html @@ -6,10 +6,10 @@

Enter your VATSIM CID

See your detailed profile statistic

-

+

@@ -24,7 +24,7 @@

Open source project

This project is fully opened, so you can contribute in it if you want

- +
@@ -34,12 +34,17 @@ {% block javascript_code %}