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
110
111
112
113
114
115
116
use cron::Schedule;
use chrono::{FixedOffset, Local};
use std::str::FromStr;
use std::thread;
use std::time::Duration;
use command::Command;
pub struct CronJob {
name: String,
command: Box<Command>,
seconds: Option<String>,
minutes: Option<String>,
hours: Option<String>,
day_of_month: Option<String>,
month: Option<String>,
day_of_week: Option<String>,
year: Option<String>,
offset: Option<FixedOffset>,
}
impl CronJob {
pub fn new<C: Command>(name: &str, command: C) -> Self {
CronJob {
name: name.to_string(),
command: Box::new(command),
seconds: None,
minutes: None,
hours: None,
day_of_month: None,
month: None,
day_of_week: None,
year: None,
offset: None,
}
}
pub fn seconds(&mut self, seconds: &str) -> &mut Self {
self.seconds = Some(seconds.to_string());
self
}
pub fn minutes(&mut self, minutes: &str) -> &mut Self {
self.minutes = Some(minutes.to_string());
self
}
pub fn hours(&mut self, hours: &str) -> &mut Self {
self.hours = Some(hours.to_string());
self
}
pub fn day_of_month(&mut self, day_of_month: &str) -> &mut Self {
self.day_of_month = Some(day_of_month.to_string());
self
}
pub fn month(&mut self, month: &str) -> &mut Self {
self.month = Some(month.to_string());
self
}
pub fn day_of_week(&mut self, day_of_week: &str) -> &mut Self {
self.day_of_week = Some(day_of_week.to_string());
self
}
pub fn year(&mut self, year: &str) -> &mut Self {
self.year = Some(year.to_string());
self
}
pub fn offset(&mut self, timezone_offset: i64) -> &mut Self {
self.offset = Some(FixedOffset::east(timezone_offset as i32));
self
}
fn get_schedule(&mut self) -> Schedule {
let cron = format!("{} {} {} {} {} {} {}",
self.seconds.clone().unwrap_or("*".to_string()),
self.minutes.clone().unwrap_or("*".to_string()),
self.hours.clone().unwrap_or("*".to_string()),
self.day_of_month.clone().unwrap_or("*".to_string()),
self.month.clone().unwrap_or("*".to_string()),
self.day_of_week.clone().unwrap_or("*".to_string()),
self.year.clone().unwrap_or("*".to_string()));
Schedule::from_str(&cron).unwrap()
}
pub fn start_job(&mut self) {
let schedule = self.get_schedule();
let offset = self.offset.unwrap_or(FixedOffset::east(0));
loop {
let upcoming = schedule.upcoming(offset).take(1);
thread::sleep(Duration::new(1, 0));
for datetime in upcoming {
let local = &Local::now();
if datetime.timestamp() <= local.timestamp() {
self.command.execute(&self.name);
}
}
}
}
pub fn start_job_threaded(mut cronjob: CronJob) {
thread::Builder::new()
.name(cronjob.name.to_string())
.spawn(move || { cronjob.start_job(); })
.expect("There was an error in an cronjob");
}
}