mirror of
https://github.com/uw935/vatsimfox.git
synced 2026-09-17 04:48:58 +00:00
@@ -0,0 +1 @@
|
||||
__pycache__
|
||||
@@ -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/<br>
|
||||
Instagram: https://instagram.com/uw_935/<br>
|
||||
Discord: uw935
|
||||
@@ -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("/<int:cid>/")
|
||||
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)
|
||||
@@ -1 +0,0 @@
|
||||
Flask==2.2.5
|
||||
@@ -0,0 +1,2 @@
|
||||
media
|
||||
README.md
|
||||
@@ -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"]
|
||||
+40
@@ -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("/<int:cid>/")
|
||||
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)
|
||||
@@ -0,0 +1,9 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "80:5000"
|
||||
@@ -0,0 +1,3 @@
|
||||
Flask==2.2.5
|
||||
requests==2.31.0
|
||||
flake8==5.0.4
|
||||
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
@@ -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 = "<div id="+ flightplan_id +" class='fox_button mb-2 p-2 text-center text-bg-white border border-1 rounded-3'>" + flightplan["callsign"] + "</div>";
|
||||
$("#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")]);
|
||||
});
|
||||
@@ -9,7 +9,7 @@
|
||||
<input class="fox_input form-control me-2" type="number" placeholder="100000" aria-label="CID">
|
||||
<button class="fox_submit btn btn-outline-success" type="submit">Search</button>
|
||||
</div>
|
||||
<p class="fox_message col-md-8 fs-4"></p>
|
||||
<p class="fox_message text-primary col-md-8 fs-4"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<div class="h-100 p-5 bg-light border rounded-3">
|
||||
<h2>Open source project</h2>
|
||||
<p>This project is fully opened, so you can contribute in it if you want</p>
|
||||
<a href="https://github.com/uw935/vatsim-fox">
|
||||
<a href="https://github.com/uw935/vatsimfox">
|
||||
<button class="btn btn-outline-secondary" type="button">GitHub</button>
|
||||
</a>
|
||||
</div>
|
||||
@@ -34,12 +34,17 @@
|
||||
{% block javascript_code %}
|
||||
<script type="text/javascript">
|
||||
$(".fox_submit").click(function() {
|
||||
const INPUT_CID = $(".fox_input").val();
|
||||
const INPUT_CID = 0 + $(".fox_input").val();
|
||||
|
||||
fetch("https://api.vatsim.net/v2/members/" + INPUT_CID, {})
|
||||
if ((0 + INPUT_CID) < 100000) {
|
||||
$(".fox_message").text("CID should be equal or more than 100000");
|
||||
return;
|
||||
}
|
||||
|
||||
fetch("/api/request?request_string=members/" + INPUT_CID, {})
|
||||
.then(response => response.json()).then(result => {
|
||||
// Checking if user existt
|
||||
if (!result.ok || result.status == 404) {
|
||||
// Checking if user exist
|
||||
if (result.result == "not found" || result.detail == "Not Found") {
|
||||
$(".fox_message").text("User not found!");
|
||||
return;
|
||||
}
|
||||
@@ -15,10 +15,13 @@
|
||||
<div id="fox_flightplans" class="mb-4 col-md-3"></div>
|
||||
|
||||
<div class="col-md" style="height: 500px; overflow-y: scroll;">
|
||||
<div id="fox_map" class="mb-4 h-50 bg-dark rounded-3">
|
||||
</div>
|
||||
<div id="fox_map" class="mb-4 h-50 bg-dark rounded-3"></div>
|
||||
<div class="h-auto p-5 bg-light border rounded-3">
|
||||
<h2><span class="fp_callsign">Flight</span> — from <span class="fp_depa_city"></span> to <span class="fp_arra_city"></span></h2>
|
||||
<span>
|
||||
<b class="fp_is_filed"></b>
|
||||
</span>
|
||||
<br>
|
||||
<span>
|
||||
<b>Aircraft type:</b>
|
||||
<span class="fp_aicraft"></span>
|
||||
@@ -91,37 +94,37 @@
|
||||
<h2 class="atc_callsign">UUEE_DEL</h2>
|
||||
<span>
|
||||
<b>Start time:</b>
|
||||
<span class="atc_start_time">2024-01-05T16:11:22Z</span>
|
||||
<span class="atc_start_time"></span>
|
||||
</span>
|
||||
<br>
|
||||
<span>
|
||||
<b>End time:</b>
|
||||
<span class="atc_end_time">2024-01-05T16:32:46Z</span>
|
||||
<span class="atc_end_time"></span>
|
||||
</span>
|
||||
<br>
|
||||
<span>
|
||||
<b>Aircraft tracked:</b>
|
||||
<span class="atc_trackedair">7</span>
|
||||
<span class="atc_trackedair"></span>
|
||||
</span>
|
||||
<br>
|
||||
<span>
|
||||
<b>Aircraft seen:</b>
|
||||
<span class="atc_seenair">35</span>
|
||||
<span class="atc_seenair"></span>
|
||||
</span>
|
||||
<br>
|
||||
<span>
|
||||
<b>Squawk assigned:</b>
|
||||
<span class="atc_squawks">12</span>
|
||||
<span class="atc_squawks"></span>
|
||||
</span>
|
||||
<br>
|
||||
<span>
|
||||
<b>Aircraft's transferred:</b>
|
||||
<span class="atc_transfers">3</span>
|
||||
<span class="atc_transfers"></span>
|
||||
</span>
|
||||
<br>
|
||||
<span>
|
||||
<b>Aircraft's received:</b>
|
||||
<span class="atc_received">0</span>
|
||||
<span class="atc_received"></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -131,8 +134,8 @@
|
||||
<script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"></script>
|
||||
<script type="text/javascript">
|
||||
const USER_CID = '{{data[0]["id"]}}';
|
||||
const FLIGHTPLANS_API_URL = "https://api.vatsim.net/v2/members/" + USER_CID + "/flightplans";
|
||||
const ATC_API_URL = "https://api.vatsim.net/v2/members/" + USER_CID + "/atc";
|
||||
const FLIGHTPLANS_API_URL = "/api/request?request_string=members/" + USER_CID + "/flightplans";
|
||||
const ATC_API_URL = "/api/request?request_string=members/" + USER_CID + "/atc";
|
||||
|
||||
$(".date_registration").text("{{data[0]['reg_date']}}".replace("T", " "));
|
||||
</script>
|
||||
Reference in New Issue
Block a user