index : paprika

A blogging platform written in Rust for Cloudflare Workers, integrated with Standard Notes

diff options
context:
space:
mode:
authorPeter Cai <[email protected]>2020-04-16 15:59:42 +0800
committerPeter Cai <[email protected]>2020-04-16 15:59:42 +0800
commita9e3490478b2a0bec4efa91a33b272efd48b0387 (patch)
treeecfdfb926512b02f054a596cdb46bb03f30703c4
parentbcd52491c90e335f657c31b4c7eb8bdcf023ae9a (diff)
downloadpaprika-a9e3490478b2a0bec4efa91a33b272efd48b0387.tar.gz
sn: implement the Delete action
-rw-r--r--src/blog.rs8
-rw-r--r--src/sn.rs56
-rw-r--r--src/store.rs7
3 files changed, 62 insertions, 9 deletions
diff --git a/src/blog.rs b/src/blog.rs
index 6acd57d..6ee1c43 100644
--- a/src/blog.rs
+++ b/src/blog.rs
@@ -118,6 +118,10 @@ impl Post {
Self::create_url_mapping(&self.url, &self.uuid).await?;
store::put_obj(&Self::uuid_to_post_key(&self.uuid), self).await
}
+
+ pub async fn delete_by_uuid(uuid: &str) -> MyResult<()> {
+ store::delete(&Self::uuid_to_post_key(uuid)).await
+ }
}
lazy_static! {
@@ -342,4 +346,8 @@ impl PostContentCache {
pub async fn save(&self) -> MyResult<()> {
store::put_obj(&Self::uuid_to_cache_key(&self.uuid), self).await
}
+
+ pub async fn delete_by_uuid(uuid: &str) -> MyResult<()> {
+ store::delete(&Self::uuid_to_cache_key(uuid)).await
+ }
} \ No newline at end of file
diff --git a/src/sn.rs b/src/sn.rs
index 39b4c64..8fef95f 100644
--- a/src/sn.rs
+++ b/src/sn.rs
@@ -11,6 +11,7 @@ use web_sys::*;
pub fn build_routes(router: &mut Router) {
router.add_route("/actions", &get_actions);
router.add_route("/post", &create_or_update_post);
+ router.add_route("/delete", &delete_post);
}
macro_rules! verify_secret {
@@ -55,13 +56,22 @@ async fn get_actions(_req: Request, url: Url) -> MyResult<Response> {
if post_exists {
actions.push(Action {
+ label: "Delete".into(),
+ url: format!("{}/delete?secret={}", origin, CONFIG.secret.clone()),
+ verb: Verb::Post,
+ context: Context::Item,
+ content_types: vec![ContentType::Note],
+ access_type: Some(AccessType::Decrypted)
+ });
+
+ actions.push(Action {
label: "Open Post".into(),
url: format!("{}/{}/", origin, post.unwrap().url),
verb: Verb::Show,
context: Context::Item,
content_types: vec![ContentType::Note],
access_type: None
- })
+ });
}
let info = ActionsExtension {
@@ -173,6 +183,19 @@ fn build_metadata(custom: Option<CustomMetadata>, uuid: &str, title: &str) -> Me
ret
}
+macro_rules! load_post_body {
+ ($data:ident, $req:expr) => {
+ let $data: ActionsPostData = serde_json::from_str(
+ &JsFuture::from($req.text().internal_err()?)
+ .await.internal_err()?
+ .as_string().ok_or(Error::BadRequest("Unable to parse POST body".into()))?
+ ).internal_err()?;
+ if $data.items.len() == 0 {
+ return Err(Error::BadRequest("At least one item must be supplied".into()));
+ }
+ };
+}
+
async fn create_or_update_post(req: Request, url: Url) -> MyResult<Response> {
verify_secret!(url, params);
if req.method() != "POST" {
@@ -180,14 +203,7 @@ async fn create_or_update_post(req: Request, url: Url) -> MyResult<Response> {
}
// Load the information sent as POST body
- let data: ActionsPostData = serde_json::from_str(
- &JsFuture::from(req.text().internal_err()?)
- .await.internal_err()?
- .as_string().ok_or(Error::BadRequest("Unable to parse POST body".into()))?
- ).internal_err()?;
- if data.items.len() == 0 {
- return Err(Error::BadRequest("At least one item must be supplied".into()));
- }
+ load_post_body!(data, req);
let uuid = data.items[0].uuid.clone();
let text = data.items[0].content.text.clone();
@@ -247,6 +263,28 @@ async fn create_or_update_post(req: Request, url: Url) -> MyResult<Response> {
).internal_err()
}
+async fn delete_post(req: Request, url: Url) -> MyResult<Response> {
+ verify_secret!(url, params);
+ if req.method() != "POST" {
+ return Err(Error::BadRequest("Unsupported method".into()));
+ }
+
+ // Load the information sent as POST body
+ load_post_body!(data, req);
+
+ let uuid = &data.items[0].uuid;
+ blog::PostsList::load().await.remove_post(uuid).await?;
+ blog::Post::delete_by_uuid(uuid).await?;
+ blog::PostContentCache::delete_by_uuid(uuid).await?;
+
+ Response::new_with_opt_str_and_init(
+ None,
+ ResponseInit::new()
+ .status(200)
+ .headers(headers!().add_cors().as_ref())
+ ).internal_err()
+}
+
pub enum Verb {
Show,
Post,
diff --git a/src/store.rs b/src/store.rs
index 5878464..a5615de 100644
--- a/src/store.rs
+++ b/src/store.rs
@@ -12,6 +12,8 @@ extern "C" {
fn kv_get(key: &str) -> Promise;
#[wasm_bindgen(js_namespace = PAPRIKA, js_name = "put")]
fn kv_put_str(key: &str, value: &str) -> Promise;
+ #[wasm_bindgen(js_namespace = PAPRIKA, js_name = "delete")]
+ fn kv_delete(key: &str) -> Promise;
}
// Returns empty string ("") if the key is not found
@@ -37,4 +39,9 @@ pub async fn put_obj<T: Serialize>(key: &str, value: T) -> MyResult<()> {
// For example, the user may want to manually edit the order in which posts appear
pub async fn put_obj_pretty<T: Serialize>(key: &str, value: T) -> MyResult<()> {
put_str(key, &serde_json::to_string_pretty(&value).internal_err()?).await
+}
+
+pub async fn delete(key: &str) -> MyResult<()> {
+ JsFuture::from(kv_delete(key)).await.internal_err()?;
+ Ok(())
} \ No newline at end of file