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 98 99 100 101 102 103 104 105 106 107 108 109
use octocrab::models::issues::*; use reqwest::Url; use serde::*; use crate::*; type DateTime = chrono::DateTime<chrono::Utc>; #[derive(Serialize, Debug)] pub struct CommentRec { pub id: u64, pub node_id: String, pub url: Url, pub html_url: Url, pub body: Option<String>, pub body_text: Option<String>, pub body_html: Option<String>, pub user_id: i64, pub created_at: DateTime, pub updated_at: Option<DateTime>, pub sdc_repository: String, } impl RepositryAware for CommentRec { fn set_repository(&mut self, name: String) { self.sdc_repository = name; } } impl From<Comment> for CommentRec { fn from(from: Comment) -> CommentRec { CommentRec { id: from.id, node_id: from.node_id, url: from.url, html_url: from.html_url, body: from.body, body_text: from.body_text, body_html: from.body_html, user_id: from.user.id, created_at: from.created_at, updated_at: from.updated_at, sdc_repository: String::default(), } } } pub struct CommentFetcher { owner: String, name: String, since: Option<DateTime>, octocrab: octocrab::Octocrab, } impl CommentFetcher { pub fn new( owner: String, name: String, since: Option<DateTime>, octocrab: octocrab::Octocrab, ) -> Self { Self { owner, name, since, octocrab, } } } impl UrlConstructor for CommentFetcher { fn reponame(&self) -> String { format!("{}/{}", self.owner, self.name) } fn entrypoint(&self) -> Option<Url> { let param = Params { since: self.since, ..Default::default() }; let route = format!( "repos/{owner}/{repo}/issues/comments?{query}", owner = &self.owner, repo = &self.name, query = param.to_query(), ); self.octocrab.absolute_url(route).ok() } } impl LoopWriter for CommentFetcher { type Model = Comment; type Record = CommentRec; } impl CommentFetcher { pub async fn fetch<T: std::io::Write>(&self, mut wtr: csv::Writer<T>) -> octocrab::Result<()> { let mut next: Option<Url> = self.entrypoint(); while let Some(page) = self.octocrab.get_page(&next).await? { next = self.write_and_continue(page, &mut wtr); } Ok(()) } }