move function out of lib

This commit is contained in:
Manuel Gugger 2022-04-25 21:00:42 +02:00
parent 657ad8ffc9
commit 7648c4bced
4 changed files with 90 additions and 66 deletions

View File

@ -1,16 +1,16 @@
use actix_web::{error, guard, web, Error, HttpRequest, HttpResponse};
use actix_web::{ dev, App, FromRequest};
use actix_web::error::ErrorBadRequest;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use tera::{Context, Tera};
use futures::future::{ok, err, Ready};
use actix_web::{dev, App, FromRequest};
use actix_web::{error, guard, web, Error, HttpRequest, HttpResponse};
use futures::future::{err, ok, Ready};
use lazy_static::lazy_static;
use sea_orm::DatabaseConnection;
use sea_orm::EntityTrait;
use sea_orm::ModelTrait;
use std::pin::Pin;
use serde::{Deserialize, Serialize};
use std::any::Any;
use std::collections::HashMap;
use std::pin::Pin;
use tera::{Context, Tera};
use async_trait::async_trait;
@ -20,7 +20,8 @@ const DEFAULT_POSTS_PER_PAGE: usize = 5;
// templates
lazy_static! {
static ref TERA: Tera = Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
static ref TERA: Tera =
Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
}
// Paging
@ -33,19 +34,18 @@ pub struct Params {
// Fields
#[derive(Clone, Debug, Serialize)]
pub enum Field {
Text
Text,
}
// AppDataTrait
pub trait AppDataTrait {
fn get_db(&self) -> &DatabaseConnection;
fn get_view_model_map(&self) -> &HashMap<&'static str, ActixAdminViewModel>;
}
// ActixAdminModel
#[async_trait]
pub trait ActixAdminModelTrait : Clone {
async fn list(&self, db: &DatabaseConnection, page: usize, posts_per_page: usize) -> Vec<&str>;
pub trait ActixAdminModelTrait: Clone {
async fn list(db: &DatabaseConnection, page: usize, posts_per_page: usize) -> Vec<&str>;
}
#[derive(Clone, Debug, Serialize)]
@ -54,68 +54,47 @@ pub struct ActixAdminModel {
}
// ActixAdminViewModel
pub trait ActixAdminViewModelTrait : Clone {
pub trait ActixAdminViewModelTrait: Clone {
fn get_model_name(&self) -> &str;
}
#[derive(Clone, Debug, Serialize)]
pub struct ActixAdminViewModel {
pub entity_name: &'static str,
pub admin_model: ActixAdminModel
pub entity_name: String
}
// ActixAdminController
#[derive(Clone, Debug)]
pub struct ActixAdmin {
view_models: HashMap<&'static str, ActixAdminViewModel>,
}
impl ActixAdmin {
pub fn new() -> Self {
let actix_admin = ActixAdmin {
view_models: HashMap::new(),
};
actix_admin
}
pub fn create_scope<T: AppDataTrait + 'static>(self, _app_state: &T) -> actix_web::Scope {
let mut scope = web::scope("/admin").route("/", web::get().to(index::<T>));
for view_model in self.view_models {
scope = scope.service(
web::scope(&format!("/{}", view_model.0)).route("/list", web::get().to(list::<T>))
);
}
let scope = web::scope("/admin").route("/", web::get().to(index::<T>));
scope
}
pub fn add_entity(mut self, view_model: ActixAdminViewModel) -> Self {
self.view_models.insert(view_model.entity_name, view_model);
self
}
pub fn get_view_model_map(&self) -> HashMap<&'static str, ActixAdminViewModel> {
self.view_models.clone()
}
}
async fn index<T: AppDataTrait>(data: web::Data<T>) -> Result<HttpResponse, Error> {
let view_models = Vec::from_iter(data.get_view_model_map().values());
let view_models: Vec<&str> = Vec::new();
let mut ctx = Context::new();
ctx.insert("view_models", &view_models);
let body = TERA
.render("index.html", &ctx)
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
.render("index.html", &ctx)
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
Ok(HttpResponse::Ok().content_type("text/html").body(body))
}
async fn list<T: AppDataTrait>(req: HttpRequest, data: web::Data<T>) -> Result<HttpResponse, Error> {
let view_model = data.get_view_model_map().get("posts").unwrap();
let db = &data.get_db();
pub fn list_model(req: HttpRequest, view_model: ActixAdminViewModel) -> Result<HttpResponse, Error> {
let params = web::Query::<Params>::from_query(req.query_string()).unwrap();
let page = params.page.unwrap_or(1);
@ -133,7 +112,7 @@ async fn list<T: AppDataTrait>(req: HttpRequest, data: web::Data<T>) -> Result<H
ctx.insert("columns", &columns);
let body = TERA
.render("list.html", &ctx)
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
.render("list.html", &ctx)
.map_err(|_| error::ErrorInternalServerError("Template error"))?;
Ok(HttpResponse::Ok().content_type("text/html").body(body))
}

47
src/entity/comment.rs Normal file
View File

@ -0,0 +1,47 @@
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
use actix_admin::{ DeriveActixAdminModel };
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize, DeriveActixAdminModel)]
#[sea_orm(table_name = "comment")]
pub struct Model {
#[sea_orm(primary_key)]
#[serde(skip_deserializing)]
pub id: i32,
pub title: String,
#[sea_orm(column_type = "Text")]
pub text: String,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}
impl From<Entity> for ActixAdminModel {
fn from(entity: Entity) -> Self {
ActixAdminModel {
fields: Vec::new()
}
}
}
#[async_trait]
impl ActixAdminModelTrait for Entity {
async fn list(&self, db: &DatabaseConnection, page: usize, posts_per_page: usize) -> Vec<&str> {
use sea_orm::{ query::* };
let paginator = Entity::find()
.order_by_asc(Column::Id)
.paginate(db, posts_per_page);
let entities = paginator
.fetch_page(page - 1)
.await
.expect("could not retrieve entities");
//entities to ActixAdminModel
vec![
]
}
}

View File

@ -1,7 +1,7 @@
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
use actix_admin::{ DeriveActixAdminModel };
use actix_admin::{ DeriveActixAdminModel, ActixAdminViewModel };
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Deserialize, Serialize, DeriveActixAdminModel)]
#[sea_orm(table_name = "post")]
@ -19,18 +19,17 @@ pub enum Relation {}
impl ActiveModelBehavior for ActiveModel {}
impl From<Entity> for ActixAdminModel {
impl From<Entity> for ActixAdminViewModel {
fn from(entity: Entity) -> Self {
ActixAdminModel {
fields: Vec::new()
ActixAdminViewModel {
entity_name: entity.table_name().to_string()
}
}
}
#[async_trait]
impl ActixAdminModelTrait for Entity {
async fn list(&self, db: &DatabaseConnection, page: usize, posts_per_page: usize) -> Vec<&str> {
async fn list(db: &DatabaseConnection, page: usize, posts_per_page: usize) -> Vec<&str> {
use sea_orm::{ query::* };
let paginator = Entity::find()
.order_by_asc(Column::Id)

View File

@ -1,16 +1,15 @@
extern crate serde_derive;
use actix_session::{Session, CookieSession};
use actix_web::{web, App, HttpResponse, HttpServer};
use actix_web::{web, App, HttpResponse, HttpServer, HttpRequest, Error};
use tera::{ Tera, Context};
use oauth2::basic::BasicClient;
use oauth2::{ RedirectUrl };
use std::time::{Duration};
use std::env;
use std::collections::HashMap;
use sea_orm::{{ DatabaseConnection, ConnectOptions }};
use actix_admin::{ AppDataTrait as ActixAdminAppDataTrait, ActixAdminViewModel, ActixAdminModel};
use actix_admin::{ AppDataTrait as ActixAdminAppDataTrait, ActixAdminViewModel, ActixAdminModelTrait};
use azure_auth::{ AzureAuth, UserInfo, AppDataTrait as AzureAuthAppDataTrait };
mod entity;
@ -21,17 +20,12 @@ pub struct AppState {
pub oauth: BasicClient,
pub tmpl: Tera,
pub db: DatabaseConnection,
pub view_model_map: HashMap<&'static str, ActixAdminViewModel>
}
impl ActixAdminAppDataTrait for AppState {
fn get_db(&self) -> &DatabaseConnection {
&self.db
}
fn get_view_model_map(&self) -> &HashMap<&'static str, ActixAdminViewModel> {
&self.view_model_map
}
}
impl AzureAuthAppDataTrait for AppState {
@ -82,19 +76,10 @@ async fn main() {
let conn = sea_orm::Database::connect(opt).await.unwrap();
let _ = entity::create_post_table(&conn).await;
let viewmodel_entity = ActixAdminViewModel {
entity_name: "posts",
admin_model: ActixAdminModel::from(Post)
};
let actix_admin = actix_admin::ActixAdmin::new()
.add_entity(viewmodel_entity.clone());
let app_state = AppState {
oauth: client,
tmpl: tera,
db: conn,
view_model_map: actix_admin.get_view_model_map()
};
HttpServer::new(move || {
@ -102,12 +87,26 @@ async fn main() {
.app_data(web::Data::new(app_state.clone()))
.wrap(CookieSession::signed(&[0; 32]).secure(false))
.route("/", web::get().to(index))
.service(actix_admin.clone().create_scope(&app_state))
.service(azure_auth.clone().create_scope(&app_state))
.service(
actix_admin::ActixAdmin::new()
.create_scope(&app_state)
.service(
web::scope(&format!("/{}", "posts")).route("/list", web::get().to(list)),
)
)
})
.bind("127.0.0.1:5000")
.expect("Can not bind to port 5000")
.run()
.await
.unwrap();
}
// Actix admin Routes to be auto generated
async fn list(req: HttpRequest, data: web::Data<AppState>)-> Result<HttpResponse, Error> {
let db = &data.get_db();
let entities = Post::list(db, 1, 5);
let model = ActixAdminViewModel::from(Post);
actix_admin::list_model(req, model)
}