mirror of
https://github.com/spiral-project/ihatemoney.git
synced 2025-05-05 12:41:49 +02:00
csv compatible import
This commit is contained in:
parent
d24efac10a
commit
e7d991ecc2
3 changed files with 24 additions and 7 deletions
|
@ -187,8 +187,7 @@ class ImportProjectForm(FlaskForm):
|
|||
"File",
|
||||
validators=[
|
||||
FileRequired(),
|
||||
"JSON",
|
||||
validators=[FileRequired(), FileAllowed(["json", "JSON"], "JSON only!")],
|
||||
FileAllowed(["json", "JSON", "csv", "CSV"], "Incorrect file format"),
|
||||
],
|
||||
description=_("Import previously exported JSON file"),
|
||||
)
|
||||
|
|
|
@ -2,7 +2,7 @@ import ast
|
|||
import csv
|
||||
from datetime import datetime, timedelta
|
||||
from enum import Enum
|
||||
from io import BytesIO, StringIO
|
||||
from io import BytesIO, StringIO, TextIOWrapper
|
||||
from json import JSONEncoder, dumps
|
||||
import operator
|
||||
import os
|
||||
|
@ -150,6 +150,21 @@ def list_of_dicts2csv(dict_to_convert):
|
|||
return csv_file
|
||||
|
||||
|
||||
def csv2list_of_dicts(csv_to_convert):
|
||||
"""Take a csv in-memory file and turns it into
|
||||
a list of dictionnaries
|
||||
"""
|
||||
csv_file = TextIOWrapper(csv_to_convert)
|
||||
reader = csv.DictReader(csv_file)
|
||||
result = []
|
||||
for r in reader:
|
||||
r["amount"] = float(r["amount"])
|
||||
r["payer_weight"] = float(r["payer_weight"])
|
||||
r["owers"] = [o.strip() for o in r["owers"].split(",")]
|
||||
result.append(r)
|
||||
return result
|
||||
|
||||
|
||||
class LoginThrottler:
|
||||
"""Simple login throttler used to limit authentication attempts based on client's ip address.
|
||||
When using multiple workers, remaining number of attempts can get inconsistent
|
||||
|
|
|
@ -58,6 +58,7 @@ from ihatemoney.models import Bill, LoggingMode, Person, Project, db
|
|||
from ihatemoney.utils import (
|
||||
LoginThrottler,
|
||||
Redirect303,
|
||||
csv2list_of_dicts,
|
||||
format_form_errors,
|
||||
get_members,
|
||||
list_of_dicts2csv,
|
||||
|
@ -451,6 +452,11 @@ def import_project():
|
|||
data = form.file.data
|
||||
if data.mimetype == "application/json":
|
||||
json_file = json.load(data.stream)
|
||||
elif data.mimetype == "text/csv":
|
||||
try:
|
||||
json_file = csv2list_of_dicts(data)
|
||||
except Exception as e:
|
||||
raise ValueError(_("Unable to parse CSV"))
|
||||
else:
|
||||
raise ValueError("Unsupported file type")
|
||||
|
||||
|
@ -554,10 +560,7 @@ def import_project():
|
|||
return redirect(url_for("main.list_bills"))
|
||||
except ValueError as e:
|
||||
flash(e.args[0], category="danger")
|
||||
return render_template(
|
||||
"edit_project.html",
|
||||
current_view="edit_project",
|
||||
)
|
||||
return redirect(url_for(".edit_project"))
|
||||
else:
|
||||
for component, errors in form.errors.items():
|
||||
flash(_(component + ": ") + ", ".join(errors), category="danger")
|
||||
|
|
Loading…
Reference in a new issue