Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit af31e6e

Browse files
committedNov 9, 2024
fmt & enhancements & changelog
1 parent acf9d3d commit af31e6e

File tree

9 files changed

+197
-227
lines changed

9 files changed

+197
-227
lines changed
 

‎Cargo.lock

-83
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,3 @@ edition = "2021"
77
async-std = "1.12.0"
88
lettre = "0.11"
99
maud = "0.26.0"
10-
tracing-subscriber = "0.3.18"

‎changelog/1.0.0.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# 1.0.0 Release
2+
This is the first `ServerAPI` **stable** release you can enjoy!
3+
4+
Added features:
5+
- installation wizard
6+
- launching rust modules in parallel
7+
- config support (you can change everything manually)
8+
- implemented fancy html header (use of `maud` crate)
9+
- implemented a text raw alternative to html in case client does not support it
10+
11+
12+
Waited soon:
13+
- crate organization, such as in my [`LimitPush`](https://github.com/heydocode/limitpush) project
14+
- launching of processes via the CLI environment
15+
- responsible CLI with commands
16+
- inter-operability with [`LimitPush`](https://github.com/heydocode/limitpush) template, and any other bevy game
17+
- feature organization
18+
- custom multiplayer protocol that'll work with `LimitPush` if "mp-protocol" feature enabled

‎src/file_reader.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::fs::{create_dir_all, File, metadata};
1+
use std::fs::{create_dir_all, metadata, File};
22
use std::io::{BufReader, Read};
33
use std::path::Path;
44

@@ -41,7 +41,12 @@ pub fn mc_status_reader() -> String {
4141
}
4242

4343
let contents = read_from_file(file_path.to_str().unwrap_or("config/logs.txt"));
44-
if contents.clone().expect("Could not convert contents to Ok()").len() <= 5 {
44+
if contents
45+
.clone()
46+
.expect("Could not convert contents to Ok()")
47+
.len()
48+
<= 5
49+
{
4550
String::from("The server's logs are empty! Is there a problem?")
4651
} else {
4752
contents.expect("Could not convert contents to Ok()")
@@ -63,11 +68,14 @@ fn read_from_file(file_path: &str) -> Result<String, String> {
6368
}
6469

6570
// Attempt to open the file
66-
let file = File::open(file_path).map_err(|e| format!("Error opening file '{}': {}", file_path, e))?;
71+
let file =
72+
File::open(file_path).map_err(|e| format!("Error opening file '{}': {}", file_path, e))?;
6773
let mut buf_reader = BufReader::new(file);
6874
let mut contents = String::new();
69-
70-
buf_reader.read_to_string(&mut contents).map_err(|e| format!("Error reading file '{}': {}", file_path, e))?;
75+
76+
buf_reader
77+
.read_to_string(&mut contents)
78+
.map_err(|e| format!("Error reading file '{}': {}", file_path, e))?;
7179

7280
Ok(contents)
7381
}

‎src/file_writer.rs

+18-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
use async_std::fs::File;
12
use async_std::fs::OpenOptions;
23
use async_std::path::Path;
3-
use async_std::fs::File;
44
use async_std::prelude::*;
55

66
pub async fn write_to_file(text: String, file_path: &str) -> Result<(), String> {
@@ -11,27 +11,37 @@ pub async fn write_to_file(text: String, file_path: &str) -> Result<(), String>
1111
.await
1212
.map_err(|e| e.to_string())?;
1313

14-
file.write_all(text.as_bytes()).await.map_err(|e| e.to_string())
14+
file.write_all(text.as_bytes())
15+
.await
16+
.map_err(|e| e.to_string())
1517
}
1618

17-
pub async fn update_credentials(username: String, password: String, receiver: String) -> Result<(), String> {
19+
pub async fn update_credentials(
20+
username: String,
21+
password: String,
22+
receiver: String,
23+
) -> Result<(), String> {
1824
let file_path = "config/smtp_account.txt";
1925
let path = Path::new(file_path);
2026

2127
let mut content = String::new();
2228
{
23-
let mut file = File::open(path)
24-
.await
25-
.map_err(|e| e.to_string())?;
29+
let mut file = File::open(path).await.map_err(|e| e.to_string())?;
2630
file.read_to_string(&mut content)
2731
.await
2832
.map_err(|e| e.to_string())?;
2933
}
3034

3135
let updated_content = content
32-
.replace("username:example@gmail.com", &format!("username:{}", username))
36+
.replace(
37+
"username:example@gmail.com",
38+
&format!("username:{}", username),
39+
)
3340
.replace("password:password123123", &format!("password:{}", password))
34-
.replace("receiver:example@gmail.com", &format!("receiver:{}", receiver));
41+
.replace(
42+
"receiver:example@gmail.com",
43+
&format!("receiver:{}", receiver),
44+
);
3545

3646
{
3747
let mut file = OpenOptions::new()

‎src/mail.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
use crate::file_reader::smtp_account_reader;
22
use crate::file_writer::write_to_file;
33
use lettre::{
4-
message::{header::{self, ContentType}, MultiPart, SinglePart}, transport::smtp::authentication::Credentials, Message,
5-
SmtpTransport, Transport,
4+
message::{
5+
header::{self}, MaybeString, MultiPart, SinglePart
6+
},
7+
transport::smtp::authentication::Credentials,
8+
Message, SmtpTransport, Transport,
69
};
710
use maud::PreEscaped;
811

@@ -28,8 +31,7 @@ pub async fn mail_sender(title: &str, html: PreEscaped<String>) {
2831
.singlepart(
2932
SinglePart::builder()
3033
.header(header::ContentType::TEXT_PLAIN)
31-
.body(format!(
32-
"Hello there!\nYour server is working fine! The next status email will be sent in 5 minutes.\n\nServer's Logs:\nYour client does not support html...")),
34+
.body(MaybeString::String(String::from("Hello there!\nYour server is working fine! The next status email will be sent in 5 minutes.\n\nServer's Logs:\nYour client does not support html..."))),
3335
)
3436
.singlepart(
3537
SinglePart::builder()
@@ -50,7 +52,7 @@ pub async fn mail_sender(title: &str, html: PreEscaped<String>) {
5052
match mailer.send(&email) {
5153
Ok(_) => {
5254
match write_to_file(
53-
format!("Email has been sent successfully!"),
55+
"Email has been sent successfully!".to_string(),
5456
"config/mail_logs.txt",
5557
)
5658
.await

‎src/main.rs

+24-20
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@ use scheduler::status_upload;
1212
use file_writer::write_to_file;
1313
use setup::check_config_components;
1414
use std::thread;
15-
use tracing_subscriber;
1615

1716
fn main() {
18-
tracing_subscriber::fmt::init();
19-
2017
let setup_handle = thread::Builder::new().name("setup".to_string()).spawn(|| {
2118
println!("Setup Process has been launched");
2219
match check_config_components() {
@@ -26,7 +23,7 @@ fn main() {
2623

2724
async_std::task::block_on(async {
2825
match write_to_file(
29-
format!("All config components are OK, loading the server.."),
26+
"All config components are OK, loading the server..".to_string(),
3027
"config/logs.txt",
3128
)
3229
.await
@@ -37,23 +34,30 @@ fn main() {
3734
});
3835
});
3936

40-
if let Err(_) = setup_handle.expect("Unable to join setup handle").join() {
37+
let mail_handle = thread::Builder::new()
38+
.name("mail_server".to_string())
39+
.spawn(|| {
40+
println!("Mail Server has been enabled");
41+
status_upload();
42+
println!("Mail Server has been disabled");
43+
});
44+
45+
if setup_handle
46+
.expect("Unable to join setup handle")
47+
.join()
48+
.is_err()
49+
{
4150
eprintln!("An error occured when tried to join setup handle");
42-
} else {
43-
let mail_handle = thread::Builder::new()
44-
.name("mail_server".to_string())
45-
.spawn(|| {
46-
println!("Mail Server has been enabled");
47-
status_upload();
48-
println!("Mail Server has been disabled");
49-
});
50-
if let Err(_) = mail_handle.expect("Unable to join mail handle").join() {
51-
eprintln!("An error occured when tried to join mail handle");
52-
}
53-
// Please consider adding `else if` blocks until all handles won't be joined
54-
else {
55-
println!("All config components are OK, loading the server..");
56-
}
51+
} else if mail_handle
52+
.expect("Unable to join mail handle")
53+
.join()
54+
.is_err()
55+
{
56+
eprintln!("An error occured when tried to join mail handle");
57+
}
58+
// Please consider adding `else if` blocks until all handles won't be joined
59+
else {
60+
println!("All config components are OK, loading the server..");
5761
}
5862
/*
5963
MINECRAFT SERVER SUPPORT USING VALENCE

‎src/setup.rs

+41-33
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1-
use std::path::Path;
21
use std::fs::OpenOptions;
3-
use std::io::*;
42
use std::io;
3+
use std::io::*;
4+
use std::path::Path;
55

66
use crate::file_reader::smtp_account_reader;
77
use crate::file_writer::update_credentials;
88

99
fn read_line() -> String {
1010
let mut input = String::new();
1111
io::stdout().flush().unwrap();
12-
io::stdin().read_line(&mut input).expect("Failed to read line");
12+
io::stdin()
13+
.read_line(&mut input)
14+
.expect("Failed to read line");
1315
input.trim().to_string()
1416
}
1517

@@ -18,7 +20,7 @@ pub fn check_config_components() -> std::result::Result<(), String> {
1820
Path::new("config/logs.txt"),
1921
Path::new("config/smtp_account.txt"),
2022
Path::new("config/mail_logs.txt"),
21-
];
23+
];
2224

2325
for path in components.into_iter() {
2426
let prefix = path.parent().unwrap();
@@ -27,16 +29,12 @@ pub fn check_config_components() -> std::result::Result<(), String> {
2729
.read(true)
2830
.write(true)
2931
.create(true)
32+
.truncate(false)
3033
.open(path)
3134
.map_err(|e| e.to_string())?;
32-
if path == Path::new("config/smtp_account.txt") {
33-
match smtp_account_reader() {
34-
Err(_) => {
35-
let _ = write!(file, "username:example@gmail.com\npassword:password123123\nreceiver:example@gmail.com\n\n### The username is your gmail account (example@gmail.com)\n### The password is a 'password for apps' created in Google\n## NOTICE: To create an app-password, you have to have 2-step verification\n## enabled and maybe all rescue options of saving the account.").map_err(|e| e.to_string());
36-
setup_wizard();
37-
},
38-
_ => {}
39-
}
35+
if path == Path::new("config/smtp_account.txt") && smtp_account_reader().is_err() {
36+
let _ = write!(file, "username:example@gmail.com\npassword:password123123\nreceiver:example@gmail.com\n\n### The username is your gmail account (example@gmail.com)\n### The password is a 'password for apps' created in Google\n## NOTICE: To create an app-password, you have to have 2-step verification\n## enabled and maybe all rescue options of saving the account.").map_err(|e| e.to_string());
37+
setup_wizard();
4038
}
4139
}
4240
Ok(())
@@ -52,70 +50,80 @@ pub fn setup_wizard() {
5250
match iter {
5351
1 => {
5452
println!("Enter your smtp account username:");
55-
},
53+
}
5654
2 => {
5755
println!("Can you confirm your smtp account username (Y or N)?");
58-
},
56+
}
5957
3 => {
6058
println!("Enter your smtp account password:");
61-
},
59+
}
6260
4 => {
6361
println!("Can you confirm your smtp account password (Y or N)?");
64-
},
62+
}
6563
5 => {
6664
println!("Enter your gmail account as a receiver\n(you will receive status emails on this gmail address):")
6765
}
6866
6 => {
6967
println!("Can you confirm your gmail account username (Y or N)?");
7068
}
71-
_ => ()
69+
_ => (),
7270
}
7371
let input = read_line();
7472
match iter {
7573
1 => {
76-
println!("You have entered \"{}\" as your smtp account username", input);
74+
println!(
75+
"You have entered \"{}\" as your smtp account username",
76+
input
77+
);
7778
smtp_account_username = input.clone();
7879
iter += 1;
79-
},
80+
}
8081
2 => {
8182
if input.to_lowercase() == "y" {
8283
iter += 1;
83-
}
84-
else {
84+
} else {
8585
iter = 1
8686
}
87-
},
87+
}
8888
3 => {
89-
println!("You have entered \"{}\" as your smtp account password", input);
89+
println!(
90+
"You have entered \"{}\" as your smtp account password",
91+
input
92+
);
9093
smtp_account_password = input.clone();
9194
iter += 1;
92-
},
95+
}
9396
4 => {
9497
if input.to_lowercase() == "y" {
9598
iter += 1;
96-
}
97-
else {
99+
} else {
98100
iter = 3
99101
}
100-
},
102+
}
101103
5 => {
102-
println!("You have entered \"{}\" as your gmail account username", input);
104+
println!(
105+
"You have entered \"{}\" as your gmail account username",
106+
input
107+
);
103108
receiver_gmail = input.clone();
104109
iter += 1;
105110
}
106111
6 => {
107112
if input.to_lowercase() == "y" {
108113
iter += 1;
109-
}
110-
else {
114+
} else {
111115
iter = 5
112116
}
113117
}
114118
_ => {
115119
async_std::task::block_on(async move {
116-
update_credentials(smtp_account_username, smtp_account_password, receiver_gmail)
117-
.await
118-
.expect("Failed to update credentials");
120+
update_credentials(
121+
smtp_account_username,
122+
smtp_account_password,
123+
receiver_gmail,
124+
)
125+
.await
126+
.expect("Failed to update credentials");
119127
});
120128
return;
121129
}

‎src/tests.rs

+76-72
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,90 @@
11
#[cfg(test)]
2-
mod tests {
3-
use crate::*;
4-
use async_std::fs::{self, File};
5-
use async_std::path::Path;
6-
use async_std::prelude::*;
7-
use file_writer::update_credentials;
2+
use crate::*;
3+
use async_std::fs::{self, File};
4+
use async_std::path::Path;
5+
use async_std::prelude::*;
6+
use file_writer::update_credentials;
87

9-
#[test]
10-
fn test_write_to_file() {
11-
let test_file_path = "test_write_to_file.txt";
8+
#[test]
9+
fn test_write_to_file() {
10+
let test_file_path = "test_write_to_file.txt";
1211

13-
// Use block_on to run the async code inside the test
14-
async_std::task::block_on(async {
15-
// Ensure the test file is clean
16-
if Path::new(test_file_path).exists().await {
17-
fs::remove_file(test_file_path)
18-
.await
19-
.expect("Failed to remove test file");
20-
}
21-
22-
// Write to the file
23-
write_to_file("Hello, world!".to_string(), test_file_path)
12+
// Use block_on to run the async code inside the test
13+
async_std::task::block_on(async {
14+
// Ensure the test file is clean
15+
if Path::new(test_file_path).exists().await {
16+
fs::remove_file(test_file_path)
2417
.await
25-
.expect("Failed to write to file");
18+
.expect("Failed to remove test file");
19+
}
2620

27-
// Read the file content
28-
let mut file = File::open(test_file_path)
29-
.await
30-
.expect("Failed to open test file");
31-
let mut content = String::new();
32-
file.read_to_string(&mut content)
33-
.await
34-
.expect("Failed to read test file");
21+
// Write to the file
22+
write_to_file("Hello, world!".to_string(), test_file_path)
23+
.await
24+
.expect("Failed to write to file");
3525

36-
// Check the content
37-
assert_eq!(content, "Hello, world!");
26+
// Read the file content
27+
let mut file = File::open(test_file_path)
28+
.await
29+
.expect("Failed to open test file");
30+
let mut content = String::new();
31+
file.read_to_string(&mut content)
32+
.await
33+
.expect("Failed to read test file");
3834

39-
// Clean up
40-
fs::remove_file(test_file_path)
41-
.await
42-
.expect("Failed to remove test file");
43-
});
44-
}
35+
// Check the content
36+
assert_eq!(content, "Hello, world!");
37+
38+
// Clean up
39+
fs::remove_file(test_file_path)
40+
.await
41+
.expect("Failed to remove test file");
42+
});
43+
}
4544

46-
#[test]
47-
fn test_update_credentials() {
48-
let test_file_path = "config/test_smtp_account.txt";
45+
#[test]
46+
fn test_update_credentials() {
47+
let test_file_path = "config/test_smtp_account.txt";
4948

50-
// Use block_on to run the async code inside the test
51-
async_std::task::block_on(async {
52-
// Ensure the config directory exists
53-
fs::create_dir_all("config")
54-
.await
55-
.expect("Failed to create config directory");
49+
// Use block_on to run the async code inside the test
50+
async_std::task::block_on(async {
51+
// Ensure the config directory exists
52+
fs::create_dir_all("config")
53+
.await
54+
.expect("Failed to create config directory");
5655

57-
// Prepare the test file
58-
let initial_content = "username:example@gmail.com\npassword:password123123\nreceiver:example@gmail.com\n";
59-
fs::write(test_file_path, initial_content)
60-
.await
61-
.expect("Failed to write initial content");
56+
// Prepare the test file
57+
let initial_content =
58+
"username:example@gmail.com\npassword:password123123\nreceiver:example@gmail.com\n";
59+
fs::write(test_file_path, initial_content)
60+
.await
61+
.expect("Failed to write initial content");
6262

63-
// Update credentials
64-
update_credentials("new_username".to_string(), "new_password".to_string(), "examplereceiver".to_string())
65-
.await
66-
.expect("Failed to update credentials");
67-
// Read the updated file content
68-
let mut file = File::open(test_file_path)
69-
.await
70-
.expect("Failed to open test file");
71-
let mut content = String::new();
72-
file.read_to_string(&mut content)
73-
.await
74-
.expect("Failed to read test file");
63+
// Update credentials
64+
update_credentials(
65+
"new_username".to_string(),
66+
"new_password".to_string(),
67+
"examplereceiver".to_string(),
68+
)
69+
.await
70+
.expect("Failed to update credentials");
71+
// Read the updated file content
72+
let mut file = File::open(test_file_path)
73+
.await
74+
.expect("Failed to open test file");
75+
let mut content = String::new();
76+
file.read_to_string(&mut content)
77+
.await
78+
.expect("Failed to read test file");
7579

76-
// Check the updated content
77-
let expected_content = "username:new_username\npassword:new_password\nreceiver:example_receiver\n";
78-
assert_eq!(content, expected_content);
80+
// Check the updated content
81+
let expected_content =
82+
"username:new_username\npassword:new_password\nreceiver:example_receiver\n";
83+
assert_eq!(content, expected_content);
7984

80-
// Clean up
81-
fs::remove_file(test_file_path)
82-
.await
83-
.expect("Failed to remove test file");
84-
});
85-
}
85+
// Clean up
86+
fs::remove_file(test_file_path)
87+
.await
88+
.expect("Failed to remove test file");
89+
});
8690
}

0 commit comments

Comments
 (0)
Please sign in to comment.