Skip to content

Commit

Permalink
feat: add timer component
Browse files Browse the repository at this point in the history
  • Loading branch information
baerwang committed Apr 18, 2024
1 parent 6f4e2e9 commit f953751
Show file tree
Hide file tree
Showing 14 changed files with 216 additions and 60 deletions.
57 changes: 54 additions & 3 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ tauri-build = { version = "1", features = [] }

[dependencies]
tauri = { version = "1", features = ["system-tray", "shell-open"] }
reqwest = { version = "0.12", features = ["json", "blocking"] }
reqwest = { version = "0.12", features = ["json"] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
anyhow = "1.0"
toml = "0.8.8"
notify-rust = "4"
tokio-cron-scheduler = "*"

[features]
# This feature is used for production builds or when a dev server is not specified, DO NOT REMOVE!!
Expand Down
13 changes: 9 additions & 4 deletions src-tauri/src/conf/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ pub struct ConfigData {
pub reviews: Vec<String>,
pub owners: Owner,
pub orgs: HashMap<String, Vec<String>>,
pub dispatch: u64,
}

impl ConfigData {
Expand All @@ -34,12 +35,16 @@ impl ConfigData {
"token not allowed empty"
} else if self.plugin.is_empty() {
"plugin not allowed empty"
} else if self.dispatch == 0 {
"dispatch not allowed empty"
} else if self.reviews.is_empty() || self.reviews.iter().any(|s| s.is_empty()) {
"reviews not allowed empty"
} else if self.owners.name.is_empty() {
"owner not allowed empty"
} else if self.owners.repos.is_empty() || self.owners.repos.iter().any(|s| s.is_empty()) {
"owner repos not allowed empty"
} else if self.orgs.is_empty()
&& (self.owners.name.is_empty()
|| self.owners.repos.is_empty()
|| self.owners.repos.iter().any(|s| s.is_empty()))
{
"owner/repos or orgs/repos not allowed empty"
} else {
""
}
Expand Down
35 changes: 35 additions & 0 deletions src-tauri/src/console/create.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

use crate::{conf, dispatch};

#[tauri::command]
pub async fn create(conf: conf::config::ConfigData) -> String {
match conf.valid() {
r => r.to_string(),
"" => match dispatch::execute(conf).await {
Ok(uuid) => {
println!("uuid:{}", uuid);
"".to_string()
}
Err(_) => "start schedule task fail".to_string(),
},
}
}

#[tauri::command]
pub fn repos() -> () {}
18 changes: 18 additions & 0 deletions src-tauri/src/console/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

pub mod create;
54 changes: 54 additions & 0 deletions src-tauri/src/dispatch/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

use std::collections::HashMap;
use std::time::Duration;

use tokio_cron_scheduler::{Job, JobScheduler, JobSchedulerError};

use crate::conf::config::ConfigData;
use crate::plugins::github::GitHub;

pub async fn execute(c: ConfigData) -> Result<String, JobSchedulerError> {
let sched = JobScheduler::new().await?;
let token = c.token;
let reviews: HashMap<String, ()> = c.reviews.iter().map(|key| (key.clone(), ())).collect();
let task = Job::new_repeated(Duration::from_secs(c.dispatch), move |_uuid, _l| {
if !c.owners.name.is_empty() {
let hub = GitHub::new(c.owners.name.clone(), reviews.clone());
c.owners.repos.iter().for_each(|repo| {
if !repo.is_empty() {
_ = hub.execute(token.as_str(), repo.as_str());
}
});
}

if !c.orgs.is_empty() {
for (org, repos) in &c.orgs {
if !org.is_empty() && !repos.is_empty() {
let hub = GitHub::new(org.clone(), reviews.clone());
for repo in repos {
_ = hub.execute(token.as_str(), repo.as_str());
}
}
}
}
})?;
let uuid = sched.add(task).await?;
sched.start().await?;
Ok(uuid.to_string())
}
2 changes: 2 additions & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@
*/

pub mod conf;
pub mod console;
pub mod dispatch;
pub mod notification;
pub mod plugins;
9 changes: 2 additions & 7 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,13 @@

#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use flexible::conf;
use flexible::console;

mod tray;

#[tauri::command]
fn done(conf: conf::config::ConfigData) -> String {
conf.valid().to_string()
}

fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![done])
.invoke_handler(tauri::generate_handler![console::create::create])
.system_tray(tray::menu())
.on_system_tray_event(tray::handler)
.run(tauri::generate_context!())
Expand Down
1 change: 0 additions & 1 deletion src-tauri/src/plugins/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ pub struct PullRequest {

pub trait Api {
fn api(&self) -> &str;
fn execute(&self, token: &str, repo: &str) -> Result<(), anyhow::Error>;
fn headers(&self, token: &str) -> HeaderMap;
fn repo(&self, repo: &str) -> String;
fn repos(&self) -> String;
Expand Down
44 changes: 22 additions & 22 deletions src-tauri/src/plugins/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@ impl GitHub {
pub fn new(owner: String, reviews: HashMap<String, ()>) -> Self {
GitHub { owner, reviews }
}

pub async fn execute(&self, token: &str, repo: &str) -> Result<(), anyhow::Error> {
let rsp = client(self.pull_requests(repo), self.headers(token)).await?;
let prs: Vec<PullRequest> = serde_json::from_str(&rsp)?;
for pr in prs {
let reviews_data = client(self.reviews(repo, pr.number), self.headers(token)).await?;
let reviews: Reviews = serde_json::from_str(&reviews_data)?;
reviews.users.iter().for_each(|user| {
if self.reviews.contains_key(user.login.as_str()) {
self.notify(
repo,
"",
crate::plugins::api::PullRequest {
title: pr.title.clone(),
number: pr.number,
},
)
}
});
}
Ok(())
}
}

#[derive(Debug, Deserialize)]
Expand All @@ -58,28 +80,6 @@ impl Api for GitHub {
"https://api.github.com"
}

fn execute(&self, token: &str, repo: &str) -> Result<(), anyhow::Error> {
let rsp = client(self.pull_requests(repo), self.headers(token))?;
let prs: Vec<PullRequest> = serde_json::from_str(&rsp)?;
for pr in prs {
let reviews_data = client(self.reviews(repo, pr.number), self.headers(token))?;
let reviews: Reviews = serde_json::from_str(&reviews_data)?;
reviews.users.iter().for_each(|user| {
if self.reviews.contains_key(user.login.as_str()) {
self.notify(
repo,
"",
PR {
title: pr.title.clone(),
number: pr.number,
},
)
}
});
}
Ok(())
}

fn headers(&self, token: &str) -> HeaderMap {
let mut headers = HeaderMap::new();
headers.insert(AUTHORIZATION, format!("Bearer: {}", token).parse().unwrap());
Expand Down
12 changes: 7 additions & 5 deletions src-tauri/src/plugins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use reqwest::header::HeaderMap;
use crate::plugins::api::Api;

mod api;
mod github;
pub mod github;

pub fn get_api(api: &str, owner: String, reviews: HashMap<String, ()>) -> Box<dyn Api> {
match api {
Expand All @@ -31,12 +31,14 @@ pub fn get_api(api: &str, owner: String, reviews: HashMap<String, ()>) -> Box<dy
}
}

pub fn client(url: String, headers: HeaderMap) -> Result<String, reqwest::Error> {
let resp = reqwest::blocking::Client::new()
pub async fn client(url: String, headers: HeaderMap) -> Result<String, reqwest::Error> {
let resp = reqwest::Client::new()
.get(url)
.headers(headers)
.timeout(std::time::Duration::from_secs(3))
.send()?
.text()?;
.send()
.await?
.text()
.await?;
Ok(resp)
}
Loading

0 comments on commit f953751

Please sign in to comment.