Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
6873a71363 |
11 changed files with 113 additions and 155 deletions
3
backend/.gitignore
vendored
3
backend/.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
.env
|
**/target/**
|
||||||
|
Cargo.lock
|
10
backend/Cargo.toml
Normal file
10
backend/Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "backend"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
actix-web = "4.10.2"
|
||||||
|
chrono = "0.4.41"
|
||||||
|
serde = { version = "1.0.219", features = ["derive"]}
|
||||||
|
serde_json = "1.0.140"
|
|
@ -1,3 +0,0 @@
|
||||||
module backend
|
|
||||||
|
|
||||||
go 1.24.2
|
|
|
@ -1,14 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"backend/server"
|
|
||||||
"backend/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// Checking arguments
|
|
||||||
util.SetLevel(util.NOLOG)
|
|
||||||
|
|
||||||
// Rest API start on port
|
|
||||||
server.Start(8085)
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"backend/util"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func getphoto(w http.ResponseWriter, r *http.Request) {
|
|
||||||
idStr := r.URL.Query().Get("id")
|
|
||||||
if idStr == "" {
|
|
||||||
util.Logformat(util.ERROR, "%s: Missing 'id' parameter.", util.GetFunctionName())
|
|
||||||
http.Error(w, "Missing or invalid parameters : id", http.StatusBadRequest)
|
|
||||||
} else {
|
|
||||||
sendResponse(w, 0)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package server
|
|
||||||
|
|
||||||
import (
|
|
||||||
"backend/util"
|
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Start(port int64) {
|
|
||||||
// Creating endpoints
|
|
||||||
http.HandleFunc("/getphoto", wrapHeader(getphoto))
|
|
||||||
|
|
||||||
util.Logformat(util.INFO, "Starting server on port %d...\n", port)
|
|
||||||
if err := http.ListenAndServe(":"+strconv.FormatInt(port, 10), nil); err != nil {
|
|
||||||
util.Logformat(util.ERROR, "Could not start server (%s)\n", err.Error())
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func sendResponse(w http.ResponseWriter, r any) {
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
if err := json.NewEncoder(w).Encode(r); err != nil {
|
|
||||||
util.Logformat(util.ERROR, "%s\n", err.Error())
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not sure about that, might change it later... (added by Lemonochrme on 'yoboujon/automatic-management')
|
|
||||||
func wrapHeader(next http.HandlerFunc) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
||||||
w.Header().Set("Access-Control-Allow-Methods", "GET")
|
|
||||||
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
|
|
||||||
|
|
||||||
if r.Method == http.MethodOptions {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
next(w, r)
|
|
||||||
}
|
|
||||||
}
|
|
80
backend/src/log.rs
Normal file
80
backend/src/log.rs
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::fmt::Arguments;
|
||||||
|
use chrono::{Datelike, Local, Timelike};
|
||||||
|
use std::io::{self, Write};
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Hash)]
|
||||||
|
pub enum LogLevel {
|
||||||
|
NOLOG,
|
||||||
|
INFO,
|
||||||
|
CORRECT,
|
||||||
|
WARNING,
|
||||||
|
ERROR,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub enum ColorFormat {
|
||||||
|
BLUE,
|
||||||
|
GREEN,
|
||||||
|
YELLOW,
|
||||||
|
RED,
|
||||||
|
LIGHTRED,
|
||||||
|
WHITE,
|
||||||
|
RESET,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ColorFormat {
|
||||||
|
fn as_str(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
ColorFormat::BLUE => "\x1b[34m",
|
||||||
|
ColorFormat::GREEN => "\x1b[32m",
|
||||||
|
ColorFormat::YELLOW => "\x1b[33m",
|
||||||
|
ColorFormat::RED => "\x1b[31m",
|
||||||
|
ColorFormat::LIGHTRED => "\x1b[91m",
|
||||||
|
ColorFormat::WHITE => "\x1b[97m",
|
||||||
|
ColorFormat::RESET => "\x1b[0m",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_color_print() -> HashMap<LogLevel, &'static str> {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert(LogLevel::NOLOG, "");
|
||||||
|
map.insert(LogLevel::INFO, concat!("\x1b[34m","[INFO]","\x1b[0m"));
|
||||||
|
map.insert(LogLevel::CORRECT, concat!("\x1b[32m","[OK ]", "\x1b[92m"));
|
||||||
|
map.insert(LogLevel::WARNING, concat!("\x1b[33m", "[WARN]", "\x1b[93m"));
|
||||||
|
map.insert(LogLevel::ERROR, concat!("\x1b[31m", "[ERR ]", "\x1b[91m"));
|
||||||
|
map
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log_format(level: LogLevel, args: Arguments) {
|
||||||
|
let color_map = get_color_print();
|
||||||
|
let header = color_map.get(&level).copied().unwrap_or("");
|
||||||
|
let message = format!("{}", args);
|
||||||
|
let now = Local::now();
|
||||||
|
let time = format!(
|
||||||
|
"[{:02}/{:02}/{} {:02}:{:02}:{:02}]",
|
||||||
|
now.day(),
|
||||||
|
now.month(),
|
||||||
|
now.year(),
|
||||||
|
now.hour(),
|
||||||
|
now.minute(),
|
||||||
|
now.second()
|
||||||
|
);
|
||||||
|
|
||||||
|
if level == LogLevel::NOLOG {
|
||||||
|
println!("{}\t\t{}", time, message);
|
||||||
|
} else if level != LogLevel::INFO {
|
||||||
|
println!("{}{}\t{}{}", header, time, message, ColorFormat::RESET.as_str());
|
||||||
|
} else {
|
||||||
|
println!("{}{}\t{}", header, time, message);
|
||||||
|
}
|
||||||
|
io::stdout().flush().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! logf {
|
||||||
|
($level:expr, $fmt:expr $(, $arg:expr)* $(,)?) => {
|
||||||
|
log::log_format($level, format_args!($fmt $(, $arg)*))
|
||||||
|
};
|
||||||
|
}
|
21
backend/src/main.rs
Normal file
21
backend/src/main.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use actix_web::{web, App, HttpResponse, HttpServer, Responder};
|
||||||
|
|
||||||
|
mod log;
|
||||||
|
use log::LogLevel;
|
||||||
|
|
||||||
|
async fn hello() -> impl Responder {
|
||||||
|
HttpResponse::Ok().body("Hello world")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_web::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
logf!(LogLevel::INFO, "This is an info log.");
|
||||||
|
logf!(LogLevel::CORRECT, "This is a correct log.");
|
||||||
|
logf!(LogLevel::ERROR, "This is an error log.");
|
||||||
|
logf!(LogLevel::WARNING, "This is a warning log.");
|
||||||
|
logf!(LogLevel::NOLOG, "This is no log.");
|
||||||
|
HttpServer::new(|| App::new().route("/hello", web::get().to(hello)))
|
||||||
|
.bind("127.0.0.1:8080")?
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
|
@ -1,59 +0,0 @@
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type colorFormat string
|
|
||||||
type LogLevel int
|
|
||||||
|
|
||||||
const (
|
|
||||||
BLUE colorFormat = "\033[34m"
|
|
||||||
GREEN colorFormat = "\033[32m"
|
|
||||||
YELLOW colorFormat = "\033[33m"
|
|
||||||
RED colorFormat = "\033[31m"
|
|
||||||
LIGHT_RED colorFormat = "\033[91m"
|
|
||||||
WHITE colorFormat = "\033[97m"
|
|
||||||
RESET colorFormat = "\033[0m"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
NOLOG LogLevel = iota
|
|
||||||
INFO
|
|
||||||
CORRECT
|
|
||||||
WARNING
|
|
||||||
ERROR
|
|
||||||
)
|
|
||||||
|
|
||||||
var colorPrint = map[LogLevel]colorFormat{
|
|
||||||
NOLOG: "",
|
|
||||||
INFO: BLUE + "[INFO]" + RESET,
|
|
||||||
CORRECT: GREEN,
|
|
||||||
WARNING: YELLOW + "[WARN]",
|
|
||||||
ERROR: RED + "[ERR.]" + LIGHT_RED,
|
|
||||||
}
|
|
||||||
|
|
||||||
var minimumlog = NOLOG
|
|
||||||
|
|
||||||
func Logformat(level LogLevel, format string, args ...interface{}) {
|
|
||||||
if level < minimumlog {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
header := colorPrint[level]
|
|
||||||
message := fmt.Sprintf(format, args...)
|
|
||||||
currentTime := time.Now()
|
|
||||||
time := fmt.Sprintf("[%02d/%02d/%d %02d:%02d:%02d]", currentTime.Day(), currentTime.Month(), currentTime.Year(), currentTime.Hour(), currentTime.Minute(), currentTime.Second())
|
|
||||||
if level == NOLOG {
|
|
||||||
fmt.Printf("%s\t\t%s", time, message)
|
|
||||||
} else if level != INFO {
|
|
||||||
fmt.Printf("%s%s\t%s%s", header, time, message, RESET)
|
|
||||||
} else {
|
|
||||||
fmt.Printf("%s%s\t%s", header, time, message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetLevel(level LogLevel) {
|
|
||||||
minimumlog = level
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetFunctionName() string {
|
|
||||||
pc, _, _, _ := runtime.Caller(1)
|
|
||||||
f := runtime.FuncForPC(pc)
|
|
||||||
return strings.Split(strings.Split(f.Name(), "/")[1], ".")[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func HasSubURI(r *http.Request) (bool, string) {
|
|
||||||
url := strings.Split(r.URL.Path, "/")
|
|
||||||
return (len(url[2]) > 0), url[2]
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue