Compare commits
1 Commits
af1b4ff9d8
...
401be97073
Author | SHA1 | Date | |
---|---|---|---|
|
401be97073 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
build/
|
||||
*.gpx
|
||||
.vscode/settings.json
|
||||
*.pyc
|
||||
|
@ -14,7 +14,7 @@ LOG_FORMAT = "%(asctime)s %(levelname)s %(message)s"
|
||||
UPDATE_INTERVAL = 60
|
||||
|
||||
logging.basicConfig(format=LOG_FORMAT, level=log_level, filename=LOG_FILE)
|
||||
#logging.basicConfig(format=LOG_FORMAT, level=log_level)
|
||||
# logging.basicConfig(format=LOG_FORMAT, level=log_level)
|
||||
log = logging.getLogger('bicycle-statistics')
|
||||
|
||||
def parse_args():
|
||||
|
@ -47,6 +47,46 @@ def plot_bar_chart(labels, ticklabels, values, title, xlabel, ylabel, filename,
|
||||
plt.savefig(filename)
|
||||
plt.close('all')
|
||||
|
||||
|
||||
def plot_line_chart(values, ticklabels, title, xlabel, ylabel, filename, xtick_rotation=0):
|
||||
'''Plot a line chart.
|
||||
|
||||
Args:
|
||||
values (dict): key: line name
|
||||
value (list): line values
|
||||
ticklabels (list): Names for the tick labels (must be same length as value list).
|
||||
title (str): Title of the chart.
|
||||
|
||||
'''
|
||||
fig = plt.figure()
|
||||
ax1 = fig.add_subplot(111)
|
||||
ax1.grid(zorder=0)
|
||||
ax1.spines["top"].set_visible(False)
|
||||
ax1.spines["bottom"].set_visible(False)
|
||||
ax1.spines["left"].set_visible(False)
|
||||
ax1.spines["right"].set_visible(False)
|
||||
|
||||
plt.title(title)
|
||||
plt.xlabel(xlabel)
|
||||
plt.ylabel(ylabel)
|
||||
|
||||
for key in values.keys():
|
||||
if len(ticklabels) == len(values[key]):
|
||||
plt.plot(ticklabels, values[key], label=key)
|
||||
else:
|
||||
short_ticklabels = list()
|
||||
for i in range(0, len(values[key])):
|
||||
short_ticklabels.append(ticklabels[i])
|
||||
plt.plot(short_ticklabels, values[key], label=key)
|
||||
|
||||
x_base = numpy.arange(len(ticklabels))
|
||||
plt.xticks(x_base, ticklabels, rotation=xtick_rotation)
|
||||
|
||||
plt.legend()
|
||||
plt.savefig(filename)
|
||||
plt.close('all')
|
||||
|
||||
|
||||
class Gpx2Html(object):
|
||||
def __init__(self, infolder, outfolder, logger):
|
||||
self.logger = logger
|
||||
@ -67,9 +107,12 @@ class Gpx2Html(object):
|
||||
self.logger.info("Begin update of png's/html...")
|
||||
distances = list()
|
||||
avg_speeds = list()
|
||||
distances_dict = dict()
|
||||
for year in self.tracks.years():
|
||||
distances.append(self.tracks.distances(year))
|
||||
distances_dict[year] = self.tracks.distances(year)
|
||||
avg_speeds.append(self.tracks.avg_speeds(year))
|
||||
self.logger.info("{}: {}".format(year, self.tracks.distances))
|
||||
|
||||
plot_bar_chart(self.tracks.years(), MONTH_LABELS, distances,
|
||||
'Distance', 'Month', 'km',
|
||||
@ -79,6 +122,26 @@ class Gpx2Html(object):
|
||||
'Average Speed', 'Month', 'km/h',
|
||||
os.path.join(self.outfolder, 'avg_spd.png'))
|
||||
|
||||
# Accumulated distance:
|
||||
accumulated_distances = dict()
|
||||
for year in distances_dict.keys():
|
||||
accumulated_distance = list()
|
||||
accumulated_distance.append(0)
|
||||
for i in range(0, len(distances_dict[year])):
|
||||
accumulated_distance.append(accumulated_distance[i] + distances_dict[year][i])
|
||||
accumulated_distances[year] = accumulated_distance
|
||||
|
||||
current_year = datetime.datetime.today().year
|
||||
current_month = datetime.datetime.today().month
|
||||
current_year_distance = list()
|
||||
for i in range(0, current_month):
|
||||
current_year_distance.append(accumulated_distances[current_year][i])
|
||||
accumulated_distances[current_year] = current_year_distance
|
||||
|
||||
plot_line_chart(accumulated_distances, [""] + MONTH_LABELS,
|
||||
"accumulated distance", 'Month', 'km',
|
||||
os.path.join(self.outfolder, 'acc_dist.png'))
|
||||
|
||||
end_date = datetime.datetime.today()
|
||||
start_date = end_date - datetime.timedelta(days=14)
|
||||
last_n_tracks = self.tracks.tracks(start_date, end_date)
|
||||
@ -182,6 +245,7 @@ class Gpx2Html(object):
|
||||
|
||||
handle.write('<p>\n')
|
||||
handle.write('<IMG SRC="{}" ALT="Distance">\n'.format('distance.png'))
|
||||
handle.write('<IMG SRC="{}" ALT="Distance">\n'.format('acc_dist.png'))
|
||||
handle.write('<IMG SRC="{}" ALT="Distance">\n'.format('avg_spd.png'))
|
||||
handle.write('<IMG SRC="{}" ALT="Distance">\n'.format('last_14_days.png'))
|
||||
handle.write('</p>\n')
|
||||
|
@ -1,32 +0,0 @@
|
||||
from watchdog.events import PatternMatchingEventHandler
|
||||
|
||||
import threading
|
||||
|
||||
class InputObserver(PatternMatchingEventHandler):
|
||||
def __init__(self, patterns=None, ignore_patterns=None,
|
||||
ignore_directories=False, case_sensitive=False):
|
||||
super(InputObserver, self).__init__(patterns, ignore_patterns,
|
||||
ignore_directories, case_sensitive)
|
||||
|
||||
self.lock = threading.Lock()
|
||||
self.lock.acquire()
|
||||
self.new_filename = None
|
||||
self.run_condition = True
|
||||
|
||||
|
||||
# def on_created(self, event):
|
||||
def on_any_event(self, event):
|
||||
self.new_filename = event.src_path
|
||||
self.lock.release()
|
||||
|
||||
|
||||
def get_new_file(self):
|
||||
self.lock.acquire() # don't release - will be released with next on_created
|
||||
if self.run_condition == True:
|
||||
return self.new_filename
|
||||
else:
|
||||
return None
|
||||
|
||||
def stop(self):
|
||||
self.run_condition = False
|
||||
self.lock.release()
|
2
setup.py
2
setup.py
@ -10,7 +10,7 @@ NAME = 'bicycle-statistics'
|
||||
VERSION = '0.2.0'
|
||||
AUTHOR = 'Thomas Klaehn'
|
||||
EMAIL = 'tkl@blackfinn.de'
|
||||
PACKAGES = ['bicycle_statistics', 'gpx_parser', 'gpx2html', 'input_observer']
|
||||
PACKAGES = ['bicycle_statistics', 'gpx_parser', 'gpx2html']
|
||||
SCRIPTS = ['example-gpx-parser', 'bicycle-stat']
|
||||
|
||||
DAEMON_START_SCRIPT = os.path.join("/lib/systemd/system", "bicycle-stat.service")
|
||||
|
Loading…
Reference in New Issue
Block a user