Skip to content

Commit

Permalink
Merge pull request #3 from daystram/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
daystram authored Jan 21, 2021
2 parents 43d8c2b + 03a8bae commit af104be
Show file tree
Hide file tree
Showing 12 changed files with 267 additions and 142 deletions.
12 changes: 9 additions & 3 deletions cut-be/src/app/controllers/v1/cut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ pub async fn get_cut_raw(m: web::Data<Module>, req: HttpRequest) -> impl Respond
let id: String = req.match_info().query("id").parse().unwrap();
match handlers::cut::get_one(m, id) {
Ok(cut) => match cut.variant.as_str() {
constants::VARIANT_SNIPPET => HttpResponse::Ok().body(cut.data),
constants::VARIANT_SNIPPET => HttpResponse::Ok()
.header("Content-Type", "text/plain")
.body(cut.data),
constants::VARIANT_URL => HttpResponse::TemporaryRedirect()
.header("Location", cut.data)
.finish(),
Expand Down Expand Up @@ -42,7 +44,7 @@ pub async fn get_cut(m: web::Data<Module>, req: HttpRequest) -> impl Responder {
#[post("")]
pub async fn post_snippet_create(
m: web::Data<Module>,
cut: web::Json<Cut>,
mut cut: web::Json<Cut>,
req: HttpRequest,
) -> impl Responder {
let user: TokenInfo = match handlers::auth::authorize(&m, &req).await {
Expand All @@ -57,7 +59,11 @@ pub async fn post_snippet_create(
constants::VARIANT_URL => (),
_ => return HttpResponse::BadRequest().finish(),
};
match handlers::cut::insert(m, user.sub, cut.0) {
if cut.data.trim().chars().count() == 0 {
return HttpResponse::BadRequest().finish();
};
cut.0.owner = user.sub;
match handlers::cut::insert(m, cut.0) {
Ok(hash) => HttpResponse::Ok().json(CreateResponse { hash: hash }),
Err(e) => HttpResponse::InternalServerError().body(format!("{:?}", e)),
}
Expand Down
67 changes: 66 additions & 1 deletion cut-be/src/app/datatransfers/cut.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::core::error::{HandlerError, HandlerErrorKind};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::time::{SystemTime, UNIX_EPOCH};

#[derive(Debug, Serialize, Deserialize)]
pub struct Cut {
Expand All @@ -8,8 +11,70 @@ pub struct Cut {
pub variant: String,
pub metadata: String,
pub data: String,
#[serde(skip_deserializing)]
pub expiry: i64,
#[serde(default = "current_time")]
pub created_at: u64,
#[serde(default = "Default::default")]
pub views: u64,
}

fn current_time() -> u64 {
match SystemTime::now().duration_since(UNIX_EPOCH) {
Ok(duration) => duration.as_secs(),
Err(_) => 0,
}
}

impl Cut {
pub fn from_hashmap(res: HashMap<String, String>) -> Result<Self, HandlerError> {
Ok(Cut {
name: res
.get("name")
.ok_or(HandlerErrorKind::RedisError)?
.to_string(),
owner: res
.get("owner")
.ok_or(HandlerErrorKind::RedisError)?
.to_string(),
variant: res
.get("variant")
.ok_or(HandlerErrorKind::RedisError)?
.to_string(),
metadata: res
.get("metadata")
.ok_or(HandlerErrorKind::RedisError)?
.to_string(),
data: res
.get("data")
.ok_or(HandlerErrorKind::RedisError)?
.to_string(),
expiry: res
.get("expiry")
.ok_or(HandlerErrorKind::RedisError)?
.parse()?,
created_at: res
.get("created_at")
.ok_or(HandlerErrorKind::RedisError)?
.parse()?,
views: res
.get("views")
.ok_or(HandlerErrorKind::RedisError)?
.parse()?,
})
}

pub fn to_array(&self) -> [(&str, String); 8] {
return [
("name", self.name.clone()),
("owner", self.owner.clone()),
("variant", self.variant.clone()),
("metadata", self.metadata.clone()),
("data", self.data.clone()),
("expiry", self.expiry.to_string()),
("created_at", self.created_at.to_string()),
("views", self.views.to_string()),
];
}
}

#[derive(Debug, Serialize, Deserialize)]
Expand Down
79 changes: 25 additions & 54 deletions cut-be/src/app/handlers/cut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,72 +3,43 @@ use crate::core::error::{HandlerError, HandlerErrorKind};
use crate::utils::hash;
use actix_web::web;
use r2d2_redis::redis::Commands;
use std::{
collections::HashMap,
time::{SystemTime, UNIX_EPOCH},
};
use std::collections::HashMap;

pub fn get_one(m: web::Data<Module>, id: String) -> Result<Cut, HandlerError> {
pub fn get_one(m: web::Data<Module>, hash: String) -> Result<Cut, HandlerError> {
let rd = &mut m.rd_pool.get()?;
match rd.hgetall::<String, HashMap<String, String>>(id) {
let key = format!("cut::{}", hash);
let mut cut: Cut = match rd.hgetall::<String, HashMap<String, String>>(key.clone()) {
Ok(res) => {
if res.is_empty() {
return Err(HandlerErrorKind::CutNotFoundError.into());
}
Ok(Cut {
name: res
.get("name")
.ok_or(HandlerErrorKind::CutNotFoundError)?
.to_string(),
owner: res
.get("owner")
.ok_or(HandlerErrorKind::CutNotFoundError)?
.to_string(),
variant: res
.get("variant")
.ok_or(HandlerErrorKind::CutNotFoundError)?
.to_string(),
metadata: res
.get("metadata")
.ok_or(HandlerErrorKind::CutNotFoundError)?
.to_string(),
data: res
.get("data")
.ok_or(HandlerErrorKind::CutNotFoundError)?
.to_string(),
created_at: res
.get("created_at")
.ok_or(HandlerErrorKind::CutNotFoundError)?
.parse()?,
})
Cut::from_hashmap(res)?
}
Err(e) => Err(e.into()),
Err(e) => return Err(e.into()),
};
cut.views += 1;
if cut.expiry < 0 {
let _ = rd.del::<String, i32>(key.clone());
} else {
let _ = rd.hset::<String, &str, u64, i32>(key.clone(), "views", cut.views);
}
Ok(cut)
}

pub fn insert(
m: web::Data<Module>,
user_subject: String,
cut: Cut,
) -> Result<String, HandlerError> {
pub fn insert(m: web::Data<Module>, cut: Cut) -> Result<String, HandlerError> {
let rd = &mut m.rd_pool.get()?;
let hash: String = hash::generate(HASH_LENGTH).into();
let created_at = match SystemTime::now().duration_since(UNIX_EPOCH) {
Ok(duration) => duration.as_secs(),
Err(_) => return Err(HandlerErrorKind::GeneralError.into()),
};
match rd.hset_multiple::<String, &str, String, String>(
hash.clone(),
&[
("name", cut.name),
("owner", user_subject),
("variant", cut.variant),
("metadata", cut.metadata),
("data", cut.data),
("created_at", created_at.to_string()),
],
) {
Ok(_) => Ok(hash),
let key = format!("cut::{}", hash.clone());
match rd.hset_multiple::<String, &str, String, String>(key.clone(), &cut.to_array()) {
Ok(_) => {
if cut.expiry < 0 {
return Ok(hash);
};
match rd.expire::<String, i32>(key.clone(), cut.expiry as usize) {
Ok(_) => Ok(hash),
Err(e) => Err(e.into()),
}
}
Err(e) => Err(e.into()),
}
}
12 changes: 12 additions & 0 deletions cut-fe/src/constants/expiries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const expiries: {
[name: string]: number;
} = {
"Delete after read": -1,
"1 minute": 60,
"10 minutes": 600,
"1 hour": 3600,
"12 hours": 12 * 3600,
"1 day": 24 * 3600,
"2 days": 2 * 24 * 3600,
"1 week": 7 * 24 * 3600
};
5 changes: 5 additions & 0 deletions cut-fe/src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { expiries } from "./expiries";
import { languages } from "./languages";
import { STATUS } from "./status";

export { expiries, languages, STATUS };
6 changes: 5 additions & 1 deletion cut-fe/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const routes: Array<RouteConfig> = [
beforeEnter: authenticatedOnly,
component: Create,
meta: {
title: "Create Cut | Cut"
title: "Create | Cut"
}
},
{
Expand Down Expand Up @@ -75,6 +75,10 @@ const routes: Array<RouteConfig> = [
meta: {
title: "View Cut | Cut"
}
},
{
path: "*",
redirect: { name: "home" }
}
]
}
Expand Down
3 changes: 3 additions & 0 deletions cut-fe/src/styles/App.sass
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ a.text-link:hover
box-shadow: inset 0 -2px 0 var(--v-primary-base)
transition: 200ms

h1
line-height: normal !important

.v-card > .v-card__title
padding: 16px 16px 16px 24px !important

Expand Down
1 change: 1 addition & 0 deletions cut-fe/src/styles/Create.sass
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
font-size: 14px
line-height: 1.5
padding: 20px 5px
border: 1px solid #fff4

#view-link, #raw-link
font-family: Fira code, Fira Mono, Consolas, Menlo, Courier, monospace
Expand Down
17 changes: 17 additions & 0 deletions cut-fe/src/utils/highlighter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Prism from "prismjs";
import { languages } from "@/constants";

export function highlighter(language: string): Function {
return (code: string): string => {
if (language === "Plaintext")
return code
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
return Prism.highlight(
code,
languages[language].grammar,
languages[language].language
);
};
}
Loading

0 comments on commit af104be

Please sign in to comment.