aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortilpner2020-05-28 19:34:05 +0200
committertilpner2020-05-28 19:34:05 +0200
commit6f0beed9c2219268807b9a7302ec374431624043 (patch)
tree8822151aa7ad77e42e71de6c514a03e1caa1af92
parentda07a2ca3a8c5ee97eac179b28dc3d4a064fd026 (diff)
downloadgithub-label-feed-6f0beed9c2219268807b9a7302ec374431624043.tar.gz
github-label-feed-6f0beed9c2219268807b9a7302ec374431624043.tar.xz
github-label-feed-6f0beed9c2219268807b9a7302ec374431624043.zip
atom: add state, other labels, update time, author
-rw-r--r--Cargo.lock22
-rw-r--r--Cargo.toml3
-rw-r--r--src/atom.rs61
-rw-r--r--src/query/issues.rs8
4 files changed, 82 insertions, 12 deletions
diff --git a/Cargo.lock b/Cargo.lock
index a7914b7..57b53a9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -521,7 +521,9 @@ dependencies = [
"futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-retry 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"graphql_client 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rss 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.110 (registry+https://github.com/rust-lang/crates.io-index)",
"smol 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"sqlx 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1048,6 +1050,15 @@ dependencies = [
[[package]]
name = "quick-xml"
+version = "0.17.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "encoding_rs 0.8.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "quick-xml"
version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
@@ -1174,6 +1185,15 @@ dependencies = [
]
[[package]]
+name = "rss"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "derive_builder 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quick-xml 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "rustc-demangle"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1951,6 +1971,7 @@ dependencies = [
"checksum proc-macro-hack 0.5.16 (registry+https://github.com/rust-lang/crates.io-index)" = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
"checksum proc-macro-nested 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694"
"checksum proc-macro2 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "1502d12e458c49a4c9cbff560d0fe0060c252bc29799ed94ca2ed4bb665a0101"
+"checksum quick-xml 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fe1e430bdcf30c9fdc25053b9c459bb1a4672af4617b6c783d7d91dc17c6bbb0"
"checksum quick-xml 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3cc440ee4802a86e357165021e3e255a9143724da31db1e2ea540214c96a0f82"
"checksum quote 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea"
"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
@@ -1963,6 +1984,7 @@ dependencies = [
"checksum regex-syntax 0.6.17 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5bd57d1d7414c6b5ed48563a2c855d995ff777729dcd91c369ec7fea395ae"
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
"checksum reqwest 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b81e49ddec5109a9dcfc5f2a317ff53377c915e9ae9d4f2fb50914b85614e2"
+"checksum rss 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "99979205510c60f80a119dedbabd0b8426517384edf205322f8bcd51796bcef9"
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
"checksum ryu 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1"
"checksum schannel 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
diff --git a/Cargo.toml b/Cargo.toml
index 3a3f747..592719d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,7 +18,10 @@ sqlx = { version = "0.3", default-features = false, features = [ "runtime-tokio"
anyhow = "1.0"
+# sqlx pretty-prints all queries with sqlformat to log, which is very expensive
+log = { version = "0.4", features = [ "max_level_off", "release_max_level_off" ] }
tracing = "0.1"
tracing-subscriber = "0.2.4"
atom_syndication = "0.9"
+rss = "1.9"
diff --git a/src/atom.rs b/src/atom.rs
index f431f42..e87901d 100644
--- a/src/atom.rs
+++ b/src/atom.rs
@@ -5,12 +5,13 @@ use std::{
use sqlx::prelude::*;
use atom_syndication::*;
-use anyhow::Result;
+use anyhow::{ Result, Context };
use futures::{ Stream, StreamExt };
+use chrono::{ Utc, TimeZone };
use tracing::info;
-use crate::{ Conn, query::repo_id };
+use crate::{ Conn, query::{ self, repo_id } };
#[allow(dead_code)]
#[derive(sqlx::FromRow)]
@@ -34,10 +35,40 @@ async fn query_issues_for_label<'conn>(conn: &'conn mut Conn, repo_id: i64, labe
.fetch(conn)
}
-fn issue_to_entry(issue: Issue) -> Entry {
- EntryBuilder::default()
+async fn issue_to_entry(conn: &mut Conn, repo_id: i64, issue: Issue) -> Result<Entry> {
+ let state_label = query::issues::integer_to_state_desc(issue.state);
+ let labels_of_issue = sqlx::query_as::<_, (String,)>(
+ "SELECT labels.name FROM is_labeled
+ JOIN labels ON is_labeled.label=labels.id
+ JOIN issues ON (is_labeled.issue=issues.number AND is_labeled.repo=issues.repo)
+ WHERE is_labeled.repo=? AND is_labeled.issue=?"
+ ).bind(repo_id).bind(issue.number)
+ .fetch(&mut *conn);
+
+ let all_labels = futures::stream::iter(state_label)
+ .chain(labels_of_issue
+ .filter_map(|row| async { row.ok() })
+ .map(|(name,)| name))
+ .map(|name| Category {
+ term: name,
+ scheme: None,
+ label: None
+ })
+ .collect::<Vec<_>>()
+ .await;
+
+ Ok(EntryBuilder::default()
.title(issue.title)
.id(issue.html_url.clone())
+ .updated(Utc.timestamp(issue.updated_at, 0))
+ .authors(vec![
+ Person {
+ uri: Some(format!("https://github.com/{}", issue.user_login)),
+ name: issue.user_login,
+ email: None
+ }
+ ])
+ .categories(all_labels)
.links(vec![LinkBuilder::default()
.href(issue.html_url)
.build()
@@ -48,7 +79,8 @@ fn issue_to_entry(issue: Issue) -> Entry {
.build()
.expect("Failed to build content"))
.build()
- .expect("Failed to build entry")
+ .map_err(|err_str| anyhow::anyhow!(err_str))
+ .context("Failed to build atom entry")?)
}
pub async fn generate(mut conn: &mut Conn, (ref owner, ref name): (String, String), out_path: PathBuf, labels: Vec<String>) -> Result<()> {
@@ -73,13 +105,18 @@ pub async fn generate(mut conn: &mut Conn, (ref owner, ref name): (String, Strin
let mut feed = FeedBuilder::default();
feed.title(label.clone());
- let issues = query_issues_for_label(&mut conn, repo_id, &label).await;
- feed.entries(
- issues.filter_map(|issue| async { issue.ok() })
- .map(issue_to_entry)
- .collect::<Vec<_>>()
- .await
- );
+ let issues: Vec<Issue> = query_issues_for_label(&mut conn, repo_id, &label).await
+ .filter_map(|res| async { res.ok() })
+ .collect().await;
+
+ let entries: Vec<Entry> = {
+ let mut acc = Vec::new();
+ for issue in issues.into_iter() {
+ acc.push(issue_to_entry(&mut conn, repo_id, issue).await?);
+ }
+ acc
+ };
+ feed.entries(entries);
let feed = feed.build().expect("Failed to build feed");
diff --git a/src/query/issues.rs b/src/query/issues.rs
index c829a22..b9473d3 100644
--- a/src/query/issues.rs
+++ b/src/query/issues.rs
@@ -30,6 +30,14 @@ fn state_to_integer(state: issues_query::IssueState) -> i64 {
}
}
+pub fn integer_to_state_desc(state: i64) -> Option<String> {
+ match state {
+ 0 => Some("open"),
+ 1 => Some("closed"),
+ _ => None
+ }.map(str::to_owned)
+}
+
pub async fn update(mut conn: &mut Conn, github_api_token: &str, (ref owner, ref name): (String, String)) -> anyhow::Result<()> {
let repo = repo_id(conn, owner, name).await?;