Añade configuración y conexión a la base de datos
This commit is contained in:
parent
b6dd473578
commit
76785af4dc
13 changed files with 210 additions and 83 deletions
12
Cargo.toml
12
Cargo.toml
|
|
@ -29,6 +29,7 @@ once_cell = "1.9.0"
|
||||||
figlet-rs = "0.1.3"
|
figlet-rs = "0.1.3"
|
||||||
|
|
||||||
config_rs = { package = "config", version = "0.11.0", features = ["toml"] }
|
config_rs = { package = "config", version = "0.11.0", features = ["toml"] }
|
||||||
|
url = "2.2.2"
|
||||||
|
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-appender = "0.2"
|
tracing-appender = "0.2"
|
||||||
|
|
@ -47,9 +48,20 @@ downcast-rs = "1.2.0"
|
||||||
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
|
||||||
|
[dependencies.sea-orm]
|
||||||
|
version = "0.6"
|
||||||
|
features = ["macros", "debug-print", "runtime-async-std-native-tls"]
|
||||||
|
default-features = false
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
actix-web-static-files = "3.0.5"
|
actix-web-static-files = "3.0.5"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["sea-orm/sqlx-mysql"]
|
||||||
|
mysql = ["sea-orm/sqlx-mysql"]
|
||||||
|
postgres = ["sea-orm/sqlx-postgres"]
|
||||||
|
sqlite = ["sea-orm/sqlx-sqlite"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "pagetop"
|
name = "pagetop"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,20 @@ prefix = "tracing.log"
|
||||||
# Presentación de las trazas: "Json", "Full", "Compact" o "Pretty".
|
# Presentación de las trazas: "Json", "Full", "Compact" o "Pretty".
|
||||||
format = "Json"
|
format = "Json"
|
||||||
|
|
||||||
|
[database]
|
||||||
|
# Ajustes para conectar con la base de datos.
|
||||||
|
# El tipo de base de datos es una característica de compilación.
|
||||||
|
# Nombre (mysql/postgres) o referencia (sqlite) de la base de datos.
|
||||||
|
db_name = "dbname"
|
||||||
|
# Usuario y contraseña (mysql/postgres).
|
||||||
|
db_user = "dbuser"
|
||||||
|
db_pass = "dbpass"
|
||||||
|
# Servidor (mysql/postgres) y puerto predeterminado (0 para 3306 ó 5432).
|
||||||
|
db_host = "localhost"
|
||||||
|
db_port = 0
|
||||||
|
# Número máximo de conexiones habilitadas.
|
||||||
|
max_pool_size = 5
|
||||||
|
|
||||||
[webserver]
|
[webserver]
|
||||||
# Configuración del servidor web.
|
# Configuración del servidor web.
|
||||||
bind_address = "localhost"
|
bind_address = "localhost"
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use super::l;
|
||||||
|
|
||||||
pub async fn summary() -> server::Result<Markup> {
|
pub async fn summary() -> server::Result<Markup> {
|
||||||
let top_menu = Menu::prepare()
|
let top_menu = Menu::prepare()
|
||||||
.add(MenuItem::label("Opción 1"))
|
.add(MenuItem::label(l("module_fullname").as_str()))
|
||||||
.add(MenuItem::link("Opción 2", "https://www.google.es"))
|
.add(MenuItem::link("Opción 2", "https://www.google.es"))
|
||||||
.add(MenuItem::link_blank("Opción 3", "https://www.google.es"))
|
.add(MenuItem::link_blank("Opción 3", "https://www.google.es"))
|
||||||
.add(MenuItem::submenu("Submenú 1", Menu::prepare()
|
.add(MenuItem::submenu("Submenú 1", Menu::prepare()
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,16 @@ pub struct Log {
|
||||||
pub format : String,
|
pub format : String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct Database {
|
||||||
|
pub db_name : String,
|
||||||
|
pub db_user : String,
|
||||||
|
pub db_pass : String,
|
||||||
|
pub db_host : String,
|
||||||
|
pub db_port : u16,
|
||||||
|
pub max_pool_size : u32,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Webserver {
|
pub struct Webserver {
|
||||||
pub bind_address : String,
|
pub bind_address : String,
|
||||||
|
|
@ -97,6 +107,7 @@ pub struct Webserver {
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
pub app : App,
|
pub app : App,
|
||||||
pub log : Log,
|
pub log : Log,
|
||||||
|
pub database : Database,
|
||||||
pub webserver : Webserver,
|
pub webserver : Webserver,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,6 +132,14 @@ Ajustes globales y valores predeterminados para las secciones *\[app\]*,
|
||||||
"log.prefix" => "tracing.log",
|
"log.prefix" => "tracing.log",
|
||||||
"log.format" => "json",
|
"log.format" => "json",
|
||||||
|
|
||||||
|
// [database]
|
||||||
|
"database.db_name" => "dbname",
|
||||||
|
"database.db_user" => "dbuser",
|
||||||
|
"database.db_pass" => "dbpass",
|
||||||
|
"database.db_host" => "localhost",
|
||||||
|
"database.db_port" => 0,
|
||||||
|
"database.max_pool_size" => 5,
|
||||||
|
|
||||||
// [webserver]
|
// [webserver]
|
||||||
"webserver.bind_address" => "localhost",
|
"webserver.bind_address" => "localhost",
|
||||||
"webserver.bind_port" => 8088
|
"webserver.bind_port" => 8088
|
||||||
|
|
|
||||||
138
src/core/server/app.rs
Normal file
138
src/core/server/app.rs
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
use crate::{Lazy, base, locale, trace};
|
||||||
|
use crate::config::SETTINGS;
|
||||||
|
use crate::core::{Server, global, server};
|
||||||
|
use crate::core::theme::register_theme;
|
||||||
|
use crate::core::module::register_module;
|
||||||
|
|
||||||
|
use std::io::Error;
|
||||||
|
use actix_web::middleware::normalize::{NormalizePath, TrailingSlash};
|
||||||
|
|
||||||
|
pub struct Application {
|
||||||
|
server: Server,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Application {
|
||||||
|
pub async fn build(bootstrap: Option<fn()>) -> Result<Self, Error> {
|
||||||
|
// Imprime rótulo (opcional) de bienvenida.
|
||||||
|
if SETTINGS.app.startup_banner.to_lowercase() != "off" {
|
||||||
|
let figfont = figlet_rs::FIGfont::from_content(
|
||||||
|
match SETTINGS.app.startup_banner.to_lowercase().as_str() {
|
||||||
|
"slant" => include_str!("figfonts/slant.flf"),
|
||||||
|
"small" => include_str!("figfonts/small.flf"),
|
||||||
|
"speed" => include_str!("figfonts/speed.flf"),
|
||||||
|
"starwars" => include_str!("figfonts/starwars.flf"),
|
||||||
|
_ => {
|
||||||
|
println!(
|
||||||
|
"FIGfont \"{}\" not found for banner. {}. {}.",
|
||||||
|
SETTINGS.app.startup_banner,
|
||||||
|
"Using \"Small\"",
|
||||||
|
"Check the settings file",
|
||||||
|
);
|
||||||
|
include_str!("figfonts/small.flf")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).unwrap();
|
||||||
|
println!("\n{} {}\n\n Powered by PageTop {}\n",
|
||||||
|
figfont.convert(&SETTINGS.app.name).unwrap(),
|
||||||
|
&SETTINGS.app.description,
|
||||||
|
env!("CARGO_PKG_VERSION")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inicia registro de trazas y eventos.
|
||||||
|
Lazy::force(&server::tracing::TRACING);
|
||||||
|
|
||||||
|
// Valida el identificador de idioma.
|
||||||
|
Lazy::force(&locale::LANGID);
|
||||||
|
|
||||||
|
// Inicializa la conexión con la base de datos.
|
||||||
|
trace::info!(
|
||||||
|
"Connecting to database \"{}\" with a pool of {} connections.",
|
||||||
|
&SETTINGS.database.db_name,
|
||||||
|
&SETTINGS.database.max_pool_size
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(any(feature = "default", feature = "mysql"))]
|
||||||
|
let db_uri = format!(
|
||||||
|
"mysql://{}/{}",
|
||||||
|
&SETTINGS.database.db_host,
|
||||||
|
&SETTINGS.database.db_name
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "postgres")]
|
||||||
|
let db_uri = format!(
|
||||||
|
"postgres://{}/{}",
|
||||||
|
&SETTINGS.database.db_host,
|
||||||
|
&SETTINGS.database.db_name
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(feature = "sqlite")]
|
||||||
|
let db_uri = format!("sqlite://{}", &SETTINGS.database.db_name);
|
||||||
|
|
||||||
|
let mut uri = url::Url::parse(&db_uri).unwrap();
|
||||||
|
|
||||||
|
// https://github.com/launchbadge/sqlx/issues/1624
|
||||||
|
|
||||||
|
#[cfg(not(feature = "sqlite"))]
|
||||||
|
uri.set_username(&SETTINGS.database.db_user.as_str()).unwrap();
|
||||||
|
|
||||||
|
#[cfg(not(feature = "sqlite"))]
|
||||||
|
uri.set_password(Some(&SETTINGS.database.db_pass.as_str())).unwrap();
|
||||||
|
|
||||||
|
#[cfg(not(feature = "sqlite"))]
|
||||||
|
if SETTINGS.database.db_port != 0 {
|
||||||
|
uri.set_port(Some(SETTINGS.database.db_port)).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut db_options = sea_orm::ConnectOptions::new(uri.to_string());
|
||||||
|
db_options.max_connections(SETTINGS.database.max_pool_size);
|
||||||
|
|
||||||
|
let mut db_conn = server::dbconn::DBCONN.write().unwrap();
|
||||||
|
*db_conn = Some(
|
||||||
|
sea_orm::Database::connect::<sea_orm::ConnectOptions>(
|
||||||
|
db_options.into()
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("Failed to connect to database")
|
||||||
|
);
|
||||||
|
|
||||||
|
// Registra los temas predefinidos.
|
||||||
|
register_theme(&base::theme::aliner::AlinerTheme);
|
||||||
|
register_theme(&base::theme::minimal::MinimalTheme);
|
||||||
|
register_theme(&base::theme::bootsier::BootsierTheme);
|
||||||
|
|
||||||
|
// Registra los módulos predeterminados.
|
||||||
|
register_module(&base::module::admin::AdminModule);
|
||||||
|
register_module(&base::module::user::UserModule);
|
||||||
|
|
||||||
|
// Ejecuta la función de inicio de la aplicación.
|
||||||
|
if bootstrap != None {
|
||||||
|
trace::debug!("Calling application bootstrap");
|
||||||
|
let _ = &(bootstrap.unwrap())();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Registra el módulo para la página de inicio de PageTop.
|
||||||
|
// Al ser el último, puede sobrecargarse con la función de inicio.
|
||||||
|
register_module(&base::module::homepage::HomepageModule);
|
||||||
|
|
||||||
|
// Prepara el servidor web.
|
||||||
|
let server = server::HttpServer::new(|| {
|
||||||
|
server::App::new()
|
||||||
|
.wrap(tracing_actix_web::TracingLogger)
|
||||||
|
.wrap(NormalizePath::new(TrailingSlash::Trim))
|
||||||
|
.configure(&global::themes)
|
||||||
|
.configure(&global::modules)
|
||||||
|
})
|
||||||
|
.bind(format!("{}:{}",
|
||||||
|
&SETTINGS.webserver.bind_address,
|
||||||
|
&SETTINGS.webserver.bind_port
|
||||||
|
))?
|
||||||
|
.run();
|
||||||
|
|
||||||
|
Ok(Self { server })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(self) -> Result<Server, Error> {
|
||||||
|
Ok(self.server)
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/core/server/dbconn.rs
Normal file
8
src/core/server/dbconn.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
use crate::Lazy;
|
||||||
|
use crate::database::DatabaseConnection;
|
||||||
|
|
||||||
|
use std::sync::RwLock;
|
||||||
|
|
||||||
|
pub static DBCONN: Lazy<RwLock<Option<DatabaseConnection>>> = Lazy::new(|| {
|
||||||
|
RwLock::new(None)
|
||||||
|
});
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
use crate::{Lazy, base, locale, trace};
|
|
||||||
use crate::config::SETTINGS;
|
|
||||||
use crate::core::{Server, global, server};
|
|
||||||
use crate::core::theme::register_theme;
|
|
||||||
use crate::core::module::register_module;
|
|
||||||
|
|
||||||
use actix_web::middleware::normalize;
|
|
||||||
|
|
||||||
pub fn run(bootstrap: Option<fn()>) -> Result<Server, std::io::Error> {
|
|
||||||
// Imprime el rótulo (opcional) de bienvenida.
|
|
||||||
if SETTINGS.app.startup_banner.to_lowercase() != "off" {
|
|
||||||
let figfont = figlet_rs::FIGfont::from_content(
|
|
||||||
match SETTINGS.app.startup_banner.to_lowercase().as_str() {
|
|
||||||
"slant" => include_str!("figfonts/slant.flf"),
|
|
||||||
"small" => include_str!("figfonts/small.flf"),
|
|
||||||
"speed" => include_str!("figfonts/speed.flf"),
|
|
||||||
"starwars" => include_str!("figfonts/starwars.flf"),
|
|
||||||
_ => {
|
|
||||||
println!(
|
|
||||||
"FIGfont \"{}\" not found for banner. {}. {}.",
|
|
||||||
SETTINGS.app.startup_banner,
|
|
||||||
"Using \"Small\"",
|
|
||||||
"Check the settings file",
|
|
||||||
);
|
|
||||||
include_str!("figfonts/small.flf")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
).unwrap();
|
|
||||||
println!("\n{} {}\n\n Powered by PageTop {}\n",
|
|
||||||
figfont.convert(&SETTINGS.app.name).unwrap(),
|
|
||||||
&SETTINGS.app.description,
|
|
||||||
env!("CARGO_PKG_VERSION")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inicia registro de trazas y eventos.
|
|
||||||
Lazy::force(&server::tracing::TRACING);
|
|
||||||
|
|
||||||
// Asigna identificador de idioma.
|
|
||||||
Lazy::force(&locale::LANGID);
|
|
||||||
|
|
||||||
// Registra los temas predefinidos.
|
|
||||||
register_theme(&base::theme::aliner::AlinerTheme);
|
|
||||||
register_theme(&base::theme::minimal::MinimalTheme);
|
|
||||||
register_theme(&base::theme::bootsier::BootsierTheme);
|
|
||||||
|
|
||||||
// Registra los módulos predeterminados.
|
|
||||||
register_module(&base::module::admin::AdminModule);
|
|
||||||
register_module(&base::module::user::UserModule);
|
|
||||||
|
|
||||||
// Ejecuta la función de inicio de la aplicación.
|
|
||||||
if bootstrap != None {
|
|
||||||
trace::debug!("Calling application bootstrap");
|
|
||||||
let _ = &(bootstrap.unwrap())();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Registra el módulo para la página de inicio de PageTop.
|
|
||||||
// Al ser el último, puede sobrecargarse en la función de arranque.
|
|
||||||
register_module(&base::module::homepage::HomepageModule);
|
|
||||||
|
|
||||||
|
|
||||||
// Inicializa el servidor web.
|
|
||||||
let server = server::HttpServer::new(|| {
|
|
||||||
server::App::new()
|
|
||||||
.wrap(tracing_actix_web::TracingLogger)
|
|
||||||
.wrap(normalize::NormalizePath::new(normalize::TrailingSlash::Trim))
|
|
||||||
.configure(&global::themes)
|
|
||||||
.configure(&global::modules)
|
|
||||||
})
|
|
||||||
.bind(format!("{}:{}",
|
|
||||||
&SETTINGS.webserver.bind_address,
|
|
||||||
&SETTINGS.webserver.bind_port
|
|
||||||
))?
|
|
||||||
.run();
|
|
||||||
Ok(server)
|
|
||||||
}
|
|
||||||
|
|
@ -4,5 +4,7 @@ pub use actix_web::{
|
||||||
|
|
||||||
mod tracing;
|
mod tracing;
|
||||||
|
|
||||||
mod main;
|
mod dbconn;
|
||||||
pub use main::run;
|
|
||||||
|
mod app;
|
||||||
|
pub use app::Application;
|
||||||
|
|
|
||||||
1
src/database.rs
Normal file
1
src/database.rs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
pub use sea_orm::DatabaseConnection;
|
||||||
|
|
@ -10,8 +10,11 @@ pub use once_cell::sync::Lazy;
|
||||||
pub mod config; // Gestión de la configuración.
|
pub mod config; // Gestión de la configuración.
|
||||||
pub mod trace; // Registro de trazas y eventos de la aplicación.
|
pub mod trace; // Registro de trazas y eventos de la aplicación.
|
||||||
pub mod locale; // Localización.
|
pub mod locale; // Localización.
|
||||||
|
pub mod database; // Acceso a la base de datos.
|
||||||
pub mod core; // Servidor web y sistemas para Temas, Módulos y Respuestas.
|
pub mod core; // Servidor web y sistemas para Temas, Módulos y Respuestas.
|
||||||
pub mod base; // Temas, Módulos y Componentes base.
|
pub mod base; // Temas, Módulos y Componentes base.
|
||||||
pub mod util; // Macros y funciones útiles.
|
pub mod util; // Macros y funciones útiles.
|
||||||
|
|
||||||
pub mod prelude; // Re-exporta recursos comunes.
|
pub mod prelude; // Re-exporta recursos comunes.
|
||||||
|
|
||||||
|
pub use crate::core::server::Application;
|
||||||
|
|
|
||||||
|
|
@ -44,12 +44,12 @@ macro_rules! localize {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn l(key: &str) -> String {
|
fn l(key: &str) -> String {
|
||||||
LOCALES.lookup(&LANGID, key)
|
LOCALES.lookup(&LANGID, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn t(
|
fn t(
|
||||||
key: &str,
|
key: &str,
|
||||||
args: &std::collections::HashMap<String, FluentValue>
|
args: &std::collections::HashMap<String, FluentValue>
|
||||||
) -> String {
|
) -> String {
|
||||||
|
|
@ -57,7 +57,7 @@ macro_rules! localize {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn e(
|
fn e(
|
||||||
key: &str,
|
key: &str,
|
||||||
args: &std::collections::HashMap<String, FluentValue>
|
args: &std::collections::HashMap<String, FluentValue>
|
||||||
) -> crate::core::theme::PreEscaped<String> {
|
) -> crate::core::theme::PreEscaped<String> {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
pagetop::core::server::run(None)?.await
|
// ```
|
||||||
|
// let app = pagetop::Application::build(None).await?;
|
||||||
|
// app.run()?.await
|
||||||
|
// ```
|
||||||
|
pagetop::Application::build(None).await?.run()?.await
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ pub use crate::util;
|
||||||
pub use crate::config::SETTINGS;
|
pub use crate::config::SETTINGS;
|
||||||
pub use crate::trace;
|
pub use crate::trace;
|
||||||
pub use crate::localize;
|
pub use crate::localize;
|
||||||
|
pub use crate::database;
|
||||||
|
|
||||||
pub use crate::core::theme::*;
|
pub use crate::core::theme::*;
|
||||||
pub use crate::core::module::*;
|
pub use crate::core::module::*;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue