mirror of
https://github.com/flibusta-apps/users_settings_server.git
synced 2025-12-06 06:35:39 +01:00
Add pre-commit config
This commit is contained in:
7
.pre-commit-config.yaml
Normal file
7
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
repos:
|
||||
- repo: https://github.com/doublify/pre-commit-rust
|
||||
rev: v1.0
|
||||
hooks:
|
||||
- id: fmt
|
||||
- id: cargo-check
|
||||
- id: clippy
|
||||
@@ -9,15 +9,13 @@ pub struct Config {
|
||||
pub postgres_port: u32,
|
||||
pub postgres_db: String,
|
||||
|
||||
pub sentry_dsn: String
|
||||
pub sentry_dsn: String,
|
||||
}
|
||||
|
||||
|
||||
fn get_env(env: &'static str) -> String {
|
||||
std::env::var(env).unwrap_or_else(|_| panic!("Cannot get the {} env variable", env))
|
||||
}
|
||||
|
||||
|
||||
impl Config {
|
||||
pub fn load() -> Config {
|
||||
Config {
|
||||
@@ -29,12 +27,9 @@ impl Config {
|
||||
postgres_port: get_env("POSTGRES_PORT").parse().unwrap(),
|
||||
postgres_db: get_env("POSTGRES_DB"),
|
||||
|
||||
sentry_dsn: get_env("SENTRY_DSN")
|
||||
sentry_dsn: get_env("SENTRY_DSN"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub static CONFIG: Lazy<Config> = Lazy::new(|| {
|
||||
Config::load()
|
||||
});
|
||||
pub static CONFIG: Lazy<Config> = Lazy::new(Config::load);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::{prisma::PrismaClient, config::CONFIG};
|
||||
|
||||
use crate::{config::CONFIG, prisma::PrismaClient};
|
||||
|
||||
pub async fn get_prisma_client() -> PrismaClient {
|
||||
let database_url: String = format!(
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
pub mod config;
|
||||
pub mod db;
|
||||
pub mod prisma;
|
||||
pub mod views;
|
||||
pub mod db;
|
||||
|
||||
use sentry::{ClientOptions, types::Dsn, integrations::debug_images::DebugImagesIntegration};
|
||||
use sentry::{integrations::debug_images::DebugImagesIntegration, types::Dsn, ClientOptions};
|
||||
use tracing::info;
|
||||
|
||||
use std::{net::SocketAddr, str::FromStr};
|
||||
|
||||
|
||||
async fn start_app() {
|
||||
let app = views::get_router().await;
|
||||
|
||||
|
||||
101
src/prisma.rs
101
src/prisma.rs
@@ -1,7 +1,8 @@
|
||||
// Code generated by Prisma Client Rust. DO NOT EDIT
|
||||
|
||||
pub static DATAMODEL_STR: &str =
|
||||
include_str!("../prisma/schema.prisma");
|
||||
#![allow(clippy::all)]
|
||||
|
||||
pub static DATAMODEL_STR: &str = include_str!("../prisma/schema.prisma");
|
||||
static DATABASE_STR: &str = "postgresql";
|
||||
pub async fn new_client() -> Result<PrismaClient, ::prisma_client_rust::NewClientError> {
|
||||
PrismaClient::_builder().build().await
|
||||
@@ -21,9 +22,7 @@ pub mod user_settings {
|
||||
pub mod id {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
|
||||
pub const NAME: &str = "id";
|
||||
pub struct Set(pub i32);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -92,9 +91,7 @@ pub mod user_settings {
|
||||
pub mod user_id {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
|
||||
pub const NAME: &str = "user_id";
|
||||
pub struct Set(pub i64);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -167,9 +164,7 @@ pub mod user_settings {
|
||||
pub mod last_name {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
|
||||
pub const NAME: &str = "last_name";
|
||||
pub struct Set(pub String);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -234,9 +229,7 @@ pub mod user_settings {
|
||||
pub mod first_name {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
|
||||
pub const NAME: &str = "first_name";
|
||||
pub struct Set(pub String);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -301,9 +294,7 @@ pub mod user_settings {
|
||||
pub mod username {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
|
||||
pub const NAME: &str = "username";
|
||||
pub struct Set(pub String);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -368,9 +359,7 @@ pub mod user_settings {
|
||||
pub mod source {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
|
||||
pub const NAME: &str = "source";
|
||||
pub struct Set(pub String);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -435,9 +424,7 @@ pub mod user_settings {
|
||||
pub mod user_activity {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
SetParam, WhereParam, WithParam,
|
||||
};
|
||||
use super::{SetParam, WhereParam, WithParam};
|
||||
pub const NAME: &str = "user_activity";
|
||||
pub struct Fetch(pub user_activity::UniqueArgs);
|
||||
impl Fetch {
|
||||
@@ -523,9 +510,7 @@ pub mod user_settings {
|
||||
pub mod languages {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
SetParam, WhereParam, WithParam,
|
||||
};
|
||||
use super::{SetParam, WhereParam, WithParam};
|
||||
pub const NAME: &str = "languages";
|
||||
pub struct Fetch(pub language_to_user::ManyArgs);
|
||||
impl Fetch {
|
||||
@@ -1385,9 +1370,7 @@ pub mod chat_donate_notifications {
|
||||
pub mod id {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
|
||||
pub const NAME: &str = "id";
|
||||
pub struct Set(pub i64);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -1456,9 +1439,7 @@ pub mod chat_donate_notifications {
|
||||
pub mod chat_id {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
|
||||
pub const NAME: &str = "chat_id";
|
||||
pub struct Set(pub i64);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -1531,9 +1512,7 @@ pub mod chat_donate_notifications {
|
||||
pub mod sended {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
|
||||
pub const NAME: &str = "sended";
|
||||
pub struct Set(
|
||||
pub ::prisma_client_rust::chrono::DateTime<::prisma_client_rust::chrono::FixedOffset>,
|
||||
@@ -2068,9 +2047,7 @@ pub mod language {
|
||||
pub mod id {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
|
||||
pub const NAME: &str = "id";
|
||||
pub struct Set(pub i32);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -2139,9 +2116,7 @@ pub mod language {
|
||||
pub mod label {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
|
||||
pub const NAME: &str = "label";
|
||||
pub struct Set(pub String);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -2206,9 +2181,7 @@ pub mod language {
|
||||
pub mod code {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
|
||||
pub const NAME: &str = "code";
|
||||
pub struct Set(pub String);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -2269,9 +2242,7 @@ pub mod language {
|
||||
pub mod users {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
SetParam, WhereParam, WithParam,
|
||||
};
|
||||
use super::{SetParam, WhereParam, WithParam};
|
||||
pub const NAME: &str = "users";
|
||||
pub struct Fetch(pub language_to_user::ManyArgs);
|
||||
impl Fetch {
|
||||
@@ -2891,9 +2862,7 @@ pub mod user_activity {
|
||||
pub mod id {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
|
||||
pub const NAME: &str = "id";
|
||||
pub struct Set(pub i32);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -2962,9 +2931,7 @@ pub mod user_activity {
|
||||
pub mod user_id {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
|
||||
pub const NAME: &str = "user_id";
|
||||
pub struct Set(pub i32);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -3033,9 +3000,7 @@ pub mod user_activity {
|
||||
pub mod updated {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
|
||||
pub const NAME: &str = "updated";
|
||||
pub struct Set(
|
||||
pub ::prisma_client_rust::chrono::DateTime<::prisma_client_rust::chrono::FixedOffset>,
|
||||
@@ -3138,9 +3103,7 @@ pub mod user_activity {
|
||||
pub mod user {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
SetParam, WhereParam, WithParam,
|
||||
};
|
||||
use super::{SetParam, WhereParam, WithParam};
|
||||
pub const NAME: &str = "user";
|
||||
pub struct Fetch(pub user_settings::UniqueArgs);
|
||||
impl Fetch {
|
||||
@@ -3725,9 +3688,7 @@ pub mod language_to_user {
|
||||
pub mod id {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, UniqueWhereParam, WhereParam};
|
||||
pub const NAME: &str = "id";
|
||||
pub struct Set(pub i32);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -3796,9 +3757,7 @@ pub mod language_to_user {
|
||||
pub mod language_id {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
|
||||
pub const NAME: &str = "language_id";
|
||||
pub struct Set(pub i32);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -3871,9 +3830,7 @@ pub mod language_to_user {
|
||||
pub mod user_id {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
OrderByParam, SetParam, UncheckedSetParam, WhereParam,
|
||||
};
|
||||
use super::{OrderByParam, SetParam, UncheckedSetParam, WhereParam};
|
||||
pub const NAME: &str = "user_id";
|
||||
pub struct Set(pub i32);
|
||||
impl From<Set> for SetParam {
|
||||
@@ -3942,9 +3899,7 @@ pub mod language_to_user {
|
||||
pub mod language {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
SetParam, WhereParam, WithParam,
|
||||
};
|
||||
use super::{SetParam, WhereParam, WithParam};
|
||||
pub const NAME: &str = "language";
|
||||
pub struct Fetch(pub language::UniqueArgs);
|
||||
impl Fetch {
|
||||
@@ -4048,9 +4003,7 @@ pub mod language_to_user {
|
||||
pub mod user {
|
||||
use super::super::*;
|
||||
|
||||
use super::{
|
||||
SetParam, WhereParam, WithParam,
|
||||
};
|
||||
use super::{SetParam, WhereParam, WithParam};
|
||||
pub const NAME: &str = "user";
|
||||
pub struct Fetch(pub user_settings::UniqueArgs);
|
||||
impl Fetch {
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
use axum::{Router, response::IntoResponse, routing::{get, post}, extract::Path, Json, http::StatusCode};
|
||||
use axum::{
|
||||
extract::Path,
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::{get, post},
|
||||
Json, Router,
|
||||
};
|
||||
use chrono::Duration;
|
||||
|
||||
use crate::prisma::chat_donate_notifications;
|
||||
|
||||
use super::Database;
|
||||
|
||||
|
||||
async fn is_need_send(
|
||||
Path(chat_id): Path<i64>,
|
||||
db: Database
|
||||
) -> impl IntoResponse {
|
||||
async fn is_need_send(Path(chat_id): Path<i64>, db: Database) -> impl IntoResponse {
|
||||
const NOTIFICATION_DELTA_DAYS: i64 = 60;
|
||||
|
||||
let notification = db.chat_donate_notifications()
|
||||
let notification = db
|
||||
.chat_donate_notifications()
|
||||
.find_unique(chat_donate_notifications::chat_id::equals(chat_id))
|
||||
.exec()
|
||||
.await
|
||||
@@ -20,31 +23,24 @@ async fn is_need_send(
|
||||
|
||||
match notification {
|
||||
Some(notification) => {
|
||||
let result = notification.sended.naive_local() + Duration::days(NOTIFICATION_DELTA_DAYS) <= chrono::offset::Local::now().naive_local();
|
||||
let result = notification.sended.naive_local()
|
||||
+ Duration::days(NOTIFICATION_DELTA_DAYS)
|
||||
<= chrono::offset::Local::now().naive_local();
|
||||
Json(result).into_response()
|
||||
},
|
||||
}
|
||||
None => Json(true).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async fn mark_sent(
|
||||
Path(chat_id): Path<i64>,
|
||||
db: Database
|
||||
) -> impl IntoResponse {
|
||||
let _ = db.chat_donate_notifications()
|
||||
async fn mark_sent(Path(chat_id): Path<i64>, db: Database) -> impl IntoResponse {
|
||||
let _ = db
|
||||
.chat_donate_notifications()
|
||||
.upsert(
|
||||
chat_donate_notifications::chat_id::equals(chat_id),
|
||||
chat_donate_notifications::create(
|
||||
chat_id,
|
||||
chat_donate_notifications::create(chat_id, chrono::offset::Local::now().into(), vec![]),
|
||||
vec![chat_donate_notifications::sended::set(
|
||||
chrono::offset::Local::now().into(),
|
||||
vec![]
|
||||
),
|
||||
vec![
|
||||
chat_donate_notifications::sended::set(
|
||||
chrono::offset::Local::now().into()
|
||||
)
|
||||
]
|
||||
)],
|
||||
)
|
||||
.exec()
|
||||
.await;
|
||||
@@ -52,7 +48,6 @@ async fn mark_sent(
|
||||
StatusCode::OK
|
||||
}
|
||||
|
||||
|
||||
pub fn get_router() -> Router {
|
||||
Router::new()
|
||||
.route("/:chat_id/is_need_send", get(is_need_send))
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
use axum::{Router, response::IntoResponse, routing::get, Json, extract::Path, http::StatusCode};
|
||||
use axum::{extract::Path, http::StatusCode, response::IntoResponse, routing::get, Json, Router};
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::prisma::language;
|
||||
use super::Database;
|
||||
|
||||
use crate::prisma::language;
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct LanguageDetail {
|
||||
@@ -12,24 +11,19 @@ pub struct LanguageDetail {
|
||||
pub code: String,
|
||||
}
|
||||
|
||||
|
||||
impl From<language::Data> for LanguageDetail {
|
||||
fn from(value: language::Data) -> Self {
|
||||
let language::Data { id, label, code, .. } = value;
|
||||
let language::Data {
|
||||
id, label, code, ..
|
||||
} = value;
|
||||
|
||||
Self {
|
||||
id,
|
||||
label,
|
||||
code
|
||||
}
|
||||
Self { id, label, code }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async fn get_languages(
|
||||
db: Database
|
||||
) -> impl IntoResponse {
|
||||
let languages: Vec<LanguageDetail> = db.language()
|
||||
async fn get_languages(db: Database) -> impl IntoResponse {
|
||||
let languages: Vec<LanguageDetail> = db
|
||||
.language()
|
||||
.find_many(vec![])
|
||||
.exec()
|
||||
.await
|
||||
@@ -41,12 +35,9 @@ async fn get_languages(
|
||||
Json(languages).into_response()
|
||||
}
|
||||
|
||||
|
||||
async fn get_language_by_code(
|
||||
Path(code): Path<String>,
|
||||
db: Database
|
||||
) -> impl IntoResponse {
|
||||
let language = db.language()
|
||||
async fn get_language_by_code(Path(code): Path<String>, db: Database) -> impl IntoResponse {
|
||||
let language = db
|
||||
.language()
|
||||
.find_unique(language::code::equals(code))
|
||||
.exec()
|
||||
.await
|
||||
@@ -58,7 +49,6 @@ async fn get_language_by_code(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn get_router() -> Router {
|
||||
Router::new()
|
||||
.route("/", get(get_languages))
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
use axum::{Router, response::Response, http::{StatusCode, self, Request}, middleware::{Next, self}, Extension, routing::get};
|
||||
use axum::{
|
||||
http::{self, Request, StatusCode},
|
||||
middleware::{self, Next},
|
||||
response::Response,
|
||||
routing::get,
|
||||
Extension, Router,
|
||||
};
|
||||
use axum_prometheus::PrometheusMetricLayer;
|
||||
use tower_http::trace::{TraceLayer, self};
|
||||
use tracing::Level;
|
||||
use std::sync::Arc;
|
||||
use tower_http::trace::{self, TraceLayer};
|
||||
use tracing::Level;
|
||||
|
||||
use crate::{config::CONFIG, db::get_prisma_client, prisma::PrismaClient};
|
||||
|
||||
pub mod users;
|
||||
pub mod pagination;
|
||||
pub mod languages;
|
||||
pub mod donate_notifications;
|
||||
|
||||
pub mod languages;
|
||||
pub mod pagination;
|
||||
pub mod users;
|
||||
|
||||
pub type Database = Extension<Arc<PrismaClient>>;
|
||||
|
||||
|
||||
async fn auth<B>(req: Request<B>, next: Next<B>) -> Result<Response, StatusCode> {
|
||||
let auth_header = req.headers()
|
||||
let auth_header = req
|
||||
.headers()
|
||||
.get(http::header::AUTHORIZATION)
|
||||
.and_then(|header| header.to_str().ok());
|
||||
|
||||
@@ -33,7 +38,6 @@ async fn auth<B>(req: Request<B>, next: Next<B>) -> Result<Response, StatusCode>
|
||||
Ok(next.run(req).await)
|
||||
}
|
||||
|
||||
|
||||
pub async fn get_router() -> Router {
|
||||
let client = Arc::new(get_prisma_client().await);
|
||||
|
||||
@@ -47,17 +51,15 @@ pub async fn get_router() -> Router {
|
||||
.layer(Extension(client))
|
||||
.layer(prometheus_layer);
|
||||
|
||||
let metric_router = Router::new()
|
||||
.route("/metrics", get(|| async move { metric_handle.render() }));
|
||||
let metric_router =
|
||||
Router::new().route("/metrics", get(|| async move { metric_handle.render() }));
|
||||
|
||||
Router::new()
|
||||
.nest("/", app_router)
|
||||
.nest("/", metric_router)
|
||||
.layer(
|
||||
TraceLayer::new_for_http()
|
||||
.make_span_with(trace::DefaultMakeSpan::new()
|
||||
.level(Level::INFO))
|
||||
.on_response(trace::DefaultOnResponse::new()
|
||||
.level(Level::INFO)),
|
||||
.make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO))
|
||||
.on_response(trace::DefaultOnResponse::new().level(Level::INFO)),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Pagination {
|
||||
#[serde(default = "default_page")]
|
||||
pub page: usize,
|
||||
#[serde(default = "default_size")]
|
||||
pub size: usize
|
||||
pub size: usize,
|
||||
}
|
||||
|
||||
fn default_page() -> usize { 1 }
|
||||
fn default_size() -> usize { 50 }
|
||||
fn default_page() -> usize {
|
||||
1
|
||||
}
|
||||
fn default_size() -> usize {
|
||||
50
|
||||
}
|
||||
|
||||
impl Pagination {
|
||||
pub fn skip(&self) -> i64 {
|
||||
@@ -22,28 +25,29 @@ impl Pagination {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct Page<T> where T: Serialize {
|
||||
pub struct Page<T>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
pub items: Vec<T>,
|
||||
pub total: usize,
|
||||
pub page: usize,
|
||||
pub size: usize,
|
||||
pub pages: usize
|
||||
pub pages: usize,
|
||||
}
|
||||
|
||||
impl<T> Page<T> where T: Serialize {
|
||||
pub fn create(
|
||||
items: Vec<T>,
|
||||
items_count: i64,
|
||||
pagination: Pagination
|
||||
) -> Self {
|
||||
impl<T> Page<T>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
pub fn create(items: Vec<T>, items_count: i64, pagination: Pagination) -> Self {
|
||||
Self {
|
||||
items,
|
||||
total: items_count.try_into().unwrap(),
|
||||
page: pagination.page,
|
||||
size: pagination.size,
|
||||
pages: (items_count as f64 / pagination.size as f64).ceil() as usize
|
||||
pages: (items_count as f64 / pagination.size as f64).ceil() as usize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
pub mod serializers;
|
||||
pub mod utils;
|
||||
|
||||
use axum::{Router, response::IntoResponse, routing::{get, post}, extract::{Query, Path}, Json, http::StatusCode};
|
||||
use crate::prisma::{user_settings, language_to_user, user_activity};
|
||||
use crate::prisma::{language_to_user, user_activity, user_settings};
|
||||
use axum::{
|
||||
extract::{Path, Query},
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
routing::{get, post},
|
||||
Json, Router,
|
||||
};
|
||||
|
||||
use self::{serializers::{UserDetail, CreateOrUpdateUserData}, utils::update_languages};
|
||||
use self::{
|
||||
serializers::{CreateOrUpdateUserData, UserDetail},
|
||||
utils::update_languages,
|
||||
};
|
||||
|
||||
use super::{pagination::{Pagination, Page}, Database};
|
||||
use super::{
|
||||
pagination::{Page, Pagination},
|
||||
Database,
|
||||
};
|
||||
|
||||
|
||||
async fn get_users(
|
||||
pagination: Query<Pagination>,
|
||||
db: Database
|
||||
) -> impl IntoResponse {
|
||||
async fn get_users(pagination: Query<Pagination>, db: Database) -> impl IntoResponse {
|
||||
let pagination: Pagination = pagination.0;
|
||||
|
||||
let users_count = db.user_settings()
|
||||
.count(vec![])
|
||||
.exec()
|
||||
.await
|
||||
.unwrap();
|
||||
let users_count = db.user_settings().count(vec![]).exec().await.unwrap();
|
||||
|
||||
let users: Vec<UserDetail> = db.user_settings()
|
||||
let users: Vec<UserDetail> = db
|
||||
.user_settings()
|
||||
.find_many(vec![])
|
||||
.with(
|
||||
user_settings::languages::fetch(vec![])
|
||||
.with(
|
||||
language_to_user::language::fetch()
|
||||
)
|
||||
)
|
||||
.with(user_settings::languages::fetch(vec![]).with(language_to_user::language::fetch()))
|
||||
.order_by(user_settings::id::order(prisma_client_rust::Direction::Asc))
|
||||
.skip(pagination.skip())
|
||||
.take(pagination.take())
|
||||
@@ -39,26 +39,14 @@ async fn get_users(
|
||||
.map(|item| item.into())
|
||||
.collect();
|
||||
|
||||
Json(Page::create(
|
||||
users,
|
||||
users_count,
|
||||
pagination
|
||||
)).into_response()
|
||||
Json(Page::create(users, users_count, pagination)).into_response()
|
||||
}
|
||||
|
||||
|
||||
async fn get_user(
|
||||
Path(user_id): Path<i64>,
|
||||
db: Database
|
||||
) -> impl IntoResponse {
|
||||
let user = db.user_settings()
|
||||
async fn get_user(Path(user_id): Path<i64>, db: Database) -> impl IntoResponse {
|
||||
let user = db
|
||||
.user_settings()
|
||||
.find_unique(user_settings::user_id::equals(user_id))
|
||||
.with(
|
||||
user_settings::languages::fetch(vec![])
|
||||
.with(
|
||||
language_to_user::language::fetch()
|
||||
)
|
||||
)
|
||||
.with(user_settings::languages::fetch(vec![]).with(language_to_user::language::fetch()))
|
||||
.exec()
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -70,12 +58,12 @@ async fn get_user(
|
||||
Json::<UserDetail>(user.unwrap().into()).into_response()
|
||||
}
|
||||
|
||||
|
||||
async fn create_or_update_user(
|
||||
db: Database,
|
||||
Json(data): Json<CreateOrUpdateUserData>,
|
||||
) -> impl IntoResponse {
|
||||
let user = db.user_settings()
|
||||
let user = db
|
||||
.user_settings()
|
||||
.upsert(
|
||||
user_settings::user_id::equals(data.user_id),
|
||||
user_settings::create(
|
||||
@@ -84,21 +72,16 @@ async fn create_or_update_user(
|
||||
data.first_name.clone(),
|
||||
data.username.clone(),
|
||||
data.source.clone(),
|
||||
vec![]
|
||||
vec![],
|
||||
),
|
||||
vec![
|
||||
user_settings::last_name::set(data.last_name),
|
||||
user_settings::first_name::set(data.first_name),
|
||||
user_settings::username::set(data.username),
|
||||
user_settings::source::set(data.source)
|
||||
]
|
||||
)
|
||||
.with(
|
||||
user_settings::languages::fetch(vec![])
|
||||
.with(
|
||||
language_to_user::language::fetch()
|
||||
)
|
||||
user_settings::source::set(data.source),
|
||||
],
|
||||
)
|
||||
.with(user_settings::languages::fetch(vec![]).with(language_to_user::language::fetch()))
|
||||
.exec()
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -106,14 +89,10 @@ async fn create_or_update_user(
|
||||
let user_id = user.id;
|
||||
update_languages(user, data.allowed_langs, db.clone()).await;
|
||||
|
||||
let user = db.user_settings()
|
||||
let user = db
|
||||
.user_settings()
|
||||
.find_unique(user_settings::id::equals(user_id))
|
||||
.with(
|
||||
user_settings::languages::fetch(vec![])
|
||||
.with(
|
||||
language_to_user::language::fetch()
|
||||
)
|
||||
)
|
||||
.with(user_settings::languages::fetch(vec![]).with(language_to_user::language::fetch()))
|
||||
.exec()
|
||||
.await
|
||||
.unwrap()
|
||||
@@ -122,12 +101,9 @@ async fn create_or_update_user(
|
||||
Json::<UserDetail>(user.into()).into_response()
|
||||
}
|
||||
|
||||
|
||||
async fn update_activity(
|
||||
Path(user_id): Path<i64>,
|
||||
db: Database
|
||||
) -> impl IntoResponse {
|
||||
let user = db.user_settings()
|
||||
async fn update_activity(Path(user_id): Path<i64>, db: Database) -> impl IntoResponse {
|
||||
let user = db
|
||||
.user_settings()
|
||||
.find_unique(user_settings::user_id::equals(user_id))
|
||||
.exec()
|
||||
.await
|
||||
@@ -138,17 +114,18 @@ async fn update_activity(
|
||||
None => return StatusCode::NOT_FOUND.into_response(),
|
||||
};
|
||||
|
||||
let _ = db.user_activity()
|
||||
let _ = db
|
||||
.user_activity()
|
||||
.upsert(
|
||||
user_activity::user_id::equals(user.id),
|
||||
user_activity::create(
|
||||
chrono::offset::Local::now().into(),
|
||||
user_settings::id::equals(user.id),
|
||||
vec![]
|
||||
vec![],
|
||||
),
|
||||
vec![
|
||||
user_activity::updated::set(chrono::offset::Local::now().into())
|
||||
]
|
||||
vec![user_activity::updated::set(
|
||||
chrono::offset::Local::now().into(),
|
||||
)],
|
||||
)
|
||||
.exec()
|
||||
.await;
|
||||
@@ -156,7 +133,6 @@ async fn update_activity(
|
||||
StatusCode::OK.into_response()
|
||||
}
|
||||
|
||||
|
||||
pub fn get_router() -> Router {
|
||||
Router::new()
|
||||
.route("/", get(get_users))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
use crate::prisma::{user_settings, language};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::prisma::{language, user_settings};
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct UserLanguage {
|
||||
@@ -10,18 +9,16 @@ pub struct UserLanguage {
|
||||
pub code: String,
|
||||
}
|
||||
|
||||
|
||||
impl From<language::Data> for UserLanguage {
|
||||
fn from(value: language::Data) -> Self {
|
||||
Self {
|
||||
id: value.id,
|
||||
label: value.label,
|
||||
code: value.code
|
||||
code: value.code,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct UserDetail {
|
||||
pub id: i32,
|
||||
@@ -30,14 +27,14 @@ pub struct UserDetail {
|
||||
pub first_name: String,
|
||||
pub username: String,
|
||||
pub source: String,
|
||||
pub allowed_langs: Vec<UserLanguage>
|
||||
pub allowed_langs: Vec<UserLanguage>,
|
||||
}
|
||||
|
||||
|
||||
impl From<user_settings::Data> for UserDetail {
|
||||
fn from(value: user_settings::Data) -> Self {
|
||||
let allowed_langs: Vec<UserLanguage> = value
|
||||
.languages.unwrap()
|
||||
.languages
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|item| *item.language.unwrap())
|
||||
.map(|item| item.into())
|
||||
@@ -50,7 +47,7 @@ impl From<user_settings::Data> for UserDetail {
|
||||
first_name: value.first_name,
|
||||
username: value.username,
|
||||
source: value.source,
|
||||
allowed_langs
|
||||
allowed_langs,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,5 +59,5 @@ pub struct CreateOrUpdateUserData {
|
||||
pub first_name: String,
|
||||
pub username: String,
|
||||
pub source: String,
|
||||
pub allowed_langs: Vec<String>
|
||||
pub allowed_langs: Vec<String>,
|
||||
}
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::{prisma::{user_settings, language, language_to_user}, views::Database};
|
||||
use crate::{
|
||||
prisma::{language, language_to_user, user_settings},
|
||||
views::Database,
|
||||
};
|
||||
|
||||
|
||||
pub async fn update_languages(
|
||||
user: user_settings::Data,
|
||||
new_langs: Vec<String>,
|
||||
db: Database
|
||||
) {
|
||||
pub async fn update_languages(user: user_settings::Data, new_langs: Vec<String>, db: Database) {
|
||||
// Delete
|
||||
{
|
||||
let need_delete: Vec<_> = user.languages().unwrap()
|
||||
let need_delete: Vec<_> = user
|
||||
.languages()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|item| {
|
||||
let language::Data{ id, code, .. } = *item.clone().language.unwrap();
|
||||
let language::Data { id, code, .. } = *item.clone().language.unwrap();
|
||||
(id, code)
|
||||
})
|
||||
.filter(|(_, code)| !new_langs.contains(code))
|
||||
.map(|(id, _)| id)
|
||||
.collect();
|
||||
|
||||
let _ = db.language_to_user()
|
||||
.delete_many(
|
||||
vec![language_to_user::id::in_vec(need_delete)]
|
||||
)
|
||||
let _ = db
|
||||
.language_to_user()
|
||||
.delete_many(vec![language_to_user::id::in_vec(need_delete)])
|
||||
.exec()
|
||||
.await;
|
||||
}
|
||||
|
||||
// Create
|
||||
{
|
||||
let languages: HashMap<_, _> = db.language()
|
||||
let languages: HashMap<_, _> = db
|
||||
.language()
|
||||
.find_many(vec![])
|
||||
.exec()
|
||||
.await
|
||||
@@ -39,7 +39,9 @@ pub async fn update_languages(
|
||||
.map(|l| (l.code, l.id))
|
||||
.collect();
|
||||
|
||||
let current_langs: Vec<_> = user.languages().unwrap()
|
||||
let current_langs: Vec<_> = user
|
||||
.languages()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|item| item.clone().language.unwrap().code)
|
||||
.collect();
|
||||
@@ -50,16 +52,15 @@ pub async fn update_languages(
|
||||
.map(|code| *languages.get(&code).unwrap())
|
||||
.collect();
|
||||
|
||||
let _ = db.language_to_user()
|
||||
let _ = db
|
||||
.language_to_user()
|
||||
.create_many(
|
||||
need_create
|
||||
.iter()
|
||||
.map(|language_id| language_to_user::create_unchecked(
|
||||
*language_id,
|
||||
user.id,
|
||||
vec![]
|
||||
))
|
||||
.collect()
|
||||
.map(|language_id| {
|
||||
language_to_user::create_unchecked(*language_id, user.id, vec![])
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
.exec()
|
||||
.await;
|
||||
|
||||
Reference in New Issue
Block a user