コード例 #1
0
ファイル: routes.py プロジェクト: fund3/thewarden
def importcsv():

    form = ImportCSV()

    if request.method == "POST":

        if form.validate_on_submit():
            if form.submit.data:
                if form.csvfile.data:
                    test_file = "thewarden/dailydata/test.csv"
                    filename = os.path.join(current_path(), test_file)
                    os.makedirs(os.path.dirname(filename), exist_ok=True)

                    filename = "thewarden/dailydata/" + form.csvfile.data.filename
                    filename = os.path.join(current_path(), filename)
                    form.csvfile.data.save(filename)

                else:
                    filename = Config.LOCAL_TRADES_PATH
                csv_reader = open(filename, "r", encoding="utf-8")
                csv_reader = csv.DictReader(csv_reader)
                csvfile = form.csvfile.data
                return render_template(
                    "importcsv.html",
                    title="Import CSV File",
                    form=form,
                    csv=csv_reader,
                    csvfile=csvfile,
                    filename=filename,
                )
    if request.method == "GET":
        filename = request.args.get("f")
        if filename:
            importcsvfile(filename)

    return render_template("importcsv.html",
                           title="Import CSV File",
                           form=form)
コード例 #2
0
def exportcsv():
    transactions = Trades.query.filter_by(
        user_id=current_user.username).order_by(Trades.trade_date)

    if transactions.count() == 0:
        return render_template("empty.html")

    filename = ("thewarden/dailydata/" + current_user.username + "_" +
                datetime.now().strftime("%Y%m%d") + ".csv")
    filename = os.path.join(current_path(), filename)
    os.makedirs(os.path.dirname(filename), exist_ok=True)

    with open(filename, "w") as f:

        fnames = [
            "TimeStamp",
            "Account",
            "Operator",
            "Asset",
            "Quantity",
            "Price",
            "Fee",
            "Cash_Value",
            "Notes",
            "trade_reference_id",
        ]
        writer = csv.DictWriter(f, fieldnames=fnames)

        writer.writeheader()
        for item in transactions:
            writer.writerow({
                "TimeStamp": item.trade_date,
                "Account": item.trade_account,
                "Operator": item.trade_operation,
                "Asset": item.trade_asset_ticker,
                "Quantity": item.trade_quantity,
                "Price": item.trade_price,
                "Fee": item.trade_fees,
                "Cash_Value": item.cash_value,
                "Notes": item.trade_notes,
                "trade_reference_id": item.trade_reference_id,
            })

    return send_file(filename, as_attachment=True)
コード例 #3
0
def fxsymbol(context, fx, output='symbol'):
    # Gets an FX 3 letter symbol and returns the HTML symbol
    # Sample outputs are:
    # "EUR": {
    # "symbol": "",
    # "name": "Euro",
    # "symbol_native": "",
    # "decimal_digits": 2,
    # "rounding": 0,
    # "code": "EUR",
    # "name_plural": "euros"
    try:
        from thewarden.users.utils import current_path
        filename = os.path.join(current_path(),
                                'static/json_files/currency.json')
        with open(filename) as fx_json:
            fx_list = json.load(fx_json, encoding='utf-8')
        out = fx_list[fx][output]
    except Exception:
        out = fx
    return (out)
コード例 #4
0
def importcsv():

    form = ImportCSV()

    if request.method == "POST":

        if form.validate_on_submit():
            if form.submit.data:
                if form.csvfile.data:
                    test_file = "thewarden/dailydata/test.csv"
                    filename = os.path.join(current_path(), test_file)
                    os.makedirs(os.path.dirname(filename), exist_ok=True)

                    filename = "thewarden/dailydata/" + form.csvfile.data.filename
                    filename = os.path.join(current_path(), filename)
                    form.csvfile.data.save(filename)

                    csv_reader = open(filename, "r", encoding="utf-8")
                    csv_reader = csv.DictReader(csv_reader)
                    csvfile = form.csvfile.data

                return render_template(
                    "importcsv.html",
                    title="Import CSV File",
                    form=form,
                    csv=csv_reader,
                    csvfile=csvfile,
                    filename=filename,
                )
    if request.method == "GET":
        filename = request.args.get("f")
        if filename:
            csv_reader = open(filename, "r", encoding="utf-8")
            # csv_reader = csv.DictReader(csv_reader)

            errors = 0
            errorlist = []
            a = 0  # skip first line where field names are

            accounts = AccountInfo.query.filter_by(
                user_id=current_user.username).order_by(
                    AccountInfo.account_longname)

            for line in csv_reader:
                if a != 0:
                    items = line.split(",")
                    random_hex = secrets.token_hex(21)

                    # Check if there is any data on this line:
                    empty = True
                    for l in range(0, 10):
                        try:
                            if items[l] != "":
                                empty = False
                        except IndexError:
                            pass
                    if empty:
                        continue

                    # import TimeStamp Field
                    try:
                        tradedate = parser.parse(items[0])
                    except ValueError:
                        tradedate = datetime.now()
                        errors = errors + 1
                        errorlist.append(f"missing date on line: {a}")

                    # Check the Operation Type
                    try:
                        if "B" in items[2]:
                            qop = 1
                            operation = "B"
                        elif "S" in items[2]:
                            qop = -1
                            operation = "S"
                        elif "D" in items[2]:
                            qop = 1
                            operation = "D"
                        elif "W" in items[2]:
                            qop = -1
                            operation = "W"
                        else:
                            qop = 0
                            operation = "X"
                            errors = errors + 1
                            errorlist.append(f"missing operation on line {a}")
                    except IndexError:
                        qop = 0
                        operation = "X"
                        errors = errors + 1
                        errorlist.append(f"missing operation on line {a}")

                    # Import Quantity
                    try:
                        if items[4].replace(" ", "") != "":
                            quant = abs(cleancsv(items[4])) * qop
                        else:
                            quant = 0
                    except ValueError:
                        quant = 0
                        errors = errors + 1
                        errorlist.append(
                            f"Quantity error on line {a} - quantity \
                            {items[4]} could not be converted")

                    # Import Price
                    try:
                        if items[5].replace(" ", "") != "":
                            price = cleancsv(items[5])
                        else:
                            price = 0
                    except ValueError:
                        price = 0
                        errors = errors + 1
                        errorlist.append(f"Price error on line {a} - price \
                            {items[5]} could not be converted")

                    # Import Fees
                    try:
                        if items[6].replace(" ", "").replace("\n", "") != "":
                            fees = cleancsv(items[6])
                        else:
                            fees = 0
                    except ValueError:
                        fees = 0
                        errors = errors + 1
                        errorlist.append(
                            f"error #{errors}: Fee error on line {a} - Fee --\
                            {items[6]}-- could not be converted")

                    # Import Notes
                    try:
                        notes = items[8]
                    except IndexError:
                        notes = ""

                    # Import Account
                    try:
                        account = items[1]
                    except ValueError:
                        account = ""
                        errors = errors + 1
                        errorlist.append(f"Missing account on line {a}")

                    # Import Asset Symbol
                    try:
                        ticker = items[3].replace(" ", "")
                        if ticker != "USD":
                            listcrypto = listofcrypto.query.filter_by(
                                symbol=ticker)
                            if listcrypto is None:
                                errors = errors + 1
                                errorlist.append(
                                    f"ticker {ticker} in line {a} \
                                    imported but not found in pricing list")

                    except ValueError:
                        ticker = ""
                        errors = errors + 1
                        errorlist.append(f"Missing ticker on line {a}")

                    # Find Trade Reference, if none, assign one
                    try:
                        tradeid = items[9]
                    except (ValueError, IndexError):
                        random_hex = secrets.token_hex(21)
                        tradeid = random_hex

                    # Import Cash Value - if none, calculate
                    try:
                        if items[7].replace(" ", "").replace("\n", "") != "":
                            cashvalue = cleancsv(items[7])
                        else:
                            cashvalue = ((price) * (quant)) + fees
                    except ValueError:
                        cashvalue = 0
                        errors = errors + 1
                        errorlist.append(
                            f"error #{errors}: Cash_Value error on line \
                             {a} - Cash_Value --{items[7]}-- could not \
                             be converted")

                    trade = Trades(
                        user_id=current_user.username,
                        trade_date=tradedate,
                        trade_account=account,
                        trade_asset_ticker=ticker,
                        trade_quantity=quant,
                        trade_operation=operation,
                        trade_price=price,
                        trade_fees=fees,
                        trade_notes=notes,
                        cash_value=qop * cashvalue,
                        trade_reference_id=tradeid,
                    )
                    db.session.add(trade)
                    db.session.commit()
                    regenerate_nav()

                    # Check if current account is in list, if not, include

                    curacc = accounts.filter_by(
                        account_longname=account).first()

                    if not curacc:
                        account = AccountInfo(user_id=current_user.username,
                                              account_longname=account)
                        db.session.add(account)
                        db.session.commit()

                a = a + 1

            # re-generates the NAV on the background
            # re-generates the NAV on the background - delete First
            # the local NAV file so it's not used.
            usernamehash = hashlib.sha256(
                current_user.username.encode("utf-8")).hexdigest()
            filename = "thewarden/nav_data/" + usernamehash + ".nav"
            filename = os.path.join(current_path(), filename)
            logging.info(f"[newtrade] {filename} marked for deletion.")
            # Since this function can be run as a thread,
            # it's safer to delete the current NAV file if it exists.
            # This avoids other tasks reading the local file which
            # is outdated
            try:
                os.remove(filename)
                logging.info("[importcsv] Local NAV file deleted")
            except OSError:
                logging.info("[importcsv] Local NAV file not found" +
                             " for removal - continuing")
            generatenav_thread = threading.Thread(target=generatenav,
                                                  args=(current_user.username,
                                                        True))
            logging.info("[importcsv] Change to database - generate NAV")
            generatenav_thread.start()

            if errors == 0:
                flash("CSV Import successful", "success")
            if errors > 0:
                logging.error("Errors found. Total of ", errors)

                flash(
                    "CSV Import done but with errors\
                 - CHECK TRANSACTION LIST",
                    "danger",
                )
                for error in errorlist:
                    flash(error, "warning")

            return redirect(url_for("main.home"))

    return render_template("importcsv.html",
                           title="Import CSV File",
                           form=form)