flickr_api/
get_info.rs

1#![allow(dead_code)]
2use crate::*;
3
4#[derive(Deserialize, Debug, Hash)]
5#[serde(untagged)]
6enum FlickrGetInfoAnswer {
7    Ok(FlickrGetInfoSuccess),
8    Err(FlickrError),
9}
10
11impl Resultable<PhotoInfo, Box<dyn Error>> for FlickrGetInfoAnswer {
12    fn to_result(self) -> Result<PhotoInfo, Box<dyn Error>> {
13        match self {
14            FlickrGetInfoAnswer::Ok(info) => Ok(info.photo),
15            FlickrGetInfoAnswer::Err(e) => Err(Box::new(e)),
16        }
17    }
18}
19
20#[derive(Deserialize, Debug, Hash)]
21struct FlickrGetInfoSuccess {
22    stat: String,
23    photo: PhotoInfo,
24}
25
26#[derive(Deserialize, Debug, Hash)]
27pub struct PhotoInfo {
28    pub dateuploaded: String,
29    pub farm: u32,
30    pub id: String,
31    pub isfavorite: u32,
32    pub license: String,
33    pub originalformat: String,
34    pub originalsecret: String,
35    pub rotation: u32,
36    pub safety_level: String,
37    pub secret: String,
38    pub server: String,
39    pub views: String,
40    pub media: String,
41
42    pub owner: Owner,
43    pub dates: Dates,
44
45    #[serde(deserialize_with = "deserialize_content")]
46    pub title: String,
47
48    #[serde(deserialize_with = "deserialize_content")]
49    pub description: String,
50
51    #[serde(deserialize_with = "deserialize_content")]
52    pub comments: String,
53
54    pub permissions: Permissions,
55    pub editability: Editability,
56    pub publiceditability: Editability,
57
58    // Either "" or a whole object
59    pub location: Location,
60
61    pub geoperms: GeoPerms,
62
63    pub notes: NoteWrapper,
64    pub tags: TagWrapper,
65    pub urls: UrlWrapper,
66    pub usage: Usage,
67}
68
69#[derive(Deserialize, Debug, Hash)]
70pub struct Owner {
71    pub nsid: String,
72    pub username: String,
73    pub realname: String,
74    pub location: String,
75    pub iconserver: String,
76    pub iconfarm: u32,
77    pub path_alias: Option<String>,
78}
79
80#[derive(Deserialize, Debug, Hash)]
81pub struct Dates {
82    pub posted: String,
83    pub taken: String,
84    pub takengranularity: u32,
85    pub takenunknown: String,
86    pub lastupdate: String,
87}
88
89#[derive(Deserialize, Debug, Hash)]
90pub struct Permissions {
91    pub permcomment: u32,
92    pub permaddmeta: u32,
93}
94
95#[derive(Deserialize, Debug, Hash)]
96pub struct Editability {
97    pub cancomment: u32,
98    pub canaddmeta: u32,
99}
100
101#[derive(Deserialize, Debug, Hash)]
102pub struct Usage {
103    pub candownload: u32,
104    pub canblog: u32,
105    pub canprint: u32,
106    pub canshare: u32,
107}
108
109#[derive(Deserialize, Debug, Hash)]
110#[serde(untagged)]
111pub enum Location {
112    Full(LocationData),
113    Empty(String),
114}
115
116#[derive(Deserialize, Debug, Hash)]
117pub struct LocationData {
118    pub latitude: String,
119    pub longitude: String,
120    pub accuracy: String,
121    pub context: String,
122    #[serde(deserialize_with = "deserialize_content")]
123    pub locality: String,
124    #[serde(deserialize_with = "deserialize_content")]
125    pub county: String,
126    #[serde(deserialize_with = "deserialize_content")]
127    pub region: String,
128    #[serde(deserialize_with = "deserialize_content")]
129    pub country: String,
130    #[serde(deserialize_with = "deserialize_content")]
131    pub neighbourhood: String,
132}
133
134#[derive(Deserialize, Debug, Hash)]
135pub struct GeoPerms {
136    pub ispublic: u32,
137    pub iscontact: u32,
138    pub isfriend: u32,
139    pub isfamily: u32,
140}
141
142#[derive(Deserialize, Debug, Hash)]
143pub struct NoteWrapper {
144    pub note: Vec<Note>,
145}
146
147#[derive(Deserialize, Debug, Hash)]
148pub struct Note {
149    pub id: String,
150    pub photo_id: String,
151    pub author: String,
152    pub authorname: String,
153    pub authorrealname: String,
154    pub authorispro: u32,
155    pub authorisdeleted: u32,
156    pub x: String,
157    pub y: String,
158    pub w: String,
159    pub h: String,
160    pub _content: String,
161}
162
163#[derive(Deserialize, Debug, Hash)]
164pub struct TagWrapper {
165    pub tag: Vec<Tag>,
166}
167
168#[derive(Deserialize, Debug, Hash)]
169pub struct Tag {
170    pub id: String,
171    pub author: String,
172    pub authorname: String,
173    pub raw: String,
174    pub _content: String,
175    pub machine_tag: u32,
176}
177
178#[derive(Deserialize, Debug, Hash)]
179pub struct UrlWrapper {
180    pub url: Vec<Url>,
181}
182
183#[derive(Deserialize, Debug, Hash)]
184pub struct Url {
185    #[serde(rename = "type")]
186    pub urltype: String,
187    pub _content: String,
188}
189
190impl PhotoRequestBuilder {
191    /// [flickr.photos.getInfo](https://www.flickr.com/services/api/flickr.photos.getInfo.html)
192    /// endpoint. Returns information associated with the photo of the given ID.
193    ///
194    /// `secret` allows bypassing the permission checks if given. Does not require authentication but
195    /// will authenticate the user if given the token.
196    pub async fn get_info(
197        &self,
198        id: &String,
199        secret: Option<&String>,
200    ) -> Result<PhotoInfo, Box<dyn Error>> {
201        let mut params = vec![
202            ("method", "flickr.photos.getInfo".into()),
203            ("photo_id", id.clone()),
204            ("nojsoncallback", "1".into()),
205            ("format", "json".into()),
206            ("api_key", self.handle.key.key.clone()),
207        ];
208        if let Some(value) = secret {
209            params.push(("secret", value.clone()));
210        }
211        oauth::build_request(
212            oauth::RequestTarget::Get(URL_API),
213            &mut params,
214            &self.handle.key,
215            self.handle.token.as_ref(),
216        );
217
218        let url = reqwest::Url::parse_with_params(URL_API, &params)?;
219        let fetch = self.handle.client.get(url).send().await?;
220        let raw = fetch.text().await?;
221        #[cfg(debug_assertions)]
222        log::debug!("Received {raw}");
223        let answer: FlickrGetInfoAnswer = serde_json::from_str(&raw)?;
224
225        answer.to_result()
226    }
227}