]>
Commit | Line | Data |
---|---|---|
1 | #!/usr/bin/env python | |
2 | import requests | |
3 | from datetime import datetime, timedelta | |
4 | from collections import defaultdict | |
5 | import json | |
6 | import os, sys | |
7 | import pytz | |
8 | import argparse | |
9 | ||
10 | URL= "https://maps.googleapis.com/maps/api/distancematrix/json" | |
11 | ||
12 | parser = argparse.ArgumentParser(description='Plot traffic information for various origin-destinations') | |
13 | parser.add_argument('-c', '--config', type=str, default='config.json', help='Config file to load (default config.jsonà') | |
14 | parser.add_argument('-n', '--dry-run', action='store_true', help='Run in dry-run mode (don’t make any api call)') | |
15 | parser.add_argument('-d', '--date', type=str, default='now', help='date (%%Y-%%m-%%d) for which to generate the plots') | |
16 | parser.add_argument('-s', '--stats', action='store_true', help='only print number of weekly calls for the config') | |
17 | args = parser.parse_args() | |
18 | ||
19 | WEEKDAYS = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"] | |
20 | SETTINGS = json.load(open(args.config, "r")) | |
21 | ||
22 | if args.date == "now": | |
23 | date = datetime.now(tz=pytz.timezone("Europe/Paris")) | |
24 | else: | |
25 | date = datetime.strptime(args.date, "%Y-%m-%d").replace(tzinfo=pytz.timezone("Europe/Paris")) | |
26 | ||
27 | def parse_plot(info): | |
28 | def condition(d): | |
29 | return "days" not in info or WEEKDAYS[d.weekday()] in info["days"] | |
30 | return { | |
31 | "name": info["name"], | |
32 | "origin": SETTINGS.get("locations", {}).get(info["origin"], info["origin"]), | |
33 | "destination": SETTINGS.get("locations", {}).get(info["destination"], info["destination"]), | |
34 | "condition": condition, | |
35 | "times": [t.split(":") for t in info["times"]], | |
36 | } | |
37 | ||
38 | plots = {} | |
39 | for name,info in SETTINGS["plots"].items(): | |
40 | plots[name] = parse_plot(info) | |
41 | ||
42 | def to_time(date, hour, minute): | |
43 | return date.replace(date.year, date.month, date.day, int(hour), int(minute), 0, 0) | |
44 | ||
45 | def get(time, origin, destination): | |
46 | keys = { | |
47 | "origins": origin, | |
48 | "destinations": destination, | |
49 | "departure_time": int(time.timestamp()), | |
50 | "key": SETTINGS["api_key"], | |
51 | } | |
52 | return requests.get(URL, params=keys) | |
53 | ||
54 | def stats(): | |
55 | total_calls_per_week = 0 | |
56 | for k, infos in plots.items(): | |
57 | calls_per_week = 0 | |
58 | for i in range(0, 7): | |
59 | if infos["condition"](date + timedelta(i)): | |
60 | calls_per_week += 1 | |
61 | total_calls_per_week += calls_per_week * len(infos["times"]) | |
62 | print("{} calls per week to api".format(total_calls_per_week)) | |
63 | if args.stats: | |
64 | stats() | |
65 | sys.exit(0) | |
66 | ||
67 | gnuplot = """ | |
68 | reset | |
69 | set terminal png size 1024,768 enhanced font "Helvetica" | |
70 | set output 'outputs/{fname}.png' | |
71 | set datafile separator "\\t" | |
72 | set xlabel "Time" | |
73 | set ylabel "Duration" | |
74 | ||
75 | set xdata time | |
76 | set timefmt "%H:%M" | |
77 | set format x "%H:%M" | |
78 | set title "{date} {name}" | |
79 | plot '{fname}.dat' using 1:2 with linespoints pointtype 5 title "" | |
80 | """ | |
81 | ||
82 | def get_times(name, infos, date, dry_run=False): | |
83 | result = {} | |
84 | if "condition" in infos and not infos["condition"](date): | |
85 | return result | |
86 | for time in infos["times"]: | |
87 | t = to_time(date, time[0], time[1]) | |
88 | try: | |
89 | if dry_run: | |
90 | v = 42 | |
91 | else: | |
92 | v = get(t, infos["origin"], infos["destination"]).json() | |
93 | v = int(v["rows"][0]["elements"][0]["duration_in_traffic"]["value"] / 60) | |
94 | except: | |
95 | continue | |
96 | result[t.strftime("%H:%M")] = v | |
97 | with open(date.strftime("%Y-%m-%d_{}.json".format(name)), "w") as f: | |
98 | f.write(json.dumps(result, indent=True)) | |
99 | ||
100 | fname = date.strftime("%Y-%m-%d_{}".format(name)) | |
101 | with open("{}.dat".format(fname), "w") as f: | |
102 | for time, duration in result.items(): | |
103 | f.write('{}\t{}\n'.format(time, duration)) | |
104 | with open("{}.gnuplot".format(fname), "w") as f: | |
105 | f.write(gnuplot.format(**{ | |
106 | "fname": fname, | |
107 | "name": infos["name"], | |
108 | "date": date.strftime("%Y-%m-%d") | |
109 | })) | |
110 | os.system("gnuplot -c {}.gnuplot".format(fname)) | |
111 | return result | |
112 | ||
113 | for name, infos in plots.items(): | |
114 | get_times(name, infos, date, dry_run=args.dry_run) |