custom errors
61
Cargo.lock
generated
|
@ -122,6 +122,16 @@ dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bstr"
|
||||||
|
version = "1.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
|
@ -432,6 +442,19 @@ version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "globset"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"bstr",
|
||||||
|
"log",
|
||||||
|
"regex-automata 0.4.6",
|
||||||
|
"regex-syntax 0.8.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.3.26"
|
version = "0.3.26"
|
||||||
|
@ -1154,6 +1177,41 @@ dependencies = [
|
||||||
"uncased",
|
"uncased",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-embed"
|
||||||
|
version = "8.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19549741604902eb99a7ed0ee177a0663ee1eda51a29f71401f166e47e77806a"
|
||||||
|
dependencies = [
|
||||||
|
"rust-embed-impl",
|
||||||
|
"rust-embed-utils",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-embed-impl"
|
||||||
|
version = "8.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb9f96e283ec64401f30d3df8ee2aaeb2561f34c824381efa24a35f79bf40ee4"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rust-embed-utils",
|
||||||
|
"syn",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-embed-utils"
|
||||||
|
version = "8.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "38c74a686185620830701348de757fd36bef4aa9680fd23c49fc539ddcc1af32"
|
||||||
|
dependencies = [
|
||||||
|
"globset",
|
||||||
|
"sha2",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.24"
|
version = "0.1.24"
|
||||||
|
@ -1564,11 +1622,12 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "traque"
|
name = "traque"
|
||||||
version = "0.1.0"
|
version = "0.2.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand",
|
"rand",
|
||||||
"rocket",
|
"rocket",
|
||||||
"rocket_dyn_templates",
|
"rocket_dyn_templates",
|
||||||
|
"rust-embed",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "traque"
|
name = "traque"
|
||||||
version = "0.1.0"
|
version = "0.2.4"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
@ -8,6 +8,10 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
|
||||||
|
[dependencies.rust-embed]
|
||||||
|
version = "8.4.0"
|
||||||
|
features = ["include-exclude"]
|
||||||
|
|
||||||
[dependencies.rocket]
|
[dependencies.rocket]
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
features = ["json"]
|
features = ["json"]
|
||||||
|
|
29
src/main.rs
|
@ -3,13 +3,16 @@ extern crate rocket;
|
||||||
use rocket::{
|
use rocket::{
|
||||||
fairing::AdHoc,
|
fairing::AdHoc,
|
||||||
fs::{relative, FileServer},
|
fs::{relative, FileServer},
|
||||||
response::stream::Event,
|
http::Status,
|
||||||
|
response::{content, stream::Event},
|
||||||
tokio::{
|
tokio::{
|
||||||
self, select,
|
self, select,
|
||||||
time::{self, Duration},
|
time::{self, Duration},
|
||||||
},
|
},
|
||||||
|
Request,
|
||||||
};
|
};
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
|
use rust_embed::Embed;
|
||||||
use std::{
|
use std::{
|
||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
|
@ -68,6 +71,27 @@ fn clean_expired_evt(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Embed)]
|
||||||
|
#[folder = "static/errors"]
|
||||||
|
#[include = "*.html"]
|
||||||
|
#[exclude = "*.jpg"]
|
||||||
|
struct ErrorPages;
|
||||||
|
|
||||||
|
#[catch(default)]
|
||||||
|
fn handler(status: Status, _: &Request) -> content::RawHtml<String> {
|
||||||
|
content::RawHtml(
|
||||||
|
std::str::from_utf8(
|
||||||
|
ErrorPages::get(format!("{}.html", status.code).as_str())
|
||||||
|
//501 not implemented
|
||||||
|
.unwrap_or(ErrorPages::get("501.html").unwrap())
|
||||||
|
.data
|
||||||
|
.as_ref(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.to_string(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[launch]
|
#[launch]
|
||||||
async fn rocket() -> _ {
|
async fn rocket() -> _ {
|
||||||
let rocket = rocket::build();
|
let rocket = rocket::build();
|
||||||
|
@ -106,7 +130,8 @@ async fn rocket() -> _ {
|
||||||
.manage(admin_evt_queue.clone())
|
.manage(admin_evt_queue.clone())
|
||||||
.mount("/", routes![index])
|
.mount("/", routes![index])
|
||||||
.mount("/track", track::routes())
|
.mount("/track", track::routes())
|
||||||
.mount("/admin", admin::routes());
|
.mount("/admin", admin::routes())
|
||||||
|
.register("/", catchers![handler]);
|
||||||
if config.serve_static {
|
if config.serve_static {
|
||||||
rocket = rocket.mount("/", FileServer::from(relative!("static")));
|
rocket = rocket.mount("/", FileServer::from(relative!("static")));
|
||||||
}
|
}
|
||||||
|
|
196
src/track.rs
|
@ -1,4 +1,5 @@
|
||||||
use rocket::{
|
use rocket::{
|
||||||
|
http::Status,
|
||||||
response::stream::{Event, EventStream},
|
response::stream::{Event, EventStream},
|
||||||
tokio::{
|
tokio::{
|
||||||
self, select,
|
self, select,
|
||||||
|
@ -10,15 +11,20 @@ use rocket_dyn_templates::{context, Template};
|
||||||
|
|
||||||
use crate::global::{TrackedState::*, *};
|
use crate::global::{TrackedState::*, *};
|
||||||
|
|
||||||
|
#[get("/")]
|
||||||
|
fn no_id() -> Status {
|
||||||
|
Status::ImATeapot
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/<id>?<gpslog>&<dbg>")]
|
#[get("/<id>?<gpslog>&<dbg>")]
|
||||||
fn tracked_view(
|
fn tracked_view(
|
||||||
id: &str,
|
id: &str,
|
||||||
gpslog: Option<bool>,
|
gpslog: Option<bool>,
|
||||||
dbg: Option<bool>,
|
dbg: Option<bool>,
|
||||||
tracking: &State<Tracking>,
|
tracking: &State<Tracking>,
|
||||||
) -> Option<Template> {
|
) -> Result<Template, Status> {
|
||||||
if let Some(tracked) = tracking.get(&id.to_string()) {
|
if let Some(tracked) = tracking.get(&id.to_string()) {
|
||||||
Some(Template::render(
|
Ok(Template::render(
|
||||||
match tracked.read().unwrap().state {
|
match tracked.read().unwrap().state {
|
||||||
Vieux { .. } => "vieux",
|
Vieux { .. } => "vieux",
|
||||||
Conscrit { .. } => "conscrit",
|
Conscrit { .. } => "conscrit",
|
||||||
|
@ -31,7 +37,7 @@ fn tracked_view(
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
Err(Status::BadRequest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,10 +47,10 @@ fn tracked_events<'a>(
|
||||||
evt_queue: &'a State<TrackingEventQueue>,
|
evt_queue: &'a State<TrackingEventQueue>,
|
||||||
config: &State<Config>,
|
config: &State<Config>,
|
||||||
mut shutdown: Shutdown,
|
mut shutdown: Shutdown,
|
||||||
) -> Option<EventStream![Event + 'a]> {
|
) -> Result<EventStream![Event + 'a], Status> {
|
||||||
if evt_queue.contains_key(&id.to_string()) {
|
if evt_queue.contains_key(&id.to_string()) {
|
||||||
let timeout = Duration::from_millis(config.event_timeout);
|
let timeout = Duration::from_millis(config.event_timeout);
|
||||||
Some(EventStream! {
|
Ok(EventStream! {
|
||||||
let mut interval = time::interval(timeout);
|
let mut interval = time::interval(timeout);
|
||||||
loop {
|
loop {
|
||||||
select!{
|
select!{
|
||||||
|
@ -59,7 +65,7 @@ fn tracked_events<'a>(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
Err(Status::BadRequest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,10 +77,13 @@ fn store_pos(
|
||||||
tracking: &State<Tracking>,
|
tracking: &State<Tracking>,
|
||||||
evt_queues: &State<TrackingEventQueue>,
|
evt_queues: &State<TrackingEventQueue>,
|
||||||
admin_queue: &State<AdminEventQueue>,
|
admin_queue: &State<AdminEventQueue>,
|
||||||
) {
|
) -> Status {
|
||||||
if let Some(tracked) = tracking.get(&id.to_string()) {
|
if let Some(tracked) = tracking.get(&id.to_string()) {
|
||||||
tracked.write().unwrap().pos = (lat, long);
|
tracked.write().unwrap().pos = (lat, long);
|
||||||
state_update(&tracked.read().unwrap(), &evt_queues, &admin_queue);
|
state_update(&tracked.read().unwrap(), &evt_queues, &admin_queue);
|
||||||
|
Status::Accepted
|
||||||
|
} else {
|
||||||
|
Status::BadRequest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,19 +95,23 @@ fn set_state(
|
||||||
tracking: &State<Tracking>,
|
tracking: &State<Tracking>,
|
||||||
evt_queues: &State<TrackingEventQueue>,
|
evt_queues: &State<TrackingEventQueue>,
|
||||||
admin_queue: &State<AdminEventQueue>,
|
admin_queue: &State<AdminEventQueue>,
|
||||||
) -> Option<()> {
|
) -> Status {
|
||||||
let tracked = &mut tracking.get(&id.to_string()).unwrap().write().unwrap();
|
if let Some(tracked) = tracking.get(&id.to_string()) {
|
||||||
if let Vieux {
|
let tracked = &mut tracked.write().unwrap();
|
||||||
ref mut invisible,
|
if let Vieux {
|
||||||
ref mut color,
|
ref mut invisible,
|
||||||
} = tracked.state
|
ref mut color,
|
||||||
{
|
} = tracked.state
|
||||||
*invisible = inv;
|
{
|
||||||
*color = col;
|
*invisible = inv;
|
||||||
state_update(&tracked, &evt_queues, &admin_queue);
|
*color = col;
|
||||||
Some(())
|
state_update(&tracked, &evt_queues, &admin_queue);
|
||||||
|
Status::Accepted
|
||||||
|
} else {
|
||||||
|
Status::MethodNotAllowed
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
Status::BadRequest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,43 +122,47 @@ pub async fn activate_invisibility(
|
||||||
evt_queues: &State<TrackingEventQueue>,
|
evt_queues: &State<TrackingEventQueue>,
|
||||||
admin_queue: &State<AdminEventQueue>,
|
admin_queue: &State<AdminEventQueue>,
|
||||||
config: &State<Config>,
|
config: &State<Config>,
|
||||||
) -> Option<()> {
|
) -> Status {
|
||||||
let tracked = &mut tracking.get(&id.to_string()).unwrap().write().unwrap();
|
if let Some(tracked) = tracking.get(&id.to_string()) {
|
||||||
if let Conscrit {
|
let tracked = &mut tracked.write().unwrap();
|
||||||
ref mut invisible,
|
if let Conscrit {
|
||||||
ref mut invisibility_codes,
|
ref mut invisible,
|
||||||
..
|
ref mut invisibility_codes,
|
||||||
} = tracked.state
|
..
|
||||||
{
|
} = tracked.state
|
||||||
if *invisibility_codes > 0 {
|
{
|
||||||
*invisibility_codes -= 1;
|
if *invisibility_codes > 0 {
|
||||||
*invisible = true;
|
*invisibility_codes -= 1;
|
||||||
state_update(&tracked, &evt_queues, &admin_queue);
|
*invisible = true;
|
||||||
let track_clone = (*tracking).clone();
|
state_update(&tracked, &evt_queues, &admin_queue);
|
||||||
let queue_clone = (*evt_queues).clone();
|
let track_clone = (*tracking).clone();
|
||||||
let admin_clone = (*admin_queue).clone();
|
let queue_clone = (*evt_queues).clone();
|
||||||
let id_str = id.to_string();
|
let admin_clone = (*admin_queue).clone();
|
||||||
let timeout = Duration::from_millis(config.bonus_timeout);
|
let id_str = id.to_string();
|
||||||
tokio::spawn(async move {
|
let timeout = Duration::from_millis(config.bonus_timeout);
|
||||||
sleep(timeout).await;
|
tokio::spawn(async move {
|
||||||
if let Conscrit {
|
sleep(timeout).await;
|
||||||
ref mut invisible, ..
|
if let Conscrit {
|
||||||
} = track_clone.get(&id_str).unwrap().write().unwrap().state
|
ref mut invisible, ..
|
||||||
{
|
} = track_clone.get(&id_str).unwrap().write().unwrap().state
|
||||||
*invisible = false;
|
{
|
||||||
}
|
*invisible = false;
|
||||||
state_update(
|
}
|
||||||
&track_clone.get(&id_str).unwrap().read().unwrap(),
|
state_update(
|
||||||
&queue_clone,
|
&track_clone.get(&id_str).unwrap().read().unwrap(),
|
||||||
&admin_clone,
|
&queue_clone,
|
||||||
);
|
&admin_clone,
|
||||||
});
|
);
|
||||||
Some(())
|
});
|
||||||
|
Status::Accepted
|
||||||
|
} else {
|
||||||
|
Status::PaymentRequired
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
Status::MethodNotAllowed
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
Status::BadRequest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,43 +173,47 @@ pub async fn activate_blur(
|
||||||
evt_queues: &State<TrackingEventQueue>,
|
evt_queues: &State<TrackingEventQueue>,
|
||||||
admin_queue: &State<AdminEventQueue>,
|
admin_queue: &State<AdminEventQueue>,
|
||||||
config: &State<Config>,
|
config: &State<Config>,
|
||||||
) -> Option<()> {
|
) -> Status {
|
||||||
let tracked = &mut tracking.get(&id.to_string()).unwrap().write().unwrap();
|
if let Some(tracked) = tracking.get(&id.to_string()) {
|
||||||
if let Conscrit {
|
let tracked = &mut tracked.write().unwrap();
|
||||||
ref mut blurred,
|
if let Conscrit {
|
||||||
ref mut blur_codes,
|
ref mut blurred,
|
||||||
..
|
ref mut blur_codes,
|
||||||
} = tracked.state
|
..
|
||||||
{
|
} = tracked.state
|
||||||
if *blur_codes > 0 {
|
{
|
||||||
*blur_codes -= 1;
|
if *blur_codes > 0 {
|
||||||
*blurred = true;
|
*blur_codes -= 1;
|
||||||
state_update(&tracked, &evt_queues, &admin_queue);
|
*blurred = true;
|
||||||
let track_clone = (*tracking).clone();
|
state_update(&tracked, &evt_queues, &admin_queue);
|
||||||
let queue_clone = (*evt_queues).clone();
|
let track_clone = (*tracking).clone();
|
||||||
let admin_clone = (*admin_queue).clone();
|
let queue_clone = (*evt_queues).clone();
|
||||||
let id_str = id.to_string();
|
let admin_clone = (*admin_queue).clone();
|
||||||
let timeout = Duration::from_millis(config.bonus_timeout);
|
let id_str = id.to_string();
|
||||||
tokio::spawn(async move {
|
let timeout = Duration::from_millis(config.bonus_timeout);
|
||||||
sleep(timeout).await;
|
tokio::spawn(async move {
|
||||||
if let Conscrit {
|
sleep(timeout).await;
|
||||||
ref mut blurred, ..
|
if let Conscrit {
|
||||||
} = track_clone.get(&id_str).unwrap().write().unwrap().state
|
ref mut blurred, ..
|
||||||
{
|
} = track_clone.get(&id_str).unwrap().write().unwrap().state
|
||||||
*blurred = false;
|
{
|
||||||
}
|
*blurred = false;
|
||||||
state_update(
|
}
|
||||||
&track_clone.get(&id_str).unwrap().read().unwrap(),
|
state_update(
|
||||||
&queue_clone,
|
&track_clone.get(&id_str).unwrap().read().unwrap(),
|
||||||
&admin_clone,
|
&queue_clone,
|
||||||
);
|
&admin_clone,
|
||||||
});
|
);
|
||||||
Some(())
|
});
|
||||||
|
Status::Accepted
|
||||||
|
} else {
|
||||||
|
Status::PaymentRequired
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
Status::MethodNotAllowed
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
Status::BadRequest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,5 +225,6 @@ pub fn routes() -> Vec<Route> {
|
||||||
set_state,
|
set_state,
|
||||||
activate_invisibility,
|
activate_invisibility,
|
||||||
activate_blur,
|
activate_blur,
|
||||||
|
no_id,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
19
static/errors/400.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<title>400 Bad Request</title>
|
||||||
|
</head>
|
||||||
|
<body align="center">
|
||||||
|
<div role="main" align="center">
|
||||||
|
<h1>400 Bad Request</h1>
|
||||||
|
<img src="/errors/cat/400.jpg"/>
|
||||||
|
<p>Conscrit ! Cet identifiant ne correspond à aucune équipe.</p>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div role="contentinfo" align="center">
|
||||||
|
<small>Crédit à <a href="https://http.cat">http.cat</a> pour l'image.</small>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
static/errors/401.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<title>401 Unauthorized</title>
|
||||||
|
</head>
|
||||||
|
<body align="center">
|
||||||
|
<div role="main" align="center">
|
||||||
|
<h1>401 Unauthorized</h1>
|
||||||
|
<img src="/errors/cat/401.jpg"/>
|
||||||
|
<p>Il faut s'identifié pour accéder à cette ressource.</p>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div role="contentinfo" align="center">
|
||||||
|
<small>Crédit à <a href="https://http.cat">http.cat</a> pour l'image.</small>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
static/errors/402.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<title>402 Payment Required</title>
|
||||||
|
</head>
|
||||||
|
<body align="center">
|
||||||
|
<div role="main" align="center">
|
||||||
|
<h1>402 Payment Required</h1>
|
||||||
|
<img src="/errors/cat/402.jpg"/>
|
||||||
|
<p>Toute les utilisations de ce bonus ont été utilisées.</p>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div role="contentinfo" align="center">
|
||||||
|
<small>Crédit à <a href="https://http.cat">http.cat</a> pour l'image.</small>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
static/errors/404.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<title>404 Not Found</title>
|
||||||
|
</head>
|
||||||
|
<body align="center">
|
||||||
|
<div role="main" align="center">
|
||||||
|
<h1>404 Not Found</h1>
|
||||||
|
<img src="/errors/cat/404.jpg"/>
|
||||||
|
<p>Page non trouvé</p>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div role="contentinfo" align="center">
|
||||||
|
<small>Crédit à <a href="https://http.cat">http.cat</a> pour l'image.</small>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
static/errors/405.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<title>405 Method Not Allowed</title>
|
||||||
|
</head>
|
||||||
|
<body align="center">
|
||||||
|
<div role="main" align="center">
|
||||||
|
<h1>405 Method Not Allowed</h1>
|
||||||
|
<img src="/errors/cat/405.jpg"/>
|
||||||
|
<p>Cette équipe n'a pas le droit d'utiliser cet endpoint.</p>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div role="contentinfo" align="center">
|
||||||
|
<small>Crédit à <a href="https://http.cat">http.cat</a> pour l'image.</small>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
static/errors/418.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<title>418 I’m a teapot</title>
|
||||||
|
</head>
|
||||||
|
<body align="center">
|
||||||
|
<div role="main" align="center">
|
||||||
|
<h1>418 I’m a teapot</h1>
|
||||||
|
<img src="/errors/cat/418.jpg"/>
|
||||||
|
<p>Il y a quelque-chose ici, mais je montrerai rien.</p>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div role="contentinfo" align="center">
|
||||||
|
<small>Crédit à <a href="https://http.cat">http.cat</a> pour l'image.</small>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
static/errors/498.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<title>498 Token expired/invalid</title>
|
||||||
|
</head>
|
||||||
|
<body align="center">
|
||||||
|
<div role="main" align="center">
|
||||||
|
<h1>498 Token expired/invalid</h1>
|
||||||
|
<img src="/errors/cat/498.jpg"/>
|
||||||
|
<p>Le token d'authentification est invalide.</p>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div role="contentinfo" align="center">
|
||||||
|
<small>Crédit à <a href="https://http.cat">http.cat</a> pour l'image.</small>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
static/errors/500.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<title>500 Internal Server Error</title>
|
||||||
|
</head>
|
||||||
|
<body align="center">
|
||||||
|
<div role="main" align="center">
|
||||||
|
<h1>500 Internal Server Error</h1>
|
||||||
|
<img src="/errors/cat/500.jpg"/>
|
||||||
|
<p>Erreur Interne</p>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div role="contentinfo" align="center">
|
||||||
|
<small>Crédit à <a href="https://http.cat">http.cat</a> pour l'image.</small>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
static/errors/501.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<title>501 Not Implemented</title>
|
||||||
|
</head>
|
||||||
|
<body align="center">
|
||||||
|
<div role="main" align="center">
|
||||||
|
<h1>501 Not Implemented</h1>
|
||||||
|
<img src="/errors/cat/501.jpg"/>
|
||||||
|
<p>Une erreur inconnue a été rencontré.</p>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div role="contentinfo" align="center">
|
||||||
|
<small>Crédit à <a href="https://http.cat">http.cat</a> pour l'image.</small>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
static/errors/503.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<title>503 Service Unavailable</title>
|
||||||
|
</head>
|
||||||
|
<body align="center">
|
||||||
|
<div role="main" align="center">
|
||||||
|
<h1>503 Service Unavailable</h1>
|
||||||
|
<img src="/errors/cat/503.jpg"/>
|
||||||
|
<p>La traque n'est pas encore prête, on arrive bientôt...</p>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<div role="contentinfo" align="center">
|
||||||
|
<small>Crédit à <a href="https://http.cat">http.cat</a> pour l'image.</small>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
static/errors/cat/400.jpg
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
static/errors/cat/401.jpg
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
static/errors/cat/402.jpg
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
static/errors/cat/404.jpg
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
static/errors/cat/405.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
static/errors/cat/418.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
static/errors/cat/498.jpg
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
static/errors/cat/500.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
static/errors/cat/501.jpg
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
static/errors/cat/503.jpg
Normal file
After Width: | Height: | Size: 26 KiB |
|
@ -45,30 +45,30 @@
|
||||||
<body>
|
<body>
|
||||||
<div id="map"></div>
|
<div id="map"></div>
|
||||||
|
|
||||||
<div id="right">
|
<div id="right">
|
||||||
<div class="tableFixHead">
|
<div class="tableFixHead">
|
||||||
<table>
|
<table>
|
||||||
<thead><tr>
|
<thead><tr>
|
||||||
<th>Nom</th>
|
<th>Nom</th>
|
||||||
<th>Mallette</th>
|
<th>Mallette</th>
|
||||||
<th>Tracker</th>
|
<th>Tracker</th>
|
||||||
<th>Invisible</th>
|
<th>Invisible</th>
|
||||||
<th>Brouillé</th>
|
<th>Brouillé</th>
|
||||||
<th>Code Invisibilité</th>
|
<th>Code Invisibilité</th>
|
||||||
<th>Code Brouillage</th>
|
<th>Code Brouillage</th>
|
||||||
<th>Couleur</th>
|
<th>Couleur</th>
|
||||||
<!-- <th>Last Update</th> -->
|
<!-- <th>Last Update</th> -->
|
||||||
</tr></thead>
|
</tr></thead>
|
||||||
<tbody id="teamInfos">
|
<tbody id="teamInfos">
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input id="popup"/><button id="sendPopup">Send popup to all clients</button><br/>
|
<input id="popup"/><button id="sendPopup">Send popup to all clients</button><br/>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://dgnum.eu"><img src="/dgnum-logo.png" height=50px /></a><br/>
|
<a href="https://dgnum.eu"><img src="/dgnum-logo.png" height=50px /></a><br/>
|
||||||
<span style="font-size: 0.8em">Merci à la <a href="https://dgnum.eu">Délégation Générale NUMérique de l'ENS</a>, qui héberge ce site.</span>
|
<span style="font-size: 0.8em">Merci à la <a href="https://dgnum.eu">Délégation Générale NUMérique de l'ENS</a>, qui héberge ce site.</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
setup_map();
|
setup_map();
|
||||||
|
|