mirror of
https://github.com/cupcakearmy/cryptgeon.git
synced 2025-09-06 01:10:40 +00:00
2 (#38)
* use redis * update frontend and switch sanitize library * changelog * theming * docker image * documentation * changelog * clear up limit sizes * version bump * version bump
This commit is contained in:
@@ -1,13 +1,18 @@
|
||||
use byte_unit::Byte;
|
||||
|
||||
// General
|
||||
lazy_static! {
|
||||
pub static ref VERSION: String = option_env!("CARGO_PKG_VERSION")
|
||||
.unwrap_or("Unknown")
|
||||
.to_string();
|
||||
pub static ref LIMIT: u32 =
|
||||
pub static ref VERSION: String = option_env!("CARGO_PKG_VERSION")
|
||||
.unwrap_or("Unknown")
|
||||
.to_string();
|
||||
}
|
||||
|
||||
// CONFIG
|
||||
lazy_static! {
|
||||
pub static ref LIMIT: usize =
|
||||
Byte::from_str(std::env::var("SIZE_LIMIT").unwrap_or("1 KiB".to_string()))
|
||||
.unwrap()
|
||||
.get_bytes() as u32;
|
||||
.get_bytes() as usize;
|
||||
pub static ref MAX_VIEWS: u32 = std::env::var("MAX_VIEWS")
|
||||
.unwrap_or("100".to_string())
|
||||
.parse()
|
||||
@@ -21,3 +26,15 @@ lazy_static! {
|
||||
.parse()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// THEME
|
||||
lazy_static! {
|
||||
pub static ref THEME_IMAGE: String = std::env::var("THEME_IMAGE")
|
||||
.unwrap_or("".to_string())
|
||||
.parse()
|
||||
.unwrap();
|
||||
pub static ref THEME_TEXT: String = std::env::var("THEME_TEXT")
|
||||
.unwrap_or("".to_string())
|
||||
.parse()
|
||||
.unwrap();
|
||||
}
|
||||
|
@@ -1,4 +1,7 @@
|
||||
use actix_web::{middleware, web, App, HttpServer};
|
||||
use actix_web::{
|
||||
middleware::{self, Logger},
|
||||
web, App, HttpServer,
|
||||
};
|
||||
use dotenv::dotenv;
|
||||
|
||||
#[macro_use]
|
||||
@@ -15,8 +18,10 @@ mod store;
|
||||
#[actix_web::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
dotenv().ok();
|
||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("warning"));
|
||||
return HttpServer::new(|| {
|
||||
App::new()
|
||||
.wrap(Logger::new("%a \"%r\" %s %b %T"))
|
||||
.wrap(middleware::Compress::default())
|
||||
.wrap(middleware::DefaultHeaders::default())
|
||||
.configure(size::init)
|
||||
|
@@ -22,9 +22,11 @@ struct NotePath {
|
||||
async fn one(path: web::Path<NotePath>) -> impl Responder {
|
||||
let p = path.into_inner();
|
||||
let note = store::get(&p.id);
|
||||
|
||||
match note {
|
||||
None => return HttpResponse::NotFound().finish(),
|
||||
Some(_) => return HttpResponse::Ok().json(NoteInfo {}),
|
||||
Ok(Some(_)) => HttpResponse::Ok().json(NoteInfo {}),
|
||||
Ok(None) => HttpResponse::NotFound().finish(),
|
||||
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,8 +66,10 @@ async fn create(note: web::Json<Note>) -> impl Responder {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
store::set(&id.clone(), &n.clone());
|
||||
return HttpResponse::Ok().json(CreateResponse { id: id });
|
||||
match store::set(&id.clone(), &n.clone()) {
|
||||
Ok(_) => return HttpResponse::Ok().json(CreateResponse { id: id }),
|
||||
Err(e) => return HttpResponse::InternalServerError().body(e.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
#[delete("/{id}")]
|
||||
@@ -73,8 +77,9 @@ async fn delete(path: web::Path<NotePath>) -> impl Responder {
|
||||
let p = path.into_inner();
|
||||
let note = store::get(&p.id);
|
||||
match note {
|
||||
None => return HttpResponse::NotFound().finish(),
|
||||
Some(note) => {
|
||||
Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
|
||||
Ok(None) => return HttpResponse::NotFound().finish(),
|
||||
Ok(Some(note)) => {
|
||||
let mut changed = note.clone();
|
||||
if changed.views == None && changed.expiration == None {
|
||||
return HttpResponse::BadRequest().finish();
|
||||
@@ -84,9 +89,19 @@ async fn delete(path: web::Path<NotePath>) -> impl Responder {
|
||||
changed.views = Some(v - 1);
|
||||
let id = p.id.clone();
|
||||
if v <= 1 {
|
||||
store::del(&id);
|
||||
match store::del(&id) {
|
||||
Err(e) => {
|
||||
return HttpResponse::InternalServerError().body(e.to_string())
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
store::set(&id, &changed.clone());
|
||||
match store::set(&id, &changed.clone()) {
|
||||
Err(e) => {
|
||||
return HttpResponse::InternalServerError().body(e.to_string())
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@@ -96,8 +111,12 @@ async fn delete(path: web::Path<NotePath>) -> impl Responder {
|
||||
match changed.expiration {
|
||||
Some(e) => {
|
||||
if e < n {
|
||||
store::del(&p.id.clone());
|
||||
return HttpResponse::BadRequest().finish();
|
||||
match store::del(&p.id.clone()) {
|
||||
Ok(_) => return HttpResponse::BadRequest().finish(),
|
||||
Err(e) => {
|
||||
return HttpResponse::InternalServerError().body(e.to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@@ -1,18 +1,11 @@
|
||||
use crate::config;
|
||||
use actix_web::web;
|
||||
use byte_unit::Byte;
|
||||
use mime;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref LIMIT: usize =
|
||||
Byte::from_str(std::env::var("SIZE_LIMIT").unwrap_or("1 KiB".to_string()))
|
||||
.unwrap()
|
||||
.get_bytes() as usize;
|
||||
}
|
||||
|
||||
pub fn init(cfg: &mut web::ServiceConfig) {
|
||||
let json = web::JsonConfig::default().limit(*LIMIT);
|
||||
let json = web::JsonConfig::default().limit(*config::LIMIT);
|
||||
let plain = web::PayloadConfig::default()
|
||||
.limit(*LIMIT)
|
||||
.limit(*config::LIMIT)
|
||||
.mimetype(mime::STAR_STAR);
|
||||
cfg.app_data(json).app_data(plain);
|
||||
}
|
||||
|
@@ -2,9 +2,14 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Status {
|
||||
// General
|
||||
pub version: String,
|
||||
// Config
|
||||
pub max_size: u32,
|
||||
pub max_views: u32,
|
||||
pub max_expiration: u32,
|
||||
pub allow_advanced: bool,
|
||||
// Theme
|
||||
pub theme_image: String,
|
||||
pub theme_text: String,
|
||||
}
|
||||
|
@@ -7,10 +7,12 @@ use crate::status::Status;
|
||||
async fn get_status() -> impl Responder {
|
||||
return HttpResponse::Ok().json(Status {
|
||||
version: config::VERSION.to_string(),
|
||||
max_size: *config::LIMIT,
|
||||
max_size: *config::LIMIT as u32,
|
||||
max_views: *config::MAX_VIEWS,
|
||||
max_expiration: *config::MAX_EXPIRATION,
|
||||
allow_advanced: *config::ALLOW_ADVANCED,
|
||||
theme_image: config::THEME_IMAGE.to_string(),
|
||||
theme_text: config::THEME_TEXT.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -1,36 +1,55 @@
|
||||
use memcache;
|
||||
use redis;
|
||||
use redis::Commands;
|
||||
|
||||
use crate::note::now;
|
||||
use crate::note::Note;
|
||||
|
||||
lazy_static! {
|
||||
static ref CLIENT: memcache::Client = memcache::connect(format!(
|
||||
"memcache://{}?timeout=10&tcp_nodelay=true",
|
||||
std::env::var("MEMCACHE").unwrap_or("127.0.0.1:11211".to_string())
|
||||
))
|
||||
.unwrap();
|
||||
static ref REDIS_CLIENT: String = std::env::var("REDIS")
|
||||
.unwrap_or("redis://127.0.0.1/".to_string())
|
||||
.parse()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn set(id: &String, note: &Note) {
|
||||
fn get_connection() -> Result<redis::Connection, &'static str> {
|
||||
let client =
|
||||
redis::Client::open(REDIS_CLIENT.to_string()).map_err(|_| "Unable to connect to redis")?;
|
||||
client
|
||||
.get_connection()
|
||||
.map_err(|_| "Unable to connect to redis")
|
||||
}
|
||||
|
||||
pub fn set(id: &String, note: &Note) -> Result<(), &'static str> {
|
||||
let serialized = serde_json::to_string(¬e.clone()).unwrap();
|
||||
let expiration: u32 = match note.expiration {
|
||||
Some(e) => e - now(),
|
||||
None => 0,
|
||||
let mut conn = get_connection()?;
|
||||
|
||||
conn.set(id, serialized)
|
||||
.map_err(|_| "Unable to set note in redis")?;
|
||||
match note.expiration {
|
||||
Some(e) => {
|
||||
let seconds = e - now();
|
||||
conn.expire(id, seconds as usize)
|
||||
.map_err(|_| "Unable to set expiration on notion")?
|
||||
}
|
||||
None => {}
|
||||
};
|
||||
CLIENT.set(id, serialized, expiration).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get(id: &String) -> Option<Note> {
|
||||
let value: Option<String> = CLIENT.get(&id).unwrap();
|
||||
pub fn get(id: &String) -> Result<Option<Note>, &'static str> {
|
||||
let mut conn = get_connection()?;
|
||||
let value: Option<String> = conn.get(id).map_err(|_| "Could not load note in redis")?;
|
||||
match value {
|
||||
None => return None,
|
||||
None => return Ok(None),
|
||||
Some(s) => {
|
||||
let deserialize: Note = serde_json::from_str(&s).unwrap();
|
||||
return Some(deserialize);
|
||||
return Ok(Some(deserialize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn del(id: &String) {
|
||||
CLIENT.delete(id).unwrap();
|
||||
pub fn del(id: &String) -> Result<(), &'static str> {
|
||||
let mut conn = get_connection()?;
|
||||
conn.del(id).map_err(|_| "Unable to delete note in redis")?;
|
||||
Ok(())
|
||||
}
|
||||
|
Reference in New Issue
Block a user