Skip to content

Commit

Permalink
Allow to export new data
Browse files Browse the repository at this point in the history
  • Loading branch information
armicron committed Feb 8, 2017
1 parent 03b0350 commit ad7e783
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 0 deletions.
39 changes: 39 additions & 0 deletions octoprint_printhistory/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ def exportHistoryData(self, exportType):
import flask
import csv
import StringIO
import re
from utils import namedtuple_with_defaults, prepare_dict, load_json, rename_duplicates

history_dict = self._getHistoryDict()

Expand All @@ -33,6 +35,43 @@ def exportHistoryData(self, exportType):
response = flask.make_response(si.getvalue())
response.headers["Content-type"] = "text/csv"
response.headers["Content-Disposition"] = "attachment; filename=octoprint_print_history_export.csv"
elif exportType == 'csv_extra':
fields = ["fileName", "timestamp", "success", "printTime", "filamentLength", "filamentVolume"]
unused_fields = ["spool", "user", "note", "id", "parameters"]
csv_header = set(fields)

for historyDetails in history_dict:
parameters = load_json(historyDetails, "parameters")
csv_header |= set(parameters.keys())

csv_header = map(lambda x: x.replace(" ", "_"), csv_header)
csv_header = rename_duplicates(fields, csv_header, prefix="g")
rearranged_header = fields[:]
for column in csv_header:
if column not in headers:
rearranged_header.append(column)
csv_header = rearranged_header

ParametersRow = namedtuple_with_defaults('TableRow', csv_header)
writer = csv.writer(si, quoting=csv.QUOTE_ALL)
writer.writerow(csv_header)
for historyDetails in history_dict:
parameters = load_json(historyDetails, "parameters")
historyDetails.update(parameters)
for key in unused_fields:
historyDetails.pop(key)
for key in ["Plastic volume", "Plastic weight", "Filament length"]:
if historyDetails.get(key, None):
historyDetails[key] = re.search(r"[\d\.]*", historyDetails[key]).group(0)
if historyDetails.get("Build time", None):
match = re.match(r"(\d+) hours (\d+) minutes", historyDetails.get("Build time", None))
historyDetails["Build time"] = (int(match.group(1)) * 60 + int(match.group(2))) * 60
parameters_row = ParametersRow(**prepare_dict(historyDetails))
writer.writerow([getattr(parameters_row, field) for field in parameters_row._fields])

response = flask.make_response(si.getvalue())
response.headers["Content-type"] = "text/csv"
response.headers["Content-Disposition"] = "attachment; filename=octoprint_print_history(extra)_export.csv"
elif exportType == 'excel':
import xlsxwriter

Expand Down
1 change: 1 addition & 0 deletions octoprint_printhistory/templates/printhistory_tab.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ Refresh <a href="#" data-bind="click: function() { requestData({force: true}); }
<div style="float: left; width: 50%">
<h1>Export as</h1>
<a href="#" data-bind="attr: {href: $root.export('csv'), css: {disabled: !$root.export('csv')}}">CSV</a> |
<a href="#" data-bind="attr: {href: $root.export('csv_extra'), css: {disabled: !$root.export('csv_extra')}}">CSV Extra</a> |
<a href="#" data-bind="attr: {href: $root.export('excel'), css: {disabled: !$root.export('excel')}}">Excel</a>
<!--
<a href="#" data-bind="attr: {href: $root.export('pdf'), css: {disabled: !$root.export('pdf')}}">PDF</a>
Expand Down
45 changes: 45 additions & 0 deletions octoprint_printhistory/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/python
import collections
import json


def prepare_dict(dictionary):
for key in dictionary.keys():
if key.count(" ") > 0:
new_key = key.replace(" ", "_")
dictionary[new_key] = dictionary.pop(key)
return dictionary

def rename_duplicates(immutable, mutable, prefix):
"""
Add prefix to elements of `mutable` if they are in `immutable`.
:param immutable: list of strings
:param mutable: list of strings
:param prefix: string
:return: list with renamed elements
"""
for value in mutable:
if value in immutable:
mutable[mutable.index(value)] = str(prefix) + value
return mutable

def namedtuple_with_defaults(typename, field_names, default_values=()):
"""
http://stackoverflow.com/questions/11351032/named-tuple-and-optional-keyword-arguments
"""
T = collections.namedtuple(typename, field_names)
T.__new__.__defaults__ = (None,) * len(T._fields)
if isinstance(default_values, collections.Mapping):
prototype = T(**default_values)
else:
prototype = T(*default_values)
T.__new__.__defaults__ = tuple(prototype)
return T

def load_json(dictionary, key):
parameters_json = dictionary.get(key)
try:
parameters = json.loads(parameters_json)
except ValueError:
parameters = {}
return parameters

0 comments on commit ad7e783

Please sign in to comment.