Skip to content

Commit 4fcf164

Browse files
committed
system finder
1 parent 18888a0 commit 4fcf164

File tree

9 files changed

+220
-2
lines changed

9 files changed

+220
-2
lines changed

app.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from server.database.cycle import get_cycle_week, write_cycle_week
3232
from server.handlers.powerpoints import handle_powerpoints
3333
from server.handlers.conflict import handle_conflict_result, handle_conflict_search
34+
from server.handlers.systemSearch import handle_system_search
3435
from server.handlers.powerpoints import (
3536
nicey_powerpoints,
3637
kruger_powerpoints,
@@ -136,6 +137,10 @@ def results():
136137
def handle_choice():
137138
return handle_task_choice(request)
138139

140+
@app.route("/system_search", methods=["GET", "POST"])
141+
def system_search():
142+
return handle_system_search(request, database)
143+
139144

140145
@app.route("/conflict", methods=["GET"])
141146
def conflicts():

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ itsdangerous==2.2.0
1515
Jinja2==3.1.6
1616
MarkupSafe==3.0.2
1717
narwhals==1.47.1
18+
numpy==2.2.6
1819
packaging==24.2
1920
plotly==6.2.0
2021
pluggy==1.6.0

server/handlers/index.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,21 @@ def handle_index(request):
6464
cg_title = ""
6565
else:
6666
cg_title = "Powerplay Commuinity Goals"
67+
68+
default_system = "Sol"
69+
try:
70+
if request.args.get("system_name") != None:
71+
default_system = request.args.get("system_name")
72+
except Exception:
73+
default_system = "Sol"
74+
6775

6876
return render_template(
6977
"index.html",
7078
missions=TASKNAMES,
7179
powers=POWERNAMES,
7280
status_text=get_status(),
73-
default_system="Sol",
81+
default_system=default_system,
7482
cg_title=cg_title,
7583
cg_data=cg,
7684
)

server/handlers/systemSearch.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from flask import render_template
2+
from server.constants import POWERNAMES
3+
from server.powers import power_full_to_short
4+
from server.tasks.findNear import find_nearby_system
5+
6+
def handle_system_search(request, database):
7+
if request.method == "GET":
8+
return render_template(
9+
"system_search/search.html",
10+
powers=POWERNAMES
11+
)
12+
else:
13+
system_name = request.form.get("system")
14+
power_short_code = power_full_to_short(request.form.get("power"))
15+
system_type = request.form.get("system_type")
16+
found_system_name = find_nearby_system(system_name, power_short_code,system_type, database.session)
17+
system_type_clean = ""
18+
match system_type:
19+
case "no_owner":
20+
system_type_clean = "Unoccupied"
21+
case "you_own":
22+
system_type_clean = "Reinforcing"
23+
case "enemy_owns":
24+
system_type_clean = "Undermining"
25+
return render_template(
26+
"system_search/found.html",
27+
original_system=system_name,
28+
power=request.form.get("power"),
29+
system_type=system_type_clean,
30+
found_system=found_system_name
31+
)

server/tasks/findNear.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from sqlalchemy import func
2+
3+
from server.database.database import PowerData, StarSystem
4+
5+
6+
def find_nearby_system(
7+
system_name: str, power_short_code: str, system_type: str, session
8+
) -> str:
9+
"""
10+
Finds a nearby system matching the passed parameters
11+
Returns the name
12+
"""
13+
# find user
14+
user_system = session.query(StarSystem).filter_by(system_name=system_name).first()
15+
if not user_system:
16+
# nowhere.....
17+
return []
18+
19+
user_coords = (user_system.longitude, user_system.latitude, user_system.height)
20+
21+
distance = func.sqrt(
22+
func.pow(StarSystem.longitude - user_coords[0], 2)
23+
+ func.pow(StarSystem.latitude - user_coords[1], 2)
24+
+ func.pow(StarSystem.height - user_coords[2], 2)
25+
).label("distance")
26+
27+
query = None
28+
29+
match system_type:
30+
case "no_owner":
31+
query = (
32+
session.query(StarSystem, distance)
33+
.join(PowerData, PowerData.system_name == StarSystem.system_name)
34+
.filter(PowerData.state == "Unoccupied")
35+
.order_by(distance)
36+
)
37+
case "you_own":
38+
query = (
39+
session.query(StarSystem, distance)
40+
.join(PowerData, PowerData.system_name == StarSystem.system_name)
41+
.filter(PowerData.shortcode == power_short_code)
42+
.order_by(distance)
43+
)
44+
case "enemy_owns":
45+
query = (
46+
session.query(StarSystem, distance)
47+
.join(PowerData, PowerData.system_name == StarSystem.system_name)
48+
.filter(PowerData.state != "Unoccupied")
49+
.filter(PowerData.shortcode != power_short_code)
50+
.order_by(distance)
51+
)
52+
53+
result = query.first()
54+
55+
return result.StarSystem.system_name
56+
57+

templates/changelog.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ <h2>Version 1. - !</h2>
2020
<body>
2121
<h1>Changelog</h1>
2222

23+
<h2>Version 1.8.1 - Find that system!</h2>
24+
<p>A system finder has now been added.</p>
25+
<p>It will find a system matching your requirements, then import it to the main page</p>
26+
<p><i>Updated on /3311 (2025)</i></p>
27+
<br>
28+
2329
<h2>Version 1.8.0 - Community Goals!</h2>
2430
<p>PPA will now pick up powerplay CGs, and display some basic info</p>
2531
<p><i>Updated 09:08 on 09/07/3311 (2025)</i></p>

templates/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ <h2>{{cg_title}}</h2>
8080
</body>
8181
<div class="footer">
8282
<a href="{{ url_for('changelog') }}">Changelog</a>
83-
<a href="{{ url_for('database_stats') }}">Database Stats</a>
83+
<a href="{{ url_for('system_search') }}">System Finder</a>
8484
<a href="{{ url_for('powerpoints') }}">PowerPoints</a>
8585
<a href="{{ url_for('conflicts') }}">Conflict Finder</a>
8686
<br />

templates/system_search/found.html

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}" />
7+
<link rel="icon" href="{{ url_for('static', filename='icons/favicon.ico') }}" type="image/x-icon" />
8+
<script defer src="https://data.niceygy.net/script.js" data-website-id="5a305d97-fef0-4c86-9528-243ae53470ad"></script>
9+
<title>PowerPlay Assistant - System Found</title>
10+
<script>
11+
function redirect() {
12+
window.location.href = "/?system_name={{found_system}}"
13+
14+
}
15+
</script>
16+
</head>
17+
<body>
18+
<div class="main">
19+
<h1>Selected Options</h1>
20+
<p><strong>System:</strong> {{ original_system }}</p>
21+
<p><strong>Power:</strong> {{ power }}</p>
22+
<p><strong>Type:</strong> {{ system_type }}</p>
23+
24+
<h1>System:</h1>
25+
<p>The system {{ found_system }} matches your requirements!</p>
26+
<p>Click below to import it to the homepage, and search from there.</p>
27+
28+
<br><br>
29+
30+
<button onclick="redirect()">Go!</button>
31+
32+
<br><br>
33+
34+
<a href="{{ url_for('index') }}">Back to Home</a>
35+
</div>
36+
</body>
37+
</html>

templates/system_search/search.html

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>PowerPlay Assistant - Find that systenm!</title>
7+
<link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}">
8+
<script defer src="https://data.niceygy.net/script.js" data-website-id="5a305d97-fef0-4c86-9528-243ae53470ad"></script>
9+
<link rel="icon" href="{{ url_for('static', filename='icons/favicon.ico') }}" type="image/x-icon">
10+
<meta name='description' content='PowerPlay Assistant is a compainon website for Elite: Dangerous, to help commanders with their powerplay 2.0 tasks.'>
11+
<script defer>
12+
async function searchSystems() {
13+
let elementID = "system";
14+
const query = document.getElementById(elementID).value;
15+
const response = await fetch(`/search_systems?query=${query}`);
16+
const results = await response.json();
17+
const datalist = document.getElementById(elementID + '-results');
18+
datalist.innerHTML = '';
19+
results.forEach(system => {
20+
const option = document.createElement('option');
21+
option.value = system;
22+
datalist.appendChild(option);
23+
});
24+
}
25+
function toggleLoadingBtn() {
26+
var x = document.getElementById("loadingIcon");
27+
if (x.style.display === "none") {
28+
x.style.display = "block";
29+
} else {
30+
x.style.display = "none";
31+
}
32+
}
33+
34+
window.onload = function() {
35+
document.getElementById("loadingIcon").style.display = "none";
36+
}
37+
</script>
38+
<body>
39+
<h1>PowerPlay Assistant</h1>
40+
<div class="specifyTask">
41+
<h2>Find nearby system</h2>
42+
<form action="/system_search" method="post">
43+
<label for="system">Your current system:</label>
44+
<input list="system-results" id="system" name="system" oninput="searchSystems()" autocomplete="off" value="{{ default_system }}">
45+
<datalist id="system-results"></datalist><br><br>
46+
47+
<label for="power">For:</label>
48+
<select id="power" name="power">
49+
{% for power in powers %}
50+
<option value="{{ power }}" {% if selected_power == power %}selected{% endif %}>{{ power }}</option>
51+
{% endfor %}
52+
</select><br><br>
53+
54+
<label for="system_type">System Type</label>
55+
<select id="system_type" name="system_type">
56+
<option value="no_owner">Unoccupied</option>
57+
<option value="you_own">Reinforcing</option>
58+
<option value="enemy_owns">Undermining</option>
59+
</select><br><br>
60+
61+
62+
<button type="submit" onclick="toggleLoadingBtn()">Go!</button>
63+
</form>
64+
<div class="loadingIcon" >
65+
<img id="loadingIcon" src="{{ url_for('static', filename='icons/edloader.svg')}}" width="50" height="50">
66+
</div>
67+
</div>
68+
69+
</body>
70+
<div class="footer">
71+
<a href="{{url_for('index')}}">Home</a>
72+
</div>
73+
</html>

0 commit comments

Comments
 (0)