From 23e93564ca7de185aacab4c494312d8b732922dd Mon Sep 17 00:00:00 2001 From: tilpner Date: Fri, 29 May 2020 11:36:29 +0200 Subject: atom: add option to only include open issues --- src/atom.rs | 14 ++++++++++---- src/main.rs | 8 +++++--- src/query/issues.rs | 39 +++++++++++++++++++++++++-------------- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/atom.rs b/src/atom.rs index f7e96ec..2894ccb 100644 --- a/src/atom.rs +++ b/src/atom.rs @@ -44,18 +44,22 @@ fn entity_escape(from: &str) -> String { escaped } -async fn query_issues_for_label<'conn>(conn: &'conn mut Conn, repo_id: i64, label: &str) -> impl Stream> + 'conn { +async fn query_issues_for_label<'conn>(conn: &'conn mut Conn, + repo_id: i64, label: &str, only_open: bool) -> impl Stream> + 'conn { sqlx::query_as::<_, Issue>(r#" SELECT issues.number, state, title, body, user_login, html_url, updated_at FROM issues INNER JOIN is_labeled ON is_labeled.issue=issues.number WHERE is_labeled.label=(SELECT id FROM labels WHERE repo=? AND name=?) + AND (?=0 OR issues.state=?) ORDER BY issues.number DESC "#).bind(repo_id).bind(label) + .bind(only_open).bind(query::issues::IssueState::OPEN.to_integer()) .fetch(conn) } async fn issue_to_entry(conn: &mut Conn, repo_id: i64, issue: Issue) -> Result { - let state_label = query::issues::integer_to_state_desc(issue.state); + let state_label = query::issues::IssueState::from_integer(issue.state) + .expect("Inconsistent database, invalid issue state").to_string(); let labels_of_issue = sqlx::query_as::<_, (String,)>( "SELECT labels.name FROM is_labeled JOIN labels ON is_labeled.label=labels.id @@ -102,7 +106,9 @@ async fn issue_to_entry(conn: &mut Conn, repo_id: i64, issue: Issue) -> Result) -> Result<()> { +pub async fn generate(mut conn: &mut Conn, (ref owner, ref name): (String, String), + out_path: PathBuf, labels: Vec, + only_open: bool) -> Result<()> { let labels = if labels.is_empty() { sqlx::query_as::<_, (String,)>( "SELECT name FROM labels WHERE repo=(SELECT id FROM repositories WHERE owner=? AND name=?)" @@ -142,7 +148,7 @@ pub async fn generate(mut conn: &mut Conn, (ref owner, ref name): (String, Strin .map_err(anyhow::Error::msg)? ]); - let issues: Vec = query_issues_for_label(&mut conn, repo_id, &label).await + let issues: Vec = query_issues_for_label(&mut conn, repo_id, &label, only_open).await .filter_map(|res| async { res.ok() }) .collect().await; diff --git a/src/main.rs b/src/main.rs index 196e587..e544da1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,7 +31,9 @@ enum OptMode { Atom { repo: String, out_path: PathBuf, - labels: Vec + labels: Vec, + #[structopt(long)] + only_open: bool } } @@ -127,9 +129,9 @@ fn main() -> Result<()> { tx.commit().await?; Ok(()) }, - OptMode::Atom { repo, out_path, labels } => { + OptMode::Atom { repo, out_path, labels, only_open } => { let repo = parse_repo(&repo)?; - atom::generate(&mut *pool.acquire().await?, repo, out_path, labels).await + atom::generate(&mut *pool.acquire().await?, repo, out_path, labels, only_open).await .context("Failed to generate Atom feed")?; Ok(()) } diff --git a/src/query/issues.rs b/src/query/issues.rs index b9473d3..525ebe5 100644 --- a/src/query/issues.rs +++ b/src/query/issues.rs @@ -21,23 +21,34 @@ type DateTime = String; )] pub struct IssuesQuery; -fn state_to_integer(state: issues_query::IssueState) -> i64 { - use issues_query::IssueState::*; - match state { - OPEN => 0, - CLOSED => 1, - Other(_) => 2 +pub use issues_query::IssueState; +impl IssueState { + pub fn from_integer(i: i64) -> Option { + match i { + 0 => Some(Self::OPEN), + 1 => Some(Self::CLOSED), + _ => None + } } -} -pub fn integer_to_state_desc(state: i64) -> Option { - match state { - 0 => Some("open"), - 1 => Some("closed"), - _ => None - }.map(str::to_owned) + pub fn to_integer(&self) -> i64 { + match self { + Self::OPEN => 0, + Self::CLOSED => 1, + Self::Other(_) => 2 + } + } + + pub fn to_string(&self) -> Option { + match self { + Self::OPEN => Some("open"), + Self::CLOSED => Some("closed"), + Self::Other(_) => 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?; @@ -90,7 +101,7 @@ pub async fn update(mut conn: &mut Conn, github_api_token: &str, (ref owner, ref "REPLACE INTO issues (repo, number, state, title, body, user_login, html_url, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)" ).bind(repo).bind(issue.number) - .bind(state_to_integer(issue.state)).bind(issue.title).bind(issue.body_html) + .bind(issue.state.to_integer()).bind(issue.title).bind(issue.body_html) .bind(author).bind(issue.url).bind(ts) .execute(&mut conn) .await?; -- cgit v1.2.3