#![allow(dead_code, missing_docs)]
#![allow(clippy::enum_variant_names, clippy::large_enum_variant)]
//! This module contains the transcript of types from Definitions section of
//! the Letterboxd API:
//!
//! http://letterboxd-api.dev.cactuslab.com/#definitions.
//!
//! Note that, in the API it is not always specified if a field is optional.
//! Therefore, most of the types below have to be adjusted with optional
//! values. Further, only the types that are in the API implementation are
//! public.
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "type")]
enum AbstractActivity {
/// Common fields:
/// member The member associated with the activity.
/// when_created The timestamp of the activity, in ISO 8601 format with UTC
/// timezone, i.e. YYYY-MM-DDThh:mm:ssZ "1997-08-29T07:14:00Z"
DiaryEntryActivity {
member: MemberSummary,
when_created: String,
/// The log entry associated with this activity.
diary_entry: LogEntry,
},
FilmLikeActivity {
member: MemberSummary,
when_created: String,
/// The film associated with the activity. Includes a
/// MemberFilmRelationship for the member who added the activity.
film: FilmSummary,
},
FilmRatingActivity {
member: MemberSummary,
when_created: String,
/// The film associated with the activity. Includes a
/// MemberFilmRelationship for the member who added the activity.
film: FilmSummary,
/// The member’s rating for the film. Allowable values are between 0.5
/// and 5.0, with increments of 0.5.
rating: f32,
},
FilmWatchActivity {
member: MemberSummary,
when_created: String,
/// The film associated with the activity. Includes a
/// MemberFilmRelationship for the member who added the activity.
film: FilmSummary,
},
FollowActivity {
member: MemberSummary,
when_created: String,
/// A summary of the member that was followed.
followed: MemberSummary,
},
InvitationAcceptedActivity {
member: MemberSummary,
when_created: String,
invitor: MemberSummary,
},
ListActivity {
member: MemberSummary,
when_created: String,
/// The list associated with the activity.
list: ListSummary,
/// The list that was cloned, if applicable.
cloned_from: Option<ListSummary>,
},
ListCommentActivity {
member: MemberSummary,
when_created: String,
/// The list associated with the activity.
list: ListSummary,
/// The comment associated with the activity.
comment: ListComment,
},
ListLikeActivity {
member: MemberSummary,
when_created: String,
/// The list associated with the activity.
list: ListSummary,
},
RegistrationActivity {
member: MemberSummary,
when_created: String,
},
ReviewActivity {
member: MemberSummary,
when_created: String,
/// The log entry associated with this activity.
review: LogEntry,
},
ReviewCommentActivity {
member: MemberSummary,
when_created: String,
/// The review associated with the activity.
review: LogEntry,
/// The comment associated with the activity.
comment: ReviewComment,
},
ReviewLikeActivity {
member: MemberSummary,
when_created: String,
/// The review associated with the activity.
review: LogEntry,
},
WatchlistActivity {
member: MemberSummary,
when_created: String,
/// The film associated with the activity. Includes a
/// MemberFilmRelationship for the member who added the activity.
film: FilmSummary,
},
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "type")]
enum AbstractComment {
ListComment {
/// The LID of the comment.
id: String,
/// The member who posted the comment.
member: MemberSummary,
/// ISO 8601 format with UTC timezone, i.e. YYYY-MM-DDThh:mm:ssZ:
/// "1997-08-29T07:14:00Z"
when_created: String,
/// ISO 8601 format with UTC timezone, i.e. YYYY-MM-DDThh:mm:ssZ:
/// "1997-08-29T07:14:00Z"
when_updated: String,
/// The message portion of the comment in LBML. May contain the
/// following HTML tags: `<br>` `<strong>` `<em>` `<b>` `<i>` `<a
/// href="">` `<blockquote>`.
comment_lbml: String,
/// If Letterboxd moderators have removed the comment from the site,
/// removedByAdmin will be true and comment will not be included.
removed_by_admin: bool,
/// If the comment owner has removed the comment from the site, deleted
/// will be true and comment will not be included.
deleted: bool,
/// If the authenticated member has blocked the commenter, blocked will
/// be true and comment will not be included.
blocked: bool,
/// If the content owner has blocked the commenter, blockedByOwner will
/// be true and comment will not be included.
blocked_by_owner: bool,
/// If the authenticated member posted this comment, and the comment is
/// still editable, this value shows the number of seconds remaining
/// until the editing window closes.
editable_window_expires_in: Option<usize>,
/// The list on which the comment was posted.
list: ListIdentifier,
/// The message portion of the comment formatted as HTML.
comment: String,
},
ReviewComment {
/// The LID of the comment.
id: String,
/// The member who posted the comment.
member: MemberSummary,
/// ISO 8601 format with UTC timezone, i.e. YYYY-MM-DDThh:mm:ssZ:
/// "1997-08-29T07:14:00Z"
when_created: String,
/// ISO 8601 format with UTC timezone, i.e. YYYY-MM-DDThh:mm:ssZ:
/// "1997-08-29T07:14:00Z"
when_updated: String,
/// The message portion of the comment in LBML. May contain the
/// following HTML tags: `<br>` `<strong>` `<em>` `<b>` `<i>` `<a
/// href="">` `<blockquote>`.
comment_lbml: String,
/// If Letterboxd moderators have removed the comment from the site,
/// removedByAdmin will be true and comment will not be included.
removed_by_admin: bool,
/// If the comment owner has removed the comment from the site, deleted
/// will be true and comment will not be included.
deleted: bool,
/// If the authenticated member has blocked the commenter, blocked will
/// be true and comment will not be included.
blocked: bool,
/// If the content owner has blocked the commenter, blockedByOwner will
/// be true and comment will not be included.
blocked_by_owner: bool,
/// If the authenticated member posted this comment, and the comment is
/// still editable, this value shows the number of seconds remaining
/// until the editing window closes.
editable_window_expires_in: Option<usize>,
/// The review on which the comment was posted.
review: ReviewIdentifier,
/// The message portion of the comment formatted as HTML.
comment: String,
},
}
#[derive(Clone, Debug, Deserialize)]
#[serde(tag = "type")]
pub enum AbstractSearchItem {
/// Common fields:
/// score A relevancy value that can be used to order results.
ContributorSearchItem {
/// A relevancy value that can be used to order results.
score: f32,
/// Contributor Details of the contributor.
contributor: Contributor,
},
FilmSearchItem {
score: f32,
film: FilmSummary,
},
ListSearchItem {
score: f32,
list: ListSummary,
},
MemberSearchItem {
score: f32,
member: MemberSummary,
},
ReviewSearchItem {
score: f32,
/// Details of the review.
review: LogEntry,
},
TagSearchItem {
score: f32,
tag: String,
},
}
#[derive(Deserialize, Debug, Default, Clone)]
pub struct AccessToken {
/// The access token that grants the member access. Combine this with the
/// token_type to form the Authorization header.
pub access_token: String,
/// The type of the access token. Use value: bearer
pub token_type: String,
/// The refresh token is used to obtain a new access token, after the
/// access token expires, without needing to prompt the member for their
/// credentials again. The refresh token only expires if it is explicitly
/// invalidated by Letterboxd, in which case the member should be prompted
/// for their credentials (or stored credentials used).
pub refresh_token: String,
/// The number of seconds before the access token expires.
pub expires_in: usize,
}
#[derive(Deserialize, Debug, Clone)]
enum ActivityClass {
OwnActivity,
NotOwnActivity,
IncomingActivity,
NotIncomingActivity,
NetworkActivity,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct ActivityRequest {
/// The pagination cursor.
cursor: Option<Cursor>,
/// The number of items to include per page (default is 20, maximum is 100).
per_page: Option<usize>,
/// Only supported for paying members.
/// Use include to specify the subset of activity to be returned. If
/// neither include nor exclude is set, the activity types included depend
/// on the where parameter:
/// If where=OwnActivity is specified, all activity except
/// FilmLikeActivity, FilmWatchActivity and InvitationAcceptedActivity is
/// included.
/// Otherwise all activity except FilmLikeActivity, FilmWatchActivity,
/// FilmRatingActivity, FollowActivity, RegistrationActivity and
/// InvitationAcceptedActivity is included.
/// These defaults mimic those shown on the website.
include: Option<Vec<ActivityType>>,
/// Use where to reduce the subset of activity to be returned. If where is
/// not set, all default activity types relating to the member are
/// returned. If multiple values are supplied, only activity matching all
/// terms will be returned, e.g.
/// where=OwnActivity&where=NotIncomingActivity will return all activity by
/// the member except their comments on their own lists and reviews.
/// NetworkActivity is activity performed either by the member or their
/// followers. Use where=NetworkActivity&where=NotOwnActivity to only see
/// activity from followers. If you don’t specify any of NetworkActivity,
/// OwnActivity or NotIncomingActivity, you will receive activity related
/// to the member’s content from members outside their network (e.g.
/// comments and likes on the member’s lists and reviews).
#[serde(rename = "where")]
where_activity: Option<Vec<ActivityClass>>,
}
#[derive(Deserialize, Debug, Clone)]
enum ActivityType {
ReviewActivity,
ReviewCommentActivity,
ReviewLikeActivity,
ListActivity,
ListCommentActivity,
ListLikeActivity,
DiaryEntryActivity,
FilmRatingActivity,
FilmWatchActivity,
FilmLikeActivity,
WatchlistActivity,
FollowActivity,
RegistrationActivity,
InvitationAcceptedActivity,
}
#[derive(Deserialize, Debug, Clone)]
struct ActivityResponse {
/// The cursor to the next page of results.
next: Option<Cursor>,
/// The list of activity items.
items: Vec<AbstractActivity>,
}
#[derive(Serialize, Debug, Clone)]
pub struct CommentCreationRequest {
/// The message portion of the comment in LBML. May contain the following
/// HTML tags: `<br>` `<strong>` `<em>` `<b>` `<i>` `<a href="">`
/// `<blockquote>`. This field has a maximum size of 100,000 characters.
comment: String,
}
#[derive(Deserialize, Debug, Clone)]
enum CommentUpdateMessageCode {
MissingComment,
CommentOnContentYouBlocked,
CommentOnBlockedContent,
CommentBan,
CommentEditWindowExpired,
CommentTooLong,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(tag = "type")]
enum CommentUpdateMessage {
Error {
/// The error message code.
code: CommentUpdateMessageCode,
/// The error message text in human-readable form.
title: String,
},
Success,
}
#[derive(Deserialize, Debug, Clone)]
struct CommentUpdateRequest {
/// The message portion of the comment in LBML. May contain the following
/// HTML tags: `<br>` `<strong>` `<em>` `<b>` `<i>` `<a href="">`
/// `<blockquote>`. This field has a maximum size of 100,000 characters.
comment: String,
}
#[derive(Deserialize, Debug, Clone)]
struct CommentUpdateResponse {
/// The response object.
data: AbstractComment,
/// A list of messages the API client should show to the user.
messages: Vec<CommentUpdateMessage>,
}
// TODO: Ordering
#[derive(Deserialize, Debug, Clone)]
enum CommentsRequestSort {
Date,
Updates,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct CommentsRequest {
/// The pagination cursor.
cursor: Option<Cursor>,
/// The number of items to include per page (default is 20, maximum is 100).
per_page: Option<usize>,
/// Defaults to Date. The Updates sort order returns newest content first.
/// Use this to get the most recently posted or edited comments, and pass
/// include_deletions=true to remain consistent in the case where a comment
/// has been deleted.
sort: CommentsRequestSort,
/// Use this to discover any comments that were deleted.
include_deletions: bool,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct ContributionStatistics {
/// The type of contribution.
#[serde(rename = "type")]
contribution_type: ContributionType,
/// The number of films for this contribution type.
film_count: usize,
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub enum ContributionType {
Director,
Actor,
Producer,
Writer,
Editor,
Cinematography,
ArtDirection,
VisualEffects,
Composer,
Sound,
Costumes,
MakeUp,
Studio,
}
#[derive(Deserialize, Debug, Clone)]
pub struct Contributor {
/// The LID of the contributor.
pub id: String,
/// The name of the contributor.
pub name: String,
/// An array of the types of contributions made, with a count of films for
/// each contribution type.
// TODO
// statistics: ContributorStatistics,
// A list of relevant URLs to this entity, on Letterboxd and external sites.
pub links: Vec<Link>,
}
#[derive(Deserialize, Debug, Clone)]
struct ContributorStatistics {
// The statistics for each contribution type.
contributions: Vec<ContributionStatistics>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ContributorSummary {
/// The LID of the contributor.
pub id: String,
/// The name of the contributor.
pub name: String,
/// The character name if available (only if the contribution is as an
/// Actor; see the type field in FilmContributions).
pub character_name: Option<String>,
}
/// A cursor is a String value provided by the API. It should be treated as an
/// opaque value — don’t change it.
pub type Cursor = String;
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DiaryDetails {
/// The date the film was watched, if specified, in ISO 8601 format, i.e.
/// YYYY-MM-DD
pub diary_date: String,
/// Will be true if the member has indicated (or it can be otherwise
/// determined) that the member has seen the film prior to this date.
pub rewatch: bool,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Film {
/// The LID of the film.
pub id: String,
/// The title of the film.
pub name: String,
/// The original title of the film, if it was first released with a
/// non-English title.
pub original_name: Option<String>,
/// The other names by which the film is known (including alternative
/// titles and/or foreign translations).
pub alternative_names: Vec<String>,
/// The year in which the film was first released.
pub release_year: u16,
/// The tagline for the film.
pub tagline: String,
/// A synopsis of the film.
pub description: String,
/// The film’s duration (in minutes).
pub run_time: u16,
/// The film’s poster image (2:3 ratio in multiple sizes).
pub poster: Image,
/// The film’s backdrop image (16:9 ratio in multiple sizes).
pub backdrop: Image,
/// The backdrop’s vertical focal point, expressed as a proportion of the
/// image’s height, using values between 0.0 and 1.0. Use when cropping the
/// image into a shorter space, such as in the page for a film on the
/// Letterboxd site.
pub backdrop_focal_point: f32,
/// The film’s trailer.
pub trailer: FilmTrailer,
/// The film’s genres.
pub genres: Vec<Genre>,
/// The film’s contributors (director, cast and crew) grouped by discipline.
pub contributions: Vec<FilmContributions>,
/// A list of relevant URLs to this entity, on Letterboxd and external
/// sites.
pub links: Vec<Link>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct FilmAutocompleteRequest {
/// The number of items to include per page (default is 20, maximum is 100).
per_page: Option<usize>,
/// The word, partial word or phrase to match against.
input: String,
}
#[derive(Deserialize, Debug, Clone)]
pub enum FilmAvailabilityService {
Amazon,
AmazonVideo,
AmazonPrime,
#[allow(non_camel_case_types)]
iTunes,
Netflix,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct FilmAvailability {
/// The service.
pub service: FilmAvailabilityService,
/// The service’s name.
pub display_name: String,
/// The regional store for the service. Not all countries are supported on
/// all services.
pub country: Country,
/// The unique ID (if any) for the film on the store.
pub id: String,
/// The fully qualified URL for the film on this store.
pub url: String,
}
// TODO: order
#[derive(Deserialize, Debug, Clone)]
pub enum Country {
AIA,
ARE,
ARG,
ARM,
ATG,
AUS,
AUT,
AZE,
BEL,
BFA,
BGR,
BHR,
BHS,
BLR,
BLZ,
BMU,
BOL,
BRA,
BRB,
BRN,
BWA,
CAN,
CHE,
CHL,
CHN,
COL,
CPV,
CRI,
CYM,
CYP,
CZE,
DEU,
DMA,
DNK,
DOM,
ECU,
EGY,
ESP,
EST,
FIN,
FJI,
FRA,
FSM,
GBR,
GHA,
GMB,
GNB,
GRC,
GRD,
GTM,
HKG,
HND,
HUN,
IDN,
IND,
IRL,
ISR,
ITA,
JOR,
JPN,
KAZ,
KEN,
KGZ,
KHM,
KNA,
LAO,
LBN,
LKA,
LTU,
LUX,
LVA,
MAC,
MDA,
MEX,
MLT,
MNG,
MOZ,
MUS,
MYS,
NAM,
NER,
NGA,
NIC,
NLD,
NOR,
NPL,
NZL,
OMN,
PAN,
PER,
PHL,
PNG,
POL,
PRT,
PRY,
QAT,
ROU,
RUS,
SAU,
SGP,
SLV,
SVK,
SVN,
SWE,
SWZ,
THA,
TJK,
TKM,
TTO,
TUR,
TWN,
UGA,
UKR,
USA,
UZB,
VEN,
VGB,
VNM,
ZAF,
ZWE,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct FilmAvailabilityResponse {
/// The list of stores where the film is available for streaming or
/// purchasing, in order of preference. If the member has not specified
/// their preferred stores for a service, the USA store will be assumed.
pub items: Option<Vec<FilmAvailability>>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct FilmContribution {
/// The type of contribution.
#[serde(rename = "type")]
contribution_type: ContributionType,
/// The film.
film: FilmSummary,
/// The name of the character (only when type is Actor).
character_name: String,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct FilmContributions {
/// The type of contribution.
pub contribution_type: Option<ContributionType>,
/// The list of contributors of the specified type for the film.
pub contributors: Vec<ContributorSummary>,
}
// TODO: Ordering, Dedup
#[derive(Serialize, Debug, Clone)]
pub enum FilmStatus {
Released,
NotReleased,
InWatchlist,
NotInWatchlist,
Watched,
NotWatched,
FeatureLength,
NotFeatureLength,
}
// TODO: Ordering
#[derive(Serialize, Debug, Clone)]
pub enum FilmRelationshipType {
Watched,
NotWatched,
Liked,
NotLiked,
InWatchlist,
NotInWatchlist,
Favorited,
}
#[derive(Serialize, Debug, Clone)]
enum FilmContributionsSort {
FilmName,
ReleaseDateLatestFirst,
ReleaseDateEarliestFirst,
RatingHighToLow,
RatingLowToHigh,
FilmDurationShortestFirst,
FilmDurationLongestFirst,
FilmPopularity,
FilmPopularityThisWeek,
FilmPopularityThisMonth,
FilmPopularityThisYear,
}
#[derive(Serialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct FilmContributionsRequest {
/// The pagination cursor.
cursor: Option<Cursor>,
/// The number of items to include per page (default is 20, maximum is 100).
per_page: Option<usize>,
/// The order in which the films should be returned. Defaults to
/// FilmPopularity, which is an all-time measurement of the amount of
/// activity the film has received. The FilmPopularityWithFriends values
/// are only available to signed-in members and consider popularity amongst
/// the signed-in member’s friends.
sort: FilmContributionsSort,
/// The type of contribution.
#[serde(rename = "type")]
contribution_type: ContributionType,
/// Specify the LID of a genre to limit films to those within the specified
/// genre.
genre: String,
/// Specify the starting year of a decade (must end in 0) to limit films to
/// those released during the decade. 1990
decade: u16,
/// Specify a year to limit films to those released during that year. 1994
year: u16,
/// Specify the ID of a supported service to limit films to those available
/// from that service. The list of available services can be found by using
/// the /films/film-services endpoint.
service: String,
/// Specify one or more values to limit the list of films accordingly.
/// where=Watched&where=Released
#[serde(rename = "where")]
where_film_status: Vec<FilmStatus>,
/// Specify the LID of a member to limit the returned films according to
/// the value set in memberRelationship.
member: String,
/// Must be used in conjunction with member. Defaults to Watched. Specify
/// the type of relationship to limit the returned films accordingly.
member_relationship: FilmRelationshipType,
/// Must be used in conjunction with member. Defaults to None, which only
/// returns films from the member’s account. Use Only to return films from
/// the member’s friends, and All to return films from both the member and
/// their friends.
include_friends: IncludeFriends,
/// Specify a tag code to limit the returned films to those tagged
/// accordingly.
tag_code: String,
/// Must be used with tag. Specify the LID of a member to focus the tag
/// filter on the member.
tagger: String,
/// Must be used in conjunction with tagger. Defaults to None, which
/// filters tags set by the member. Use Only to filter tags set by the
/// member’s friends, and All to filter tags set by both the member and
/// their friends.
include_tagger_friends: IncludeFriends,
}
#[derive(Deserialize, Debug, Clone)]
struct FilmContributionsResponse {
/// The cursor to the next page of results.
next: Option<Cursor>,
/// The list of contributions.
items: Vec<FilmContribution>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct FilmIdentifier {
/// The LID of the film.
pub id: String,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct FilmRelationship {
/// Will be true if the member has indicated they’ve seen the film (via the
/// ‘eye’ icon) or has a log entry for the film.
pub watched: bool,
/// Will be true if the member likes the film (via the ‘heart’ icon).
pub liked: bool,
/// Will be true if the member listed the film as one of their four
/// favorites.
pub favorited: bool,
/// Will be true if the film is in the member’s watchlist.
pub in_watchlist: bool,
/// The member’s rating for the film.
pub rating: Option<f32>,
/// A list of LIDs for reviews the member has written for the film in the
/// order they were added, with most recent reviews first.
pub reviews: Vec<String>,
/// A list of LIDs for log entries the member has added for the film in
/// diary order, with most recent entries first.
pub diary_entries: Vec<String>,
}
#[derive(Deserialize, Debug, Clone)]
pub enum FilmRelationshipUpdateMessageCode {
InvalidRatingValue,
UnableToRemoveWatch,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(tag = "type")]
pub enum FilmRelationshipUpdateMessage {
Error {
/// The error message code.
code: FilmRelationshipUpdateMessageCode,
/// The error message text in human-readable form.
title: String,
},
}
/// When PATCHing a film relationship, you may send all of the current property
/// struct values, or just those you wish to change. Properties that violate
/// business rules (see watched below) or contain invalid values will be
/// ignored.
#[derive(Serialize, Debug, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct FilmRelationshipUpdateRequest {
/// Set to true to change the film’s status for the authenticated member to
/// ‘watched’ or false for ‘not watched’. If the status is changed to
/// ‘watched’ and the film is in the member’s watchlist, it will be removed
/// as part of this action. You may not change the status of a film to ‘not
/// watched’ if there is existing activity (a review or diary entry) for
/// the authenticated member—check the messages returned from this endpoint
/// to ensure no such business rules have been violated.
pub watched: Option<bool>,
/// Set to true to change the film’s status for the authenticated member to
/// ‘liked’ or false for ‘not liked’.
pub liked: Option<bool>,
/// Set to true to add the film to the authenticated member’s watchlist, or
/// false to remove it.
pub in_watchlist: Option<bool>,
/// Accepts values between 0.5 and 5.0, with increments of 0.5, or null (to
/// remove the rating).
pub rating: Option<f32>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct FilmRelationshipUpdateResponse {
/// The response object.
pub data: FilmRelationship,
/// A list of messages the API client should show to the user.
pub messages: Vec<FilmRelationshipUpdateMessage>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct FilmServicesResponse {
// The list of film services.
pub items: Vec<Service>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct FilmStatistics {
/// The film for which statistics were requested.
pub film: FilmIdentifier,
/// The number of watches, ratings, likes, etc. for the film.
pub counts: FilmStatisticsCounts,
/// The weighted average rating of the film between 0.5 and 5.0. Will not
/// be present if the film has not received sufficient ratings.
pub rating: Option<f32>,
/// A summary of the number of ratings at each increment between 0.5 and
/// 5.0.
pub ratings_histogram: Vec<RatingsHistogramBar>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct FilmStatisticsCounts {
/// The number of members who have watched the film.
pub watches: usize,
/// The number of members who have liked the film.
pub likes: usize,
/// The number of members who have rated the film.
pub ratings: usize,
/// The number of members who have the film as one of their four favorites.
pub fans: usize,
/// The number of lists in which the film appears.
pub lists: usize,
/// The number of reviews for the film.
pub reviews: usize,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct FilmSummary {
/// The LID of the film.
pub id: String,
/// The title of the film.
pub name: String,
/// The original title of the film, if it was first released with a
/// non-English title.
pub original_name: Option<String>,
/// The other names by which the film is known (including alternative
/// titles and/or foreign translations).
pub alternative_names: Option<Vec<String>>,
/// The year in which the film was first released.
pub release_year: Option<u16>,
/// The list of directors for the film.
pub directors: Vec<ContributorSummary>,
/// The film’s poster image (2:3 ratio in multiple sizes).
pub poster: Option<Image>,
/// Relationships to the film for the authenticated member (if any) and
/// other members where relevant.
pub relationships: Vec<MemberFilmRelationship>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct FilmTrailer {
/// The YouTube ID of the trailer. "ICp4g9p_rgo".
pub id: String,
/// The YouTube URL for the trailer.
/// "https://www.youtube.com/watch?v=ICp4g9p_rgo"
pub url: String,
}
#[derive(Deserialize, Debug, Clone)]
struct FilmsAutocompleteResponse {
// The list of films.
items: Vec<FilmSummary>,
}
#[derive(Serialize, Debug, Clone)]
pub enum FilmRequestSort {
FilmName,
ReleaseDateLatestFirst,
ReleaseDateEarliestFirst,
RatingHighToLow,
RatingLowToHigh,
FilmDurationShortestFirst,
FilmDurationLongestFirst,
FilmPopularity,
FilmPopularityThisWeek,
FilmPopularityThisMonth,
FilmPopularityThisYear,
FilmPopularityWithFriends,
FilmPopularityWithFriendsThisWeek,
FilmPopularityWithFriendsThisMonth,
FilmPopularityWithFriendsThisYear,
}
#[derive(Serialize, Debug, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct FilmsRequest {
/// The pagination cursor.
pub cursor: Option<Cursor>,
/// The number of items to include per page (default is 20, maximum is 100).
pub per_page: Option<usize>,
/// The order in which the films should be returned. Defaults to
/// FilmPopularity, which is an all-time measurement of the amount of
/// activity the film has received. The FilmPopularityWithFriends values
/// are only available to signed-in members and consider popularity amongst
/// the signed-in member’s friends.
pub sort: Option<FilmRequestSort>,
/// Specify the LID of a genre to limit films to those within the specified
/// genre.
pub genre: Option<String>,
/// Specify the LID of up to 100 genres to limit films to those within none
/// of the specified genres.
pub include_genre: Option<Vec<String>>,
/// Specify the LID of up to 100 genres to limit films to those within none
/// of the specified genres.
pub exclude_genre: Option<Vec<String>>,
/// Specify the ISO 3166-1 defined code of the country to limit films to those
/// produced in the specified country.
pub country: Option<String>,
/// Specify the ISO 639-1 defined code of the language to limit films to those
/// using the specified spoken language.
pub language: Option<String>,
/// Specify the starting year of a decade (must end in 0) to limit films to
/// those released during the decade. 1990
pub decade: Option<u16>,
/// Specify a year to limit films to those released during that year. 1994
pub year: Option<u16>,
/// Specify the ID of a supported service to limit films to those available
/// from that service. The list of available services can be found by using
/// the /films/film-services endpoint.
pub service: Option<String>,
/// Specify one or more values to limit the list of films accordingly.
/// where=Watched&where=Released
#[serde(rename = "where")]
pub where_film_status: Vec<FilmStatus>,
/// Specify the LID of a member to limit the returned films according to
/// the value set in memberRelationship.
pub member: Option<String>,
/// Must be used in conjunction with member. Defaults to Watched. Specify
/// the type of relationship to limit the returned films accordingly.
pub member_relationship: Option<FilmRelationshipType>,
/// Must be used in conjunction with member. Defaults to None, which only
/// returns films from the member’s account. Use Only to return films from
/// the member’s friends, and All to return films from both the member and
/// their friends.
pub include_friends: Option<IncludeFriends>,
/// Specify a tag code to limit the returned films to those tagged
/// accordingly.
pub tag_code: Option<String>,
/// Must be used with tag. Specify the LID of a member to focus the tag
/// filter on the member.
pub tagger: Option<String>,
/// Must be used in conjunction with tagger. Defaults to None, which
/// filters tags set by the member. Use Only to filter tags set by the
/// member’s friends, and All to filter tags set by both the member and
/// their friends.
pub include_tagger_friends: Option<IncludeFriends>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct FilmsResponse {
/// The cursor to the next page of results.
pub next: Option<Cursor>,
/// The list of films.
pub items: Vec<FilmSummary>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct ForgottenPasswordRequest {
email_address: String,
}
#[derive(Deserialize, Debug, Clone)]
pub struct Genre {
/// The LID of the genre.
pub id: String,
/// The name of the genre.
pub name: String,
}
#[derive(Deserialize, Debug, Clone)]
pub struct GenresResponse {
/// The list of genres.
pub items: Vec<Genre>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct Language {
/// The ISO 639-1 defined code of the language.
pub code: String,
/// The name of the language.
pub name: String,
}
#[derive(Deserialize, Debug, Clone)]
pub struct LanguagesResponse {
/// The list of languages.
pub items: Vec<Language>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct Image {
/// The available sizes for the image.
pub sizes: Vec<ImageSize>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct ImageSize {
/// The image width in pixels.
pub width: usize,
/// The image height in pixels.
pub height: usize,
/// The URL to the image file.
pub url: String,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum Link {
Letterboxd {
/// The object ID for the linked entity on the destination site.
id: String,
/// The fully qualified URL on the destination site.
url: String,
},
Tmdb {
/// The object ID for the linked entity on the destination site.
id: String,
/// The fully qualified URL on the destination site.
url: String,
},
Imdb {
/// The object ID for the linked entity on the destination site.
id: String,
/// The fully qualified URL on the destination site.
url: String,
},
Gwi {
/// The object ID for the linked entity on the destination site.
id: String,
/// The fully qualified URL on the destination site.
url: String,
},
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct List {
/// The LID of the list.
pub id: String,
/// The name of the list.
pub name: String,
/// The number of films in the list.
pub film_count: usize,
/// Will be true if the owner has elected to publish the list for other
/// members to see.
pub published: bool,
/// Will be true if the owner has elected to make this a ranked list.
pub ranked: bool,
/// Will be true if the owner has added notes to any entries.
pub has_entries_with_notes: bool,
/// The list description in LBML. May contain the following HTML tags:
/// `<br>` `<strong>` `<em>` `<b>` `<i>` `<a href="">` `<blockquote>`.
pub description_lbml: Option<String>,
/// The tags for the list.
pub tags2: Vec<Tag>,
/// The third-party service or services to which this list can be shared.
/// Only included if the authenticated member is the list’s owner.
pub can_share_on: Option<Vec<ThirdPartyService>>,
/// The third-party service or services to which this list has been shared.
/// Only included if the authenticated member is the list’s owner.
pub shared_on: Option<Vec<ThirdPartyService>>,
/// ISO 8601 format with UTC timezone, i.e. YYYY-MM-DDThh:mm:ssZ
/// "1997-08-29T07:14:00Z"
pub when_created: String,
/// ISO 8601 format with UTC timezone, i.e. YYYY-MM-DDThh:mm:ssZ
/// "1997-08-29T07:14:00Z"
pub when_published: Option<String>,
/// The member who owns the list.
pub owner: MemberSummary,
/// The list this was cloned from, if applicable.
pub cloned_from: Option<ListIdentifier>,
/// The first 12 entries in the list. To fetch more than 12 entries, and to
/// fetch the entry notes, use the /list/{id}/entries endpoint.
pub preview_entries: Vec<ListEntrySummary>,
/// A list of relevant URLs to this entity, on Letterboxd and external
/// sites.
pub links: Vec<Link>,
/// The list description formatted as HTML.
pub description: Option<String>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct ListComment {
/// The LID of the comment.
id: String,
/// The member who posted the comment.
member: MemberSummary,
/// ISO 8601 format with UTC timezone, i.e. YYYY-MM-DDThh:mm:ssZ
/// "1997-08-29T07:14:00Z"
when_created: String,
/// ISO 8601 format with UTC timezone, i.e. YYYY-MM-DDThh:mm:ssZ
/// "1997-08-29T07:14:00Z"
when_updated: String,
/// The message portion of the comment in LBML. May contain the following
/// HTML tags: `<br>` `<strong>` `<em>` `<b>` `<i>` `<a href="">`
/// `<blockquote>`.
comment_lbml: String,
/// If Letterboxd moderators have removed the comment from the site,
/// removedByAdmin will be true and comment will not be included.
removed_by_admin: bool,
/// If the comment owner has removed the comment from the site, deleted
/// will be true and comment will not be included.
deleted: bool,
/// If the authenticated member has blocked the commenter, blocked will be
/// true and comment will not be included.
blocked: bool,
/// If the list owner has blocked the commenter, blockedByOwner will be
/// true and comment will not be included.
blocked_by_owner: bool,
/// If the authenticated member posted this comment, and the comment is
/// still editable, this value shows the number of seconds remaining until
/// the editing window closes.
editable_window_expires_in: Option<usize>,
/// The list on which the comment was posted.
list: ListIdentifier,
/// The message portion of the comment formatted as HTML.
comment: String,
}
#[derive(Deserialize, Debug, Clone)]
struct ListCommentsResponse {
/// The cursor to the next page of results.
next: Option<Cursor>,
/// The list of comments.
items: Vec<ListComment>,
}
#[derive(Serialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ListCreateEntry {
/// The LID of the film.
film: String,
/// The entry’s rank in the list, numbered from 1. If not set, the entry
/// will be appended to the end of the list. Sending two or more
/// ListCreateEntrys with the same rank will return an error.
rank: usize,
/// The notes for the list entry in LBML. May contain the following HTML tags: `<br>` `<strong>` `<em>` `<b>` `<i>` `<a href="">` `<blockquote>`.
notes: String,
/// Set to true if the member has indicated that the notes field contains
/// plot spoilers for the film.
contains_spoilers: bool,
}
#[derive(Deserialize, Debug, Clone)]
pub enum ListCreateMessageCode {
ListNameIsBlank,
UnknownFilmCode,
InvalidRatingValue,
DuplicateRank,
EmptyPublicList,
CloneSourceNotFound,
SharingServiceNotAuthorized,
CannotSharePrivateList,
ListDescriptionIsTooLong,
ListEntryNotesTooLong,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(tag = "type")]
pub enum ListCreateMessage {
Error {
/// The error message code.
code: ListCreateMessageCode,
/// The error message text in human-readable form.
title: String,
},
Success,
}
#[derive(Deserialize, Debug, Clone)]
pub struct ListCreateResponse {
/// The response object.
pub data: List,
// A list of messages the API client should show to the user.
pub messages: Vec<ListCreateMessage>,
}
#[derive(Serialize, Debug, Clone)]
pub struct ListCreationRequest {
/// The name of the list.
name: String,
/// Set to true if the owner has elected to publish the list for other
/// members to see.
published: bool,
/// Set to true if the owner has elected to make this a ranked list.
ranked: bool,
/// The list description in LBML. May contain the following HTML tags:
/// `<br>` `<strong>` `<em>` `<b>` `<i>` `<a href="">` `<blockquote>`. This
/// field has a maximum size of 100,000 characters.
#[serde(skip_serializing_if = "Option::is_none")]
description: Option<String>,
/// The LID of a list to clone from. Only supported for paying members.
#[serde(skip_serializing_if = "Option::is_none")]
cloned_from: Option<String>,
// The tags for the list.
#[serde(skip_serializing_if = "Vec::is_empty")]
tags: Vec<String>,
/// The films that comprise the list. Required unless source is set.
#[serde(skip_serializing_if = "Vec::is_empty")]
entries: Vec<ListCreateEntry>,
/// The third-party service or services to which this list should be shared. Valid options are found in the MemberAccount.authorizedSharingServicesForLists (see the /me endpoint).
#[serde(skip_serializing_if = "Vec::is_empty")]
share: Vec<ThirdPartyService>,
}
impl ListCreationRequest {
pub fn new(name: String) -> Self {
Self {
name,
published: false,
ranked: false,
description: None,
cloned_from: None,
tags: Vec::new(),
entries: Vec::new(),
share: Vec::new(),
}
}
}
#[derive(Serialize, Debug, Clone)]
pub enum ListEntriesRequestSort {
ListRanking,
WhenAddedToList,
RatingHighToLow,
RatingLowToHigh,
FilmName,
ReleaseDateLatestFirst,
ReleaseDateEarliestFirst,
FilmDurationShortestFirst,
FilmDurationLongestFirst,
FilmPopularity,
FilmPopularityThisWeek,
FilmPopularityThisMonth,
FilmPopularityThisYear,
}
#[derive(Serialize, Debug, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct ListEntriesRequest {
/// The pagination cursor.
pub cursor: Option<Cursor>,
/// The number of items to include per page (default is 20, maximum is 100).
pub per_page: Option<usize>,
/// The order in which the entries should be returned. Defaults to
/// ListRanking, which is the order specified by the list owner.
pub sort: Option<ListEntriesRequestSort>,
/// Specify the LID of a genre to limit films to those within the specified
/// genre.
pub genre: Option<String>,
/// Specify the starting year of a decade (must end in 0) to limit films to
/// those released during the decade. 1990
pub decade: Option<u16>,
/// Specify a year to limit films to those released during that year. 1994
pub year: Option<u16>,
/// Specify the ID of a supported service to limit films to those available
/// from that service. The list of available services can be found by using
/// the /films/film-services endpoint.
pub service: Option<String>,
/// Specify one or more values to limit the list of films accordingly.
/// where=Watched&where=Released
#[serde(rename = "where")]
pub where_film_status: Vec<FilmStatus>,
/// Specify the LID of a member to limit the returned films according to
/// the value set in memberRelationship.
pub member: Option<String>,
/// Must be used in conjunction with member. Defaults to Watched. Specify
/// the type of relationship to limit the returned films accordingly.
pub member_relationship: Option<FilmRelationshipType>,
/// Must be used in conjunction with member. Defaults to None, which only
/// returns films from the member’s account. Use Only to return films from
/// the member’s friends, and All to return films from both the member and
/// their friends.
pub include_friends: Option<IncludeFriends>,
/// Specify a tag code to limit the returned films to those tagged
/// accordingly.
pub tag_code: Option<String>,
/// Must be used with tag. Specify the LID of a member to focus the tag
/// filter on the member.
pub tagger: Option<String>,
/// Must be used in conjunction with tagger. Defaults to None, which
/// filters tags set by the member. Use Only to filter tags set by the
/// member’s friends, and All to filter tags set by both the member and
/// their friends.
pub include_tagger_friends: Option<IncludeFriends>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct ListEntriesResponse {
/// The cursor to the next page of results.
pub next: Option<Cursor>,
// The list of entries.
pub items: Vec<ListEntry>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ListEntry {
/// The entry’s rank in the list, numbered from 1.
pub rank: Option<usize>,
/// The notes for the list entry in LBML. May contain the following HTML tags: `<br>` `<strong>` `<em>` `<b>` `<i>` `<a href="">` `<blockquote>`.
pub notes_lbml: Option<String>,
/// Will be true if the member has indicated that the notes field contains
/// plot spoilers for the film.
pub contains_spoilers: Option<bool>,
/// The film for this entry. Includes a MemberFilmRelationship for the
/// member who created the list.
pub film: FilmSummary,
/// The notes for the list entry formatted as HTML.
pub notes: Option<String>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct ListEntrySummary {
/// The entry’s rank in the list, numbered from 1.
#[serde(skip_serializing_if = "Option::is_none")]
pub rank: Option<usize>,
/// The film for this entry.
pub film: FilmSummary,
}
#[derive(Deserialize, Debug, Clone)]
pub struct ListIdentifier {
/// The LID of the list.
pub id: String,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct ListRelationship {
/// Will be true if the member likes the list (via the ‘heart’ icon). A
/// member may not like their own list.
liked: bool,
/// Will be true if the member is subscribed to comment notifications for
/// the list
subscribed: bool,
/// Defaults to Subscribed for the list’s owner, and NotSubscribed for
/// other members. The subscription value may change when a member (other
/// than the owner) posts a comment, as follows: the member will become
/// automatically Subscribed unless they have previously Unsubscribed from
/// the comment thread via the web interface or API, or unless they have
/// disabled comment notifications in their profile settings.
subscription_state: SubscriptionState,
/// The authenticated member’s state with respect to adding comments for
/// this list.
comment_thread_state: CommentThreadState,
}
#[derive(Deserialize, Debug, Clone)]
enum ListRelationshipUpdateMessageCode {
LikeBlockedContent,
LikeOwnList,
SubscribeWhenOptedOut,
SubscribeToContentYouBlocked,
SubscribeToBlockedContent,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(tag = "type")]
enum ListRelationshipUpdateMessage {
Error {
/// The error message code.
code: ListRelationshipUpdateMessageCode,
/// The error message text in human-readable form.
title: String,
},
Success,
}
#[derive(Deserialize, Debug, Clone)]
struct ListRelationshipUpdateRequest {
/// Set to true if the member likes the list (via the ‘heart’ icon). A
/// member may not like their own list.
liked: bool,
/// Set to true to subscribe the member to comment notifications for the list, or false to unsubscribe them. A value of true will be ignored if the member has disabled comment notifications in their profile settings.
subscribed: bool,
}
#[derive(Deserialize, Debug, Clone)]
struct ListRelationshipUpdateResponse {
/// The response object.
data: ListRelationship,
/// A list of messages the API client should show to the user.
messages: Vec<ListRelationshipUpdateMessage>,
}
#[derive(Deserialize, Debug, Clone)]
struct ListStatistics {
/// The list for which statistics were requested.
list: ListIdentifier,
/// The number of comments and likes for the list.
counts: ListStatisticsCounts,
}
#[derive(Deserialize, Debug, Clone)]
struct ListStatisticsCounts {
/// The number of comments for the list.
comments: usize,
/// The number of members who like the list.
likes: usize,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ListSummary {
/// The LID of the list.
pub id: String,
/// The name of the list.
pub name: String,
/// The number of films in the list.
pub film_count: usize,
/// Will be true if the owner has elected to publish the list for other
/// members to see.
pub published: bool,
/// Will be true if the owner has elected to make this a ranked list.
pub ranked: bool,
/// The list description in LBML. May contain the following HTML tags:
/// `<br>` `<strong>` `<em>` `<b>` `<i>` `<a href="">` `<blockquote>`. The
/// text is a preview extract, and may be truncated if it’s too long.
pub description_lbml: Option<String>,
/// Will be true if the list description was truncated because it’s very
/// long.
pub description_truncated: Option<bool>,
/// The member who owns the list.
pub owner: MemberSummary,
/// The list this was cloned from, if applicable.
pub cloned_from: Option<ListIdentifier>,
/// The first 12 entries in the list. To fetch more than 12 entries, and to
/// fetch the entry notes, use the /list/{id}/entries endpoint.
pub preview_entries: Vec<ListEntrySummary>,
/// The list description formatted as HTML. The text is a preview extract,
/// and may be truncated if it’s too long.
pub description: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ListUpdateEntry {
/// The LID of the film.
pub film: String,
/// The entry’s rank in the list, numbered from 1. If not set, the entry
/// will stay in the same place (if already in the list) or be appended to
/// the end of the list (if not in the list). If set, any entries at or
/// after this position will be incremented by one. Sending two or more
/// ListUpdateEntrys with the same rank will return an error.
#[serde(skip_serializing_if = "Option::is_none")]
pub rank: Option<usize>,
/// The notes for the list entry in LBML. May contain the following HTML
/// tags: `<br>` `<strong>` `<em>` `<b>` `<i>` `<a href="">`
/// `<blockquote>`. This field has a maximum size of 100,000 characters.
#[serde(skip_serializing_if = "Option::is_none")]
pub notes: Option<String>,
/// Set to true if the member has indicated that the notes field contains
/// plot spoilers for the film.
#[serde(skip_serializing_if = "Option::is_none")]
pub contains_spoilers: Option<bool>,
}
impl ListUpdateEntry {
pub fn new(film: String) -> ListUpdateEntry {
ListUpdateEntry {
film,
rank: None,
notes: None,
contains_spoilers: None,
}
}
}
#[derive(Deserialize, Debug, Clone)]
pub enum ListUpdateMessageCode {
ListNameIsBlank,
UnknownFilmCode,
InvalidRatingValue,
DuplicateRank,
EmptyPublicList,
SharingServiceNotAuthorized,
CannotSharePrivateList,
ListDescriptionIsTooLong,
ListEntryNotesTooLong,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(tag = "type")]
pub enum ListUpdateMessage {
Error {
/// The error message code.
code: ListUpdateMessageCode,
/// The error message text in human-readable form.
title: String,
},
Success,
}
#[derive(Serialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ListUpdateRequest {
/// Set to true if the owner has elected to publish the list for other
/// members to see.
#[serde(skip_serializing_if = "Option::is_none")]
pub published: Option<bool>,
/// The name of the list.
pub name: String,
/// Set to true if the owner has elected to make this a ranked list.
#[serde(skip_serializing_if = "Option::is_none")]
pub ranked: Option<bool>,
/// The list description in LBML. May contain the following HTML tags:
/// `<br>` `<strong>` `<em>` `<b>` `<i>` `<a href="">` `<blockquote>`. This
/// field has a maximum size of 100,000 characters.
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
/// The tags for the list.
#[serde(skip_serializing_if = "Vec::is_empty")]
pub tags: Vec<String>,
/// Specify the LIDs of films to be removed from the list.
#[serde(skip_serializing_if = "Vec::is_empty")]
pub films_to_remove: Vec<String>,
/// The specified entries will be inserted/appended to the list if they are
/// not already present, or updated if they are present.
#[serde(skip_serializing_if = "Vec::is_empty")]
pub entries: Vec<ListUpdateEntry>,
/// The third-party service or services to which this list should be
/// shared. Valid options are found in the ListRelationship (see the
/// /list/{id}/me endpoint).
#[serde(skip_serializing_if = "Vec::is_empty")]
pub share: Vec<ThirdPartyService>,
}
impl ListUpdateRequest {
pub fn new(name: String) -> ListUpdateRequest {
ListUpdateRequest {
published: None,
name,
ranked: None,
description: None,
tags: Vec::new(),
films_to_remove: Vec::new(),
entries: Vec::new(),
share: Vec::new(),
}
}
}
#[derive(Deserialize, Debug, Clone)]
pub struct ListUpdateResponse {
/// The response object.
pub data: List,
// A list of messages the API client should show to the user.
pub messages: Vec<ListUpdateMessage>,
}
#[derive(Serialize, Debug, Clone)]
pub enum ListRequestSort {
Date,
WhenCreatedLatestFirst,
WhenCreatedEarliestFirst,
ListName,
ListPopularity,
ListPopularityThisWeek,
ListPopularityThisMonth,
ListPopularityThisYear,
ListPopularityWithFriends,
ListPopularityWithFriendsThisWeek,
ListPopularityWithFriendsThisMonth,
ListPopularityWithFriendsThisYear,
}
#[derive(Serialize, Debug, Clone)]
pub enum ListMemberRelationship {
Owner,
Liked,
}
#[derive(Serialize, Debug, Clone)]
pub enum ListStatus {
Clean,
Published,
Unpublished,
}
#[derive(Serialize, Debug, Clone)]
pub enum ListRequestFilter {
NoDuplicateMembers,
}
#[derive(Serialize, Debug, Default, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ListsRequest {
/// The pagination cursor.
pub cursor: Option<Cursor>,
/// The number of items to include per page (default is 20, maximum is 100).
pub per_page: Option<usize>,
/// Defaults to Date, which returns lists that were most recently
/// created/updated first. The ListPopularityWithFriends values are only
/// available to signed-in members and consider popularity amongst the
/// signed-in member’s friends.
pub sort: Option<ListRequestSort>,
/// Specify the LID of a film to return lists that include that film.
pub film: Option<String>,
/// Specify the LID of a list to return lists that were cloned from that
/// list.
pub cloned_from: Option<String>,
/// Specify a tag code to limit the returned lists to those tagged
/// accordingly. Must be used with member and memberRelationship=Owner.
pub tag_code: Option<String>,
/// Specify the LID of a member to return lists that are owned or liked by
/// the member (or their friends, when used with includeFriends).
pub member: Option<String>,
/// Must be used in conjunction with member. Defaults to Owner, which
/// returns lists owned by the specified member. Use Liked to return lists
/// liked by the member.
pub member_relationship: Option<ListMemberRelationship>,
/// Must be used in conjunction with member. Defaults to None, which only
/// returns lists from the member’s account. Use Only to return lists from
/// the member’s friends, and All to return lists from both the member and
/// their friends.
pub include_friends: Option<IncludeFriends>,
/// Specify Clean to return lists that do not contain profane language.
/// Specify Published to return the member’s lists that have been made
/// public. Note that unpublished lists for members other than the
/// authenticated member are never returned. Specify NotPublished to return
/// the authenticated member’s lists that have not been made public.
#[serde(rename = "where")]
pub where_list_status: Vec<ListStatus>,
/// Specify NoDuplicateMembers to limit the list to only the first list for
/// each member. filter=NoDuplicateMembers
pub filter: Vec<ListRequestFilter>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct ListsResponse {
/// The cursor to the next page of results.
next: Option<Cursor>,
/// The list of lists.
items: Vec<ListSummary>,
}
#[derive(Serialize, Debug, Clone)]
enum LogEntriesRequestSort {
WhenAdded,
Date,
RatingHighToLow,
RatingLowToHigh,
ReleaseDateLatestFirst,
ReleaseDateEarliestFirst,
FilmName,
FilmDurationShortestFirst,
FilmDurationLongestFirst,
ReviewPopularity,
ReviewPopularityThisWeek,
ReviewPopularityThisMonth,
ReviewPopularityThisYear,
ReviewPopularityWithFriends,
ReviewPopularityWithFriendsThisWeek,
ReviewPopularityWithFriendsThisMonth,
ReviewPopularityWithFriendsThisYear,
FilmPopularity,
FilmPopularityThisWeek,
FilmPopularityThisMonth,
FilmPopularityThisYear,
FilmPopularityWithFriends,
FilmPopularityWithFriendsThisWeek,
FilmPopularityWithFriendsThisMonth,
FilmPopularityWithFriendsThisYear,
}
#[derive(Serialize, Debug, Clone)]
enum LogEntryRelationshipType {
Owner,
Liked,
}
#[derive(Serialize, Debug, Clone)]
enum LogEntryStatus {
HasDiaryDate,
HasReview,
Clean,
NoSpoilers,
Released,
NotReleased,
FeatureLength,
NotFeatureLength,
InWatchlist,
NotInWatchlist,
Watched,
NotWatched,
Rated,
NotRated,
}
#[derive(Serialize, Debug, Clone)]
enum LogEntryFilter {
NoDuplicateMembers,
}
#[derive(Serialize, Debug, Clone)]
struct LogEntriesRequest {
/// The pagination cursor.
cursor: Option<Cursor>,
/// The number of items to include per page (default is 20, maximum is 100).
per_page: Option<usize>,
/// The order in which the log entries should be returned. Defaults to
/// WhenAdded, which orders by creation date, unless you specify
/// where=HasDiaryDate in which case the default is Date.
/// The ReviewPopularity values return reviews with more activity
/// (likes/comments) first, and imply where=HasReview.
/// The FilmPopularity values return reviews for more popular films first.
/// The ReviewPopularityWithFriends and FilmPopularityWithFriends values
/// are only available to signed-in members and consider popularity amongst
/// the signed-in member’s friends.
/// The Date value sorts by the diary date, and implies where=HasDiaryDate
/// You may not specify a film when using ReleaseDateLatestFirst,
/// ReleaseDateEarliestFirst, FilmName, FilmDurationShortestFirst,
/// FilmDurationLongestFirst, or any of the FilmPopularity options.
sort: LogEntriesRequestSort,
/// Specify the LID of a film to return log entries for that film. Must not
/// be included if the sort value is ReleaseDateLatestFirst,
/// ReleaseDateEarliestFirst, FilmName, FilmDurationShortestFirst,
/// FilmDurationLongestFirst, or any of the FilmPopularity options.
film: String,
/// Specify the LID of a member to limit the returned log entries according
/// to the value set in memberRelationship.
member: String,
/// Must be used in conjunction with member. Use Owner to limit the
/// returned log entries to those created by the specified member. Use
/// Liked to limit the returned reviews to those liked by the specified
/// member (implies where=HasReview).
member_relationship: LogEntryRelationshipType,
/// Must be used in conjunction with member. Specify the type of
/// relationship to limit the returned films accordingly. e.g. Use Liked to
/// limit the returned reviews to those for films liked by the member.
film_member_relationship: FilmRelationshipType,
/// Must be used in conjunction with member. Defaults to None, which only
/// returns log entries created or liked by the member. Use Only to return
/// log entries created or liked by the member’s friends, and All to return
/// log entries created or liked by both the member and their friends.
include_friends: IncludeFriends,
/// If set, limits the returned log entries to those with date that falls
/// during the specified year.
year: u16,
/// Accepts values of 1 through 12. Must be used with year. If set, limits
/// the returned log entries to those with a date that falls during the
/// specified month and year.
month: u16,
/// Accepts values of 1 through 52. Must be used with year. If set, limits
/// the returned log entries to those with a date that falls during the
/// specified week and year.
week: u16,
/// Accepts values of 1 through 31. Must be used with month and year. If
/// set, limits the returned log entries to those with a date that falls on
/// the specified day, month and year.
day: u16,
/// Allowable values are between 0.5 and 5.0, with increments of 0.5. If
/// set, limits the returned log entries to those with a rating equal to or
/// higher than the specified rating.
min_rating: f32,
/// Allowable values are between 0.5 and 5.0, with increments of 0.5. If
/// set, limits the returned log entries to those with a rating equal to or
/// lower than the specified rating.
max_rating: f32,
/// Specify the starting year of a decade (must end in 0) to limit films to
/// those released during the decade. 1990
film_decade: u16,
/// Specify a year to limit films to those released during that year. 1994
film_year: u16,
/// The LID of the genre. If set, limits the returned log entries to those
/// for films that match the specified genre.
genre: String,
/// Specify a tag code to limit the returned log entries to those tagged
/// accordingly.
tag_code: String,
/// Must be used with tag. Specify the LID of a member to focus the tag
/// filter on the member.
tagger: String,
/// Must be used in conjunction with tagger. Defaults to None, which
/// filters tags set by the member. Use Only to filter tags set by the
/// member’s friends, and All to filter tags set by both the member and
/// their friends.
include_tagger_friends: IncludeFriends,
/// Specify the ID of a supported service to limit films to those available
/// from that service. The list of available services can be found by using
/// the /films/film-services endpoint.
service: String,
/// Specify one or more values to limit the returned log entries
/// accordingly. All values except HasDiaryDate, HasReview, Clean and
/// NoSpoilers refer to properties of the associated film rather than to
/// the relevant log entry. Use HasDiaryDate to limit the returned log
/// entries to those that appear in a member’s diary. Use HasReview to
/// limit the returned log entries to those containing a review. Use Clean
/// to exclude reviews that contain profane language. Use NoSpoilers to
/// exclude reviews where the owner has indicated that the review text
/// contains plot spoilers for the film. where=Clean&where=NoSpoilers
#[serde(rename = "where")]
where_logentry_status: Vec<LogEntryStatus>,
/// Specify NoDuplicateMembers to return only the first log entry for each
/// member. filter=NoDuplicateMembers
filter: Vec<LogEntryFilter>,
}
#[derive(Deserialize, Debug, Clone)]
struct LogEntriesResponse {
/// The cursor to the next page of results.
next: Option<Cursor>,
// The list of log entries.
items: Vec<LogEntry>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct LogEntry {
/// The LID of the log entry.
pub id: String,
/// A descriptive title for the log entry.
pub name: String,
/// The member who created the log entry.
pub owner: MemberSummary,
/// The film being logged. Includes a MemberFilmRelationship for the member
/// who created the log entry.
pub film: FilmSummary,
/// Details about the log entry, if present.
pub diary_details: Option<DiaryDetails>,
/// Review details for the log entry, if present.
pub review: Option<Review>,
/// The tags for the log entry.
pub tags2: Vec<Tag>,
/// The timestamp of when the log entry was created, in ISO 8601 format
/// with UTC timezone, i.e. YYYY-MM-DDThh:mm:ssZ "1997-08-29T07:14:00Z"
pub when_created: String,
/// The timestamp of when the log entry was last updated, in ISO 8601
/// format with UTC timezone, i.e. YYYY-MM-DDThh:mm:ssZ
/// "1997-08-29T07:14:00Z"
pub when_updated: String,
/// The member’s rating for the film. Allowable values are between 0.5 and
/// 5.0, with increments of 0.5.
pub rating: f32,
/// Will be true if the member likes the film (via the ‘heart’ icon).
pub like: bool,
/// Will be true if the log entry can have comments.
pub commentable: bool,
/// A list of relevant URLs to this entity, on Letterboxd and external
/// sites.
pub links: Vec<Link>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct LogEntryCreationRequest {
/// The film being logged.
film_id: String,
/// Information about this log entry if adding to the member’s diary.
diary_details: LogEntryCreationRequestDiaryDetails,
/// Information about the review if adding a review.
review: LogEntryCreationRequestReview,
/// The tags for the log entry.
tags: Vec<String>,
/// Allowable values are between 0.5 and 5.0, with increments of 0.5.
rating: f32,
/// Set to true if the member likes the film (via the ‘heart’ icon).
like: bool,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct LogEntryCreationRequestDiaryDetails {
/// The date the film was watched, if specified, in ISO 8601 format, i.e.
/// YYYY-MM-DD
diary_date: String,
/// Set to true if the member has indicated (or it can be otherwise
/// determined) that the member has seen the film prior to this date.
rewatch: bool,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct LogEntryCreationRequestReview {
/// The review text in LBML. May contain the following HTML tags: `<br>`
/// `<strong>` `<em>` `<b>` `<i>` `<a href="">` `<blockquote>`. This field
/// has a maximum size of 100,000 characters.
text: String,
/// Set to true if the member has indicated that the review field contains
/// plot spoilers for the film.
contains_spoilers: bool,
/// The third-party service or services to which this review should be
/// shared. Valid options are found in the
/// MemberAccount.authorizedSharingServicesForReviews (see the /me
/// endpoint).
share: Vec<ThirdPartyService>,
}
#[derive(Deserialize, Debug, Clone)]
enum LogEntryUpdateMessageCode {
InvalidRatingValue,
InvalidDiaryDate,
ReviewWithNoText,
ReviewIsTooLong,
LogEntryWithNoReviewOrDiaryDetails,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(tag = "type")]
enum LogEntryUpdateMessage {
Error {
/// The error message code
code: LogEntryUpdateMessageCode,
/// The error message text in human-readable form.
title: String,
},
Success,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct LogEntryUpdateRequest {
/// Information about this log entry if adding to the member’s diary. Set
/// to null to remove this log entry from the diary.
diary_details: LogEntryUpdateRequestDiaryDetails,
/// Information about the review. Set to null to remove the review from
/// this log entry.
review: LogEntryUpdateRequestReview,
// The tags for the log entry.
tags: Vec<String>,
/// Accepts values between 0.5 and 5.0, with increments of 0.5, or null (to
/// remove the rating).
rating: f32,
/// Set to true if the member likes the film (via the ‘heart’ icon).
like: bool,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct LogEntryUpdateRequestDiaryDetails {
/// The date the film was watched, if specified, in ISO 8601 format, i.e.
/// YYYY-MM-DD
diary_date: String,
/// Set to true if the member has indicated (or it can be otherwise
/// determined) that the member has seen the film prior to this date.
rewatch: bool,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct LogEntryUpdateRequestReview {
/// The review text in LBML. May contain the following HTML tags: `<br>`
/// `<strong>` `<em>` `<b>` `<i>` `<a href="">` `<blockquote>`.
text: String,
/// Set to true if the member has indicated that the review field contains
/// plot spoilers for the film.
contains_spoilers: bool,
// The third-party service or services to which this review should be shared. Valid options are found in the ReviewRelationship.canShareOn (see the /log-entry/{id}/me endpoint).
share: Vec<ThirdPartyService>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct Member {
/// The LID of the member.
id: String,
/// The member’s Letterboxd username. Usernames must be between 2 and 15
/// characters long and may only contain upper or lowercase letters,
/// numbers or the underscore (_) character.
username: String,
/// The given name of the member.
given_name: String,
/// The family name of the member.
family_name: String,
/// A convenience method that returns the member’s given name and family
/// name concatenated with a space, if both are set, or just their given
/// name or family name, if one is set, or their username, if neither is
/// set. Will never be empty.
display_name: String,
/// A convenience method that returns the member’s given name, if set, or
/// their username. Will never be empty.
short_name: String,
/// The member’s preferred pronoun set. Use the /members/pronouns endpoint
/// to request all available pronoun sets.
pronoun: Pronoun,
/// The member’s Twitter username, if they have authenticated their account.
twitter_username: String,
/// The member’s bio in LBML. May contain the following HTML tags: `<br>`
/// `<strong>` `<em>` `<b>` `<i>` `<a href="">` `<blockquote>`.
bio_lbml: String,
/// The member’s location.
location: String,
/// The member’s website URL. URLs are not validated, so sanitizing may be
/// required.
website: String,
/// The member’s avatar image at multiple sizes.
avatar: Image,
/// The member’s backdrop image at multiple sizes, sourced from the first
/// film in the member’s list of favorite films, if available. Only
/// returned for Patron members.
backdrop: Image,
/// The vertical focal point of the member’s backdrop image, if available.
/// Expressed as a proportion of the image’s height, using values between
/// 0.0 and 1.0. Use when cropping the image into a shorter space, such as
/// in the page for a film on the Letterboxd site.
backdrop_focal_point: f32,
/// The member’s account type.
member_status: MemberStatus,
/// A summary of the member’s favorite films, up to a maximum of four.
favorite_films: Vec<FilmSummary>,
/// A link to the member’s profile page on the Letterboxd website.
links: Vec<Link>,
/// The member’s bio formatted as HTML.
bio: String,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct MemberAccount {
/// The member’s email address.
email_address: String,
/// Will be true if the member has validated their emailAddress via an
/// emailed link.
email_address_validated: bool,
/// Defaults to false for new accounts. Indicates whether the member has
/// elected for their content to appear in the API (other than in the /me
/// endpoint).
private_account: bool,
/// Defaults to true for new accounts. Indicates whether the member has
/// elected to appear in the People section of the Letterboxd website.
include_in_people_section: bool,
/// Defaults to false for new accounts. Indicates whether the member has
/// elected to hide their Watchlist from other members.
private_watchlist: bool,
/// Defaults to true for new accounts. Indicates whether the member has elected to receive email notifications when they receive a new follower.
email_when_followed: bool,
/// Defaults to true for new accounts. Indicates whether the member has
/// elected to receive email notifications when new comments are posted in
/// threads they are subscribed to.
email_comments: bool,
/// Defaults to true for new accounts. Indicates whether the member has
/// elected to receive regular email news (including ‘Call Sheet’) from
/// Letterboxd.
email_news: bool,
/// Defaults to true for new accounts. Indicates whether the member has
/// elected to receive a weekly email digest of new and popular content
/// (called ‘Rushes’).
email_rushes: bool,
/// Defaults to false for new accounts. Indicates whether the member has
/// commenting privileges. Commenting is disabled on new accounts until the
/// member’s emailAddress is validated. At present canComment is synonymous
/// with emailAddressValidated (unless the member is suspended) but this
/// may change in future.
can_comment: bool,
/// Indicates whether the member is suspended from commenting due to a
/// breach of the Community Policy.
suspended: bool,
/// Indicates whether the member is able to clone other members’ lists.
/// Determined by Letterboxd based upon memberStatus.
can_clone_lists: bool,
/// Indicates whether the member is able to filter activity by type.
/// Determined by Letterboxd based upon memberStatus.
can_filter_activity: bool,
/// The services the member has authorized Letterboxd to share lists to.
/// More services may be added in the future.
authorized_sharing_services_for_lists: Vec<ThirdPartyService>,
/// The services the member has authorized Letterboxd to share reviews to.
/// More services may be added in the future.
authorized_sharing_services_for_reviews: Vec<ThirdPartyService>,
/// The number of days the member has left in their subscription. Only
/// returned for paying members.
membership_days_remaining: usize,
/// Standard member details.
member: Member,
}
#[derive(Deserialize, Debug, Clone)]
pub struct MemberFilmRelationship {
/// The member.
pub member: MemberSummary,
/// The relationship details.
pub relationship: FilmRelationship,
}
// TODO: dedup and order
#[derive(Deserialize, Debug, Clone)]
enum MemberRelationshipType {
IsFollowing,
IsFollowedBy,
}
#[derive(Serialize, Debug, Clone)]
pub enum MemberFilmRelationshipsRequestSort {
Date,
Name,
MemberPopularity,
MemberPopularityThisWeek,
MemberPopularityThisMonth,
MemberPopularityThisYear,
MemberPopularityWithFriends,
MemberPopularityWithFriendsThisWeek,
MemberPopularityWithFriendsThisMonth,
MemberPopularityWithFriendsThisYear,
}
#[derive(Serialize, Debug, Clone, Default)]
pub struct MemberFilmRelationshipsRequest {
/// The pagination cursor.
pub cursor: Option<Cursor>,
/// The number of items to include per page (default is 20, maximum is 100).
pub per_page: Option<usize>,
/// Defaults to Date, which has different semantics based on the request:
/// When review is specified, members who most recently liked the review
/// appear first.
/// When list is specified, members who most recently liked the list appear
/// first.
/// When film is specified and filmRelationship=Watched, members who most
/// recently watched the film appear first.
/// When film is specified and filmRelationship=Liked, members who most
/// recently liked the film appear first.
/// When member is specified and memberRelationship=IsFollowing, most
/// recently followed members appear first.
/// When member is specified and memberRelationship=IsFollowedBy, most
/// recent followers appear first.
/// Otherwise, members who most recently joined the site appear first.
/// The PopularWithFriends values are only available to authenticated
/// members and consider popularity amongst the member’s friends.
pub sort: Option<MemberFilmRelationshipsRequestSort>,
/// Specify the LID of a member to return members who follow or are
/// followed by that member.
pub member: Option<String>,
/// Must be used in conjunction with member. Defaults to IsFollowing, which
/// returns the list of members followed by the member. Use IsFollowedBy to
/// return the list of members that follow the member.
pub member_relationship: Option<FilmRelationshipType>,
/// Must be used in conjunction with film. Defaults to Watched, which
/// returns the list of members who have seen the film. Specify the type of
/// relationship to limit the returned members accordingly.
pub film_relationship: Option<FilmRelationshipType>,
}
#[derive(Deserialize, Debug, Clone)]
pub struct MemberFilmRelationshipsResponse {
/// The cursor to the next page of results.
pub next: Cursor,
/// The list of film relationships for members.
pub items: Vec<MemberFilmRelationship>,
}
#[derive(Deserialize, Debug, Clone)]
struct MemberIdentifier {
/// The LID of the member.
id: String,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct MemberRelationship {
/// Will be true if the authenticated member follows the member identified
/// by ID.
following: bool,
/// Will be true if the member identified by ID follows the authenticated
/// member.
followed_by: bool,
/// Will be true if the authenticated member has blocked the member
/// identified by ID.
blocking: bool,
/// Will be true if the member identified by ID has blocked the
/// authenticated member.
blocked_by: bool,
}
#[derive(Deserialize, Debug, Clone)]
enum MemberRelationshipUpdateMessageCode {
BlockYourself,
FollowYourself,
FollowBlockedMember,
FollowMemberYouBlocked,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(tag = "type")]
enum MemberRelationshipUpdateMessage {
Error {
/// The error message code.
code: MemberRelationshipUpdateMessageCode,
/// The error message text in human-readable form.
title: String,
},
Success,
}
#[derive(Deserialize, Debug, Clone)]
struct MemberRelationshipUpdateRequest {
/// Set to true if the authenticated member wishes to follow the member
/// identified by ID, or false if they wish to unfollow. A member may not
/// follow their own account, or the account of a member they have blocked
/// or that has blocked them.
following: bool,
/// Set to true if the authenticated member wishes to block the member
/// identified by ID, or false if they wish to unblock. A member may not
/// block their own account.
blocking: bool,
}
#[derive(Deserialize, Debug, Clone)]
struct MemberRelationshipUpdateResponse {
/// The response object.
data: MemberRelationship,
/// A list of messages the API client should show to the user.
messages: Vec<MemberRelationshipUpdateMessage>,
}
#[derive(Deserialize, Debug, Clone)]
enum MemberSettingsUpdateMessageCode {
IncorrectCurrentPassword,
BlankPassword,
InvalidEmailAddress,
InvalidFavoriteFilm,
BioTooLong,
InvalidPronounOption,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(tag = "type")]
enum MemberSettingsUpdateMessage {
Error {
/// The error message code.
code: MemberSettingsUpdateMessageCode,
/// The error message text in human-readable form.
title: String,
},
Success,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct MemberSettingsUpdateRequest {
/// The member’s email address.
email_address: String,
/// The member’s current password. Required when updating the password.
current_password: String,
/// The member’s new password.
password: String,
/// The given name of the member.
given_name: String,
/// The family name of the member.
family_name: String,
/// The LID of the member’s preferred pronoun set. Use the
/// /members/pronouns endpoint to request all available pronoun sets.
pronoun: String,
/// The member’s location.
location: String,
/// The member’s website URL. URLs are not validated, so sanitizing may be
/// required.
website: String,
/// The member’s bio in LBML. May contain the following HTML tags: `<br>`
/// `<strong>` `<em>` `<b>` `<i>` `<a href="">` `<blockquote>`. This field
/// has a maximum size of 100,000 characters.
bio: String,
/// The LIDs of the member’s favorite films, in order, up to a maximum of
/// four.
favorite_films: Vec<String>,
/// Set to true to prevent the member’s content from appearing in API
/// requests other than the /me endpoint.
private_account: bool,
/// Set to false to remove the account from the People section of the
/// Letterboxd website.
include_in_people_section: bool,
/// Set to true if the member wishes to receive email notifications when
/// they receive a new follower.
email_when_followed: bool,
/// Set to true if the member wishes to receive email notifications when
/// new comments are posted in threads they are subscribed to.
email_comments: bool,
/// Set to true if the member wishes to receive regular email news
/// (including ‘Call Sheet’) from Letterboxd.
email_news: bool,
/// Set to true if the member wishes to receive a weekly email digest of
/// new and popular content (called ‘Rushes’).
email_rushes: bool,
}
#[derive(Deserialize, Debug, Clone)]
struct MemberSettingsUpdateResponse {
/// The response object.
data: MemberAccount,
/// A list of messages the API client should show to the user.
messages: Vec<MemberSettingsUpdateMessage>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct MemberStatistics {
/// The member for which statistics were requested.
member: MemberIdentifier,
/// The number of watches, ratings, likes, etc. for the member.
counts: MemberStatisticsCounts,
/// A summary of the number of ratings the member has made for each
/// increment between 0.5 and 5.0. Returns only the integer increments
/// between 1.0 and 5.0 if the member never (or rarely) awards half-star
/// ratings.
ratings_histogram: Vec<RatingsHistogramBar>,
/// A list of years the member has year-in-review pages for. Only supported
/// for paying members.
years_in_review: Vec<u16>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct MemberStatisticsCounts {
/// The number of films the member has liked.
film_likes: usize,
/// The number of lists the member has liked.
list_likes: usize,
/// The number of reviews the member has liked.
review_likes: usize,
/// The number of films the member has watched. This is a distinct total —
/// films with multiple log entries are only counted once.
watches: usize,
/// The number of films the member has rated.
ratings: usize,
/// The number of films the member has reviewed.
reviews: usize,
/// The number of entries the member has in their diary.
diary_entries: usize,
/// The number of entries the member has in their diary for the current
/// year. The current year rolls over at midnight on 31 December in New
/// Zealand Daylight Time (GMT + 13).
diary_entries_this_year: usize,
/// The number of unique films the member has in their diary for the
/// current year. The current year rolls over at midnight on 31 December in
/// New Zealand Daylight Time (GMT + 13).
films_in_diary_this_year: usize,
/// The number of films the member has in their watchlist.
watchlist: usize,
/// The number of lists for the member. Includes unpublished lists if the
/// request is made for the authenticated member.
lists: usize,
/// The number of unpublished lists for the member. Only included if the
/// request is made for the authenticated member.
unpublished_lists: usize,
/// The number of members who follow the member.
followers: usize,
/// The number of members the member is following.
following: usize,
/// The number of tags the member has used for lists.
list_tags: usize,
/// The number of tags the member has used for diary entries and reviews.
film_tags: usize,
}
#[derive(Clone, Debug, Deserialize)]
pub enum MemberStatus {
Crew,
Patron,
Pro,
Member,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MemberSummary {
/// The LID of the member.
pub id: String,
/// The member’s Letterboxd username. Usernames must be between 2 and 15
/// characters long and
/// may only contain upper or lowercase letters, numbers or the underscore
/// (_) character.
pub username: String,
/// The given name of the member.
pub given_name: Option<String>,
/// The family name of the member.
pub family_name: Option<String>,
/// A convenience method that returns the member’s given name and family
/// name concatenated with
/// a space, if both are set, or just their given name or family name, if
/// one is set, or their
/// username, if neither is set. Will never be empty.
pub display_name: String,
/// A convenience method that returns the member’s given name, if set, or
/// their username. Will never be empty.
pub short_name: String,
/// The member’s preferred pronoun set. Use the /members/pronouns endpoint
/// to request all available pronoun sets.
pub pronoun: Pronoun,
/// The member’s avatar image at multiple sizes.
pub avatar: Image,
/// The member’s account type.
pub member_status: MemberStatus,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct MemberTag {
/// The tag code.
code: String,
/// The tag text as entered by the tagger.
display_tag: String,
/// Counts of the member’s uses of this tag.
counts: MemberTagCounts,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct MemberTagCounts {
/// The number of films the member has used this tag on.
films: usize,
/// The number of log entries the member has used this tag on.
log_entries: usize,
/// The number of diary entries the member has used this tag on.
diary_entries: usize,
/// The number of reviews the member has used this tag on.
reviews: usize,
/// The number of lists the member has used this tag on.
lists: usize,
}
#[derive(Clone, Debug, Serialize)]
struct MemberTagsRequest {
/// A case-insensitive prefix match. E.g. “pro” will match “pro”, “project”
/// and “Professional”. An empty input will match all tags.
input: String,
}
#[derive(Clone, Debug, Deserialize)]
struct MemberTagsResponse {
/// The list of tag items, ordered by frequency of use.
items: Vec<MemberTag>,
}
#[derive(Clone, Debug, Serialize)]
enum MembersRequestSort {
Date,
Name,
MemberPopularity,
MemberPopularityThisWeek,
MemberPopularityThisMonth,
MemberPopularityThisYear,
MemberPopularityWithFriends,
MemberPopularityWithFriendsThisWeek,
MemberPopularityWithFriendsThisMonth,
MemberPopularityWithFriendsThisYear,
}
// TODO: name
#[derive(Clone, Debug, Serialize)]
enum MembersRequestRelationship {
IsFollowing,
IsFollowedBy,
}
#[derive(Clone, Debug, Serialize)]
#[serde(rename_all = "camelCase")]
struct MembersRequest {
/// The pagination cursor.
cursor: Option<Cursor>,
/// The number of items to include per page (default is 20, maximum is 100).
per_page: Option<usize>,
/// Defaults to Date, which has different semantics based on the request:
/// When review is specified, members who most recently liked the review
/// appear first.
/// When list is specified, members who most recently liked the list appear
/// first.
/// When film is specified and filmRelationship=Watched, members who most
/// recently watched the film appear first.
/// When film is specified and filmRelationship=Liked, members who most
/// recently liked the film appear first.
/// When member is specified and memberRelationship=IsFollowing, most
/// recently followed members appear first.
/// When member is specified and memberRelationship=IsFollowedBy, most
/// recent followers appear first.
/// Otherwise, members who most recently joined the site appear first.
/// The PopularWithFriends values are only available to authenticated
/// members and consider popularity amongst the member’s friends.
sort: MembersRequestSort,
/// Specify the LID of a member to return members who follow or are
/// followed by that member.
member: String,
/// Must be used in conjunction with member. Defaults to IsFollowing, which
/// returns the list of members followed by the member. Use IsFollowedBy to
/// return the list of members that follow the member.
member_relationship: MembersRequestRelationship,
/// Specify the LID of a film to return members who have interacted with
/// that film.
film: String,
/// Must be used in conjunction with film. Defaults to Watched, which
/// returns the list of members who have seen the film. Specify the type of
/// relationship to limit the returned members accordingly. You must
/// specify a member in order to use the InWatchlist relationship.
film_relationship: FilmRelationship,
/// Specify the LID of a list to return members who like that list.
list: String,
/// Specify the LID of a review to return members who like that review.
review: String,
}
#[derive(Clone, Debug, Deserialize)]
struct MembersResponse {
/// The cursor to the next page of results.
next: Option<Cursor>,
/// The list of members.
items: Vec<MemberSummary>,
}
#[derive(Clone, Debug, Deserialize)]
struct OAuthError {
/// The error code, usually invalid_grant.
error: String,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Pronoun {
/// The LID for this pronoun set.
pub id: String,
/// A label to describe this pronoun set.
pub label: String,
/// The pronoun to use when the member is the subject. "She went to the
/// movies."
pub subject_pronoun: String,
/// The pronoun to use when the member is the object. "I went with her to
/// the cinema."
pub object_pronoun: String,
/// The adjective to use when describing a specified thing or things
/// belonging to or associated with a member previously mentioned. "He
/// bought his tickets."
pub possessive_adjective: String,
/// The pronoun to use when referring to a specified thing or things
/// belonging to or associated with a member previously mentioned. "That
/// popcorn was hers."
pub possessive_pronoun: String,
/// The pronoun to use to refer back to the member. "He saw himself as a
/// great director."
pub reflexive: String,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
struct PronounsResponse {
/// The list of pronouns.
items: Vec<Pronoun>,
}
#[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RatingsHistogramBar {
/// The rating increment between 0.5 and 5.0.
pub rating: f32,
/// The height of this rating increment’s entry in a unit-height histogram,
/// normalized between 0.0 and 1.0. The increment(s) with the highest
/// number of ratings will always return 1.0 (unless there are no ratings
/// for the film).
pub normalized_weight: f32,
/// The number of ratings made at this increment.
pub count: usize,
}
#[derive(Serialize, Clone, Debug)]
#[serde(rename_all = "camelCase")]
struct RegisterRequest {
/// The username for the new account. Use the /auth/username-check endpoint
/// to check availability.
username: String,
/// The password for the new account.
password: String,
/// The email address for the new account.
email_address: String,
/// Set to true if the person creating the account has agreed to being at
/// least 13 years of age, and to accepting Letterboxd’s Terms of Use.
accept_terms_of_use: bool,
}
#[derive(Serialize, Debug, Clone)]
enum ReportCommentReason {
Spoilers,
Spam,
Plagiarism,
Other,
}
#[derive(Serialize, Debug, Clone)]
struct ReportCommentRequest {
/// The reason why the comment was reported.
reason: ReportCommentReason,
/// An optional, explanatory message to accompany the report. Required if
/// the reason is Plagiarism or Other.
message: Option<String>,
}
#[derive(Serialize, Debug, Clone)]
enum ReportFilmReason {
Duplicate,
NotAFilm,
Other,
}
#[derive(Serialize, Debug, Clone)]
struct ReportFilmRequest {
/// The reason why the film was reported.
reason: ReportFilmReason,
/// An optional, explanatory message to accompany the report. Required if
/// the reason is Duplicate or Other.
message: Option<String>,
}
#[derive(Serialize, Debug, Clone)]
enum ReportListReason {
Spoilers,
Spam,
Plagiarism,
Other,
}
#[derive(Serialize, Debug, Clone)]
struct ReportListRequest {
/// The reason why the list was reported.
reason: ReportListReason,
/// An optional, explanatory message to accompany the report. Required if
/// the reason is Plagiarism or Other.
message: Option<String>,
}
#[derive(Serialize, Debug, Clone)]
enum ReportMemberReason {
SpamAccount,
Other,
}
#[derive(Serialize, Debug, Clone)]
struct ReportMemberRequest {
/// The reason why the member was reported.
reason: ReportMemberReason,
/// An optional, explanatory message to accompany the report. Required if
/// the reason is Other.
message: Option<String>,
}
#[derive(Serialize, Debug, Clone)]
enum ReportReviewReason {
Spoilers,
Spam,
Plagiarism,
Other,
}
#[derive(Serialize, Debug, Clone)]
struct ReportReviewRequest {
/// The reason why the review was reported.
reason: ReportReviewReason,
/// An optional, explanatory message to accompany the report. Required if
/// the reason is Plagiarism or Other.
message: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub enum ThirdPartyService {
Facebook,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Review {
/// The review text in LBML. May contain the following HTML tags: `<br>`
/// `<strong>` `<em>` `<b>` `<i>` `<a href="">` `<blockquote>`.
pub lbml: String,
/// Will be true if the member has indicated that the review field contains
/// plot spoilers for the film.
pub contains_spoilers: bool,
/// The third-party service or services to which this review can be shared.
/// Only included if the authenticated member is the review’s owner.
pub can_share_on: Option<ThirdPartyService>,
/// The third-party service or services to which this review has been shared. Only included if the authenticated member is the review’s owner.
pub shared_on: Option<ThirdPartyService>,
/// The timestamp when this log entry’s review was first published, in ISO
/// 8601 format with UTC timezone, i.e. YYYY-MM-DDThh:mm:ssZ
/// "1997-08-29T07:14:00Z"
pub when_reviewed: String,
/// The review text formatted as HTML.
pub text: String,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct ReviewComment {
/// The LID of the comment.
id: String,
/// The member who posted the comment.
member: MemberSummary,
/// ISO 8601 format with UTC timezone, i.e. YYYY-MM-DDThh:mm:ssZ
/// "1997-08-29T07:14:00Z"
when_created: String,
/// ISO 8601 format with UTC timezone, i.e. YYYY-MM-DDThh:mm:ssZ
/// "1997-08-29T07:14:00Z"
when_updated: String,
/// The message portion of the comment in LBML. May contain the following
/// HTML tags: `<br>` `<strong>` `<em>` `<b>` `<i>` `<a href="">`
/// `<blockquote>`.
comment_lbml: String,
/// If Letterboxd moderators have removed the comment from the site,
/// removedByAdmin will be true and comment will not be included.
removed_by_admin: bool,
/// If the comment owner has removed the comment from the site, deleted
/// will be true and comment will not be included.
deleted: bool,
/// If the authenticated member has blocked the commenter, blocked will be
/// true and comment will not be included.
blocked: bool,
/// If the review owner has blocked the commenter, blockedByOwner will be
/// true and comment will not be included.
blocked_by_owner: bool,
/// If the authenticated member posted this comment, and the comment is
/// still editable, this value shows the number of seconds remaining until
/// the editing window closes.
editable_window_expires_in: Option<usize>,
/// The review on which the comment was posted.
review: ReviewIdentifier,
/// The message portion of the comment formatted as HTML.
comment: String,
}
#[derive(Deserialize, Debug, Clone)]
struct ReviewCommentsResponse {
/// The cursor to the next page of results.
next: Option<Cursor>,
// The list of comments.
items: Vec<ReviewComment>,
}
#[derive(Deserialize, Debug, Clone)]
struct ReviewIdentifier {
/// The LID of the log entry.
id: String,
}
// TODO: order
#[derive(Deserialize, Debug, Clone)]
enum CommentThreadState {
/// `CanComment` means the authenticated member is authorized to add a
/// comment. All other
/// values mean the authenticated member is not authorized to add a comment.
CanComment,
/// `Banned` means the Letterboxd community managers have restricted the
/// member’s ability to
/// comment on the site.
Banned,
/// `Blocked` means the owner has blocked the member from adding comments.
Blocked,
/// `NotCommentable` means that it is invalid to try to add comments to
/// this content.
NotCommentable,
}
// TODO: order
/// `NotSubscribed` and `Unsubscribed` are maintained as separate states so the
/// UI can, if needed,
/// indicate to the member how their subscription state will be affected
/// if/when they post a
/// comment.
#[derive(Deserialize, Debug, Clone)]
enum SubscriptionState {
Subscribed,
NotSubscribed,
Unsubscribed,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct ReviewRelationship {
/// Will be true if the member likes the review (via the ‘heart’ icon). A
/// member may not like their own review.
liked: bool,
/// Will be true if the member is subscribed to comment notifications for
/// the review
subscribed: bool,
/// Defaults to Subscribed for the review’s author, and NotSubscribed for
/// other members. The subscription value may change when a member (other
/// than the owner) posts a comment, as follows: the member will become
/// automatically Subscribed unless they have previously Unsubscribed from
/// the comment thread via the web interface or API, or unless they have
/// disabled comment notifications in their profile settings.
subscription_state: SubscriptionState,
/// The authenticated member’s state with respect to adding comments for
/// this review.
comment_thread_state: CommentThreadState,
}
#[derive(Deserialize, Debug, Clone)]
enum ReviewRelationshipUpdateMessageCode {
LikeBlockedContent,
LikeOwnReview,
LikeLogEntryWithoutReview,
SubscribeWhenOptedOut,
SubscribeToContentYouBlocked,
SubscribeToBlockedContent,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(tag = "type")]
enum ReviewRelationshipUpdateMessage {
Error {
/// The error message code.
code: ReviewRelationshipUpdateMessageCode,
/// The error message text in human-readable form.
title: String,
},
Success,
}
#[derive(Serialize, Debug, Clone)]
struct ReviewRelationshipUpdateRequest {
/// Set to true if the member likes the review (via the ‘heart’ icon). A
/// member may not like their own review.
liked: bool,
/// Set to true to subscribe the member to comment notifications for the
/// review, or false to unsubscribe them. A value of true will be ignored
/// if the member has disabled comment notifications in their profile
/// settings.
subscribed: bool,
}
#[derive(Deserialize, Debug, Clone)]
struct ReviewRelationshipUpdateResponse {
/// The response object.
data: ReviewRelationship,
/// A list of messages the API client should show to the user.
messages: Vec<ReviewRelationshipUpdateMessage>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct ReviewStatistics {
/// The log entry for which statistics were requested.
log_entry: ReviewIdentifier,
/// The number of comments and likes for the review.
counts: ReviewStatisticsCounts,
}
#[derive(Deserialize, Debug, Clone)]
struct ReviewStatisticsCounts {
/// The number of comments for the review.
comments: usize,
/// The number of members who like the review.
likes: usize,
}
#[derive(Deserialize, Debug, Clone)]
struct ReviewUpdateResponse {
/// The response object.
data: LogEntry,
/// A list of messages the API client should show to the user.
messages: Vec<LogEntryUpdateMessage>,
}
#[derive(Serialize, Debug, Clone)]
pub enum SearchMethod {
FullText,
Autocomplete,
}
#[derive(Serialize, Debug, Clone, Default)]
#[serde(rename_all = "camelCase")]
pub struct SearchRequest {
/// The pagination cursor.
pub cursor: Option<Cursor>,
/// The number of items to include per page (default is 20, maximum is 100).
pub per_page: Option<usize>,
/// The word, partial word or phrase to search for.
pub input: String,
/// The type of search to perform. Defaults to FullText, which performs a
/// standard search considering text in all fields. Autocomplete only
/// searches primary fields.
pub search_method: Option<SearchMethod>,
// The types of results to search for. Default to all SearchResultTypes.
pub include: Option<Vec<SearchResultType>>,
/// The type of contributor to search for. Implies
/// include=ContributorSearchItem.
pub contribution_type: Option<ContributionType>,
}
impl SearchRequest {
pub fn new(input: String) -> SearchRequest {
SearchRequest {
cursor: None,
per_page: None,
input,
search_method: None,
include: None,
contribution_type: None,
}
}
}
#[derive(Deserialize, Debug, Clone)]
pub struct SearchResponse {
/// The cursor to the next page of results.
pub next: Option<Cursor>,
/// The list of search results.
pub items: Vec<AbstractSearchItem>,
}
#[derive(Serialize, Debug, Clone)]
pub enum SearchResultType {
ContributorSearchItem,
FilmSearchItem,
ListSearchItem,
MemberSearchItem,
/// Details of the review.
ReviewSearchItem,
TagSearchItem,
}
#[derive(Deserialize, Debug, Clone)]
pub struct Service {
/// The LID of the service.
pub id: String,
/// The name of the service.
pub name: String,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Tag {
/// The tag code.
pub code: String,
/// The tag text as entered by the tagger.
pub display_tag: String,
}
#[derive(Deserialize, Debug, Clone)]
struct TagsResponse {
/// The list of tags, ordered by frequency of use.
items: Vec<String>,
}
#[derive(Deserialize, Debug, Clone)]
enum UsernameCheckResult {
Available,
NotAvailable,
TooShort,
TooLong,
Invalid,
}
#[derive(Deserialize, Debug, Clone)]
struct UsernameCheckResponse {
/// Will be Available if the username is available to register, or
/// NotAvailable if used by another member (or attached to a deactivated
/// account, or otherwise reserved). May return an appropriate error value
/// if the username doesn’t meet Letterboxd’s requirements: Usernames must
/// be between 2 and 15 characters long and may only contain upper or
/// lowercase letters, numbers or the underscore (_) character.
result: UsernameCheckResult,
}
#[derive(Serialize, Debug, Clone)]
pub enum WatchlistSort {
Added,
FilmName,
ReleaseDateLatestFirst,
ReleaseDateEarliestFirst,
RatingHighToLow,
RatingLowToHigh,
FilmDurationShortestFirst,
FilmDurationLongestFirst,
FilmPopularity,
FilmPopularityThisWeek,
FilmPopularityThisMonth,
FilmPopularityThisYear,
}
// TODO: order
#[derive(Serialize, Debug, Clone)]
pub enum IncludeFriends {
None,
All,
Only,
}
#[derive(Serialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
struct WatchlistRequest {
/// The pagination cursor.
cursor: Option<Cursor>,
/// The number of items to include per page (default is 20, maximum is 100).
per_page: Option<usize>,
/// The order in which the entries should be returned. Defaults to Added,
/// which is the order that the films were added to the watchlist, most
/// recent first.
sort: WatchlistSort,
/// Specify the LID of a genre to limit films to those within the specified
/// genre.
genre: String,
/// Specify the starting year of a decade (must end in 0) to limit films to
/// those released during the decade. 1990
decade: u16,
/// Specify a year to limit films to those released during that year. 1994
year: u16,
/// Specify the ID of a supported service to limit films to those available
/// from that service. The list of available services can be found by using
/// the /films/film-services endpoint.
service: String,
/// Specify one or more values to limit the list of films accordingly.
/// where=Watched&where=Released
#[serde(rename = "where")]
where_film_status: Vec<FilmStatus>,
/// Specify the LID of a member to limit the returned films according to
/// the value set in memberRelationship. The member and memberRelationship
/// parameters can be used to compute comparisons between the watchlist
/// owner and another member.
member: String,
/// Must be used in conjunction with member. Defaults to Watched. Specify
/// the type of relationship to limit the returned films accordingly.
member_relationship: FilmRelationshipType,
/// Must be used in conjunction with member. Defaults to None, which only
/// returns films from the member’s account. Use Only to return films from
/// the member’s friends, and All to return films from both the member and
/// their friends.
include_friends: IncludeFriends,
/// Specify a tag code to limit the returned films to those tagged
/// accordingly.
tag_code: String,
/// Must be used with tag. Specify the LID of a member to focus the tag
/// filter on the member.
tagger: String,
/// Must be used in conjunction with tagger. Defaults to None, which
/// filters tags set by the member. Use Only to filter tags set by the
/// member’s friends, and All to filter tags set by both the member and
/// their friends.
include_tagger_friends: IncludeFriends,
}