Compare commits
5 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
27aa6a1de8 | |
|
|
32435d94ad | |
|
|
60fe1a04f2 | |
|
|
347ea99eeb | |
|
|
983020b55f |
1
.env
1
.env
|
|
@ -1 +1,2 @@
|
||||||
DATABASE_URL=mysql://root:Chenweijia113!@localhost/lottery
|
DATABASE_URL=mysql://root:Chenweijia113!@localhost/lottery
|
||||||
|
version = "1.0.8"
|
||||||
|
|
@ -2,11 +2,69 @@ on: [push, pull_request]
|
||||||
|
|
||||||
name: Continuous integration
|
name: Continuous integration
|
||||||
|
|
||||||
|
env:
|
||||||
|
VERSION_FILE: .env
|
||||||
|
REPO: sched_task
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
build:
|
||||||
name: Check
|
name: Build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
continue-on-error: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- name: Checkout
|
||||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
uses: https://gitea.com/actions/checkout@v4
|
||||||
- run: cargo check
|
|
||||||
|
- name: Setup Rust
|
||||||
|
uses: https://git.airpig.cn/actions/setup-rust-toolchain@v1
|
||||||
|
|
||||||
|
- name: Add target for musl
|
||||||
|
run: |
|
||||||
|
apt update && apt install -y musl-tools
|
||||||
|
rustup target add x86_64-unknown-linux-musl
|
||||||
|
|
||||||
|
- name: Cache cargo registry and build
|
||||||
|
uses: https://gitea.com/actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/bin/
|
||||||
|
~/.cargo/registry/index/
|
||||||
|
~/.cargo/registry/cache/
|
||||||
|
~/.cargo/git/db/
|
||||||
|
target/
|
||||||
|
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-cargo-
|
||||||
|
|
||||||
|
- name: Cargo build release for musl
|
||||||
|
run: |
|
||||||
|
cargo build -r --target x86_64-unknown-linux-musl
|
||||||
|
|
||||||
|
- name: Login to hub.airpig.cn
|
||||||
|
uses: https://gitea.com/docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: hub.airpig.cn
|
||||||
|
username: admin
|
||||||
|
password: Chenweijia113!
|
||||||
|
|
||||||
|
- name: Build Docker image and push
|
||||||
|
run: |
|
||||||
|
version=$(grep -E '^version' $VERSION_FILE | awk -F'"' '{print $2}')
|
||||||
|
new_version="v${version}"
|
||||||
|
docker build -t hub.airpig.cn/library/$REPO:$new_version .
|
||||||
|
docker push hub.airpig.cn/library/$REPO:$new_version
|
||||||
|
docker rmi hub.airpig.cn/library/$REPO:$new_version
|
||||||
|
|
||||||
|
- name: Bark Notify if success
|
||||||
|
if: success()
|
||||||
|
run: |
|
||||||
|
version=$(grep -E '^version' $VERSION_FILE | awk -F'"' '{print $2}')
|
||||||
|
msg="Build job: $REPO, version: v$version succeeded\!\!\!"
|
||||||
|
curl https://ding.airpig.cn/QfagvFa7u323xUS5yRbFR3/"${msg// /%20}"
|
||||||
|
|
||||||
|
- name: Bark Notify if failure
|
||||||
|
if: failure()
|
||||||
|
run: |
|
||||||
|
version=$(grep -E '^version' $VERSION_FILE | awk -F'"' '{print $2}')
|
||||||
|
msg="Build job: $REPO, version: v$version failed\!\!\!"
|
||||||
|
curl https://ding.airpig.cn/QfagvFa7u323xUS5yRbFR3/"${msg// /%20}"
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -14,3 +14,6 @@ reqwest = { version = "0.12.5", features = ["gzip"] }
|
||||||
scraper = "0.19.1"
|
scraper = "0.19.1"
|
||||||
sea-orm = { version = "0.12", features = [ "sqlx-mysql", "runtime-tokio-rustls", "macros" ]}
|
sea-orm = { version = "0.12", features = [ "sqlx-mysql", "runtime-tokio-rustls", "macros" ]}
|
||||||
tokio = { version = "1.39.2", features = ["full"] }
|
tokio = { version = "1.39.2", features = ["full"] }
|
||||||
|
serde = { version = "1.0.204", features = ["derive", "serde_derive"] }
|
||||||
|
toml = "0.8.19"
|
||||||
|
lazy_static = "1.5.0"
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ ENV RUST_LOG=info
|
||||||
|
|
||||||
ENV RUST_ENV=prod
|
ENV RUST_ENV=prod
|
||||||
|
|
||||||
|
RUN mkdir -p /etc/sched_rs
|
||||||
COPY ./target/x86_64-unknown-linux-musl/release/sched_tasks_rs /bin/sched_tasks_rs
|
COPY ./target/x86_64-unknown-linux-musl/release/sched_tasks_rs /bin/sched_tasks_rs
|
||||||
|
COPY ./config.toml /etc/sched_rs/config.toml
|
||||||
|
|
||||||
ENTRYPOINT ["/bin/sched_tasks_rs"]
|
ENTRYPOINT ["/bin/sched_tasks_rs"]
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
db_user = "root"
|
||||||
|
db_passwd = "Chenweijia113!"
|
||||||
|
db_host = "mysql"
|
||||||
|
db_port = 3306
|
||||||
|
db_name = "lottery"
|
||||||
|
notifyUrls = [
|
||||||
|
"https://ding.airpig.cn/QfagvFa7u323xUS5yRbFR3",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use toml;
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize)]
|
||||||
|
pub struct Config {
|
||||||
|
#[serde(rename = "db_user")]
|
||||||
|
pub username: String,
|
||||||
|
#[serde(rename = "db_passwd")]
|
||||||
|
pub password: String,
|
||||||
|
#[serde(rename = "db_host")]
|
||||||
|
pub host: String,
|
||||||
|
#[serde(rename = "db_port")]
|
||||||
|
pub port: u16,
|
||||||
|
#[serde(rename = "db_name")]
|
||||||
|
pub database: String,
|
||||||
|
#[serde(rename = "notifyUrls")]
|
||||||
|
pub notify_urls: Vec<String>,
|
||||||
|
pub pls_cron: Option<String>,
|
||||||
|
pub plw_cron: Option<String>,
|
||||||
|
pub sd_cron: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_config(file_path: &str) -> Result<Config, Box<dyn Error>> {
|
||||||
|
let mut buf = String::new();
|
||||||
|
File::open(file_path)?.read_to_string(&mut buf)?;
|
||||||
|
toml::from_str(&buf).map_err(|e| e.into())
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod config;
|
||||||
|
|
||||||
|
pub use config::read_config;
|
||||||
106
src/main.rs
106
src/main.rs
|
|
@ -1,86 +1,62 @@
|
||||||
use std::{thread, time::Duration};
|
use std::{env, thread, time::Duration};
|
||||||
|
|
||||||
use clokwerk::{Scheduler, TimeUnits, Job};
|
use clokwerk::{Scheduler, TimeUnits, Job};
|
||||||
|
use get_data::notify_msg;
|
||||||
use log::{info, error};
|
use log::info;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
mod tasks;
|
mod tasks;
|
||||||
use tasks::*;
|
use tasks::*;
|
||||||
|
mod config;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref CONFIG: config::config::Config = {
|
||||||
|
let file_path = if env::var("RUST_ENV").unwrap_or_else(|_|"dev".to_string()) == "dev" {
|
||||||
|
"./config.toml"
|
||||||
|
} else {
|
||||||
|
"/etc/sched_rs/config.toml"
|
||||||
|
};
|
||||||
|
config::read_config(file_path).unwrap()
|
||||||
|
};
|
||||||
|
static ref DB_URL: String = {
|
||||||
|
format!("mysql://{}:{}@{}:{}/{}", CONFIG.username, CONFIG.password, CONFIG.host, CONFIG.port, CONFIG.database)
|
||||||
|
};
|
||||||
|
static ref NOTIFY_URLS : Vec<String> = {
|
||||||
|
CONFIG.notify_urls.iter().map(|url| url.to_string()).collect()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
let mut scheduler = Scheduler::new();
|
let mut scheduler = Scheduler::new();
|
||||||
let fmt = "%Y年%m月%d日 %H:%M:%S";
|
// let fmt = "%Y年%m月%d日 %H:%M:%S";
|
||||||
let notify_url = "https://ding.airpig.cn/QfagvFa7u323xUS5yRbFR3";
|
|
||||||
scheduler.every(1.day()).at("00:01:00").run(move|| {
|
|
||||||
|
// 在多个定时任务之间分享配置信息
|
||||||
|
// 排列三数据采集
|
||||||
|
let pls_cron = CONFIG.clone().pls_cron.unwrap_or("00:01:00".to_string());
|
||||||
|
scheduler.every(1.day()).at(&pls_cron).run(move|| {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let res = get_data_from_500_com("pls").await;
|
let res = get_data_from_500_com("pls", &DB_URL).await;
|
||||||
let msg;
|
let _ = notify_msg("pls", &NOTIFY_URLS, res).await;
|
||||||
match res {
|
|
||||||
Ok(val) => {
|
|
||||||
msg = format!("{}: 排列3数据采集完毕, 最新数据为: {}!", chrono::Local::now().format(fmt), val);
|
|
||||||
info!("{}", msg);
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
msg = format!("{}: 排列3数据采集失败: {}!", chrono::Local::now().format(fmt), e);
|
|
||||||
error!("{}", msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let notify = reqwest::get(format!("{}/{}", notify_url, msg)).await.unwrap();
|
|
||||||
if notify.status().is_success() {
|
|
||||||
info!("{}: 排列3数据采集通知发送成功", chrono::Local::now().format(fmt));
|
|
||||||
} else {
|
|
||||||
error!("{}: 排列3数据采集通知发送失败", chrono::Local::now().format(fmt));
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
// 排列五数据采集
|
||||||
scheduler.every(1.day()).at("00:01:15").run(move|| {
|
let plw_cron = CONFIG.clone().plw_cron.unwrap_or("00:01:15".to_string());
|
||||||
|
scheduler.every(1.day()).at(&plw_cron).run(move|| {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let res = get_data_from_500_com("plw").await;
|
let res = get_data_from_500_com("plw", &DB_URL).await;
|
||||||
let msg;
|
let _ = notify_msg("plw", &NOTIFY_URLS, res).await;
|
||||||
match res {
|
|
||||||
Ok(val) => {
|
|
||||||
msg = format!("{}: 排列5数据采集完毕, 最新数据为: {}!", chrono::Local::now().format(fmt), val);
|
|
||||||
info!("{}", msg);
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
msg = format!("{}: 排列5数据采集失败: {}!", chrono::Local::now().format(fmt), e);
|
|
||||||
error!("{}", msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let notify = reqwest::get(format!("{}/{}", notify_url, msg)).await.unwrap();
|
|
||||||
if notify.status().is_success() {
|
|
||||||
info!("{}: 排列5数据采集通知发送成功", chrono::Local::now().format(fmt));
|
|
||||||
} else {
|
|
||||||
error!("{}: 排列5数据采集通知发送失败", chrono::Local::now().format(fmt));
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
// 福彩3D数据采集
|
||||||
scheduler.every(1.day()).at("00:01:30").run(move|| {
|
let sd_cron = CONFIG.clone().sd_cron.unwrap_or("00:01:30".to_string());
|
||||||
|
scheduler.every(1.day()).at(&sd_cron).run(move|| {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let res = get_data_from_500_com("sd").await;
|
let res = get_data_from_500_com("sd", &DB_URL).await;
|
||||||
let msg;
|
let _ = notify_msg("sd", &NOTIFY_URLS, res).await;
|
||||||
match res {
|
|
||||||
Ok(val) => {
|
|
||||||
msg = format!("{}: 福彩3D数据采集完毕, 最新数据为: {}!", chrono::Local::now().format(fmt), val);
|
|
||||||
info!("{}", msg);
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
msg = format!("{}: 福彩3D数据采集失败: {}!", chrono::Local::now().format(fmt), e);
|
|
||||||
error!("{}", msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let notify = reqwest::get(format!("{}/{}", notify_url, msg)).await.unwrap();
|
|
||||||
if notify.status().is_success() {
|
|
||||||
info!("{}: 福彩3D数据采集通知发送成功", chrono::Local::now().format(fmt));
|
|
||||||
} else {
|
|
||||||
error!("{}: 福彩3D数据采集通知发送失败", chrono::Local::now().format(fmt));
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
use std::{env, time::Duration};
|
use std::time::Duration;
|
||||||
|
use log::{info, error};
|
||||||
use chrono::{Local, NaiveDate};
|
use chrono::{Local, NaiveDate};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use scraper::{Html, Selector};
|
use scraper::{Html, Selector};
|
||||||
|
|
@ -10,15 +10,15 @@ use sea_orm::{ActiveModelTrait, ConnectOptions, Database};
|
||||||
use crate::model::prelude::*;
|
use crate::model::prelude::*;
|
||||||
use crate::model::{sd, pls, plw};
|
use crate::model::{sd, pls, plw};
|
||||||
|
|
||||||
pub async fn get_data_from_500_com(issue_type: &str) -> Result<String, String> {
|
pub async fn get_data_from_500_com(issue_type: &str, db_url:&str) -> Result<String, String> {
|
||||||
|
|
||||||
// 数据库连接操作
|
// 数据库连接操作
|
||||||
let db_url;
|
// let db_url;
|
||||||
if env::var("RUST_ENV").unwrap_or_else(|_|"dev".to_string()) == "dev" {
|
// if env::var("RUST_ENV").unwrap_or_else(|_|"dev".to_string()) == "dev" {
|
||||||
db_url = "mysql://root:Chenweijia113!@localhost/lottery";
|
// db_url = "mysql://root:Chenweijia113!@localhost/lottery";
|
||||||
} else {
|
// } else {
|
||||||
db_url = "mysql://root:Chenweijia113!@mysql/lottery";
|
// db_url = "mysql://root:Chenweijia113!@mysql/lottery";
|
||||||
}
|
// }
|
||||||
let mut opt = ConnectOptions::new(db_url);
|
let mut opt = ConnectOptions::new(db_url);
|
||||||
opt.max_connections(100)
|
opt.max_connections(100)
|
||||||
.min_connections(5)
|
.min_connections(5)
|
||||||
|
|
@ -157,3 +157,36 @@ pub async fn get_data_from_500_com(issue_type: &str) -> Result<String, String> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn notify_msg(issue_type: &str, notify_urls: &Vec<String>, res: Result<String, String>) -> Result<(), String> {
|
||||||
|
let lottery_type = match issue_type {
|
||||||
|
"ssq" => "双色球",
|
||||||
|
"dlt" => "大乐透",
|
||||||
|
"pls" => "排列3",
|
||||||
|
"plw" => "排列5",
|
||||||
|
"sd" => "福彩3D",
|
||||||
|
_ => "未知",
|
||||||
|
};
|
||||||
|
let fmt = "%Y年%m月%d日 %H:%M:%S";
|
||||||
|
let msg = match res {
|
||||||
|
Ok(val) => {
|
||||||
|
let msg = format!("{}: {}数据采集完毕, 最新数据为: {}!", chrono::Local::now().format(fmt), lottery_type, val);
|
||||||
|
info!("{}", msg);
|
||||||
|
msg
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
let msg = format!("{}: {}数据采集失败: {}!", chrono::Local::now().format(fmt), lottery_type, e);
|
||||||
|
error!("{}", msg);
|
||||||
|
msg
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for notify_url in notify_urls {
|
||||||
|
let notify = reqwest::get(format!("{}/{}", notify_url, msg)).await.unwrap();
|
||||||
|
if notify.status().is_success() {
|
||||||
|
info!("{}: {}数据采集通知发送成功", chrono::Local::now().format(fmt), lottery_type);
|
||||||
|
} else {
|
||||||
|
error!("{}: {}数据采集通知发送失败", chrono::Local::now().format(fmt), lottery_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue