skeleton webpage
This commit is contained in:
BIN
__pycache__/config.cpython-311.pyc
Normal file
BIN
__pycache__/config.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/main.cpython-311.pyc
Normal file
BIN
__pycache__/main.cpython-311.pyc
Normal file
Binary file not shown.
BIN
cogs/__pycache__/assignments.cpython-311.pyc
Normal file
BIN
cogs/__pycache__/assignments.cpython-311.pyc
Normal file
Binary file not shown.
BIN
cogs/__pycache__/commands.cpython-311.pyc
Normal file
BIN
cogs/__pycache__/commands.cpython-311.pyc
Normal file
Binary file not shown.
60
main.py
60
main.py
@@ -4,10 +4,54 @@ from config import ALLOWED_CHANNEL_ID, HIT_CHECK_INTERVAL, REASSIGN_DELAY
|
|||||||
from cogs.assignments import Assignments
|
from cogs.assignments import Assignments
|
||||||
from cogs.commands import HitCommands
|
from cogs.commands import HitCommands
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import uvicorn
|
||||||
|
|
||||||
|
from fastapi import FastAPI, Request, Form
|
||||||
|
from fastapi.responses import HTMLResponse
|
||||||
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
from fastapi.templating import Jinja2Templates
|
||||||
|
|
||||||
|
from services.torn_api import update_enemy_faction, update_friendly_faction
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
templates = Jinja2Templates(directory="templates")
|
||||||
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# Dashboard page
|
||||||
|
# -----------------------------
|
||||||
|
@app.get("/", response_class=HTMLResponse)
|
||||||
|
async def dashboard(request: Request):
|
||||||
|
print(">>> DASHBOARD ROUTE LOADED")
|
||||||
|
return templates.TemplateResponse("dashboard.html", {"request": request})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# API Endpoints
|
||||||
|
# -----------------------------
|
||||||
|
@app.post("/api/enemy")
|
||||||
|
async def api_enemy(faction_id: int, interval: int):
|
||||||
|
await update_enemy_faction(faction_id, interval)
|
||||||
|
return {"status": "enemy loop running", "id": faction_id, "interval": interval}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/friendly")
|
||||||
|
async def api_friendly(faction_id: int, interval: int):
|
||||||
|
await update_friendly_faction(faction_id, interval)
|
||||||
|
return {"status": "friendly loop running", "id": faction_id, "interval": interval}
|
||||||
|
|
||||||
|
|
||||||
|
# Discord
|
||||||
intents = discord.Intents.default()
|
intents = discord.Intents.default()
|
||||||
intents.message_content = True
|
intents.message_content = True
|
||||||
|
|
||||||
# Global state
|
|
||||||
enrolled_attackers = []
|
enrolled_attackers = []
|
||||||
enemy_queue = []
|
enemy_queue = []
|
||||||
active_assignments = {}
|
active_assignments = {}
|
||||||
@@ -43,4 +87,16 @@ bot = HitDispatchBot(command_prefix="!", intents=intents)
|
|||||||
async def on_ready():
|
async def on_ready():
|
||||||
print(f"Logged in as {bot.user.name}")
|
print(f"Logged in as {bot.user.name}")
|
||||||
|
|
||||||
bot.run("MTQ0Mjg3NjU3NTUzMDg3NzAxMQ.GNuHPr.UreuYD1B7YYjfsbfRcEbhFyjyqvhQDepRCN4kk")
|
TOKEN = "YOUR_DISCORD_TOKEN"
|
||||||
|
|
||||||
|
async def start_bot():
|
||||||
|
await bot.start(TOKEN)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
|
# Start Discord bot in background
|
||||||
|
loop.create_task(start_bot())
|
||||||
|
|
||||||
|
# Run FastAPI (this will keep the loop alive)
|
||||||
|
uvicorn.run(app, host="127.0.0.1", port=8000)
|
||||||
|
|||||||
31
routes/faction.py
Normal file
31
routes/faction.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
from fastapi import APIRouter
|
||||||
|
from pydantic import BaseModel
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
router = APIRouter()
|
||||||
|
|
||||||
|
class FactionRequest(BaseModel):
|
||||||
|
faction_id: int
|
||||||
|
refresh_interval: int
|
||||||
|
|
||||||
|
async def update_friendly_faction_loop(faction_id: int, interval: int):
|
||||||
|
while True:
|
||||||
|
print(f"Refreshing friendly faction {faction_id}")
|
||||||
|
# call your update_friendly_faction() here
|
||||||
|
await asyncio.sleep(interval)
|
||||||
|
|
||||||
|
async def update_enemy_faction_loop(faction_id: int, interval: int):
|
||||||
|
while True:
|
||||||
|
print(f"Refreshing enemy faction {faction_id}")
|
||||||
|
# call your update_enemy_faction() here
|
||||||
|
await asyncio.sleep(interval)
|
||||||
|
|
||||||
|
@router.post("/refresh/friendly")
|
||||||
|
async def refresh_friendly(data: FactionRequest):
|
||||||
|
asyncio.create_task(update_friendly_faction_loop(data.faction_id, data.refresh_interval))
|
||||||
|
return {"status": "friendly loop started"}
|
||||||
|
|
||||||
|
@router.post("/refresh/enemy")
|
||||||
|
async def refresh_enemy(data: FactionRequest):
|
||||||
|
asyncio.create_task(update_enemy_faction_loop(data.faction_id, data.refresh_interval))
|
||||||
|
return {"status": "enemy loop started"}
|
||||||
BIN
services/__pycache__/ffscouter.cpython-311.pyc
Normal file
BIN
services/__pycache__/ffscouter.cpython-311.pyc
Normal file
Binary file not shown.
BIN
services/__pycache__/torn_api.cpython-311.pyc
Normal file
BIN
services/__pycache__/torn_api.cpython-311.pyc
Normal file
Binary file not shown.
@@ -1,6 +1,7 @@
|
|||||||
# services/torn_api.py
|
# services/torn_api.py
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import json
|
import json
|
||||||
|
import asyncio
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from config import TORN_API_KEY, ENEMY_FACTION_ID, YOUR_FACTION_ID
|
from config import TORN_API_KEY, ENEMY_FACTION_ID, YOUR_FACTION_ID
|
||||||
from .ffscouter import fetch_batch_stats
|
from .ffscouter import fetch_batch_stats
|
||||||
@@ -8,6 +9,13 @@ from .ffscouter import fetch_batch_stats
|
|||||||
ENEMY_FILE = Path("data/enemy_faction.json")
|
ENEMY_FILE = Path("data/enemy_faction.json")
|
||||||
FRIENDLY_FILE = Path("data/friendly_faction.json")
|
FRIENDLY_FILE = Path("data/friendly_faction.json")
|
||||||
|
|
||||||
|
# Track running tasks + current faction IDs
|
||||||
|
enemy_task = None
|
||||||
|
friendly_task = None
|
||||||
|
|
||||||
|
current_enemy_id = None
|
||||||
|
current_friendly_id = None
|
||||||
|
|
||||||
|
|
||||||
async def fetch_and_save_faction(faction_id: int, file_path: Path) -> bool:
|
async def fetch_and_save_faction(faction_id: int, file_path: Path) -> bool:
|
||||||
"""
|
"""
|
||||||
@@ -59,10 +67,59 @@ async def fetch_and_save_faction(faction_id: int, file_path: Path) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
# Wrappers for clarity
|
|
||||||
async def update_enemy_faction() -> bool:
|
|
||||||
return await fetch_and_save_faction(ENEMY_FACTION_ID, ENEMY_FILE)
|
|
||||||
|
|
||||||
|
|
||||||
async def update_friendly_faction() -> bool:
|
#Loop for the constant update of members and the stop function
|
||||||
return await fetch_and_save_faction(YOUR_FACTION_ID, FRIENDLY_FILE)
|
|
||||||
|
async def stop_task_if_running(task: asyncio.Task | None):
|
||||||
|
"""Cancel an existing running task safely."""
|
||||||
|
if task and not task.done():
|
||||||
|
task.cancel()
|
||||||
|
try:
|
||||||
|
await task
|
||||||
|
except asyncio.CancelledError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def faction_loop(faction_id: int, file_path: Path, interval: int):
|
||||||
|
"""
|
||||||
|
Runs fetch_and_save_faction() in a loop forever, waiting `interval`
|
||||||
|
seconds between iterations.
|
||||||
|
"""
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
await fetch_and_save_faction(faction_id, file_path)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error during faction loop for {faction_id}: {e}")
|
||||||
|
|
||||||
|
await asyncio.sleep(interval)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#Functions to call the loop, maybe add one to just call once?
|
||||||
|
async def update_enemy_faction(new_faction_id: int, interval: int):
|
||||||
|
global enemy_task, current_enemy_id
|
||||||
|
|
||||||
|
# If faction ID changes → stop old loop
|
||||||
|
if new_faction_id != current_enemy_id:
|
||||||
|
print(f"[ENEMY] Changing faction from {current_enemy_id} → {new_faction_id}")
|
||||||
|
await stop_task_if_running(enemy_task)
|
||||||
|
current_enemy_id = new_faction_id
|
||||||
|
|
||||||
|
# Start new loop
|
||||||
|
enemy_task = asyncio.create_task(
|
||||||
|
faction_loop(new_faction_id, ENEMY_FILE, interval)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def update_friendly_faction(new_faction_id: int, interval: int):
|
||||||
|
global friendly_task, current_friendly_id
|
||||||
|
|
||||||
|
if new_faction_id != current_friendly_id:
|
||||||
|
print(f"[FRIENDLY] Changing faction from {current_friendly_id} → {new_faction_id}")
|
||||||
|
await stop_task_if_running(friendly_task)
|
||||||
|
current_friendly_id = new_faction_id
|
||||||
|
|
||||||
|
friendly_task = asyncio.create_task(
|
||||||
|
faction_loop(new_faction_id, FRIENDLY_FILE, interval)
|
||||||
|
)
|
||||||
|
|
||||||
|
|||||||
0
static/dashboard.js
Normal file
0
static/dashboard.js
Normal file
0
static/styles.css
Normal file
0
static/styles.css
Normal file
24
templates/dashboard.html
Normal file
24
templates/dashboard.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>War Dashboard</title>
|
||||||
|
<link rel="stylesheet" href="/static/styles.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>War Dashboard</h1>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h2>Enemy Faction</h2>
|
||||||
|
<button onclick="updateEnemy()">Refresh Enemy</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h2>Friendly Faction</h2>
|
||||||
|
<button onclick="updateFriendly()">Refresh Friendly</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/static/dashboard.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
Reference in New Issue
Block a user