Split server into multiple files
@ -5,7 +5,7 @@ workers = 4
|
|||||||
max_blocking = 512
|
max_blocking = 512
|
||||||
keep_alive = 5
|
keep_alive = 5
|
||||||
ident = "Rocket"
|
ident = "Rocket"
|
||||||
log_level = "normal"
|
log_level = "critical"
|
||||||
temp_dir = "/tmp"
|
temp_dir = "/tmp"
|
||||||
cli_colors = true
|
cli_colors = true
|
||||||
## NOTE: Don't (!) use this key! Generate your own!
|
## NOTE: Don't (!) use this key! Generate your own!
|
||||||
|
1
server/Arlos-Desktop.json
Normal file
1
server/DESKTOP-OLA9474.json
Normal file
1
server/SUPERPC.json
Normal file
1
server/Yeet-Skeet-Beat-My-Meat.json
Normal file
1
server/arch-server.json
Normal file
150
src/main.rs
@ -15,17 +15,28 @@ use rocket::{
|
|||||||
FileServer,
|
FileServer,
|
||||||
relative
|
relative
|
||||||
},
|
},
|
||||||
serde::{
|
|
||||||
Deserialize,
|
|
||||||
json::Json
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
use rand::Rng;
|
|
||||||
use std::{fs, vec};
|
mod typing;
|
||||||
|
mod servers;
|
||||||
|
|
||||||
|
use crate::typing::sql::*;
|
||||||
|
use crate::typing::user::{
|
||||||
|
get_tests,
|
||||||
|
login,
|
||||||
|
sign_up
|
||||||
|
};
|
||||||
|
use crate::typing::test::{
|
||||||
|
create_test,
|
||||||
|
new_test
|
||||||
|
};
|
||||||
|
use crate::typing::leaderboard::leaderboard;
|
||||||
|
use crate::servers::server::{
|
||||||
|
server,
|
||||||
|
server_info
|
||||||
|
};
|
||||||
|
|
||||||
// Imports for sql, see sql.rs for more information
|
// Imports for sql, see sql.rs for more information
|
||||||
pub mod sql;
|
|
||||||
use crate::sql::*;
|
|
||||||
|
|
||||||
/// Test api route that returns hello world.
|
/// Test api route that returns hello world.
|
||||||
/// Acessible from http://url/test
|
/// Acessible from http://url/test
|
||||||
@ -34,118 +45,8 @@ fn test() -> String {
|
|||||||
String::from("Hello World!")
|
String::from("Hello World!")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Api route that creates a database if one
|
|
||||||
/// does not already exist.
|
|
||||||
/// Acessible from http://url/api/create_database
|
|
||||||
#[get("/create_database")]
|
|
||||||
fn create_database() -> String {
|
|
||||||
sql::create_database()
|
|
||||||
.expect("couldn't create database");
|
|
||||||
String::from("Successfully created a database")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// the datascructure that the webserver will recieve
|
|
||||||
/// when a post is made to the http://url/api/post_test route
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[serde(crate = "rocket::serde")]
|
|
||||||
struct PostTest<'r> {
|
|
||||||
test_type: &'r str,
|
|
||||||
test_length: u32,
|
|
||||||
test_time: u32,
|
|
||||||
test_seed: i64,
|
|
||||||
quote_id: i32,
|
|
||||||
wpm: u8,
|
|
||||||
accuracy: u8,
|
|
||||||
user_id: u32
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Api Route that accepts test data and posts it to the database
|
|
||||||
/// Acessible from http://url/api/post_test
|
|
||||||
#[post("/post_test", data = "<test>")]
|
|
||||||
fn post_test(
|
|
||||||
test: Json<PostTest<'_>>
|
|
||||||
) {
|
|
||||||
sql::post_test(
|
|
||||||
test.test_type,
|
|
||||||
test.test_length,
|
|
||||||
test.test_time,
|
|
||||||
test.test_seed,
|
|
||||||
test.quote_id,
|
|
||||||
test.wpm,
|
|
||||||
test.accuracy,
|
|
||||||
test.user_id
|
|
||||||
).expect("error in posting test to tests table");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Struct representing the user
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
#[serde(crate = "rocket::serde")]
|
|
||||||
struct User<'r> {
|
|
||||||
username: &'r str,
|
|
||||||
password: &'r str
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Route takes data about the user as a struct
|
|
||||||
/// and then creates the user in the database
|
|
||||||
/// Acessible from http://url/api/create_user
|
|
||||||
#[post("/create_user", data = "<user>")]
|
|
||||||
fn create_user(
|
|
||||||
user: Json<User<'_>>
|
|
||||||
) {
|
|
||||||
sql::create_user(
|
|
||||||
user.username,
|
|
||||||
user.password
|
|
||||||
).expect("Error: Couldn't create new user");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// takes the users login information and returns the users user id
|
|
||||||
/// which can be used to identify their tests etc.
|
|
||||||
/// Accessible from http://url/api/login
|
|
||||||
#[get("/login/<username>/<password>")]
|
|
||||||
fn login(username: &str, password: &str) -> String {
|
|
||||||
let user_id = sql::find_user(username, password).expect("error finding user_id");
|
|
||||||
user_id.to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the users tests from the database and returns it as a
|
|
||||||
/// json array.
|
|
||||||
/// Accessible from http://url/api/get_user_tests
|
|
||||||
#[get("/get_user_tests/<user_id>")]
|
|
||||||
fn get_user_tests(user_id: u32) -> Json<Vec<Test>> {
|
|
||||||
let tests = sql::get_user_tests(user_id).expect("error finding user_id");
|
|
||||||
Json(tests)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the highest test data from each user as
|
|
||||||
/// a json array
|
|
||||||
/// Acessible from http://url/api/leaderboard
|
|
||||||
#[get("/leaderboard")]
|
|
||||||
fn leaderboard() -> Json<Vec<LeaderBoardTest>> {
|
|
||||||
let leaderboard = sql::get_leaderboard(0).expect("error finding user_id");
|
|
||||||
Json(leaderboard)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an array of words as Json
|
|
||||||
/// Accessible from http://url/api/get_test
|
|
||||||
#[get("/get_test")]
|
|
||||||
fn get_test() -> Json<Vec<String>> {
|
|
||||||
let mut word_vec: Vec<&str> = vec![];
|
|
||||||
let words = fs::read_to_string("wordlist.txt").unwrap();
|
|
||||||
for word in words.split('\n') {
|
|
||||||
word_vec.push(word.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut return_list: Vec<String> = vec![];
|
|
||||||
|
|
||||||
let mut rng = rand::thread_rng();
|
|
||||||
for _i in 0..100 {
|
|
||||||
let hi: u32 = rng.gen_range(0..999);
|
|
||||||
return_list.push(word_vec[hi as usize].to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
Json(return_list.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The main function which builds and launches the
|
/// The main function which builds and launches the
|
||||||
/// webserver with all appropriate routes and fileservers
|
/// webserver with all appropriate routes and fileservers
|
||||||
@ -157,10 +58,15 @@ fn rocket() -> Rocket<Build> {
|
|||||||
// hosts the api routes necessary for the website
|
// hosts the api routes necessary for the website
|
||||||
// to interact with the database
|
// to interact with the database
|
||||||
.mount("/api", routes![
|
.mount("/api", routes![
|
||||||
create_database, create_user,
|
create_database, sign_up,
|
||||||
post_test, login, get_user_tests,
|
create_test, login, get_tests,
|
||||||
leaderboard, get_test
|
leaderboard, new_test,
|
||||||
|
])
|
||||||
|
|
||||||
|
.mount("/api", routes![
|
||||||
|
server, server_info
|
||||||
])
|
])
|
||||||
// hosts the fileserver
|
// hosts the fileserver
|
||||||
.mount("/typing", FileServer::from(relative!("website")))
|
.mount("/typing", FileServer::from(relative!("websites/Typing")))
|
||||||
|
.mount("/servers", FileServer::from(relative!("websites/Servers")))
|
||||||
}
|
}
|
1
src/servers/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod server;
|
155
src/servers/server.rs
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
use rocket::serde::{
|
||||||
|
json::{
|
||||||
|
Json,
|
||||||
|
to_string, from_str
|
||||||
|
},
|
||||||
|
Deserialize,
|
||||||
|
Serialize
|
||||||
|
};
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
io::{
|
||||||
|
Write,
|
||||||
|
Read
|
||||||
|
},
|
||||||
|
fs::{
|
||||||
|
File,
|
||||||
|
read_dir,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(crate = "rocket::serde")]
|
||||||
|
struct Process {
|
||||||
|
name: String,
|
||||||
|
memory: String,
|
||||||
|
run_time: String,
|
||||||
|
id: String,
|
||||||
|
user_id: String,
|
||||||
|
virtual_memory: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
#[serde(crate = "rocket::serde")]
|
||||||
|
struct Disk {
|
||||||
|
name: String,
|
||||||
|
disk_type: String,
|
||||||
|
total_space: String,
|
||||||
|
available_space: String,
|
||||||
|
usage: String,
|
||||||
|
file_system: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
#[serde(crate = "rocket::serde")]
|
||||||
|
pub struct System {
|
||||||
|
key: String,
|
||||||
|
host_name: String,
|
||||||
|
uptime: String,
|
||||||
|
os: String,
|
||||||
|
total_ram: String,
|
||||||
|
used_ram: String,
|
||||||
|
available_ram: String,
|
||||||
|
ram_usage: String,
|
||||||
|
total_swap: String,
|
||||||
|
used_swap: String,
|
||||||
|
available_swap: String,
|
||||||
|
swap_usage: String,
|
||||||
|
disks: Vec<Disk>,
|
||||||
|
processes: Vec<Process>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/servers", data = "<data>")]
|
||||||
|
pub fn server(data: Json<System>) {
|
||||||
|
if data.key == "0etnmXPSr95@FNy6A3U9Bw*ZupNIR85zI!hRFGIdj6SW$Tu0q%" {
|
||||||
|
println!("Data From : {}", data.host_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut file = match File::create(format!("./server/{}.json", &data.host_name)) {
|
||||||
|
Err(why) => {
|
||||||
|
println!("Error: {why}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Ok(file) => file,
|
||||||
|
};
|
||||||
|
|
||||||
|
let data: System = System {
|
||||||
|
key: format!("null"),
|
||||||
|
host_name: format!("{}", data.host_name),
|
||||||
|
uptime: format!("{}", data.uptime),
|
||||||
|
os: format!("{}", data.os),
|
||||||
|
total_ram: format!("{}", data.total_ram),
|
||||||
|
used_ram: format!("{}", data.used_ram),
|
||||||
|
available_ram: format!("{}", data.available_ram),
|
||||||
|
ram_usage: format!("{}", data.ram_usage),
|
||||||
|
total_swap: format!("{}", data.total_swap),
|
||||||
|
used_swap: format!("{}", data.used_swap),
|
||||||
|
available_swap: format!("{}", data.available_swap),
|
||||||
|
swap_usage: format!("{}", data.swap_usage),
|
||||||
|
disks: data.disks.clone(),
|
||||||
|
processes: data.processes.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let string = match to_string(&data) {
|
||||||
|
Err(why) => {
|
||||||
|
println!("Error: {why}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Ok(string) => string,
|
||||||
|
};
|
||||||
|
|
||||||
|
let write = file.write_all(
|
||||||
|
string
|
||||||
|
.as_bytes()
|
||||||
|
);
|
||||||
|
|
||||||
|
match write {
|
||||||
|
Err(why) => println!("Error {why}"),
|
||||||
|
Ok(_) => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/server_info")]
|
||||||
|
pub fn server_info() -> Json<Vec<System>> {
|
||||||
|
let mut systems: Vec<System> = vec![];
|
||||||
|
let folder = match read_dir("./server/") {
|
||||||
|
Err(why) => {
|
||||||
|
println!("Error: {why}");
|
||||||
|
read_dir("./server/").unwrap()
|
||||||
|
},
|
||||||
|
Ok(dir) => dir,
|
||||||
|
};
|
||||||
|
let mut file: File;
|
||||||
|
let mut string;
|
||||||
|
|
||||||
|
for path in folder {
|
||||||
|
string = String::new();
|
||||||
|
let path = match path {
|
||||||
|
Err(ref why) => {
|
||||||
|
println!("Error: {why}");
|
||||||
|
path.unwrap()
|
||||||
|
},
|
||||||
|
Ok(path) => path
|
||||||
|
}.path();
|
||||||
|
|
||||||
|
file = match File::open(format!("{}", path.display())) {
|
||||||
|
Err(why) => {
|
||||||
|
println!("Error: {why}");
|
||||||
|
File::open(format!("{}", path.display())).unwrap()
|
||||||
|
}
|
||||||
|
Ok(file) => file,
|
||||||
|
};
|
||||||
|
|
||||||
|
match file.read_to_string(&mut string) {
|
||||||
|
Err(why) => println!("Error: {why}"),
|
||||||
|
Ok(_) => (),
|
||||||
|
};
|
||||||
|
|
||||||
|
match from_str(&string) {
|
||||||
|
Err(why) => println!("Error: {why}"),
|
||||||
|
Ok(string) => systems.push(string),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Json(systems)
|
||||||
|
}
|
14
src/typing/leaderboard.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
use rocket::serde::json::Json;
|
||||||
|
use crate::typing::sql::{
|
||||||
|
get_leaderboard,
|
||||||
|
LeaderBoardTest
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Returns the highest test data from each user as
|
||||||
|
/// a json array
|
||||||
|
/// Acessible from http://url/api/leaderboard
|
||||||
|
#[get("/leaderboard")]
|
||||||
|
pub fn leaderboard() -> Json<Vec<LeaderBoardTest>> {
|
||||||
|
let leaderboard: Vec<LeaderBoardTest> = get_leaderboard(0).expect("error finding user_id");
|
||||||
|
Json(leaderboard)
|
||||||
|
}
|
4
src/typing/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
pub mod sql;
|
||||||
|
pub mod user;
|
||||||
|
pub mod leaderboard;
|
||||||
|
pub mod test;
|
@ -23,7 +23,7 @@ fn get_connection() -> rusqlite::Connection {
|
|||||||
/// Creates the necessary tables inside the database with
|
/// Creates the necessary tables inside the database with
|
||||||
/// correct normalised links between data for later
|
/// correct normalised links between data for later
|
||||||
/// querying
|
/// querying
|
||||||
pub fn create_database() -> Result<()> {
|
fn new_database() -> Result<()> {
|
||||||
let connection = get_connection();
|
let connection = get_connection();
|
||||||
|
|
||||||
connection.execute(
|
connection.execute(
|
||||||
@ -54,6 +54,18 @@ pub fn create_database() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Api route that creates a database if one
|
||||||
|
/// does not already exist.
|
||||||
|
/// Acessible from http://url/api/create_database
|
||||||
|
#[get("/create_database")]
|
||||||
|
pub fn create_database() -> String {
|
||||||
|
let database = new_database();
|
||||||
|
match database {
|
||||||
|
Err(why) => format!("Error: {why}"),
|
||||||
|
Ok(_) => format!("Sucessfully created the database")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// takes necessary data about a test and creates
|
/// takes necessary data about a test and creates
|
||||||
/// a database record with the data
|
/// a database record with the data
|
||||||
pub fn post_test(
|
pub fn post_test(
|
65
src/typing/test.rs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
use crate::typing::sql::post_test;
|
||||||
|
use rocket::serde::{
|
||||||
|
Deserialize,
|
||||||
|
json::Json
|
||||||
|
};
|
||||||
|
use rand::{
|
||||||
|
Rng,
|
||||||
|
rngs::ThreadRng
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
|
fs,
|
||||||
|
vec,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// the datascructure that the webserver will recieve
|
||||||
|
/// when a post is made to the http://url/api/post_test route
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(crate = "rocket::serde")]
|
||||||
|
pub struct PostTest<'r> {
|
||||||
|
test_type: &'r str,
|
||||||
|
test_length: u32,
|
||||||
|
test_time: u32,
|
||||||
|
test_seed: i64,
|
||||||
|
quote_id: i32,
|
||||||
|
wpm: u8,
|
||||||
|
accuracy: u8,
|
||||||
|
user_id: u32
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Api Route that accepts test data and posts it to the database
|
||||||
|
/// Acessible from http://url/api/post_test
|
||||||
|
#[post("/post_test", data = "<test>")]
|
||||||
|
pub fn create_test(test: Json<PostTest<'_>>) {
|
||||||
|
post_test(
|
||||||
|
test.test_type,
|
||||||
|
test.test_length,
|
||||||
|
test.test_time,
|
||||||
|
test.test_seed,
|
||||||
|
test.quote_id,
|
||||||
|
test.wpm,
|
||||||
|
test.accuracy,
|
||||||
|
test.user_id
|
||||||
|
).expect("error in posting test to tests table");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an array of words as Json
|
||||||
|
/// Accessible from http://url/api/get_test
|
||||||
|
#[get("/new_test")]
|
||||||
|
pub fn new_test() -> Json<Vec<String>> {
|
||||||
|
let mut word_vec: Vec<&str> = vec![];
|
||||||
|
let words: String = fs::read_to_string("wordlist.txt").unwrap();
|
||||||
|
for word in words.split('\n') {
|
||||||
|
word_vec.push(word.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut return_list: Vec<String> = vec![];
|
||||||
|
|
||||||
|
let mut rng: ThreadRng = rand::thread_rng();
|
||||||
|
for _i in 0..100 {
|
||||||
|
let hi: u32 = rng.gen_range(0..999);
|
||||||
|
return_list.push(word_vec[hi as usize].to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
Json(return_list.clone())
|
||||||
|
}
|
50
src/typing/user.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use rocket::serde::{
|
||||||
|
Deserialize,
|
||||||
|
json::Json
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::typing::sql::{
|
||||||
|
get_user_tests,
|
||||||
|
find_user,
|
||||||
|
create_user,
|
||||||
|
|
||||||
|
Test,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Struct representing the user
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(crate = "rocket::serde")]
|
||||||
|
pub struct User<'r> {
|
||||||
|
username: &'r str,
|
||||||
|
password: &'r str
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Route takes data about the user as a struct
|
||||||
|
/// and then creates the user in the database
|
||||||
|
/// Acessible from http://url/api/create_user
|
||||||
|
#[post("/create_user", data = "<user>")]
|
||||||
|
pub fn sign_up(user: Json<User<'_>>) {
|
||||||
|
create_user(
|
||||||
|
user.username,
|
||||||
|
user.password
|
||||||
|
).expect("Error: Couldn't create new user");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the users tests from the database and returns it as a
|
||||||
|
/// json array.
|
||||||
|
/// Accessible from http://url/api/get_user_tests
|
||||||
|
#[get("/get_tests/<user_id>")]
|
||||||
|
pub fn get_tests(user_id: u32) -> Json<Vec<Test>> {
|
||||||
|
let tests: Vec<Test> = get_user_tests(user_id).expect("error finding user_id");
|
||||||
|
Json(tests)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// takes the users login information and returns the users user id
|
||||||
|
/// which can be used to identify their tests etc.
|
||||||
|
/// Accessible from http://url/api/login
|
||||||
|
#[get("/login/<username>/<password>")]
|
||||||
|
pub fn login(username: &str, password: &str) -> String {
|
||||||
|
let user_id = find_user(username, password).expect("error finding user_id");
|
||||||
|
user_id.to_string()
|
||||||
|
}
|
||||||
|
|
BIN
website/.DS_Store
vendored
100
websites/Servers/index.css
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
:root {
|
||||||
|
--navbar: #52b2cf;
|
||||||
|
--navbar-button: #283F3B;
|
||||||
|
--background: #7EC4CF;
|
||||||
|
--table: #FFD07B;
|
||||||
|
--table-top:#FDB833;
|
||||||
|
--title: #296EB4;
|
||||||
|
--text: #000000;
|
||||||
|
--border: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: var(--background);
|
||||||
|
font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
font-size: medium;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color:black;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#all, #systems {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navbar {
|
||||||
|
width: 100%;
|
||||||
|
background: var(--navbar);
|
||||||
|
border: 1px black solid;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navbar button {
|
||||||
|
background-color: var(--navbar-button);
|
||||||
|
color: wheat;
|
||||||
|
border: 3px black solid;
|
||||||
|
padding: 15px;
|
||||||
|
font-size: larger;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navbar button:focus {
|
||||||
|
background-color: #23296c;
|
||||||
|
}
|
||||||
|
|
||||||
|
#navbar button:hover {
|
||||||
|
background-color: #fc9e4f;
|
||||||
|
color: var(--text);
|
||||||
|
border: 3px var(--border) solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
#SystemDiv {
|
||||||
|
background: var(--title);
|
||||||
|
width: 100%;
|
||||||
|
font-family:system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||||
|
font-size: 50px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
border-bottom: black 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
#system {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border: 2px black solid;
|
||||||
|
margin: 0px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tr:nth-child(n) {
|
||||||
|
background: var(--table);
|
||||||
|
}
|
||||||
|
|
||||||
|
table tr:nth-child(1) {
|
||||||
|
background: var(--table-top);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr {
|
||||||
|
border: 1px black solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
border: 1px black solid;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: larger;
|
||||||
|
}
|
31
websites/Servers/index.html
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title id="title">Leaderboard</title>
|
||||||
|
<link rel="stylesheet" href="index.css">
|
||||||
|
<script src="index.js" defer="true"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="SystemDiv"><h1 id="system">Typing Leaderboard</h1></div>
|
||||||
|
<div id="navbar">
|
||||||
|
<div id="allButton">
|
||||||
|
<button id="all">all</button>
|
||||||
|
</div>
|
||||||
|
<div id="systems">
|
||||||
|
<button>Arch</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="navbar">
|
||||||
|
<button id="systeminfo">System</button>
|
||||||
|
<button id="Disks Header">Disks</button>
|
||||||
|
<button id="Processes Header">Processes</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="systemInfo" align="center"></div>
|
||||||
|
<div id="disks" align="center"></div>
|
||||||
|
<div id="processes" align="center"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
296
websites/Servers/index.js
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
get();
|
||||||
|
let disks = false;
|
||||||
|
let processes = false;
|
||||||
|
let sysinfo = true;
|
||||||
|
let json;
|
||||||
|
let server = 0;
|
||||||
|
|
||||||
|
setInterval(get, 5000);
|
||||||
|
function get() {
|
||||||
|
let xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', 'http://arlofilley.com/api/server_info');
|
||||||
|
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||||
|
xhr.responseType = 'json';
|
||||||
|
xhr.send();
|
||||||
|
xhr.onload = () => {
|
||||||
|
json = xhr.response
|
||||||
|
createElements(json[server]);
|
||||||
|
createButtons(json);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function createElements(pJson) {
|
||||||
|
let title = document.getElementById(`system`);
|
||||||
|
title.textContent = pJson.host_name;
|
||||||
|
document.title = pJson.host_name;
|
||||||
|
|
||||||
|
createProcesses(pJson);
|
||||||
|
createDisks(pJson);
|
||||||
|
createSystemInfo(pJson);
|
||||||
|
};
|
||||||
|
|
||||||
|
function createSystemInfo(pJson) {
|
||||||
|
let div = document.getElementById(`systemInfo`);
|
||||||
|
|
||||||
|
while (div.firstChild) {
|
||||||
|
div.removeChild(div.firstChild)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sysinfo) return;
|
||||||
|
|
||||||
|
let table = document.createElement(`table`);
|
||||||
|
|
||||||
|
let tableBody = document.createElement('tbody');
|
||||||
|
table.appendChild(tableBody);
|
||||||
|
let tr = document.createElement('tr');
|
||||||
|
tableBody.appendChild(tr);
|
||||||
|
|
||||||
|
let td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Name`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`OS`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Uptime`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Total Ram`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Used Ram`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Available Ram`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Total Swap`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
tableBody.appendChild(tr);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Used Swap`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
tableBody.appendChild(tr);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Available Swap`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
tableBody.appendChild(tr);
|
||||||
|
tr = document.createElement('tr');
|
||||||
|
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(pJson.host_name));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(pJson.os));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(pJson.uptime));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(pJson.total_ram));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(pJson.used_ram));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(pJson.available_ram));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(pJson.total_swap));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(pJson.used_swap));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(pJson.available_swap));
|
||||||
|
tr.appendChild(td);
|
||||||
|
tableBody.appendChild(tr);
|
||||||
|
tr = document.createElement('tr');
|
||||||
|
|
||||||
|
div.appendChild(table);
|
||||||
|
};
|
||||||
|
|
||||||
|
function createProcesses(pJson) {
|
||||||
|
let div = document.getElementById(`processes`);
|
||||||
|
|
||||||
|
while (div.firstChild) {
|
||||||
|
div.removeChild(div.firstChild)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!processes) return;
|
||||||
|
|
||||||
|
let table = document.createElement(`table`);
|
||||||
|
|
||||||
|
let tableBody = document.createElement('tbody');
|
||||||
|
table.appendChild(tableBody);
|
||||||
|
let tr = document.createElement('tr');
|
||||||
|
tableBody.appendChild(tr);
|
||||||
|
|
||||||
|
let td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Name`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Memory`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Run Time`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Process ID`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`User ID`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Virtual Memory`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
tableBody.appendChild(tr);
|
||||||
|
tr = document.createElement('tr');
|
||||||
|
|
||||||
|
for (let i = 0; i < pJson.processes.length; i++) {
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`${pJson.processes[i].name}`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`${pJson.processes[i].memory}`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`${pJson.processes[i].run_time}`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`${pJson.processes[i].id}`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`${pJson.processes[i].user_id}`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`${pJson.processes[i].virtual_memory}`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
tableBody.appendChild(tr);
|
||||||
|
tr = document.createElement('tr');
|
||||||
|
}
|
||||||
|
div.appendChild(table);
|
||||||
|
};
|
||||||
|
|
||||||
|
function createDisks(pJson) {
|
||||||
|
let div = document.getElementById(`disks`);
|
||||||
|
|
||||||
|
while (div.firstChild) {
|
||||||
|
div.removeChild(div.firstChild)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!disks) return;
|
||||||
|
|
||||||
|
let table = document.createElement(`table`);
|
||||||
|
|
||||||
|
let tableBody = document.createElement('tbody');
|
||||||
|
table.appendChild(tableBody);
|
||||||
|
let tr = document.createElement('tr');
|
||||||
|
tableBody.appendChild(tr);
|
||||||
|
|
||||||
|
let td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Name`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Type`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Total Space`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Available Space`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`Usage`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`File System`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
tableBody.appendChild(tr);
|
||||||
|
tr = document.createElement('tr');
|
||||||
|
|
||||||
|
for (let i = 0; i < pJson.disks.length; i++) {
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`${pJson.disks[i].name}`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`${pJson.disks[i].disk_type}`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`${pJson.disks[i].total_space}`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`${pJson.disks[i].available_space}`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`${pJson.disks[i].usage}`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
td = document.createElement('td');
|
||||||
|
td.appendChild(document.createTextNode(`${pJson.disks[i].file_system}`));
|
||||||
|
tr.appendChild(td);
|
||||||
|
|
||||||
|
tableBody.appendChild(tr);
|
||||||
|
tr = document.createElement('tr');
|
||||||
|
}
|
||||||
|
div.appendChild(table);
|
||||||
|
};
|
||||||
|
|
||||||
|
b = document.getElementById("Processes Header");
|
||||||
|
b.addEventListener("click", () => {
|
||||||
|
processes = true;
|
||||||
|
disks = false;
|
||||||
|
sysinfo = false;
|
||||||
|
createElements(json[server]);
|
||||||
|
});
|
||||||
|
|
||||||
|
c = document.getElementById("systeminfo");
|
||||||
|
c.addEventListener("click", () => {
|
||||||
|
processes = false;
|
||||||
|
disks = false;
|
||||||
|
sysinfo = true;
|
||||||
|
createElements(json[server]);
|
||||||
|
});
|
||||||
|
let button = document.getElementById
|
||||||
|
|
||||||
|
e = document.getElementById("Disks Header");
|
||||||
|
e.addEventListener("click", () => {
|
||||||
|
disks = true;
|
||||||
|
processes = false;
|
||||||
|
sysinfo = false;
|
||||||
|
createElements(json[server]);
|
||||||
|
});
|
||||||
|
|
||||||
|
function createButtons(pJson) {
|
||||||
|
let div = document.getElementById("systems");
|
||||||
|
|
||||||
|
while (div.firstChild) {
|
||||||
|
div.removeChild(div.firstChild)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < pJson.length; i++) {
|
||||||
|
let system = pJson[i];
|
||||||
|
|
||||||
|
let button = document.createElement("button");
|
||||||
|
button.textContent = system.host_name.toUpperCase();
|
||||||
|
button.id = i;
|
||||||
|
button.addEventListener("click", () => {
|
||||||
|
disks = false;
|
||||||
|
processes = false;
|
||||||
|
sysinfo = true;
|
||||||
|
server = button.id
|
||||||
|
createElements(json[button.id]);
|
||||||
|
});
|
||||||
|
div.appendChild(button);
|
||||||
|
}
|
||||||
|
}
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 552 B After Width: | Height: | Size: 552 B |
Before Width: | Height: | Size: 968 B After Width: | Height: | Size: 968 B |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |