aboutsummaryrefslogtreecommitdiff
path: root/src/orly.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/orly.rs')
-rw-r--r--src/orly.rs29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/orly.rs b/src/orly.rs
index cd8b645..0e34e5c 100644
--- a/src/orly.rs
+++ b/src/orly.rs
@@ -1,8 +1,16 @@
use crate::http_client::HttpClient;
use anyhow::{bail, Result};
+use serde::Deserialize;
pub const PROFILE_URL: &str = "https://learning.oreilly.com/profile/";
+/// Minimal subset of the book that we care about.
+#[derive(Debug, Deserialize)]
+pub struct BookInfo {
+ pub title: String,
+ pub web_url: String,
+}
+
/// Check whether cookies keep us logged in by fetching the profile page.
/// Returns:
/// - Ok(true) => HTTP 200 (assume logged in)
@@ -20,3 +28,24 @@ pub async fn check_login(client: &HttpClient) -> Result<bool> {
bail!("Profile request returned unexpected status {}", status)
}
}
+
+/// Build the v1 API URL for the book.
+pub fn book_api_url(bookid: &str) -> String {
+ format!("https://learning.oreilly.com/api/v1/book/{bookid}")
+}
+
+/// Fetch book metadata from the website.
+pub async fn fetch_book_info(client: &HttpClient, bookid: &str) -> Result<BookInfo> {
+ let url = book_api_url(bookid);
+ let res = client.client().get(url).send().await?;
+ let status = res.status();
+
+ if status == 200 {
+ let info = res.json::<BookInfo>().await?;
+ return Ok(info);
+ }
+ if status == 404 {
+ bail!("Book not found (HTTP 404). Please double-check the book ID provided")
+ }
+ bail!("Got status: {}", status)
+}