diff --git a/apps/transactions/forms.py b/apps/transactions/forms.py index 8fdabad..3da3c0a 100644 --- a/apps/transactions/forms.py +++ b/apps/transactions/forms.py @@ -24,3 +24,13 @@ class TransactionForm(forms.ModelForm): 'fiat_currency': forms.Select(choices = fiat_currencies), 'crypto_currency': forms.Select(choices = crypto_currencies), } + + +class ImportForm(forms.Form): + api_key = forms.CharField(label='API Key', widget=forms.PasswordInput, max_length=100) + api_secret = forms.CharField(label='API Secret', widget=forms.PasswordInput, max_length=100) + YEAR_CHOICES = [] + now = datetime.datetime.now() + for y in range(2000,now.year+1): + YEAR_CHOICES.append(y) + start_date = forms.DateField(label='Start Date', widget=forms.SelectDateWidget(years=YEAR_CHOICES), initial=datetime.datetime(year=now.year, month=1, day=1)) diff --git a/apps/transactions/importbtcde.py b/apps/transactions/importbtcde.py new file mode 100644 index 0000000..39ac107 --- /dev/null +++ b/apps/transactions/importbtcde.py @@ -0,0 +1,55 @@ +from django.db import connection +from apps.transactions.models import Transaction +from decimal import Decimal +import datetime +import btcde + +class ImportBtcDe: + def Import(self, apiKey, apiSecret, StartDate, Owner): + + conn = btcde.Connection(apiKey, apiSecret) + page=1 + while True: + response = conn.showMyTrades(date_start=StartDate.isoformat()+"T00:00:00+00:00", state=1,page=page) + trades = response.get('trades') + if not trades: + raise Exception(('%s' % (response,))) + raise Exception(('%s %s %s ' % (apiKey,apiSecret, StartDate.isoformat()))) + break + for trade in trades: + + # TODO: check if this trade_id does not exist in the database for this user + with connection.cursor() as cursor: + sql = """SELECT trade_id FROM `transaction` WHERE trade_id=%s and owner_id=%s""" + cursor.execute(sql, [trade['trade_id'], Owner.id]) + if cursor.rowcount > 0: + continue + + # import the trade + t = Transaction() + t.trade_id = trade['trade_id'] + supported_cryptos = ['BTC', 'BCH', 'ETH'] + for c in supported_cryptos: + if trade['trading_pair'].upper().startswith(c): + t.crypto_currency = c + supported_fiat = ['USD', 'EUR'] + for f in supported_fiat: + if trade['trading_pair'].upper().endswith(f): + t.fiat_currency = f + t.owner = Owner + t.amount_before_fee = Decimal(trade['amount']) + t.amount_after_fee = Decimal(trade['amount']) - Decimal(trade['fee_currency']) + t.amount = Decimal(trade['volume']) + if trade['type'] == 'sell': + t.amount -= Decimal(trade['fee_eur']) + t.amount_before_fee *= -1 + t.amount_after_fee *= -1 + t.amount *= -1 + t.exchange_rate = trade['price'] + t.date_valid = trade['created_at'] + t.save() + + if page >= response.get('page')['last']: + break + page += 1 + diff --git a/apps/transactions/migrations/0002_transaction_trade_id.py b/apps/transactions/migrations/0002_transaction_trade_id.py new file mode 100644 index 0000000..563b0cd --- /dev/null +++ b/apps/transactions/migrations/0002_transaction_trade_id.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.5 on 2021-02-13 21:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('transactions', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='transaction', + name='trade_id', + field=models.CharField(default='MANUAL', max_length=20), + ), + ] diff --git a/apps/transactions/models.py b/apps/transactions/models.py index f34f74e..d4a82d5 100644 --- a/apps/transactions/models.py +++ b/apps/transactions/models.py @@ -3,6 +3,7 @@ from django.contrib.auth.models import User # Create your models here. class Transaction(models.Model): + trade_id = models.CharField(max_length=20, default='MANUAL') crypto_currency = models.CharField(max_length=10) owner = models.ForeignKey(User, on_delete=models.CASCADE) amount_before_fee = models.DecimalField(max_digits=24, decimal_places=10) diff --git a/apps/transactions/templates/add.html b/apps/transactions/templates/add.html index 2285d80..faeb569 100644 --- a/apps/transactions/templates/add.html +++ b/apps/transactions/templates/add.html @@ -28,6 +28,13 @@ +
+ +
+ {{ form.trade_id }} +
+
+
diff --git a/apps/transactions/templates/import.html b/apps/transactions/templates/import.html new file mode 100644 index 0000000..5b27a83 --- /dev/null +++ b/apps/transactions/templates/import.html @@ -0,0 +1,63 @@ +{% extends 'base.html' %} + +{% block content %} +
+
+ {% csrf_token %} +
+
+{% if form.errors %} + {% for field in form %} + {% for error in field.errors %} +
+ {{field.name}}: {{ error|escape }} +
+ {% endfor %} + {% endfor %} + {% for error in form.non_field_errors %} +
+ {{ error|escape }} +
+ {% endfor %} +{% endif %} + +
+ +
+

Import Transactions from Bitcoin.de API

+

You need an API Key with Show permissions, and with access from only this IP: {{my_ip}}

+
+
+ +
+ +
+ {{ form.api_key }} +
+
+ +
+ +
+ {{ form.api_secret }} +
+
+ +
+ +
+ {{ form.start_date }} +
+
+ +
+ +
+ +
+
+ +
+
+
+{% endblock %} diff --git a/apps/transactions/templates/show.html b/apps/transactions/templates/show.html index dd0909b..686c339 100644 --- a/apps/transactions/templates/show.html +++ b/apps/transactions/templates/show.html @@ -5,6 +5,8 @@
Add New Record

+
Import from Bitcoin.de
+
diff --git a/apps/transactions/views.py b/apps/transactions/views.py index 133a5ad..22f417b 100644 --- a/apps/transactions/views.py +++ b/apps/transactions/views.py @@ -1,7 +1,10 @@ from django.shortcuts import render, redirect from django.contrib.auth.decorators import login_required from apps.transactions.forms import TransactionForm +from apps.transactions.forms import ImportForm from apps.transactions.models import Transaction +from apps.transactions.importbtcde import ImportBtcDe +import socket @login_required def add(request): @@ -20,6 +23,23 @@ def add(request): form = TransactionForm() return render(request,'add.html',{'form':form}) +@login_required +def importbtcde(request): + form = ImportForm() + if request.method == "POST": + form = ImportForm(request.POST) + if form.is_valid(): +# try: + importBtcDe = ImportBtcDe() +# importBtcDe.Import(request.POST['api_key'], request.POST['api_secret'], request.POST['start_date'], request.user.id) + importBtcDe.Import(form.cleaned_data.get('api_key'), form.cleaned_data.get('api_secret'), form.cleaned_data.get('start_date'), request.user) + return redirect('/transactions/show') +# except: +# pass + hostname = socket.gethostname() + my_ip = socket.gethostbyname(hostname) + return render(request,'import.html',{'form':form, 'my_ip': my_ip}) + @login_required def show(request): if 'crypto' in request.GET: diff --git a/requirements.txt b/requirements.txt index 677d463..cb693c9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ django django-registration matplotlib - +btcde diff --git a/walletmonitor/urls.py b/walletmonitor/urls.py index d125c18..6114574 100644 --- a/walletmonitor/urls.py +++ b/walletmonitor/urls.py @@ -29,6 +29,7 @@ urlpatterns = [ path('monitor/', monitor_views.monitor), path('graph/', monitor_views.graph), path('transactions/add', tr_views.add), + path('transactions/import', tr_views.importbtcde), path('transactions/show', tr_views.show), path('transactions/edit/', tr_views.edit), path('transactions/update/', tr_views.update),