~raboof/nixpkgs-contributor-dashboard

ref: 08df9196d56f45cbba0d6d9feeb1231481539f68 nixpkgs-contributor-dashboard/src/bin/fetch_pulls.rs -rw-r--r-- 2.8 KiB
08df9196 — Arnout Engelen Add feature for clearing PR's 1 year, 3 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
extern crate nixpkgs_contributor_dashboard;
extern crate diesel;
extern crate dotenv;

use std::env;
use github_rs::client::{Executor, Github};

use self::nixpkgs_contributor_dashboard::*;
use self::models::*;
use self::schema::*;
use self::diesel::prelude::*;
use serde::Deserialize;
use regex::Regex;
use dotenv::dotenv;

fn extract_last(link: &str) -> Option<&str> {
    let re: Regex = Regex::new(r"=(?P<last>\d+)>; rel=.last").unwrap();
    re.captures(link).and_then(|cap| {
      cap.name("last").map(|last| last.as_str())
    })
}

#[derive(Deserialize, Debug)]
pub struct Pull {
    pub id: i32,
    pub number: i32,
    pub draft: bool,
    pub title: String,
    pub html_url: String,
}

fn process_pulls(entity: Option<Vec<Pull>>) {
    // TODO use 1 connection ;)
    let connection = establish_connection();
    if let Some(the_pulls) = entity {
        for pull in the_pulls {
            let package: String = pull.title.as_str().chars().take_while(|c| *c != ':').collect();
            let new_item = NewItem {
                kind: "PR",
                draft: if pull.draft { 1 } else { 0 },
                number: pull.number,
                package: package.as_str(),
                title: pull.title.as_str(),
                html_url: pull.html_url.as_str(),
            };
            println!("{}", pull.number);
            diesel::insert_into(items::table)
                .values(&new_item)
                // Why does 'on_conflict()' not work here?
                .execute(&connection)
                .expect("Error saving pull");
        }
        println!("Done!");
    }
 }

fn fetch_page(client: &Github, page: i32) {
    let owner = "nixos";
    let repo = "nixpkgs";
    let endpoint = format!(
        "repos/{}/{}/pulls?page={}",
        owner, repo, page
        );
    println!("Getting page {}", page);
    let me = client.get()
                   .custom_endpoint(&endpoint)
                   .execute::<Vec<Pull>>();
    match me {
        Ok((_headers, _status, entity)) => {
            process_pulls(entity);
        },
        Err(e) =>
            println!("{}", e)
    }
}

fn main() {
    dotenv().ok();
    let client = Github::new(env::var("GITHUB_TOKEN").unwrap()).unwrap();
    let me = client.get()
                   .repos()
                   .owner("nixos")
                   .repo("nixpkgs")
                   .pulls()
                   .execute::<Vec<Pull>>();
    match me {
        Ok((headers, _status, entity)) => {
            let last = extract_last(headers.get("link").unwrap().to_str().unwrap());
            println!("Last: {}", last.unwrap());
            process_pulls(entity);
            for i in 2..(last.unwrap().parse::<i32>().unwrap()) {
                fetch_page(&client, i);
            }
        },
        Err(e) => println!("{}", e)
    }
}