aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Anshul Gupta <ansg191@anshulg.com> 2024-02-18 23:31:24 -0800
committerGravatar Anshul Gupta <ansg191@anshulg.com> 2024-02-18 23:33:06 -0800
commitf1165ab23eda6f5a4afe6a703333025ba68f3b11 (patch)
tree6180df1fa1a7779d7b6181b9ab583c5ff2320217
parentf41b46d02ecd9234f16c35c652b01fdd170b9944 (diff)
downloadtrakt-f1165ab23eda6f5a4afe6a703333025ba68f3b11.tar.gz
trakt-f1165ab23eda6f5a4afe6a703333025ba68f3b11.tar.zst
trakt-f1165ab23eda6f5a4afe6a703333025ba68f3b11.zip
Finishes comment endpoints
-rw-r--r--trakt-rs/src/api/comments.rs404
-rw-r--r--trakt-rs/src/smo.rs87
2 files changed, 488 insertions, 3 deletions
diff --git a/trakt-rs/src/api/comments.rs b/trakt-rs/src/api/comments.rs
index 35f2242..514f72d 100644
--- a/trakt-rs/src/api/comments.rs
+++ b/trakt-rs/src/api/comments.rs
@@ -96,6 +96,394 @@ pub mod post {
pub struct Response(pub Comment);
}
+pub mod get {
+ //! Get a comment or reply
+ //!
+ //! <https://trakt.docs.apiary.io/#reference/comments/comment/get-a-comment-or-reply>
+
+ use crate::smo::Comment;
+
+ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, trakt_macros::Request)]
+ #[trakt(
+ response = Response,
+ endpoint = "/comments/{id}",
+ )]
+ pub struct Request {
+ pub id: u64,
+ }
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, trakt_macros::Response)]
+ pub struct Response(pub Comment);
+}
+
+pub mod update {
+ //! Update a comment or repl
+ //!
+ //! <https://trakt.docs.apiary.io/#reference/comments/comment/update-a-comment-or-reply>
+
+ use bytes::BufMut;
+ use serde::Serialize;
+ use serde_json::json;
+ use trakt_core::{error::IntoHttpError, Context, Metadata};
+
+ use crate::smo::Comment;
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash)]
+ pub struct Request {
+ pub id: u64,
+ pub comment: String,
+ pub spoiler: bool,
+ }
+
+ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize)]
+ struct RequestParams {
+ id: u64,
+ }
+
+ impl trakt_core::Request for Request {
+ type Response = Response;
+ const METADATA: Metadata = Metadata {
+ endpoint: "/comments/{id}",
+ method: http::Method::PUT,
+ auth: trakt_core::AuthRequirement::Required,
+ };
+
+ fn try_into_http_request<T: Default + BufMut>(
+ self,
+ ctx: Context,
+ ) -> Result<http::Request<T>, IntoHttpError> {
+ let params = RequestParams { id: self.id };
+ let url =
+ trakt_core::construct_url(ctx.base_url, Self::METADATA.endpoint, &params, &())?;
+
+ let body = T::default();
+ let mut writer = body.writer();
+
+ let json = json!({
+ "comment": self.comment,
+ "spoiler": self.spoiler,
+ });
+ serde_json::to_writer(&mut writer, &json)?;
+
+ let request = http::Request::builder()
+ .method(Self::METADATA.method)
+ .uri(url)
+ .header("Content-Type", "application/json")
+ .header("trakt-api-version", "2")
+ .header("trakt-api-key", ctx.client_id);
+ let request = match ctx.oauth_token {
+ Some(token) => request.header("Authorization", format!("Bearer {token}")),
+ None => return Err(IntoHttpError::MissingToken),
+ };
+
+ Ok(request.body(writer.into_inner())?)
+ }
+ }
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, trakt_macros::Response)]
+ pub struct Response(pub Comment);
+}
+
+pub mod delete {
+ //! Delete a comment or reply
+ //!
+ //! <https://trakt.docs.apiary.io/#reference/comments/comment/delete-a-comment-or-reply>
+
+ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, trakt_macros::Request)]
+ #[trakt(
+ response = Response,
+ endpoint = "/comments/{id}",
+ method = DELETE,
+ auth = Required,
+ )]
+ pub struct Request {
+ pub id: u64,
+ }
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, trakt_macros::Response)]
+ #[trakt(expected = NO_CONTENT)]
+ pub struct Response;
+}
+
+pub mod get_replies {
+ //! Get comment replies
+ //!
+ //! <https://trakt.docs.apiary.io/#reference/comments/comment/get-replies-for-a-comment>
+
+ use crate::smo::Comment;
+
+ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, trakt_macros::Request)]
+ #[trakt(
+ response = Response,
+ endpoint = "/comments/{id}/replies",
+ auth = Optional,
+ )]
+ pub struct Request {
+ pub id: u64,
+ }
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, trakt_macros::Response)]
+ pub struct Response(pub Vec<Comment>);
+}
+
+pub mod post_reply {
+ //! Post a reply for a comment
+ //!
+ //! <https://trakt.docs.apiary.io/#reference/comments/replies/post-a-reply-for-a-comment>
+
+ use bytes::BufMut;
+ use serde::Serialize;
+ use serde_json::json;
+ use trakt_core::{error::IntoHttpError, Context, Metadata};
+
+ use crate::smo::Comment;
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash)]
+ pub struct Request {
+ pub id: u64,
+ pub comment: String,
+ pub spoiler: bool,
+ }
+
+ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize)]
+ struct RequestParams {
+ id: u64,
+ }
+
+ impl trakt_core::Request for Request {
+ type Response = Response;
+ const METADATA: Metadata = Metadata {
+ endpoint: "/comments/{id}/replies",
+ method: http::Method::POST,
+ auth: trakt_core::AuthRequirement::Required,
+ };
+
+ fn try_into_http_request<T: Default + BufMut>(
+ self,
+ ctx: Context,
+ ) -> Result<http::Request<T>, IntoHttpError> {
+ let params = RequestParams { id: self.id };
+ let url =
+ trakt_core::construct_url(ctx.base_url, Self::METADATA.endpoint, &params, &())?;
+
+ let body = T::default();
+ let mut writer = body.writer();
+
+ let json = json!({
+ "comment": self.comment,
+ "spoiler": self.spoiler,
+ });
+ serde_json::to_writer(&mut writer, &json)?;
+
+ let request = http::Request::builder()
+ .method(Self::METADATA.method)
+ .uri(url)
+ .header("Content-Type", "application/json")
+ .header("trakt-api-version", "2")
+ .header("trakt-api-key", ctx.client_id);
+ let request = match ctx.oauth_token {
+ Some(token) => request.header("Authorization", format!("Bearer {token}")),
+ None => return Err(IntoHttpError::MissingToken),
+ };
+
+ Ok(request.body(writer.into_inner())?)
+ }
+ }
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, trakt_macros::Response)]
+ #[trakt(expected = CREATED)]
+ pub struct Response(pub Comment);
+}
+
+pub mod item {
+ //! Get attached media item for a comment
+ //!
+ //! <https://trakt.docs.apiary.io/#reference/comments/item/get-the-attached-media-item>
+
+ use serde::Deserialize;
+
+ use crate::smo::{Episode, List, Movie, Season, Show};
+
+ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, trakt_macros::Request)]
+ #[trakt(
+ response = Response,
+ endpoint = "/comments/{id}/item",
+ )]
+ pub struct Request {
+ pub id: u64,
+ }
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, trakt_macros::Response)]
+ pub struct Response(pub Item);
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize)]
+ #[serde(rename_all = "lowercase")]
+ #[serde(tag = "type")]
+ pub enum Item {
+ Movie { movie: Box<Movie> },
+ Show { show: Box<Show> },
+ Season { season: Box<Season> },
+ Episode { episode: Box<Episode> },
+ List { list: Box<List> },
+ }
+}
+
+pub mod likes {
+ //! Get users who liked a comment
+ //!
+ //! <https://trakt.docs.apiary.io/#reference/comments/likes/get-all-users-who-liked-a-comment>
+
+ use time::OffsetDateTime;
+ use trakt_core::PaginationResponse;
+
+ use crate::smo::User;
+
+ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, trakt_macros::Request)]
+ #[trakt(
+ response = Response,
+ endpoint = "/comments/{id}/likes",
+ )]
+ pub struct Request {
+ pub id: u64,
+ }
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, trakt_macros::Response)]
+ pub struct Response {
+ #[trakt(pagination)]
+ pub users: PaginationResponse<ResponseItem>,
+ }
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, serde::Deserialize)]
+ pub struct ResponseItem {
+ #[serde(with = "time::serde::iso8601")]
+ pub liked_at: OffsetDateTime,
+ pub user: User,
+ }
+}
+
+pub mod like {
+ //! Like a comment
+ //!
+ //! <https://trakt.docs.apiary.io/#reference/comments/like/like-a-comment>
+
+ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, trakt_macros::Request)]
+ #[trakt(
+ response = Response,
+ endpoint = "/comments/{id}/like",
+ method = POST,
+ auth = Required,
+ )]
+ pub struct Request {
+ pub id: u64,
+ }
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, trakt_macros::Response)]
+ #[trakt(expected = NO_CONTENT)]
+ pub struct Response;
+}
+
+pub mod remove_like {
+ //! Remove like from a comment
+ //!
+ //! <https://trakt.docs.apiary.io/#reference/comments/like/remove-like-on-a-comment>
+
+ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, trakt_macros::Request)]
+ #[trakt(
+ response = Response,
+ endpoint = "/comments/{id}/like",
+ method = DELETE,
+ auth = Required,
+ )]
+ pub struct Request {
+ pub id: u64,
+ }
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, trakt_macros::Response)]
+ #[trakt(expected = NO_CONTENT)]
+ pub struct Response;
+}
+
+pub mod trending {
+ //! Get trending comments
+ //!
+ //! <https://trakt.docs.apiary.io/#reference/comments/like/get-trending-comments>
+
+ use trakt_core::PaginationResponse;
+
+ use crate::smo::{CommentItemType, CommentType, CommentWithItem};
+
+ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, trakt_macros::Request)]
+ #[trakt(
+ response = Response,
+ endpoint = "/comments/trending/{comment_type}/{tp}",
+ )]
+ pub struct Request {
+ pub comment_type: CommentType,
+ pub tp: CommentItemType,
+ pub include_replies: bool,
+ }
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, trakt_macros::Response)]
+ pub struct Response {
+ #[trakt(pagination)]
+ pub comments: PaginationResponse<CommentWithItem>,
+ }
+}
+
+pub mod recent {
+ //! Get recently created comments
+ //!
+ //! <https://trakt.docs.apiary.io/#reference/comments/trending/get-recently-created-comments>
+
+ use trakt_core::PaginationResponse;
+
+ use crate::smo::{CommentItemType, CommentType, CommentWithItem};
+
+ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, trakt_macros::Request)]
+ #[trakt(
+ response = Response,
+ endpoint = "/comments/recent/{comment_type}/{tp}",
+ )]
+ pub struct Request {
+ pub comment_type: CommentType,
+ pub tp: CommentItemType,
+ pub include_replies: bool,
+ }
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, trakt_macros::Response)]
+ pub struct Response {
+ #[trakt(pagination)]
+ pub comments: PaginationResponse<CommentWithItem>,
+ }
+}
+
+pub mod recent_updated {
+ //! Get recently updated comments
+ //!
+ //! <https://trakt.docs.apiary.io/#reference/comments/updates/get-recently-updated-comments>
+
+ use trakt_core::PaginationResponse;
+
+ use crate::smo::{CommentItemType, CommentType, CommentWithItem};
+
+ #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, trakt_macros::Request)]
+ #[trakt(
+ response = Response,
+ endpoint = "/comments/updates/{comment_type}/{tp}",
+ )]
+ pub struct Request {
+ pub comment_type: CommentType,
+ pub tp: CommentItemType,
+ pub include_replies: bool,
+ }
+
+ #[derive(Debug, Clone, Eq, PartialEq, Hash, trakt_macros::Response)]
+ pub struct Response {
+ #[trakt(pagination)]
+ pub comments: PaginationResponse<CommentWithItem>,
+ }
+}
+
#[cfg(test)]
mod tests {
use serde_json::json;
@@ -181,4 +569,20 @@ mod tests {
};
assert_request(CTX, request, "https://api.trakt.tv/comments", &expected);
}
+
+ #[test]
+ fn update_comment_request() {
+ const COMMENT: &str = "The quick brown fox jumps over the lazy dog.";
+
+ let expected = json!({
+ "comment": COMMENT,
+ "spoiler": false,
+ });
+ let request = update::Request {
+ id: 42,
+ comment: COMMENT.to_owned(),
+ spoiler: false,
+ };
+ assert_request(CTX, request, "https://api.trakt.tv/comments/42", &expected);
+ }
}
diff --git a/trakt-rs/src/smo.rs b/trakt-rs/src/smo.rs
index 29ce36d..234d20a 100644
--- a/trakt-rs/src/smo.rs
+++ b/trakt-rs/src/smo.rs
@@ -181,13 +181,13 @@ pub struct UserStats {
pub struct List {
pub name: EmojiString,
pub description: EmojiString,
- pub privacy: String,
+ pub privacy: ListPrivacy,
pub share_link: String,
pub r#type: ListType,
pub display_numbers: bool,
pub allow_comments: bool,
- pub sort_by: String,
- pub sort_how: String,
+ pub sort_by: ListSortBy,
+ pub sort_how: ListSortHow,
#[serde(with = "time::serde::iso8601")]
pub created_at: OffsetDateTime,
#[serde(with = "time::serde::iso8601")]
@@ -208,6 +208,40 @@ pub enum ListType {
Favorites,
}
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
+#[serde(rename_all = "snake_case")]
+pub enum ListSortBy {
+ Rank,
+ Added,
+ Title,
+ Released,
+ Runtime,
+ Popularity,
+ Percentage,
+ Votes,
+ MyRating,
+ Random,
+ Watched,
+ Collected,
+}
+
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum ListSortHow {
+ Asc,
+ Desc,
+}
+
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Default, Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum ListPrivacy {
+ #[default]
+ Private,
+ Link,
+ Friends,
+ Public,
+}
+
#[derive(Debug, Clone, PartialEq, Deserialize)]
pub struct Ratings {
pub rating: f32,
@@ -246,3 +280,50 @@ pub struct Sharing {
pub mastodon: bool,
pub tumblr: bool,
}
+
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Default, Serialize)]
+#[serde(rename_all = "lowercase")]
+pub enum CommentType {
+ #[default]
+ All,
+ Reviews,
+ Shouts,
+}
+
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Default, Serialize)]
+#[serde(rename_all = "lowercase")]
+pub enum CommentItemType {
+ #[default]
+ All,
+ Movies,
+ Shows,
+ Seasons,
+ Episodes,
+ Lists,
+}
+
+#[derive(Debug, Clone, Eq, PartialEq, Hash, serde::Deserialize)]
+#[serde(rename_all = "lowercase")]
+#[serde(tag = "type")]
+pub enum CommentWithItem {
+ Movie {
+ movie: Box<Movie>,
+ comment: Comment,
+ },
+ Show {
+ show: Box<Show>,
+ comment: Comment,
+ },
+ Season {
+ season: Box<Season>,
+ comment: Comment,
+ },
+ Episode {
+ episode: Box<Episode>,
+ comment: Comment,
+ },
+ List {
+ list: Box<List>,
+ comment: Comment,
+ },
+}