diff options
| author | Xe Iaso <me@christine.website> | 2023-09-30 10:36:37 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-30 10:36:37 -0400 |
| commit | ac6a3df0d18cc73524c0096d954a57d24cad5669 (patch) | |
| tree | 81474177d730440657f490ae29892d62392251ea /lib/patreon/src | |
| parent | cbdea8ba3fca9a663778af71f8df5965aeb6c090 (diff) | |
| download | xesite-ac6a3df0d18cc73524c0096d954a57d24cad5669.tar.xz xesite-ac6a3df0d18cc73524c0096d954a57d24cad5669.zip | |
Xesite V4 (#723)
* scripts/ditherify: fix quoting
Signed-off-by: Xe Iaso <me@xeiaso.net>
* clean up some old files
Signed-off-by: Xe Iaso <me@xeiaso.net>
* import site into lume
Signed-off-by: Xe Iaso <me@xeiaso.net>
* initial go code
Signed-off-by: Xe Iaso <me@xeiaso.net>
* move vods index to top level
Signed-off-by: Xe Iaso <me@xeiaso.net>
* remove the ads
Signed-off-by: Xe Iaso <me@xeiaso.net>
* internal/lume: metrics
Signed-off-by: Xe Iaso <me@xeiaso.net>
* delete old code
Signed-off-by: Xe Iaso <me@xeiaso.net>
* load config into memory
Signed-off-by: Xe Iaso <me@xeiaso.net>
* autogenerate data from dhall config
Signed-off-by: Xe Iaso <me@xeiaso.net>
* various cleanups, import clackset logic
Signed-off-by: Xe Iaso <me@xeiaso.net>
* Update signalboost.dhall (#722)
Added myself, and also fixed someone’s typo
* Add Connor Edwards to signal boost (#721)
* add cache headers
Signed-off-by: Xe Iaso <me@xeiaso.net>
* move command to xesite folder
Signed-off-by: Xe Iaso <me@xeiaso.net>
* xesite: listen for GitHub webhook push events
Signed-off-by: Xe Iaso <me@xeiaso.net>
* xesite: 5 minute timeout for rebuilding the site
Signed-off-by: Xe Iaso <me@xeiaso.net>
* xesite: add rebuild metrics
Signed-off-by: Xe Iaso <me@xeiaso.net>
* xesite: update default variables
Signed-off-by: Xe Iaso <me@xeiaso.net>
* don't commit binaries oops lol
Signed-off-by: Xe Iaso <me@xeiaso.net>
* lume: make search have a light background
Signed-off-by: Xe Iaso <me@xeiaso.net>
* add a notfound page
Signed-off-by: Xe Iaso <me@xeiaso.net>
* fetch info from patreon API
Signed-off-by: Xe Iaso <me@xeiaso.net>
* create contact page
Signed-off-by: Xe Iaso <me@xeiaso.net>
* Toot embedding
Signed-off-by: Xe Iaso <me@xeiaso.net>
* attempt a docker image
Signed-off-by: Xe Iaso <me@xeiaso.net>
* lume: fix deno lock
Signed-off-by: Xe Iaso <me@xeiaso.net>
* add gokrazy post
Signed-off-by: Xe Iaso <me@xeiaso.net>
* cmd/xesite: go up before trying to connect to the saas proxy
Signed-off-by: Xe Iaso <me@xeiaso.net>
* blog: add Sine post/demo
Signed-off-by: Xe Iaso <me@xeiaso.net>
---------
Signed-off-by: Xe Iaso <me@xeiaso.net>
Co-authored-by: bri <284789+b-@users.noreply.github.com>
Co-authored-by: Connor Edwards <38229097+cedws@users.noreply.github.com>
Diffstat (limited to 'lib/patreon/src')
| -rw-r--r-- | lib/patreon/src/lib.rs | 238 |
1 files changed, 0 insertions, 238 deletions
diff --git a/lib/patreon/src/lib.rs b/lib/patreon/src/lib.rs deleted file mode 100644 index e611f43..0000000 --- a/lib/patreon/src/lib.rs +++ /dev/null @@ -1,238 +0,0 @@ -use std::{fs, io}; - -use chrono::prelude::*; -use serde::{Deserialize, Serialize}; -use thiserror::Error; -use tracing::{debug, error, instrument}; -use url::Url; - -pub type Campaigns = Vec<Object<Campaign>>; -pub type Pledges = Vec<Object<Pledge>>; -pub type Users = Vec<Object<User>>; - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct Campaign { - pub summary: String, - pub creation_name: String, - pub display_patron_goals: bool, - pub pay_per_name: String, - pub one_liner: Option<String>, - pub main_video_embed: Option<String>, - pub main_video_url: Option<String>, - pub image_small_url: String, - pub image_url: String, - pub thanks_video_url: Option<String>, - pub thanks_embed: Option<String>, - pub thanks_msg: String, - pub is_charged_immediately: bool, - pub is_monthly: bool, - pub is_nsfw: bool, - pub is_plural: bool, - pub created_at: DateTime<Utc>, - pub published_at: DateTime<Utc>, - pub pledge_url: String, - pub pledge_sum: i32, - pub patron_count: u32, - pub creation_count: u32, - pub outstanding_payment_amount_cents: u64, -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct Pledge { - pub amount_cents: u32, - pub created_at: String, - pub declined_since: Option<String>, - pub pledge_cap_cents: u32, - pub patron_pays_fees: bool, - pub total_historical_amount_cents: Option<u32>, - pub is_paused: Option<bool>, - pub has_shipping_address: Option<bool>, - pub outstanding_payment_amount_cents: Option<u32>, -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct User { - pub first_name: String, - pub last_name: String, - pub full_name: String, - pub vanity: Option<String>, - pub about: Option<String>, - pub gender: i32, - pub image_url: String, - pub thumb_url: String, - pub created: DateTime<Utc>, - pub url: String, -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct RefreshGrant { - pub access_token: String, - pub refresh_token: String, - pub expires_in: serde_json::Value, - pub scope: serde_json::Value, - pub token_type: String, -} - -pub type Result<T> = std::result::Result<T, Error>; - -#[derive(Error, Debug)] -pub enum Error { - #[error("json error: {0}")] - Json(#[from] serde_json::Error), - - #[error("request error: {0}")] - Request(#[from] reqwest::Error), - - #[error("{0}")] - IO(#[from] io::Error), - - #[error("url parse error: {0}")] - URLParse(#[from] url::ParseError), -} - -#[derive(Debug, Serialize, Deserialize, Clone, Default, Eq, PartialEq)] -pub struct Credentials { - pub client_id: String, - pub client_secret: String, - pub access_token: String, - pub refresh_token: String, -} - -pub struct Client { - cli: reqwest::Client, - base_url: String, - creds: Credentials, -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct Data<T, U> { - pub data: T, - pub included: Option<Vec<U>>, -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct Object<T> { - pub id: String, - pub attributes: T, - pub r#type: String, - pub links: Option<Links>, -} - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct Links { - related: String, -} - -impl Client { - pub fn new() -> Result<Self> { - let mut p = dirs::home_dir().unwrap_or(".".into()); - p.push(".patreon.json"); - let config = fs::read_to_string(p)?; - let creds = serde_json::from_str(&config)?; - - Ok(Self { - cli: reqwest::Client::new(), - base_url: "https://api.patreon.com".into(), - creds, - }) - } - - #[instrument(skip(self))] - pub async fn campaign(&self) -> Result<Data<Vec<Object<Campaign>>, ()>> { - let data = self - .cli - .get(&format!( - "{}/oauth2/api/current_user/campaigns", - self.base_url - )) - .query(&[("include", "patron.null"), ("includes", "")]) - .header( - "Authorization", - format!("Bearer {}", self.creds.access_token), - ) - .send() - .await? - .error_for_status()? - .text() - .await?; - debug!("campaign response: {}", data); - Ok(serde_json::from_str(&data)?) - } - - #[instrument(skip(self))] - pub async fn pledges(&self, camp_id: String) -> Result<Vec<Object<User>>> { - let data = self - .cli - .get(&format!( - "{}/oauth2/api/campaigns/{}/pledges", - self.base_url, camp_id - )) - .query(&[("include", "patron.null"), ("page[count]", "100")]) - .header( - "Authorization", - format!("Bearer {}", self.creds.access_token), - ) - .send() - .await? - .error_for_status()? - .text() - .await?; - debug!("pledges for {}: {}", camp_id, data); - let data: Data<Vec<Object<Pledge>>, Object<User>> = serde_json::from_str(&data)?; - Ok(data.included.unwrap()) - } - - /* - POST www.patreon.com/api/oauth2/token - ?grant_type=refresh_token - &refresh_token=<the user‘s refresh_token> - &client_id=<your client id> - &client_secret=<your client secret> - - 1. grab new creds - 2. serialize new creds to disk - 3. reload current creds in ram - 4. ??? - 5. profit! - */ - #[instrument(skip(self))] - pub async fn refresh_token(&mut self) -> Result<()> { - let mut u = Url::parse(&self.base_url)?; - u.set_path("/api/oauth2/token"); - u.query_pairs_mut() - .append_pair("grant_type", "refresh_token") - .append_pair("refresh_token", &self.creds.refresh_token) - .append_pair("client_id", &self.creds.client_id) - .append_pair("client_secret", &self.creds.client_secret); - - let rg: RefreshGrant = self - .cli - .post(&u.to_string()) - .header( - "Authorization", - format!("Bearer {}", self.creds.access_token), - ) - .send() - .await? - .error_for_status()? - .json() - .await?; - - let mut creds = self.creds.clone(); - - creds.access_token = rg.access_token; - creds.refresh_token = rg.refresh_token; - - let mut p = dirs::home_dir().unwrap_or(".".into()); - p.push(".patreon.json"); - if p.exists() { - fs::remove_file(&p)?; - } - let mut fout = fs::File::create(p)?; - serde_json::to_writer(&mut fout, &creds)?; - - self.creds = creds; - - Ok(()) - } -} |
