"lemmy_utils",
"lemmy_websocket",
"serde",
+ "serde_json",
"url",
]
mark_post_as_read,
post::*,
};
-use lemmy_apub::{generate_apub_endpoint, ApubLikeableType, EndpointType};
+use lemmy_apub::{
+ activities::post::create::CreatePost as CreateApubPost,
+ generate_apub_endpoint,
+ ApubLikeableType,
+ EndpointType,
+};
use lemmy_db_queries::{source::post::Post_, Crud, Likeable};
use lemmy_db_schema::source::post::*;
use lemmy_db_views::post_view::PostView;
.await?
.map_err(|_| ApiError::err("couldnt_create_post"))?;
- lemmy_apub::activities::post::create::CreatePost::send(
- &updated_post,
- &local_user_view.person,
- context,
- )
- .await?;
+ CreateApubPost::send(&updated_post, &local_user_view.person, context).await?;
// They like their own post by default
let person_id = local_user_view.person.id;
NoteExt,
};
use activitystreams::{activity::kind::CreateType, base::BaseExt};
-use lemmy_apub_lib::{verify_domains_match_opt, ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{
+ values::PublicUrl,
+ verify_domains_match_opt,
+ ActivityCommonFields,
+ ActivityHandler,
+};
use lemmy_db_schema::source::comment::Comment;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
-use crate::activities::{comment::send_websocket_message, verify_mod_action};
+use crate::{
+ activities::{comment::send_websocket_message, verify_mod_action},
+ check_is_apub_id_valid,
+ fetcher::objects::get_or_fetch_and_insert_comment,
+};
use activitystreams::activity::kind::RemoveType;
use lemmy_api_common::blocking;
-use crate::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_comment};
-use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
+use lemmy_apub_lib::{
+ values::PublicUrl,
+ verify_domains_match,
+ ActivityCommonFields,
+ ActivityHandlerNew,
+};
use lemmy_db_queries::source::comment::Comment_;
use lemmy_db_schema::source::comment::Comment;
use lemmy_utils::LemmyError;
-use crate::activities::{
- comment::{remove::RemoveComment, send_websocket_message},
- verify_mod_action,
+use crate::{
+ activities::{
+ comment::{remove::RemoveComment, send_websocket_message},
+ verify_mod_action,
+ },
+ check_is_apub_id_valid,
+ fetcher::objects::get_or_fetch_and_insert_comment,
};
use activitystreams::activity::kind::UndoType;
use lemmy_api_common::blocking;
-use crate::{check_is_apub_id_valid, fetcher::objects::get_or_fetch_and_insert_comment};
-use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandlerNew, PublicUrl};
+use lemmy_apub_lib::{
+ values::PublicUrl,
+ verify_domains_match,
+ ActivityCommonFields,
+ ActivityHandlerNew,
+};
use lemmy_db_queries::source::comment::Comment_;
use lemmy_db_schema::source::comment::Comment;
use lemmy_utils::LemmyError;
NoteExt,
};
use activitystreams::{activity::kind::UpdateType, base::BaseExt};
-use lemmy_apub_lib::{verify_domains_match_opt, ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{
+ values::PublicUrl,
+ verify_domains_match_opt,
+ ActivityCommonFields,
+ ActivityHandler,
+};
use lemmy_db_schema::source::comment::Comment;
use lemmy_utils::LemmyError;
use lemmy_websocket::{LemmyContext, UserOperationCrud};
};
use activitystreams::{activity::kind::AddType, base::AnyBase};
use lemmy_api_common::blocking;
-use lemmy_apub_lib::{ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
use lemmy_db_queries::{source::community::CommunityModerator_, Joinable};
use lemmy_db_schema::source::community::{CommunityModerator, CommunityModeratorForm};
use lemmy_utils::LemmyError;
CommunityType,
};
use activitystreams::activity::kind::AnnounceType;
-use lemmy_apub_lib::{ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
use lemmy_db_schema::source::community::Community;
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
};
use activitystreams::activity::kind::BlockType;
use lemmy_api_common::blocking;
-use lemmy_apub_lib::{ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
use lemmy_db_queries::{Bannable, Followable};
use lemmy_db_schema::source::community::{
CommunityFollower,
};
use activitystreams::activity::kind::UndoType;
use lemmy_api_common::blocking;
-use lemmy_apub_lib::{ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
use lemmy_db_queries::Bannable;
use lemmy_db_schema::source::community::{CommunityPersonBan, CommunityPersonBanForm};
use lemmy_utils::LemmyError;
};
use activitystreams::activity::kind::UpdateType;
use lemmy_api_common::blocking;
-use lemmy_apub_lib::{ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
use lemmy_db_queries::{ApubObject, Crud};
use lemmy_db_schema::source::community::{Community, CommunityForm};
use lemmy_utils::LemmyError;
};
use activitystreams::activity::kind::DeleteType;
use lemmy_api_common::blocking;
-use lemmy_apub_lib::{verify_urls_match, ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, verify_urls_match, ActivityCommonFields, ActivityHandler};
use lemmy_db_queries::{
source::{comment::Comment_, community::Community_, post::Post_},
Crud,
};
use activitystreams::activity::kind::UndoType;
use lemmy_api_common::blocking;
-use lemmy_apub_lib::{verify_urls_match, ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, verify_urls_match, ActivityCommonFields, ActivityHandler};
use lemmy_db_queries::source::{comment::Comment_, community::Community_, post::Post_};
use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post};
use lemmy_utils::LemmyError;
use anyhow::anyhow;
use lemmy_api_common::blocking;
use lemmy_apub_lib::{
+ values::PublicUrl,
verify_domains_match,
verify_urls_match,
ActivityCommonFields,
ActivityHandler,
- PublicUrl,
};
use lemmy_db_queries::Crud;
use lemmy_db_schema::source::{community::Community, person::Person, post::Post};
};
use activitystreams::activity::kind::UpdateType;
use lemmy_api_common::blocking;
-use lemmy_apub_lib::{verify_urls_match, ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, verify_urls_match, ActivityCommonFields, ActivityHandler};
use lemmy_db_queries::Crud;
use lemmy_db_schema::source::{community::Community, person::Person, post::Post};
use lemmy_utils::LemmyError;
use activitystreams::{activity::kind::RemoveType, base::AnyBase};
use anyhow::anyhow;
use lemmy_api_common::blocking;
-use lemmy_apub_lib::{ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
use lemmy_db_queries::{
source::{comment::Comment_, community::Community_, post::Post_},
Joinable,
use activitystreams::activity::kind::UndoType;
use anyhow::anyhow;
use lemmy_api_common::blocking;
-use lemmy_apub_lib::{ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
use lemmy_db_queries::source::{comment::Comment_, community::Community_, post::Post_};
use lemmy_db_schema::source::{comment::Comment, community::Community, post::Post};
use lemmy_utils::LemmyError;
voting::receive_like_or_dislike,
};
use activitystreams::activity::kind::DislikeType;
-use lemmy_apub_lib::{ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
voting::receive_like_or_dislike,
};
use activitystreams::activity::kind::LikeType;
-use lemmy_apub_lib::{ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
voting::{dislike::DislikePostOrComment, receive_undo_like_or_dislike},
};
use activitystreams::activity::kind::UndoType;
-use lemmy_apub_lib::{verify_urls_match, ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, verify_urls_match, ActivityCommonFields, ActivityHandler};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
voting::{like::LikePostOrComment, receive_undo_like_or_dislike},
};
use activitystreams::activity::kind::UndoType;
-use lemmy_apub_lib::{verify_urls_match, ActivityCommonFields, ActivityHandler, PublicUrl};
+use lemmy_apub_lib::{values::PublicUrl, verify_urls_match, ActivityCommonFields, ActivityHandler};
use lemmy_utils::LemmyError;
use lemmy_websocket::LemmyContext;
use url::Url;
use anyhow::{anyhow, Context};
use chrono::NaiveDateTime;
use lemmy_api_common::blocking;
+use lemmy_apub_lib::values::MediaTypeMarkdown;
use lemmy_db_queries::{ApubObject, Crud, DbPool};
use lemmy_db_schema::{CommunityId, DbUrl};
use lemmy_utils::{
Self: Sized;
}
-#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
-pub enum MediaTypeMarkdown {
- #[serde(rename = "text/markdown")]
- Markdown,
-}
-
-#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
-pub enum MediaTypeHtml {
- #[serde(rename = "text/html")]
- Markdown,
-}
-
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Source {
activities::extract_community,
extensions::context::lemmy_context,
fetcher::person::get_or_fetch_and_upsert_person,
- objects::{create_tombstone, FromApub, MediaTypeHtml, MediaTypeMarkdown, Source, ToApub},
+ objects::{create_tombstone, FromApub, Source, ToApub},
};
use activitystreams::{
base::AnyBase,
};
use chrono::{DateTime, FixedOffset};
use lemmy_api_common::blocking;
-use lemmy_apub_lib::verify_domains_match;
+use lemmy_apub_lib::{
+ values::{MediaTypeHtml, MediaTypeMarkdown},
+ verify_domains_match,
+};
use lemmy_db_queries::{ApubObject, Crud, DbPool};
use lemmy_db_schema::{
self,
to: [community.actor_id.into(), public()],
name: self.name.clone(),
content: self.body.as_ref().map(|b| markdown_to_html(b)),
- media_type: MediaTypeHtml::Markdown,
+ media_type: MediaTypeHtml::Html,
source,
url: self.url.clone().map(|u| u.into()),
image,
serde = { version = "1.0.123", features = ["derive"] }
async-trait = "0.1.42"
url = { version = "2.2.1", features = ["serde"] }
+serde_json = { version = "1.0.64", features = ["preserve_order"] }
+pub mod values;
+
use activitystreams::{
base::AnyBase,
error::DomainError,
use lemmy_websocket::LemmyContext;
use url::Url;
-#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
-pub enum PublicUrl {
- #[serde(rename = "https://www.w3.org/ns/activitystreams#Public")]
- Public,
-}
-
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ActivityCommonFields {
--- /dev/null
+//! The enums here serve to limit a json string value to a single, hardcoded value which can be
+//! verified at compilation time. When using it as the type of a struct field, the struct can only
+//! be constructed or deserialized if the field has the exact same value.
+//!
+//! If we used String as the field type, any value would be accepted, and we would have to check
+//! manually at runtime that it contains the expected value.
+//!
+//! The enums in [`activitystreams::activity::kind`] work in the same way, and can be used to
+//! distinguish different activity types.
+//!
+//! In the example below, `MyObject` can only be constructed or
+//! deserialized if `media_type` is `text/markdown`, but not if it is `text/html`.
+//!
+//! ```
+//! use lemmy_apub_lib::values::MediaTypeMarkdown;
+//! use serde_json::from_str;
+//! use serde::{Deserialize, Serialize};
+//!
+//! #[derive(Deserialize, Serialize)]
+//! struct MyObject {
+//! content: String,
+//! media_type: MediaTypeMarkdown,
+//! }
+//!
+//! let markdown_json = r#"{"content": "**test**", "media_type": "text/markdown"}"#;
+//! let from_markdown = from_str::<MyObject>(markdown_json);
+//! assert!(from_markdown.is_ok());
+//!
+//! let markdown_html = r#"{"content": "<b>test</b>", "media_type": "text/html"}"#;
+//! let from_html = from_str::<MyObject>(markdown_html);
+//! assert!(from_html.is_err());
+//! ```
+
+use serde::{Deserialize, Serialize};
+
+/// The identifier used to address activities to the public.
+///
+/// <https://www.w3.org/TR/activitypub/#public-addressing>
+#[derive(Debug, Clone, Deserialize, Serialize)]
+pub enum PublicUrl {
+ #[serde(rename = "https://www.w3.org/ns/activitystreams#Public")]
+ Public,
+}
+
+/// Media type for markdown text.
+///
+/// <https://www.iana.org/assignments/media-types/media-types.xhtml>
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub enum MediaTypeMarkdown {
+ #[serde(rename = "text/markdown")]
+ Markdown,
+}
+
+/// Media type for HTML text/
+///
+/// <https://www.iana.org/assignments/media-types/media-types.xhtml>
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub enum MediaTypeHtml {
+ #[serde(rename = "text/html")]
+ Html,
+}