Actualiza y afina las dependencias de paquetes
También normaliza los "traits" para definir temas y módulos usando el mismo criterio visto en SeaORM.
This commit is contained in:
parent
1102a76e47
commit
2167ab9417
26 changed files with 100 additions and 100 deletions
|
|
@ -1,4 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
pagetop::Application::build(None).await?.run()?.await
|
||||
Application::prepare(essence).await?.run()?.await
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,16 +27,16 @@ categories = [
|
|||
doc-comment = "0.3.3"
|
||||
downcast-rs = "1.2.0"
|
||||
figlet-rs = "0.1.3"
|
||||
futures = "0.3"
|
||||
once_cell = "1.9.0"
|
||||
futures = "0.3.21"
|
||||
once_cell = "1.10.0"
|
||||
url = "2.2.2"
|
||||
|
||||
config_rs = { package = "config", version = "0.11.0", features = ["toml"] }
|
||||
|
||||
tracing = "0.1"
|
||||
tracing-appender = "0.2"
|
||||
tracing-subscriber = { version = "0.3", features = ["json", "env-filter"] }
|
||||
tracing-unwrap = { version = "0.9", default-features = false }
|
||||
tracing = "0.1.32"
|
||||
tracing-appender = "0.2.1"
|
||||
tracing-subscriber = { version = "0.3.9", features = ["json", "env-filter"] }
|
||||
tracing-unwrap = { version = "0.9.2", default-features = false }
|
||||
tracing-actix-web = "0.2"
|
||||
|
||||
fluent-templates = "0.6.1"
|
||||
|
|
@ -51,17 +51,20 @@ sycamore = { version = "0.7.1", features = ["ssr"] }
|
|||
serde = { version = "1.0", features = ["derive"] }
|
||||
|
||||
[dependencies.sea-orm]
|
||||
version = "0.6"
|
||||
version = "0.6.0"
|
||||
features = ["debug-print", "macros", "runtime-async-std-native-tls"]
|
||||
default-features = false
|
||||
optional = true
|
||||
|
||||
[dependencies.sea-schema]
|
||||
version = "0.5"
|
||||
version = "0.6.0"
|
||||
features = ["debug-print", "migration"]
|
||||
default-features = false
|
||||
optional = true
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1.17.0", features = ["macros", "rt-multi-thread"] }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
mysql = ["sea-orm", "sea-schema", "sea-orm/sqlx-mysql"]
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ mod summary;
|
|||
|
||||
pub struct AdminModule;
|
||||
|
||||
impl Module for AdminModule {
|
||||
impl ModuleTrait for AdminModule {
|
||||
fn name(&self) -> &'static str {
|
||||
"admin"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ localize!("en-US", "src/base/module/homepage/locales");
|
|||
|
||||
pub struct HomepageModule;
|
||||
|
||||
impl Module for HomepageModule {
|
||||
impl ModuleTrait for HomepageModule {
|
||||
fn name(&self) -> &'static str {
|
||||
"homepage"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ mod migration;
|
|||
|
||||
pub struct UserModule;
|
||||
|
||||
impl Module for UserModule {
|
||||
impl ModuleTrait for UserModule {
|
||||
fn name(&self) -> &'static str {
|
||||
"user"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ include!(concat!(env!("OUT_DIR"), "/aliner.rs"));
|
|||
|
||||
pub struct AlinerTheme;
|
||||
|
||||
impl Theme for AlinerTheme {
|
||||
impl ThemeTrait for AlinerTheme {
|
||||
fn name(&self) -> &'static str {
|
||||
"aliner"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ localize!("en-US", "src/base/theme/bootsier/locales");
|
|||
|
||||
pub struct BootsierTheme;
|
||||
|
||||
impl Theme for BootsierTheme {
|
||||
impl ThemeTrait for BootsierTheme {
|
||||
fn name(&self) -> &'static str {
|
||||
"bootsier"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use crate::prelude::*;
|
|||
|
||||
pub struct MinimalTheme;
|
||||
|
||||
impl Theme for MinimalTheme {
|
||||
impl ThemeTrait for MinimalTheme {
|
||||
fn name(&self) -> &'static str {
|
||||
"minimal"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,19 @@
|
|||
use crate::{Lazy, trace};
|
||||
use crate::core::theme::Theme;
|
||||
use crate::core::module::Module;
|
||||
use crate::core::response::page::PageContainer;
|
||||
use crate::core::theme::ThemeTrait;
|
||||
use crate::core::module::ModuleTrait;
|
||||
use crate::core::server;
|
||||
|
||||
use std::sync::RwLock;
|
||||
use std::collections::HashMap;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/theme.rs"));
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Temas registrados y tema por defecto.
|
||||
// Temas registrados y tema predeterminado.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
pub static THEMES: Lazy<RwLock<Vec<&dyn Theme>>> = Lazy::new(|| {
|
||||
RwLock::new(Vec::new())
|
||||
});
|
||||
pub static THEMES: Lazy<RwLock<Vec<&dyn ThemeTrait>>> = Lazy::new(
|
||||
|| { RwLock::new(Vec::new()) }
|
||||
);
|
||||
|
||||
pub fn themes(cfg: &mut server::web::ServiceConfig) {
|
||||
cfg.service(actix_web_static_files::ResourceFiles::new(
|
||||
|
|
@ -32,9 +30,9 @@ pub fn themes(cfg: &mut server::web::ServiceConfig) {
|
|||
// Módulos registrados.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
pub static MODULES: Lazy<RwLock<Vec<&dyn Module>>> = Lazy::new(|| {
|
||||
RwLock::new(Vec::new())
|
||||
});
|
||||
pub static MODULES: Lazy<RwLock<Vec<&dyn ModuleTrait>>> = Lazy::new(
|
||||
|| { RwLock::new(Vec::new()) }
|
||||
);
|
||||
|
||||
pub fn modules(cfg: &mut server::web::ServiceConfig) {
|
||||
for m in MODULES.read().unwrap().iter() {
|
||||
|
|
@ -43,19 +41,9 @@ pub fn modules(cfg: &mut server::web::ServiceConfig) {
|
|||
}
|
||||
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
pub fn run_migrations() {
|
||||
trace::info!("Checking migrations.");
|
||||
pub fn migrations() {
|
||||
trace::info!("Checking migrations");
|
||||
for m in MODULES.read().unwrap().iter() {
|
||||
m.migrations(
|
||||
&*server::db::DBCONN.read().unwrap()
|
||||
).expect("Failed to run migrations");
|
||||
m.migrations(&*server::db::DBCONN).expect("Failed to run migrations");
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Componentes globales.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
pub static COMPONENTS: Lazy<RwLock<HashMap<&str, PageContainer>>> = Lazy::new(
|
||||
|| { RwLock::new(HashMap::new()) }
|
||||
);
|
||||
1
pagetop/src/core/html.rs
Normal file
1
pagetop/src/core/html.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub use maud::{DOCTYPE, Markup, PreEscaped, html};
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
pub use actix_web::dev::Server;
|
||||
|
||||
mod global;
|
||||
mod all;
|
||||
|
||||
pub mod html;
|
||||
pub mod theme;
|
||||
pub mod module;
|
||||
pub mod response;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use crate::core::server;
|
|||
use crate::db;
|
||||
|
||||
/// Los módulos deben implementar este *trait*.
|
||||
pub trait Module: Send + Sync {
|
||||
pub trait ModuleTrait: Send + Sync {
|
||||
fn name(&self) -> &'static str;
|
||||
|
||||
fn fullname(&self) -> String;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
use crate::core::global;
|
||||
use crate::core::all;
|
||||
|
||||
mod definition;
|
||||
pub use definition::Module;
|
||||
pub use definition::ModuleTrait;
|
||||
|
||||
pub fn register_module(m: &'static (dyn Module + 'static)) {
|
||||
global::MODULES.write().unwrap().push(m);
|
||||
pub fn register_module(m: &'static (dyn ModuleTrait + 'static)) {
|
||||
all::MODULES.write().unwrap().push(m);
|
||||
}
|
||||
|
||||
pub fn find_module(name: &str) -> Option<&'static (dyn Module + 'static)> {
|
||||
let modules = global::MODULES.write().unwrap();
|
||||
pub fn find_module(name: &str) -> Option<&'static (dyn ModuleTrait + 'static)> {
|
||||
let modules = all::MODULES.write().unwrap();
|
||||
match modules.iter().find(|t| t.name() == name) {
|
||||
Some(module) => Some(*module),
|
||||
_ => None,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use crate::{Lazy, base};
|
||||
use crate::config::SETTINGS;
|
||||
use crate::core::global;
|
||||
use crate::core::theme::{Markup, PreEscaped, Theme, find_theme, html};
|
||||
use crate::core::all;
|
||||
use crate::core::html::{Markup, PreEscaped, html};
|
||||
use crate::core::theme::*;
|
||||
|
||||
static DEFAULT_THEME: Lazy<&dyn Theme> = Lazy::new(|| {
|
||||
for t in global::THEMES.read().unwrap().iter() {
|
||||
static DEFAULT_THEME: Lazy<&dyn ThemeTrait> = Lazy::new(|| {
|
||||
for t in all::THEMES.read().unwrap().iter() {
|
||||
if t.name().to_lowercase() == SETTINGS.app.theme.to_lowercase() {
|
||||
return *t;
|
||||
}
|
||||
|
|
@ -184,7 +185,7 @@ impl JavaScript {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
pub struct PageAssets {
|
||||
theme : &'static dyn Theme,
|
||||
theme : &'static dyn ThemeTrait,
|
||||
favicon : Option<Favicon>,
|
||||
metadata : Vec<(String, String)>,
|
||||
stylesheets: Vec<StyleSheet>,
|
||||
|
|
@ -259,7 +260,7 @@ impl PageAssets {
|
|||
|
||||
/// Assets GETTERS.
|
||||
|
||||
pub fn theme(&mut self) -> &'static dyn Theme {
|
||||
pub fn theme(&mut self) -> &'static dyn ThemeTrait {
|
||||
self.theme
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::core::theme::{Markup, html};
|
||||
use crate::core::html::{Markup, html};
|
||||
use crate::core::response::page::PageAssets;
|
||||
|
||||
use downcast_rs::{Downcast, impl_downcast};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::core::theme::{Markup, html};
|
||||
use crate::core::html::{Markup, html};
|
||||
use crate::core::response::page::{PageAssets, PageComponent, render_component};
|
||||
|
||||
use std::sync::Arc;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
use crate::{Lazy, trace, util};
|
||||
use crate::config::SETTINGS;
|
||||
use crate::core::{global, server};
|
||||
use crate::core::theme::{DOCTYPE, Markup, html};
|
||||
use crate::core::html::{DOCTYPE, Markup, html};
|
||||
use crate::core::response::page::{PageAssets, PageComponent, PageContainer};
|
||||
use crate::core::server;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::sync::RwLock;
|
||||
use std::collections::HashMap;
|
||||
|
||||
static COMPONENTS: Lazy<RwLock<HashMap<&str, PageContainer>>> = Lazy::new(|| {
|
||||
RwLock::new(HashMap::new())
|
||||
});
|
||||
|
||||
static DEFAULT_LANGUAGE: Lazy<Option<String>> = Lazy::new(|| {
|
||||
let language = SETTINGS.app.language[..2].to_lowercase();
|
||||
if !language.is_empty() {
|
||||
|
|
@ -25,9 +30,9 @@ static DEFAULT_DIRECTION: Lazy<Option<String>> = Lazy::new(|| {
|
|||
"" => None,
|
||||
_ => {
|
||||
trace::warn!(
|
||||
"Text direction \"{}\" not valid. {}.",
|
||||
"Text direction \"{}\" not valid, {}",
|
||||
SETTINGS.app.direction,
|
||||
"Check the settings file"
|
||||
"check the settings file"
|
||||
);
|
||||
None
|
||||
}
|
||||
|
|
@ -63,7 +68,7 @@ impl<'a> Page<'a> {
|
|||
description : None,
|
||||
body_classes: "body".into(),
|
||||
assets : PageAssets::new(),
|
||||
regions : global::COMPONENTS.read().unwrap().clone(),
|
||||
regions : COMPONENTS.read().unwrap().clone(),
|
||||
template : "default".to_owned(),
|
||||
}
|
||||
}
|
||||
|
|
@ -208,7 +213,7 @@ pub fn render_component(
|
|||
}
|
||||
|
||||
pub fn add_component_to(region: &'static str, component: impl PageComponent) {
|
||||
let mut hmap = global::COMPONENTS.write().unwrap();
|
||||
let mut hmap = COMPONENTS.write().unwrap();
|
||||
if let Some(regions) = hmap.get_mut(region) {
|
||||
regions.add(component);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{Lazy, base, trace};
|
||||
use crate::config::SETTINGS;
|
||||
use crate::core::{Server, global, server};
|
||||
use crate::core::{Server, all, server};
|
||||
use crate::core::theme::register_theme;
|
||||
use crate::core::module::register_module;
|
||||
|
||||
|
|
@ -11,8 +11,12 @@ pub struct Application {
|
|||
server: Server,
|
||||
}
|
||||
|
||||
pub fn essence() {
|
||||
trace::info!("No bootstrap configured");
|
||||
}
|
||||
|
||||
impl Application {
|
||||
pub async fn build(bootstrap: Option<fn()>) -> Result<Self, Error> {
|
||||
pub async fn prepare(bootstrap: fn()) -> Result<Self, Error> {
|
||||
// Imprime un rótulo de presentación (opcional).
|
||||
if SETTINGS.app.startup_banner.to_lowercase() != "off" {
|
||||
let figfont = figlet_rs::FIGfont::from_content(
|
||||
|
|
@ -61,10 +65,8 @@ impl Application {
|
|||
register_module(&base::module::user::UserModule);
|
||||
|
||||
// Ejecuta la función de inicio de la aplicación.
|
||||
if bootstrap != None {
|
||||
trace::info!("Calling application bootstrap.");
|
||||
let _ = &(bootstrap.unwrap())();
|
||||
}
|
||||
trace::info!("Calling application bootstrap");
|
||||
let _ = &bootstrap();
|
||||
|
||||
// Registra el módulo para la página de inicio de PageTop.
|
||||
// Al ser el último, puede sobrecargarse con la función de inicio.
|
||||
|
|
@ -72,15 +74,15 @@ impl Application {
|
|||
|
||||
// Comprueba actualizaciones pendientes de la base de datos (opcional).
|
||||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
global::run_migrations();
|
||||
all::migrations();
|
||||
|
||||
// Prepara el servidor web.
|
||||
let server = server::HttpServer::new(move || {
|
||||
server::App::new()
|
||||
.wrap(tracing_actix_web::TracingLogger)
|
||||
.wrap(NormalizePath::new(TrailingSlash::Trim))
|
||||
.configure(&global::themes)
|
||||
.configure(&global::modules)
|
||||
.configure(&all::themes)
|
||||
.configure(&all::modules)
|
||||
})
|
||||
.bind(format!("{}:{}",
|
||||
&SETTINGS.webserver.bind_address,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
use crate::{Lazy, db, run_now, trace};
|
||||
use crate::config::SETTINGS;
|
||||
|
||||
use std::sync::RwLock;
|
||||
use sea_orm::{ConnectOptions, Database};
|
||||
use tracing_unwrap::ResultExt;
|
||||
|
||||
pub static DBCONN: Lazy<RwLock<db::DbConn>> = Lazy::new(|| {
|
||||
pub static DBCONN: Lazy<db::DbConn> = Lazy::new(|| {
|
||||
trace::info!(
|
||||
"Connecting to database \"{}\" using a pool of {} connections.",
|
||||
"Connecting to database \"{}\" using a pool of {} connections",
|
||||
&SETTINGS.database.db_name,
|
||||
&SETTINGS.database.max_pool_size
|
||||
);
|
||||
|
|
@ -41,20 +40,18 @@ pub static DBCONN: Lazy<RwLock<db::DbConn>> = Lazy::new(|| {
|
|||
).as_str()).unwrap(),
|
||||
_ => {
|
||||
trace::error!(
|
||||
"Unrecognized database type \"{}\".",
|
||||
"Unrecognized database type \"{}\"",
|
||||
&SETTINGS.database.db_type
|
||||
);
|
||||
db::DbUri::parse("").unwrap()
|
||||
}
|
||||
};
|
||||
|
||||
let db_conn = run_now(
|
||||
run_now(
|
||||
Database::connect::<ConnectOptions>({
|
||||
let mut db_opt = ConnectOptions::new(db_uri.to_string());
|
||||
db_opt.max_connections(SETTINGS.database.max_pool_size);
|
||||
db_opt.into()
|
||||
})
|
||||
).expect_or_log("Failed to connect to database");
|
||||
|
||||
RwLock::new(db_conn)
|
||||
).expect_or_log("Failed to connect to database")
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,11 +11,12 @@ pub static LANGID: Lazy<LanguageIdentifier> = Lazy::new(|| {
|
|||
Ok(language) => language,
|
||||
Err(_) => {
|
||||
trace::warn!(
|
||||
"Failed to parse language \"{}\". {}. {}. {}.",
|
||||
"{}, {} \"{}\"! {}, {}",
|
||||
"Failed to parse language",
|
||||
"unrecognized Unicode Language Identifier",
|
||||
SETTINGS.app.language,
|
||||
"Unrecognized Unicode Language Identifier",
|
||||
"Using \"en-US\"",
|
||||
"Check the settings file",
|
||||
"check the settings file",
|
||||
);
|
||||
"en-US".parse().unwrap()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
use crate::config::SETTINGS;
|
||||
use crate::core::server;
|
||||
use crate::core::theme::{Markup, html};
|
||||
use crate::core::html::{Markup, html};
|
||||
use crate::core::response::page::{Page, PageAssets, PageComponent};
|
||||
use crate::core::server;
|
||||
use crate::base::component::Chunck;
|
||||
|
||||
/// Los temas deben implementar este "trait".
|
||||
pub trait Theme: Send + Sync {
|
||||
pub trait ThemeTrait: Send + Sync {
|
||||
fn name(&self) -> &'static str;
|
||||
|
||||
fn fullname(&self) -> String;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,14 @@
|
|||
use crate::core::global;
|
||||
|
||||
pub use maud::{DOCTYPE, Markup, PreEscaped, html};
|
||||
use crate::core::all;
|
||||
|
||||
mod definition;
|
||||
pub use definition::Theme;
|
||||
pub use definition::ThemeTrait;
|
||||
|
||||
pub fn register_theme(t: &'static (dyn Theme + 'static)) {
|
||||
global::THEMES.write().unwrap().push(t);
|
||||
pub fn register_theme(t: &'static (dyn ThemeTrait + 'static)) {
|
||||
all::THEMES.write().unwrap().push(t);
|
||||
}
|
||||
|
||||
pub fn find_theme(name: &str) -> Option<&'static (dyn Theme + 'static)> {
|
||||
let themes = global::THEMES.write().unwrap();
|
||||
pub fn find_theme(name: &str) -> Option<&'static (dyn ThemeTrait + 'static)> {
|
||||
let themes = all::THEMES.write().unwrap();
|
||||
match themes.iter().find(|t| t.name() == name) {
|
||||
Some(theme) => Some(*theme),
|
||||
_ => None,
|
||||
|
|
|
|||
|
|
@ -20,5 +20,3 @@ pub mod base; // Temas, Módulos y Componentes base.
|
|||
pub mod util; // Macros y funciones útiles.
|
||||
|
||||
pub mod prelude; // Re-exporta recursos comunes.
|
||||
|
||||
pub use crate::core::server::app::Application;
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ macro_rules! localize {
|
|||
fn e(
|
||||
key: &str,
|
||||
args: &std::collections::HashMap<String, FluentValue>
|
||||
) -> crate::core::theme::PreEscaped<String> {
|
||||
crate::core::theme::PreEscaped(
|
||||
) -> crate::core::html::PreEscaped<String> {
|
||||
crate::core::html::PreEscaped(
|
||||
LOCALES.lookup_with_args(&LANGID, key, args)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@ pub use crate::localize;
|
|||
#[cfg(any(feature = "mysql", feature = "postgres", feature = "sqlite"))]
|
||||
pub use crate::{db, db_migrations};
|
||||
|
||||
pub use crate::core::html::*;
|
||||
pub use crate::core::theme::*;
|
||||
pub use crate::core::module::*;
|
||||
pub use crate::core::response::page::*;
|
||||
pub use crate::core::server;
|
||||
pub use crate::core::server::app::{Application, essence};
|
||||
|
||||
pub use crate::base::component::*;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use pagetop::core::server;
|
||||
|
||||
fn spawn_app() {
|
||||
let server = server::run(None).expect("Failed to bind address");
|
||||
async fn spawn_app() {
|
||||
let server = pagetop::Application::prepare(None)
|
||||
.await?
|
||||
.run()?
|
||||
.expect("Failed to prepare server");
|
||||
let _ = tokio::spawn(server);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue