-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrainscheduler.py
159 lines (117 loc) · 5.14 KB
/
trainscheduler.py
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import datetime
import time
from apscheduler.scheduler import Scheduler
from apscheduler.jobstores.shelve_store import ShelveJobStore
import apscheduler.events
import passenger
import freight
import autotrain
import logging
# minutes to check before train passes by
CHECKBEFORE = 5
AUTO_TRAIN_STATION_NAME = "Hildesheim"
PASSENGER_STATION_ID = 8000169
FREIGHT_STATION_ID = 180134148
OUTPUT_FILE = "ledticker.txt"
class TrainScheduler(object):
def __init__(self):
logging.basicConfig(level=logging.DEBUG, filename="debug.log", format='%(asctime)s %(levelname)-8s %(message)s', datefmt="%d.%m.%Y %H:%M:%S")
self.scheduler = Scheduler()
self.scheduler.add_listener(self.checkForDuplicates, apscheduler.events.EVENT_JOBSTORE_JOB_ADDED)
self.scheduler.start()
if len(self.scheduler.get_jobs()) == 0:
self.createInitSchedule()
self.log("Initial tasks completed. Waiting for next event..")
while True:
try:
time.sleep(10)
#self.scheduler.print_jobs()
except KeyboardInterrupt:
self.log("Shutting down..")
self.scheduler.shutdown()
quit()
def createInitSchedule(self):
self.log("Perform initial query for passenger trains..")
self.processPassenger()
self.log("Perform initial query for freight trains..")
self.processFreight()
self.log("Perform initial query for auto trains..")
self.processAutotrain()
self.log("Creating initial train schedule..")
# request passenger trains every hour
self.scheduler.add_cron_job(self.processPassenger, hour="*/1", minute="0", day="*", month="*", year="*")
# request freight trains every day
self.scheduler.add_cron_job(self.processFreight, hour="0", minute="2", day="*", month="*", year="*")
# request auto trains every month
self.scheduler.add_cron_job(self.processAutotrain, hour="0", minute="5", day="1", month="*", year="*")
def processPassenger(self):
# return trains for station in question
tReq = passenger.PassengerTrainRequest(PASSENGER_STATION_ID)
for train in tReq.getTrainList():
trainTime = train.actualTime if (train.actualTime) else train.scheduledTime
trainTimeCheck = trainTime - datetime.timedelta(minutes=CHECKBEFORE)
try:
self.scheduler.add_date_job(self.checkIfOnTime, trainTimeCheck, args=[train], name=train.name)
self.log("Schedule passenger train '%s' to be checked on %s." % (train.name, trainTimeCheck))
except ValueError:
try:
self.scheduler.add_date_job(self.output, trainTime, args=[train], name=train.name)
self.log("Schedule passenger train '%s' to be displayed on %s." % (train.name, trainTime))
except ValueError:
self.log("Passenger train '%s' (%s) already passed by." % (train.name, trainTime))
def checkIfOnTime(self, remTrain):
# return trains for station in question
tReq = passenger.PassengerTrainRequest(PASSENGER_STATION_ID)
for train in tReq.getTrainList():
if remTrain.name == train.name:
trainTime = train.actualTime if (train.actualTime) else train.scheduledTime
try:
self.scheduler.add_date_job(self.output, trainTime, args=[train], name=train.name)
self.log("Schedule passenger train '%s' to be displayed on %s." % (train.name, trainTime))
except ValueError:
self.log("Passenger train '%s' (%s) already passed by." % (train.name, trainTime))
break
def processFreight(self):
# return trains for station in question
freightTrains = freight.FreightTrainRequest(FREIGHT_STATION_ID)
for train in freightTrains.getTrainList():
# FIXME: only arrival atm
if train.arrival > datetime.datetime.now():
self.log("Schedule freight train '%s' to be displayed on %s." % (train.name, train.arrival))
self.scheduler.add_date_job(self.output, train.arrival, args=[train], name=train.name)
else:
self.log("Freight train '%s' (%s) already passed." % (train.name, train.arrival))
def processAutotrain(self):
# return trains for station in question
freightTrains = autotrain.AutoTrainRequest(AUTO_TRAIN_STATION_NAME)
for train in freightTrains.getTrainList():
if train.arrival > datetime.datetime.now():
self.log("Schedule auto train '%s' to be displayed on %s." % (train.name, train.arrival))
self.scheduler.add_date_job(self.output, train.arrival, args=[train], name=train.name)
else:
self.log("Auto train '%s' (%s) already passed." % (train.name, train.arrival))
def checkForDuplicates(self, event):
jobs = self.scheduler.get_jobs()
if jobs:
# events with the same name (train name) and the next "next run time" are duplicates
dups = [job for job in jobs if job.name == event.job.name and job.next_run_time == event.job.next_run_time]
if len(dups) > 1:
self.log("Unscheduling %s." % event.job)
self.scheduler.unschedule_job(event.job)
def output(self, train):
self.log("OUTPUT: %s" % train)
f = open(OUTPUT_FILE, "a")
f.write("%s\n" % train)
f.close()
def log(self, message):
logging.info("* %s" % message)
#fancyMessage = "[%s] %s" % (time.strftime("%d.%m.%Y %H:%M:%S"), message)
#logfile = open("bahnanzeige.log", "a")
#logfile.write("\n%s" % fancyMessage)
#logfile.close()
def main():
TrainScheduler()
if __name__ == '__main__':
main()