add(backend): move to dorsal for database
add(backend): accept Extended_Pictographic in custom url TODO: punycode custom urls chore: bump version (v0.12.0 -> v0.12.1)
This commit is contained in:
parent
dd9d5597c9
commit
942f762949
2
.cargo/config
Normal file
2
.cargo/config
Normal file
|
@ -0,0 +1,2 @@
|
|||
[registries]
|
||||
stellular = { index = "sparse+https://code.stellular.org/api/packages/stellular/cargo/" }
|
22
Cargo.toml
22
Cargo.toml
|
@ -3,7 +3,7 @@ name = "bundlrs"
|
|||
authors = ["hkau"]
|
||||
license = "MIT"
|
||||
|
||||
version = "0.12.0"
|
||||
version = "0.12.1"
|
||||
edition = "2021"
|
||||
|
||||
rust-version = "1.75"
|
||||
|
@ -11,20 +11,21 @@ rust-version = "1.75"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[features]
|
||||
postgres = []
|
||||
mysql = []
|
||||
sqlite = []
|
||||
default = ["sqlite"]
|
||||
postgres = ["dorsal/postgres"]
|
||||
mysql = ["dorsal/mysql"]
|
||||
sqlite = ["dorsal/sqlite"]
|
||||
default = ["dorsal/sqlite"]
|
||||
|
||||
[dependencies]
|
||||
awc = { version = "3.4.0", features = ["rustls"] }
|
||||
actix-files = "0.6.5"
|
||||
actix-web = "4.4.1"
|
||||
comrak = "0.21.0"
|
||||
comrak = "0.22.0"
|
||||
dotenv = "0.15.0"
|
||||
either = "1.9.0"
|
||||
env_logger = "0.11.2"
|
||||
hex_fmt = "0.3.0"
|
||||
dorsal = { version = "0.1.1", registry = "stellular", default-features = false } # crates: disable-check
|
||||
idna = "0.5.0"
|
||||
once_cell = "1.19.0"
|
||||
pest = "2.7.7"
|
||||
|
@ -33,16 +34,7 @@ regex = "1.10.2"
|
|||
serde = "1.0.195"
|
||||
serde_json = "1.0.111"
|
||||
sha2 = "0.10.8"
|
||||
sqlx = { version = "0.7.3", features = [
|
||||
"sqlite",
|
||||
"postgres",
|
||||
"mysql",
|
||||
"any",
|
||||
"runtime-tokio",
|
||||
"tls-native-tls",
|
||||
] }
|
||||
uuid = { version = "1.6.1", features = ["v4"] }
|
||||
yew = { version = "0.21.0", features = ["ssr"] }
|
||||
redis = "0.25.2"
|
||||
handlebars = "5.1.2"
|
||||
actix-cors = "0.7.0"
|
||||
|
|
12
justfile
12
justfile
|
@ -1,6 +1,8 @@
|
|||
build database="sqlite":
|
||||
just docs
|
||||
./scripts/download_styles.sh
|
||||
just styles
|
||||
bun i
|
||||
bun run static_build.ts
|
||||
cargo build -r --no-default-features --features {{database}}
|
||||
|
||||
docs:
|
||||
|
@ -14,3 +16,11 @@ test:
|
|||
run:
|
||||
chmod +x ./target/release/bundlrs
|
||||
./target/release/bundlrs
|
||||
|
||||
styles:
|
||||
wget https://codeberg.org/api/packages/hkau/npm/fusion/-/1.0.11/fusion-1.0.11.tgz -O fusion.tgz
|
||||
tar -xzf fusion.tgz
|
||||
mv ./package/src/css ./static/css
|
||||
sed -i -e 's/\"\/utility.css\"/\"\/static\/css\/utility.css\"/' ./static/css/fusion.css
|
||||
rm -r ./package
|
||||
rm ./fusion.tgz
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
wget https://codeberg.org/api/packages/hkau/npm/fusion/-/1.0.11/fusion-1.0.11.tgz -O fusion.tgz
|
||||
mv ./fusion.tgz ./static/fusion.tgz
|
||||
|
||||
cd static
|
||||
tar -xzf fusion.tgz
|
||||
|
||||
mv package/src/css ./css
|
||||
sed -i -e 's/\"\/utility.css\"/\"\/static\/css\/utility.css\"/' ./css/fusion.css
|
||||
|
||||
rm -r package
|
||||
rm ./fusion.tgz
|
||||
|
||||
cd ../
|
||||
bun run static_build.ts
|
|
@ -1,4 +1,4 @@
|
|||
use crate::db::bundlesdb::{self, AppData};
|
||||
use crate::db::{self, AppData};
|
||||
use actix_web::{get, post, web, HttpRequest, HttpResponse, Responder};
|
||||
|
||||
#[derive(Default, PartialEq, serde::Deserialize)]
|
||||
|
@ -57,29 +57,27 @@ pub async fn logout(req: HttpRequest, data: web::Data<AppData>) -> impl Responde
|
|||
/// Get all pastes by owner
|
||||
pub async fn get_from_owner_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<bundlesdb::AppData>,
|
||||
data: web::Data<db::AppData>,
|
||||
info: web::Query<crate::api::pastes::OffsetQueryProps>,
|
||||
) -> impl Responder {
|
||||
let name: String = req.match_info().get("name").unwrap().to_string();
|
||||
|
||||
// get pastes
|
||||
let res: bundlesdb::DefaultReturn<Option<Vec<bundlesdb::PasteIdentifier>>> =
|
||||
let res: db::DefaultReturn<Option<Vec<db::PasteIdentifier>>> =
|
||||
data.db.get_pastes_by_owner_limited(name, info.offset).await;
|
||||
|
||||
// return
|
||||
return HttpResponse::Ok()
|
||||
.append_header(("Content-Type", "application/json"))
|
||||
.body(
|
||||
serde_json::to_string::<
|
||||
bundlesdb::DefaultReturn<Option<Vec<bundlesdb::PasteIdentifier>>>,
|
||||
>(&res)
|
||||
.unwrap(),
|
||||
serde_json::to_string::<db::DefaultReturn<Option<Vec<db::PasteIdentifier>>>>(&res)
|
||||
.unwrap(),
|
||||
);
|
||||
}
|
||||
|
||||
#[post("/api/auth/users/{name:.*?}/ban")]
|
||||
/// Ban user
|
||||
pub async fn ban_request(req: HttpRequest, data: web::Data<bundlesdb::AppData>) -> impl Responder {
|
||||
pub async fn ban_request(req: HttpRequest, data: web::Data<db::AppData>) -> impl Responder {
|
||||
let name: String = req.match_info().get("name").unwrap().to_string();
|
||||
|
||||
// get token user
|
||||
|
@ -116,10 +114,10 @@ pub async fn ban_request(req: HttpRequest, data: web::Data<bundlesdb::AppData>)
|
|||
}
|
||||
|
||||
// ban user
|
||||
let res: bundlesdb::DefaultReturn<Option<String>> = data.db.ban_user_by_name(name).await;
|
||||
let res: db::DefaultReturn<Option<String>> = data.db.ban_user_by_name(name).await;
|
||||
|
||||
// return
|
||||
return HttpResponse::Ok()
|
||||
.append_header(("Content-Type", "application/json"))
|
||||
.body(serde_json::to_string::<bundlesdb::DefaultReturn<Option<String>>>(&res).unwrap());
|
||||
.body(serde_json::to_string::<db::DefaultReturn<Option<String>>>(&res).unwrap());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use actix_web::{get, post, web, HttpRequest, HttpResponse, Responder};
|
||||
|
||||
use crate::db::bundlesdb::{self, AtomicPasteFSFile, DefaultReturn, FullPaste, PasteMetadata};
|
||||
use crate::db::{self, AtomicPasteFSFile, DefaultReturn, FullPaste, PasteMetadata};
|
||||
use crate::{markdown, ssm, utility};
|
||||
|
||||
#[derive(Default, PartialEq, serde::Deserialize)]
|
||||
|
@ -47,7 +47,7 @@ struct DeleteInfo {
|
|||
struct MetadataInfo {
|
||||
custom_url: String,
|
||||
edit_password: String,
|
||||
metadata: bundlesdb::PasteMetadata,
|
||||
metadata: db::PasteMetadata,
|
||||
}
|
||||
|
||||
#[post("/api/markdown")]
|
||||
|
@ -67,7 +67,7 @@ pub async fn render_ssm_request(body: web::Json<RenderInfo>) -> impl Responder {
|
|||
#[get("/api/ssm/{url:.*}")]
|
||||
pub async fn render_paste_ssm_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<bundlesdb::AppData>,
|
||||
data: web::Data<db::AppData>,
|
||||
) -> impl Responder {
|
||||
let custom_url: String = req.match_info().get("url").unwrap().to_string();
|
||||
let res = data.db.get_paste_by_url(custom_url).await;
|
||||
|
@ -109,7 +109,7 @@ pub async fn render_paste_ssm_request(
|
|||
pub async fn create_request(
|
||||
req: HttpRequest,
|
||||
body: web::Json<CreateInfo>,
|
||||
data: web::Data<bundlesdb::AppData>,
|
||||
data: web::Data<db::AppData>,
|
||||
) -> impl Responder {
|
||||
let custom_url: String = body.custom_url.trim().to_string();
|
||||
let edit_password: &String = &body.edit_password;
|
||||
|
@ -153,7 +153,7 @@ pub async fn create_request(
|
|||
let res = data
|
||||
.db
|
||||
.create_paste(
|
||||
&mut bundlesdb::Paste {
|
||||
&mut db::Paste {
|
||||
custom_url: custom_url.clone(),
|
||||
id: String::new(), // reassigned anyways, this doesn't matter
|
||||
edit_password: edit_password.to_string(),
|
||||
|
@ -184,7 +184,7 @@ pub async fn create_request(
|
|||
pub async fn edit_request(
|
||||
req: HttpRequest,
|
||||
body: web::Json<EditInfo>,
|
||||
data: web::Data<bundlesdb::AppData>,
|
||||
data: web::Data<db::AppData>,
|
||||
) -> impl Responder {
|
||||
let custom_url: String = body.custom_url.trim().to_string();
|
||||
let content: String = body.content.trim().to_string();
|
||||
|
@ -239,7 +239,7 @@ pub async fn edit_request(
|
|||
pub async fn edit_atomic_request(
|
||||
req: HttpRequest,
|
||||
body: web::Json<EditAtomicInfo>,
|
||||
data: web::Data<bundlesdb::AppData>,
|
||||
data: web::Data<db::AppData>,
|
||||
) -> impl Responder {
|
||||
// this is essentially the same as edit_request but it handles the atomic JSON file system
|
||||
// ...it does NOT accept an edit password! users must be authenticated
|
||||
|
@ -285,7 +285,7 @@ pub async fn edit_atomic_request(
|
|||
}
|
||||
|
||||
// get file from path
|
||||
let real_content = serde_json::from_str::<bundlesdb::AtomicPaste>(&unwrap.paste.content);
|
||||
let real_content = serde_json::from_str::<db::AtomicPaste>(&unwrap.paste.content);
|
||||
|
||||
if real_content.is_err() {
|
||||
return HttpResponse::NotAcceptable().body("Paste failed to deserialize");
|
||||
|
@ -312,7 +312,7 @@ pub async fn edit_atomic_request(
|
|||
.db
|
||||
.edit_paste_by_url(
|
||||
custom_url,
|
||||
serde_json::to_string::<bundlesdb::AtomicPaste>(&decoded).unwrap(), // encode content
|
||||
serde_json::to_string::<db::AtomicPaste>(&decoded).unwrap(), // encode content
|
||||
String::new(),
|
||||
Option::None,
|
||||
Option::None,
|
||||
|
@ -335,7 +335,7 @@ pub async fn edit_atomic_request(
|
|||
pub async fn delete_request(
|
||||
req: HttpRequest,
|
||||
body: web::Json<DeleteInfo>,
|
||||
data: web::Data<bundlesdb::AppData>,
|
||||
data: web::Data<db::AppData>,
|
||||
) -> impl Responder {
|
||||
let custom_url: String = body.custom_url.trim().to_string();
|
||||
let edit_password: String = body.edit_password.to_owned();
|
||||
|
@ -384,13 +384,13 @@ pub async fn delete_request(
|
|||
pub async fn metadata_request(
|
||||
req: HttpRequest,
|
||||
body: web::Json<MetadataInfo>,
|
||||
data: web::Data<bundlesdb::AppData>,
|
||||
data: web::Data<db::AppData>,
|
||||
) -> impl Responder {
|
||||
let custom_url: String = body.custom_url.trim().to_string();
|
||||
let edit_password: String = body.edit_password.to_owned();
|
||||
|
||||
let m = body.metadata.to_owned();
|
||||
let metadata: bundlesdb::PasteMetadata = m;
|
||||
let metadata: db::PasteMetadata = m;
|
||||
|
||||
// get token user
|
||||
let token_cookie = req.cookie("__Secure-Token");
|
||||
|
@ -434,10 +434,7 @@ pub async fn metadata_request(
|
|||
|
||||
#[get("/api/exists/{url:.*}")]
|
||||
/// Check if a paste exists
|
||||
pub async fn exists_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<bundlesdb::AppData>,
|
||||
) -> impl Responder {
|
||||
pub async fn exists_request(req: HttpRequest, data: web::Data<db::AppData>) -> impl Responder {
|
||||
let custom_url: String = req.match_info().get("url").unwrap().to_string();
|
||||
let res = data.db.get_paste_by_url(custom_url).await;
|
||||
|
||||
|
@ -451,7 +448,7 @@ pub async fn exists_request(
|
|||
/// Get paste by `custom_url`
|
||||
pub async fn get_from_url_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<bundlesdb::AppData>,
|
||||
data: web::Data<db::AppData>,
|
||||
) -> impl Responder {
|
||||
let custom_url: String = req.match_info().get("url").unwrap().to_string();
|
||||
let res: DefaultReturn<Option<FullPaste<PasteMetadata, String>>> =
|
||||
|
@ -489,10 +486,7 @@ pub async fn get_from_url_request(
|
|||
|
||||
#[get("/api/id/{id:.*}")]
|
||||
/// Get paste by ID
|
||||
pub async fn get_from_id_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<bundlesdb::AppData>,
|
||||
) -> impl Responder {
|
||||
pub async fn get_from_id_request(req: HttpRequest, data: web::Data<db::AppData>) -> impl Responder {
|
||||
let id: String = req.match_info().get("id").unwrap().to_string();
|
||||
let res: DefaultReturn<Option<FullPaste<PasteMetadata, String>>> =
|
||||
data.db.get_paste_by_id(id).await;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,112 +0,0 @@
|
|||
//! # CacheDB
|
||||
//!
|
||||
//! Redis connection.
|
||||
//!
|
||||
//! Identifiers should be a string following this format: `TYPE_OF_OBJECT:OBJECT_ID`. For pastes this would look like: `paste:{custom_url}`
|
||||
use redis::Commands;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CacheDB {
|
||||
pub client: redis::Client,
|
||||
}
|
||||
|
||||
impl CacheDB {
|
||||
pub async fn new() -> CacheDB {
|
||||
return CacheDB {
|
||||
client: redis::Client::open("redis://127.0.0.1:6379").unwrap(),
|
||||
};
|
||||
}
|
||||
|
||||
pub async fn get_con(&self) -> redis::Connection {
|
||||
self.client.get_connection().unwrap()
|
||||
}
|
||||
|
||||
// GET
|
||||
/// Get a cache object by its identifier
|
||||
///
|
||||
/// # Arguments:
|
||||
/// * `id` - `String` of the object's id
|
||||
pub async fn get(&self, id: String) -> Option<String> {
|
||||
// fetch from database
|
||||
let mut c = self.get_con().await;
|
||||
let res = c.get(id);
|
||||
|
||||
if res.is_err() {
|
||||
return Option::None;
|
||||
}
|
||||
|
||||
// return
|
||||
Option::Some(res.unwrap())
|
||||
}
|
||||
|
||||
// SET
|
||||
/// Set a cache object by its identifier and content
|
||||
///
|
||||
/// # Arguments:
|
||||
/// * `id` - `String` of the object's id
|
||||
/// * `content` - `String` of the object's content
|
||||
pub async fn set(&self, id: String, content: String) -> bool {
|
||||
// set
|
||||
let mut c = self.get_con().await;
|
||||
let res: Result<String, redis::RedisError> = c.set(id, content);
|
||||
|
||||
if res.is_err() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return
|
||||
true
|
||||
}
|
||||
|
||||
/// Update a cache object by its identifier and content
|
||||
///
|
||||
/// # Arguments:
|
||||
/// * `id` - `String` of the object's id
|
||||
/// * `content` - `String` of the object's content
|
||||
pub async fn update(&self, id: String, content: String) -> bool {
|
||||
self.set(id, content).await
|
||||
}
|
||||
|
||||
/// Remove a cache object by its identifier
|
||||
///
|
||||
/// # Arguments:
|
||||
/// * `id` - `String` of the object's id
|
||||
pub async fn remove(&self, id: String) -> bool {
|
||||
// remove
|
||||
let mut c = self.get_con().await;
|
||||
let res: Result<String, redis::RedisError> = c.del(id);
|
||||
|
||||
if res.is_err() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return
|
||||
true
|
||||
}
|
||||
|
||||
/// Remove a cache object by its identifier('s start)
|
||||
///
|
||||
/// # Arguments:
|
||||
/// * `id` - `String` of the object's id('s start)
|
||||
pub async fn remove_starting_with(&self, id: String) -> bool {
|
||||
let mut c = self.get_con().await;
|
||||
|
||||
// get keys
|
||||
let mut cmd = redis::cmd("DEL");
|
||||
let keys: Result<Vec<String>, redis::RedisError> = c.keys(id);
|
||||
|
||||
for key in keys.unwrap() {
|
||||
cmd.arg(key);
|
||||
}
|
||||
|
||||
// remove
|
||||
let res: Result<String, redis::RedisError> = cmd.query(&mut c);
|
||||
|
||||
if res.is_err() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// return
|
||||
true
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
//! Database handling
|
||||
pub mod bundlesdb;
|
||||
pub mod cachedb;
|
||||
pub mod sql;
|
100
src/db/sql.rs
100
src/db/sql.rs
|
@ -1,100 +0,0 @@
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct DatabaseOpts {
|
||||
pub _type: Option<String>,
|
||||
pub host: Option<String>,
|
||||
pub user: String,
|
||||
pub pass: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
// ...
|
||||
#[derive(Clone)]
|
||||
pub struct Database<T> {
|
||||
pub client: T,
|
||||
pub _type: String,
|
||||
}
|
||||
|
||||
// ...
|
||||
#[cfg(feature = "mysql")]
|
||||
/// Create a new "mysql" database
|
||||
pub async fn create_db(options: DatabaseOpts) -> Database<sqlx::MySqlPool> {
|
||||
// mysql
|
||||
let opts = sqlx::mysql::MySqlPoolOptions::new()
|
||||
.max_connections(25)
|
||||
.acquire_timeout(std::time::Duration::from_millis(2000))
|
||||
.idle_timeout(Some(std::time::Duration::from_secs(60 * 5)));
|
||||
// .max_lifetime(Some(std::time::Duration::from_secs(120)));
|
||||
|
||||
let client = opts
|
||||
.connect(&format!(
|
||||
"mysql://{}:{}@{}/{}",
|
||||
options.user,
|
||||
options.pass,
|
||||
if options.host.is_some() {
|
||||
options.host.unwrap()
|
||||
} else {
|
||||
"localhost".to_string()
|
||||
},
|
||||
options.name
|
||||
))
|
||||
.await;
|
||||
|
||||
if client.is_err() {
|
||||
panic!("failed to connect to database: {}", client.err().unwrap());
|
||||
}
|
||||
|
||||
return Database {
|
||||
client: client.unwrap(),
|
||||
_type: String::from("mysql"),
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
/// Create a new "postgres" database
|
||||
pub async fn create_db(options: DatabaseOpts) -> Database<sqlx::PgPool> {
|
||||
// postgres
|
||||
let opts = sqlx::postgres::PgPoolOptions::new()
|
||||
.max_connections(25)
|
||||
.acquire_timeout(std::time::Duration::from_millis(2000))
|
||||
.idle_timeout(Some(std::time::Duration::from_secs(60 * 5)));
|
||||
// .max_lifetime(Some(std::time::Duration::from_secs(120)));
|
||||
|
||||
let client = opts
|
||||
.connect(&format!(
|
||||
"postgres://{}:{}@{}/{}",
|
||||
options.user,
|
||||
options.pass,
|
||||
if options.host.is_some() {
|
||||
options.host.unwrap()
|
||||
} else {
|
||||
"localhost".to_string()
|
||||
},
|
||||
options.name
|
||||
))
|
||||
.await;
|
||||
|
||||
if client.is_err() {
|
||||
panic!("failed to connect to database: {}", client.err().unwrap());
|
||||
}
|
||||
|
||||
return Database {
|
||||
client: client.unwrap(),
|
||||
_type: String::from("postgres"),
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
/// Create a new "sqlite" database
|
||||
pub async fn create_db(_options: DatabaseOpts) -> Database<sqlx::SqlitePool> {
|
||||
// sqlite
|
||||
let client = sqlx::SqlitePool::connect("sqlite://bundlrs.db").await;
|
||||
|
||||
if client.is_err() {
|
||||
panic!("Failed to connect to database!");
|
||||
}
|
||||
|
||||
return Database {
|
||||
client: client.unwrap(),
|
||||
_type: String::from("sqlite"),
|
||||
};
|
||||
}
|
|
@ -2,7 +2,6 @@ use actix_files as fs;
|
|||
use actix_web::{web, App, HttpResponse, HttpServer};
|
||||
use dotenv;
|
||||
|
||||
use sqlx;
|
||||
use yew::ServerRenderer;
|
||||
|
||||
mod config;
|
||||
|
@ -16,8 +15,7 @@ mod pages;
|
|||
mod markdown;
|
||||
mod ssm;
|
||||
|
||||
use crate::db::bundlesdb::{AppData, BundlesDB};
|
||||
use crate::db::sql::DatabaseOpts;
|
||||
use crate::db::{AppData, Database};
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
|
@ -53,8 +51,7 @@ async fn main() -> std::io::Result<()> {
|
|||
panic!("Missing required database config settings!");
|
||||
}
|
||||
|
||||
sqlx::any::install_default_drivers(); // install database drivers
|
||||
let db: BundlesDB = BundlesDB::new(DatabaseOpts {
|
||||
let db: Database = Database::new(dorsal::DatabaseOpts {
|
||||
_type: db_type,
|
||||
host: db_host,
|
||||
user: if db_is_other {
|
||||
|
|
|
@ -5,8 +5,7 @@ use yew::prelude::*;
|
|||
use yew::ServerRenderer;
|
||||
|
||||
use crate::components::navigation::{Footer, GlobalMenu};
|
||||
use crate::db::bundlesdb::{AtomicPasteFSFile, FullPaste, PasteMetadata};
|
||||
use crate::db::{self, bundlesdb};
|
||||
use crate::db::{self, AtomicPasteFSFile, FullPaste, PasteMetadata};
|
||||
use crate::utility::{self, format_html};
|
||||
|
||||
#[derive(Default, Properties, PartialEq, serde::Deserialize)]
|
||||
|
@ -16,14 +15,14 @@ struct EditQueryProps {
|
|||
|
||||
#[derive(Default, Properties, PartialEq, serde::Deserialize)]
|
||||
struct FSProps {
|
||||
pub files: Vec<bundlesdb::AtomicPasteFSFile>,
|
||||
pub files: Vec<db::AtomicPasteFSFile>,
|
||||
pub auth_state: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Default, Properties, PartialEq, serde::Deserialize)]
|
||||
struct EditProps {
|
||||
pub custom_url: String,
|
||||
pub file: bundlesdb::AtomicPasteFSFile,
|
||||
pub file: db::AtomicPasteFSFile,
|
||||
pub auth_state: Option<bool>,
|
||||
}
|
||||
|
||||
|
@ -34,7 +33,7 @@ struct NewProps {
|
|||
|
||||
#[derive(Default, Properties, PartialEq, serde::Deserialize)]
|
||||
struct Props {
|
||||
pub pastes: Vec<bundlesdb::PasteIdentifier>,
|
||||
pub pastes: Vec<db::PasteIdentifier>,
|
||||
pub auth_state: Option<bool>,
|
||||
}
|
||||
|
||||
|
@ -105,10 +104,7 @@ fn build_dashboard_renderer_with_props(props: Props) -> ServerRenderer<Dashboard
|
|||
|
||||
#[get("/d/atomic")]
|
||||
/// Available at "/d/atomic"
|
||||
pub async fn dashboard_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::bundlesdb::AppData>,
|
||||
) -> impl Responder {
|
||||
pub async fn dashboard_request(req: HttpRequest, data: web::Data<db::AppData>) -> impl Responder {
|
||||
// verify auth status
|
||||
let token_cookie = req.cookie("__Secure-Token");
|
||||
let mut set_cookie: &str = "";
|
||||
|
@ -212,10 +208,7 @@ fn build_new_renderer_with_props(props: NewProps) -> ServerRenderer<CreateNew> {
|
|||
|
||||
#[get("/d/atomic/new")]
|
||||
/// Available at "/d/atomic/new"
|
||||
pub async fn new_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::bundlesdb::AppData>,
|
||||
) -> impl Responder {
|
||||
pub async fn new_request(req: HttpRequest, data: web::Data<db::AppData>) -> impl Responder {
|
||||
// verify auth status
|
||||
let token_cookie = req.cookie("__Secure-Token");
|
||||
let mut set_cookie: &str = "";
|
||||
|
@ -334,7 +327,7 @@ fn build_fs_renderer_with_props(props: FSProps) -> ServerRenderer<PasteFiles> {
|
|||
/// Available at "/d/atomic/{id}"
|
||||
pub async fn edit_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::bundlesdb::AppData>,
|
||||
data: web::Data<db::AppData>,
|
||||
info: web::Query<EditQueryProps>,
|
||||
) -> impl Responder {
|
||||
// verify auth status
|
||||
|
@ -369,7 +362,7 @@ You can create an account at: /d/auth/register",
|
|||
|
||||
// get paste
|
||||
let id: String = req.match_info().get("id").unwrap().to_string();
|
||||
let paste: bundlesdb::DefaultReturn<Option<FullPaste<PasteMetadata, String>>> =
|
||||
let paste: db::DefaultReturn<Option<FullPaste<PasteMetadata, String>>> =
|
||||
data.db.get_paste_by_id(id).await;
|
||||
|
||||
if paste.success == false {
|
||||
|
@ -391,7 +384,7 @@ You can create an account at: /d/auth/register",
|
|||
}
|
||||
|
||||
// get file from path
|
||||
let real_content = serde_json::from_str::<bundlesdb::AtomicPaste>(&unwrap.content);
|
||||
let real_content = serde_json::from_str::<db::AtomicPaste>(&unwrap.content);
|
||||
|
||||
if real_content.is_err() {
|
||||
return HttpResponse::NotAcceptable().body("Paste failed to deserialize");
|
||||
|
|
|
@ -6,7 +6,7 @@ use yew::ServerRenderer;
|
|||
|
||||
use crate::components::avatar::AvatarDisplay;
|
||||
use crate::components::navigation::{Footer, GlobalMenu};
|
||||
use crate::db::{self, bundlesdb};
|
||||
use crate::db::{self, AppData};
|
||||
use crate::utility::format_html;
|
||||
|
||||
#[derive(Default, Properties, PartialEq, serde::Deserialize)]
|
||||
|
@ -19,21 +19,21 @@ struct Props {
|
|||
|
||||
#[derive(Default, Properties, PartialEq, serde::Deserialize)]
|
||||
struct DashboardProps {
|
||||
pub user: bundlesdb::UserState<String>,
|
||||
pub user: db::UserState<String>,
|
||||
pub has_unread_notification: bool,
|
||||
pub auth_state: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Default, Properties, PartialEq, serde::Deserialize)]
|
||||
struct NotificationsProps {
|
||||
pub notifications: Vec<bundlesdb::Log>,
|
||||
pub notifications: Vec<db::Log>,
|
||||
pub offset: i32,
|
||||
pub auth_state: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Default, Properties, PartialEq, serde::Deserialize)]
|
||||
struct InboxProps {
|
||||
pub boards: Vec<bundlesdb::BoardIdentifier>,
|
||||
pub boards: Vec<db::BoardIdentifier>,
|
||||
pub offset: i32,
|
||||
pub auth_state: Option<bool>,
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ fn build_renderer_with_props(props: Props) -> ServerRenderer<Home> {
|
|||
/// Available at "/"
|
||||
pub async fn home_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::bundlesdb::AppData>,
|
||||
data: web::Data<AppData>,
|
||||
info: web::Query<Props>,
|
||||
) -> impl Responder {
|
||||
// verify auth status
|
||||
|
@ -488,10 +488,7 @@ fn build_dashboard_renderer_with_props(props: DashboardProps) -> ServerRenderer<
|
|||
|
||||
#[get("/d")]
|
||||
/// Available at "/d"
|
||||
pub async fn dashboard_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::bundlesdb::AppData>,
|
||||
) -> impl Responder {
|
||||
pub async fn dashboard_request(req: HttpRequest, data: web::Data<AppData>) -> impl Responder {
|
||||
// verify auth status
|
||||
let token_cookie = req.cookie("__Secure-Token");
|
||||
let mut set_cookie: &str = "";
|
||||
|
@ -591,7 +588,7 @@ fn Notifications(props: &NotificationsProps) -> Html {
|
|||
|
||||
<div class="flex g-4 flex-wrap">
|
||||
{for props.notifications.iter().map(|n| {
|
||||
let notif = serde_json::from_str::<bundlesdb::Notification>(&n.content).unwrap();
|
||||
let notif = serde_json::from_str::<db::Notification>(&n.content).unwrap();
|
||||
|
||||
html! {
|
||||
<a class="button secondary round full justify-start" href={notif.address} title={notif.content.clone()}>
|
||||
|
@ -631,7 +628,7 @@ fn build_notifications_renderer_with_props(
|
|||
/// Available at "/d/notifications"
|
||||
pub async fn notifications_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::bundlesdb::AppData>,
|
||||
data: web::Data<AppData>,
|
||||
info: web::Query<crate::api::pastes::OffsetQueryProps>,
|
||||
) -> impl Responder {
|
||||
// verify auth status
|
||||
|
@ -783,7 +780,7 @@ fn build_inbox_renderer_with_props(props: InboxProps) -> ServerRenderer<Inbox> {
|
|||
/// Available at "/d/inbox"
|
||||
pub async fn inbox_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::bundlesdb::AppData>,
|
||||
data: web::Data<AppData>,
|
||||
info: web::Query<crate::api::pastes::OffsetQueryProps>,
|
||||
) -> impl Responder {
|
||||
// verify auth status
|
||||
|
|
|
@ -5,9 +5,7 @@ use serde_json::json;
|
|||
use yew::prelude::*;
|
||||
use yew::ServerRenderer;
|
||||
|
||||
use crate::db::bundlesdb::{
|
||||
self, AppData, FullPaste, FullUser, Paste, PasteMetadata, UserMetadata,
|
||||
};
|
||||
use crate::db::{self, AppData, FullPaste, FullUser, Paste, PasteMetadata, UserMetadata};
|
||||
|
||||
use crate::utility;
|
||||
use crate::utility::format_html;
|
||||
|
@ -28,7 +26,7 @@ pub struct PasteViewProps {
|
|||
|
||||
#[derive(Default, Properties, PartialEq, serde::Deserialize)]
|
||||
struct DashboardProps {
|
||||
pub pastes: Vec<bundlesdb::PasteIdentifier>,
|
||||
pub pastes: Vec<db::PasteIdentifier>,
|
||||
pub auth_state: Option<bool>,
|
||||
pub offset: i32,
|
||||
}
|
||||
|
@ -204,7 +202,7 @@ pub async fn paste_view_request(
|
|||
let url: String = req.match_info().get("url").unwrap().to_string();
|
||||
let url_c = url.clone();
|
||||
|
||||
let paste: bundlesdb::DefaultReturn<Option<FullPaste<PasteMetadata, String>>> =
|
||||
let paste: db::DefaultReturn<Option<FullPaste<PasteMetadata, String>>> =
|
||||
data.db.get_paste_by_url(url).await;
|
||||
|
||||
if paste.success == false {
|
||||
|
@ -265,7 +263,7 @@ pub async fn paste_view_request(
|
|||
|
||||
// handle atomic pastes (just return index.html)
|
||||
if unwrap.paste.content.contains("\"_is_atomic\":true") {
|
||||
let real_content = serde_json::from_str::<bundlesdb::AtomicPaste>(&unwrap.paste.content);
|
||||
let real_content = serde_json::from_str::<db::AtomicPaste>(&unwrap.paste.content);
|
||||
|
||||
if real_content.is_err() {
|
||||
return HttpResponse::NotAcceptable().body("Paste failed to deserialize");
|
||||
|
@ -396,7 +394,7 @@ pub async fn atomic_paste_view_request(
|
|||
let url: String = req.match_info().get("url").unwrap().to_string();
|
||||
let path: String = req.match_info().get("path").unwrap().to_string();
|
||||
|
||||
let paste: bundlesdb::DefaultReturn<Option<FullPaste<PasteMetadata, String>>> =
|
||||
let paste: db::DefaultReturn<Option<FullPaste<PasteMetadata, String>>> =
|
||||
data.db.get_paste_by_url(url).await;
|
||||
|
||||
if paste.success == false {
|
||||
|
@ -413,7 +411,7 @@ pub async fn atomic_paste_view_request(
|
|||
|
||||
// handle atomic pastes (just return index.html)
|
||||
if unwrap.paste.content.contains("\"_is_atomic\":true") {
|
||||
let real_content = serde_json::from_str::<bundlesdb::AtomicPaste>(&unwrap.paste.content);
|
||||
let real_content = serde_json::from_str::<db::AtomicPaste>(&unwrap.paste.content);
|
||||
|
||||
if real_content.is_err() {
|
||||
return HttpResponse::NotAcceptable().body("Paste failed to deserialize");
|
||||
|
@ -526,7 +524,7 @@ fn build_dashboard_renderer_with_props(props: DashboardProps) -> ServerRenderer<
|
|||
/// Available at "/d/pastes"
|
||||
pub async fn dashboard_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<bundlesdb::AppData>,
|
||||
data: web::Data<db::AppData>,
|
||||
info: web::Query<crate::api::pastes::OffsetQueryProps>,
|
||||
) -> impl Responder {
|
||||
// verify auth status
|
||||
|
|
|
@ -4,7 +4,7 @@ use actix_web::{get, web, HttpRequest, Responder};
|
|||
use yew::prelude::*;
|
||||
use yew::ServerRenderer;
|
||||
|
||||
use crate::db::bundlesdb::{self, AppData, FullPaste, Paste, PasteMetadata};
|
||||
use crate::db::{self, AppData, FullPaste, Paste, PasteMetadata};
|
||||
use crate::utility::format_html;
|
||||
|
||||
use crate::components::navigation::Footer;
|
||||
|
@ -151,7 +151,7 @@ pub async fn paste_settings_request(
|
|||
let url: String = req.match_info().get("url").unwrap().to_string();
|
||||
let url_c = url.clone();
|
||||
|
||||
let paste: bundlesdb::DefaultReturn<Option<FullPaste<PasteMetadata, String>>> =
|
||||
let paste: db::DefaultReturn<Option<FullPaste<PasteMetadata, String>>> =
|
||||
data.db.get_paste_by_url(url).await;
|
||||
|
||||
if paste.success == false {
|
||||
|
|
|
@ -5,8 +5,7 @@ use yew::prelude::*;
|
|||
use yew::ServerRenderer;
|
||||
|
||||
use crate::components::navigation::{Footer, GlobalMenu};
|
||||
use crate::db::bundlesdb::{DefaultReturn, FullUser};
|
||||
use crate::db::{self, bundlesdb};
|
||||
use crate::db::{self, DefaultReturn, FullUser};
|
||||
use crate::utility::format_html;
|
||||
|
||||
use crate::api::pastes::OffsetQueryProps;
|
||||
|
@ -19,7 +18,7 @@ struct DashboardProps {
|
|||
#[derive(Default, Properties, PartialEq, serde::Deserialize)]
|
||||
struct BoardsProps {
|
||||
pub offset: i32,
|
||||
pub posts: Vec<bundlesdb::Log>,
|
||||
pub posts: Vec<db::Log>,
|
||||
pub auth_state: Option<bool>,
|
||||
}
|
||||
|
||||
|
@ -84,10 +83,7 @@ fn build_dashboard_renderer_with_props(props: DashboardProps) -> ServerRenderer<
|
|||
|
||||
#[get("/d/staff")]
|
||||
/// Available at "/d/staff"
|
||||
pub async fn dashboard_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::bundlesdb::AppData>,
|
||||
) -> impl Responder {
|
||||
pub async fn dashboard_request(req: HttpRequest, data: web::Data<db::AppData>) -> impl Responder {
|
||||
// verify auth status
|
||||
let token_cookie = req.cookie("__Secure-Token");
|
||||
let mut set_cookie: &str = "";
|
||||
|
@ -196,7 +192,7 @@ fn BoardsDashboard(props: &BoardsProps) -> Html {
|
|||
|
||||
<div class="card round secondary flex g-4 flex-column justify-center" id="boards_list">
|
||||
{for props.posts.iter().map(|p| {
|
||||
let post = serde_json::from_str::<bundlesdb::BoardPostLog>(&p.content).unwrap();
|
||||
let post = serde_json::from_str::<db::BoardPostLog>(&p.content).unwrap();
|
||||
|
||||
html! {
|
||||
<a class="button secondary round full justify-start" href={format!("::PUFFER_ROOT::/{}/posts/{}", &post.board, &p.id)}>
|
||||
|
@ -228,7 +224,7 @@ fn build_boards_dashboard_renderer_with_props(
|
|||
/// Available at "/d/staff/boards"
|
||||
pub async fn staff_boards_dashboard_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::bundlesdb::AppData>,
|
||||
data: web::Data<db::AppData>,
|
||||
info: web::Query<OffsetQueryProps>,
|
||||
) -> impl Responder {
|
||||
// verify auth status
|
||||
|
@ -272,7 +268,7 @@ You can create an account at: /d/auth/register",
|
|||
}
|
||||
|
||||
// get posts
|
||||
let posts: bundlesdb::DefaultReturn<Option<Vec<bundlesdb::Log>>> =
|
||||
let posts: db::DefaultReturn<Option<Vec<db::Log>>> =
|
||||
data.db.fetch_most_recent_posts(info.offset).await;
|
||||
|
||||
// ...
|
||||
|
@ -398,7 +394,7 @@ fn build_users_dashboard_renderer_with_props(props: UsersProps) -> ServerRendere
|
|||
/// Available at "/d/staff/users"
|
||||
pub async fn staff_users_dashboard_request(
|
||||
req: HttpRequest,
|
||||
data: web::Data<db::bundlesdb::AppData>,
|
||||
data: web::Data<db::AppData>,
|
||||
info: web::Query<UsersQueryProps>,
|
||||
) -> impl Responder {
|
||||
// verify auth status
|
||||
|
@ -442,7 +438,7 @@ You can create an account at: /d/auth/register",
|
|||
}
|
||||
|
||||
// get user
|
||||
let user: bundlesdb::DefaultReturn<Option<FullUser<String>>> = if info.username.is_some() {
|
||||
let user: db::DefaultReturn<Option<FullUser<String>>> = if info.username.is_some() {
|
||||
data.db
|
||||
.get_user_by_username(info.username.as_ref().unwrap().to_owned())
|
||||
.await
|
||||
|
|
Loading…
Reference in a new issue