add patrons page

This commit is contained in:
Cadey Ratio 2020-07-16 10:14:10 -04:00
parent db34860258
commit 8ec00f26ab
10 changed files with 97 additions and 136 deletions

View File

@ -35,3 +35,7 @@ jobs:
run: ./scripts/release.sh
env:
DIGITALOCEAN_ACCESS_TOKEN: ${{ secrets.DIGITALOCEAN_TOKEN }}
PATREON_ACCESS_TOKEN: ${{ secrets.PATREON_ACCESS_TOKEN }}
PATREON_REFRESH_TOKEN: ${{ secrets.PATREON_REFRESH_TOKEN }}
PATREON_CLIENT_ID: ${{ secrets.PATREON_CLIENT_ID }}
PATREON_CLIENT_SECRET: ${{ secrets.PATREON_CLIENT_SECRET }}

138
Cargo.lock generated
View File

@ -42,15 +42,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
[[package]]
name = "aho-corasick"
version = "0.6.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5"
dependencies = [
"memchr",
]
[[package]]
name = "aho-corasick"
version = "0.7.13"
@ -297,7 +288,7 @@ dependencies = [
"lazy_static",
"pest",
"pest_derive",
"regex 1.3.9",
"regex",
"twoway 0.2.1",
"typed-arena",
"unicode_categories",
@ -401,7 +392,7 @@ dependencies = [
"itertools",
"lazy_static",
"once_cell",
"percent-encoding 2.1.0",
"percent-encoding",
"pest",
"pest_consume",
"pest_generator",
@ -411,7 +402,7 @@ dependencies = [
"serde_cbor",
"sha2",
"smallvec",
"url 2.1.1",
"url",
"walkdir",
]
@ -487,7 +478,7 @@ dependencies = [
"atty",
"humantime",
"log 0.4.8",
"regex 1.3.9",
"regex",
"termcolor",
]
@ -839,17 +830,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
dependencies = [
"matches",
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "idna"
version = "0.2.0"
@ -912,20 +892,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "jsonapi"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "814fe35a3361c079fbed80fee6901a041c077c9ffe1a7cb13a31de064e1e97b5"
dependencies = [
"error-chain",
"log 0.4.8",
"queryst",
"serde",
"serde_derive",
"serde_json",
]
[[package]]
name = "jsonfeed"
version = "0.3.0"
@ -1270,7 +1236,6 @@ version = "0.1.0"
dependencies = [
"chrono",
"envy",
"jsonapi",
"log 0.3.9",
"pretty_env_logger",
"reqwest",
@ -1280,12 +1245,6 @@ dependencies = [
"tokio",
]
[[package]]
name = "percent-encoding"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
[[package]]
name = "percent-encoding"
version = "2.1.0"
@ -1511,19 +1470,6 @@ dependencies = [
"thiserror",
]
[[package]]
name = "queryst"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee648fdfde06a88a03a225276e2d52c9243439fba1af36362ad6bbe5ea4658b0"
dependencies = [
"lazy_static",
"regex 0.2.11",
"serde",
"serde_json",
"url 1.7.2",
]
[[package]]
name = "quick-error"
version = "1.2.3"
@ -1721,38 +1667,16 @@ version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "regex"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384"
dependencies = [
"aho-corasick 0.6.10",
"memchr",
"regex-syntax 0.5.6",
"thread_local 0.3.6",
"utf8-ranges",
]
[[package]]
name = "regex"
version = "1.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
dependencies = [
"aho-corasick 0.7.13",
"aho-corasick",
"memchr",
"regex-syntax 0.6.18",
"thread_local 1.0.1",
]
[[package]]
name = "regex-syntax"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
dependencies = [
"ucd-util",
"regex-syntax",
"thread_local",
]
[[package]]
@ -1791,14 +1715,14 @@ dependencies = [
"mime 0.3.16",
"mime_guess 2.0.3",
"native-tls",
"percent-encoding 2.1.0",
"percent-encoding",
"pin-project-lite",
"serde",
"serde_json",
"serde_urlencoded",
"tokio",
"tokio-tls",
"url 2.1.1",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
@ -1942,7 +1866,7 @@ dependencies = [
"dhall_proc_macros",
"doc-comment",
"serde",
"url 2.1.1",
"url",
]
[[package]]
@ -1965,7 +1889,7 @@ dependencies = [
"dtoa",
"itoa",
"serde",
"url 2.1.1",
"url",
]
[[package]]
@ -2018,7 +1942,7 @@ checksum = "5c95c7e58b4461fec85bdd58f271bcd416ecc4d630c3ac280b60efa3421016b7"
dependencies = [
"chrono",
"chrono_utils",
"url 2.1.1",
"url",
"xml-rs",
]
@ -2133,15 +2057,6 @@ dependencies = [
"syn",
]
[[package]]
name = "thread_local"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
dependencies = [
"lazy_static",
]
[[package]]
name = "thread_local"
version = "1.0.1"
@ -2281,7 +2196,7 @@ dependencies = [
"log 0.4.8",
"rand 0.7.3",
"sha-1",
"url 2.1.1",
"url",
"utf-8",
]
@ -2322,12 +2237,6 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
[[package]]
name = "ucd-util"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c85f514e095d348c279b1e5cd76795082cf15bd59b93207832abe0b1d8fed236"
[[package]]
name = "unchecked-index"
version = "0.2.2"
@ -2388,26 +2297,15 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
[[package]]
name = "url"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
dependencies = [
"idna 0.1.5",
"matches",
"percent-encoding 1.0.1",
]
[[package]]
name = "url"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
dependencies = [
"idna 0.2.0",
"idna",
"matches",
"percent-encoding 2.1.0",
"percent-encoding",
]
[[package]]
@ -2422,12 +2320,6 @@ version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7"
[[package]]
name = "utf8-ranges"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba"
[[package]]
name = "vcpkg"
version = "0.2.10"

View File

@ -8,7 +8,6 @@ edition = "2018"
[dependencies]
chrono = { version = "0.4", features = ["serde"] }
jsonapi = "0.6.6"
reqwest = { version = "0.10", features = ["json"] }
serde_json = "1.0"
serde = { version = "1", features = ["derive"] }

View File

@ -1,6 +1,4 @@
#[macro_use]
extern crate jsonapi;
#[macro_use]
extern crate log;
use serde::{Deserialize, Serialize};
@ -9,6 +7,7 @@ use chrono::prelude::*;
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 {

View File

@ -1,5 +1,6 @@
#!/usr/bin/env nix-shell
#! nix-shell -p doctl -p kubectl -i bash
nix-env -if ./nix/dhall-yaml.nix
doctl kubernetes cluster kubeconfig save kubermemes
dhall-to-yaml-ng < ./site.dhall | kubectl apply -n apps -f -
kubectl rollout status -n apps deployment/christinewebsite

View File

@ -8,11 +8,27 @@ let tag = env:GITHUB_SHA as Text ? "latest"
let image = "xena/christinewebsite:${tag}"
let prefix = env:SITE_PREFIX as Text ? ""
let vars
: List kubernetes.EnvVar.Type
= [ kubernetes.EnvVar::{ name = "PORT", value = Some "3030" } ]
= [ kubernetes.EnvVar::{ name = "PORT", value = Some "3030" }
, kubernetes.EnvVar::{ name = "RUST_LOG", value = Some "info" }
, kubernetes.EnvVar::{
, name = "PATREON_CLIENT_ID"
, value = Some env:PATREON_CLIENT_ID as Text
}
, kubernetes.EnvVar::{
, name = "PATREON_CLIENT_SECRET"
, value = Some env:PATREON_CLIENT_SECRET as Text
}
, kubernetes.EnvVar::{
, name = "PATREON_ACCESS_TOKEN"
, value = Some env:PATREON_ACCESS_TOKEN as Text
}
, kubernetes.EnvVar::{
, name = "PATREON_REFRESH_TOKEN"
, value = Some env:PATREON_REFRESH_TOKEN as Text
}
]
in kms.app.make
kms.app.Config::{

View File

@ -30,6 +30,23 @@ pub fn markdown(inp: &str) -> String {
markdown_to_html(inp, &options)
}
async fn patrons() -> Result<Option<patreon::Users>> {
use patreon::*;
let creds: Credentials = envy::prefixed("PATREON_").from_env().unwrap();
let cli = Client::new(creds);
if let Ok(camp) = cli.campaign().await {
let id = camp.data[0].id.clone();
if let Ok(users) = cli.pledges(id).await {
Ok(Some(users))
} else {
Ok(None)
}
} else {
Ok(None)
}
}
pub const ICON: &'static str = "https://christine.website/static/img/avatar.png";
pub struct State {
@ -44,9 +61,10 @@ pub struct State {
pub rf: rss::Channel,
pub af: atom::Feed,
pub sitemap: Vec<u8>,
pub patrons: Option<patreon::Users>,
}
pub fn init(cfg: PathBuf) -> Result<State> {
pub async fn init(cfg: PathBuf) -> Result<State> {
let cfg: Config = serde_dhall::from_file(cfg).parse()?;
let sb = cfg.signalboost.clone();
let resume = fs::read_to_string(cfg.resume_fname.clone())?;
@ -151,15 +169,16 @@ pub fn init(cfg: PathBuf) -> Result<State> {
af: af,
rf: rf,
sitemap: sm,
patrons: patrons().await?,
})
}
#[cfg(test)]
mod tests {
use anyhow::Result;
#[test]
fn init() -> Result<()> {
super::init("./config.dhall".into())?;
#[tokio::test]
async fn init() -> Result<()> {
super::init("./config.dhall".into()).await?;
Ok(())
}
}

View File

@ -37,6 +37,15 @@ pub async fn resume(state: Arc<State>) -> Result<impl Reply, Rejection> {
Response::builder().html(|o| templates::resume_html(o, Html(state.resume.clone())))
}
pub async fn patrons(state: Arc<State>) -> Result<impl Reply, Rejection> {
HIT_COUNTER.with_label_values(&["patrons"]).inc();
let state = state.clone();
match &state.patrons {
None => Response::builder().html(|o| templates::error_html(o, "Could not load patrons, let me know the API token expired again".to_string())),
Some(patrons) => Response::builder().html(|o| templates::patrons_html(o, patrons.clone()))
}
}
pub async fn signalboost(state: Arc<State>) -> Result<impl Reply, Rejection> {
HIT_COUNTER.with_label_values(&["signalboost"]).inc();
let state = state.clone();

View File

@ -30,7 +30,7 @@ async fn main() -> Result<()> {
.unwrap_or("./config.dhall".into())
.as_str()
.into(),
)?);
).await?);
let healthcheck = warp::get().and(warp::path(".within").and(warp::path("health")).map(|| "OK"));
@ -79,7 +79,6 @@ async fn main() -> Result<()> {
);
let index = warp::get().and(path::end().and_then(handlers::index));
let contact = warp::path!("contact").and_then(handlers::contact);
let feeds = warp::path!("feeds").and_then(handlers::feeds);
let resume = warp::path!("resume")
@ -88,6 +87,9 @@ async fn main() -> Result<()> {
let signalboost = warp::path!("signalboost")
.and(with_state(state.clone()))
.and_then(handlers::signalboost);
let patrons = warp::path!("patrons")
.and(with_state(state.clone()))
.and_then(handlers::patrons);
let files = warp::path("static").and(warp::fs::dir("./static"));
let css = warp::path("css").and(warp::fs::dir("./css"));
@ -126,7 +128,7 @@ async fn main() -> Result<()> {
});
let site = index
.or(contact.or(feeds).or(resume.or(signalboost)))
.or(contact.or(feeds).or(resume.or(signalboost)).or(patrons))
.or(blog_index.or(series.or(series_view).or(post_view)))
.or(gallery_index.or(gallery_post_view))
.or(talk_index.or(talk_post_view))

20
templates/patrons.rs.html Normal file
View File

@ -0,0 +1,20 @@
@use patreon::Users;
@use super::{header_html, footer_html};
@(users: Users)
@:header_html(Some("Patrons"), None)
<h1>Patrons</h1>
<p>These awesome people donate to me on <a href="https://patreon.com/cadey">Patreon</a>. If you would like to show up in this list, please donate to me on Patreon. This is refreshed every time the site is deployed.</p>
<p>
<ul>
@for user in users {
<li>@user.attributes.full_name</li>
}
</ul>
</p>
@:footer_html()