diff --git a/django/didgeridoo/currencies/__init__.py b/django/didgeridoo/currencies/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django/didgeridoo/currencies/admin.py b/django/didgeridoo/currencies/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/django/didgeridoo/currencies/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/django/didgeridoo/currencies/apps.py b/django/didgeridoo/currencies/apps.py new file mode 100644 index 0000000..055501d --- /dev/null +++ b/django/didgeridoo/currencies/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class CurrenciesConfig(AppConfig): + name = 'currencies' diff --git a/django/didgeridoo/currencies/exchange_rates.py b/django/didgeridoo/currencies/exchange_rates.py new file mode 100644 index 0000000..ebbbb12 --- /dev/null +++ b/django/didgeridoo/currencies/exchange_rates.py @@ -0,0 +1,117 @@ +from datetime import datetime +import urllib.request +import xml.etree.ElementTree as ET + +today = datetime.now().strftime("%Y-%m-%d") + +""" this method calls a rss/XML Resource + of Currency's and parses it to our + needed exchange rate values. + The return is a dictionary carring + Key:Value pairs of new currencys. +""" + + +def get_exchange_rate(): + # During weekends there are no updates. + # To develop i need a testresource. + # In that case i comment the Online Resource block and uncomment the + # development Block... + # ~~~~~~~~~~~~~~~~~~~~~ + # Online Resource block: + # ~~~~~~~~~~~~~~~~~~~~~ + # SNB_URL = 'https://www.snb.ch/selector/de/mmr/exfeed/rss' + # urlsocket = urllib.request.urlopen(SNB_URL) + # root = ET.parse(urlsocket) + # root = ET.ElementTree(root) + + # ~~~~~~~~~~~~~~~~~~~~~ + # development block: + # ~~~~~~~~~~~~~~~~~~~~~ + root = ET.ElementTree(file='rss') + ns = {'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', + 'none': 'http://purl.org/rss/1.0/', + 'dc': 'http://purl.org/dc/elements/1.1/', + 'dcterms': 'http://purl.org/dc/terms/', + 'cb': 'http://www.cbwiki.net/wiki/index.php/Specification_1.2/' + } + # Pathvariables to XML Namespaces + none_path = 'none:item/' + rate_path = 'cb:statistics/cb:exchangeRate/' + observation_path = 'cb:statistics/cb:exchangeRate/cb:observation/' + # THE FILE DATE: + xml_datetime_string = root.find('none:channel/dcterms:created', ns).text + # because of few knowlede just trim end of string to avoid error + xml_datestring = xml_datetime_string.split('T')[0] + # parse string to date object: + xml_date = datetime.date(datetime.strptime(xml_datestring, "%Y-%m-%d")) + + for item in root.findall('none:item', ns): + # THE CURRENCY DATE: + datetime_str = item.find('dc:date', ns).text + # convert string to date object: + # https://stackoverflow.com/a/12282040/4061870 + date = datetime.strptime(''.join(datetime_str.rsplit(':', 1)), + "%Y-%m-%dT%H:%M:%S.%f%z").strftime("%Y-%m-%d") + # only the values of today are used so check for date: + if date == today: + title = item.find('none:title', ns).text + base_currency = item.find(rate_path + + 'cb:baseCurrency', ns).text + target_currency = item.find(rate_path + + 'cb:targetCurrency', ns).text + CHFvalue = float(item.find(observation_path + + 'cb:value', ns).text) + CHFvalue = float(CHFvalue) # convert to float + FOREIGNvalue = CHFvalue # copy to new value to have both. + unit = item.find(observation_path + 'cb:unit', ns).text + decimals = int(item.find(observation_path + + 'cb:decimals', ns).text) + # because it's dangerous to check for present, i check for none + # here and have to do something in there so i set the target to 0. + if item.find(observation_path + 'cb:unit_mult', ns) is None: + unit_mult = float("1.0") + else: + # shift left by 2 digits with "/" + # https://stackoverflow.com/questions/8362792/ + # because some currencys differ widly from CHF + unit_mult = item.find(observation_path + + 'cb:unit_mult', ns).text + # unit_mult defaults to '0' so we check for 8 decimal + # values (2..-6) they represent the fracton value to + # calculate the correct decimalpoint. + if unit_mult == '2': # thinking of Bitcoins + unit_mult = '0.01' + if unit_mult == '1': + unit_mult = '0.10' + if unit_mult == '-1': + unit_mult = '10' + if unit_mult == '-2': # Japan Yen + unit_mult = '100' + if unit_mult == '-3': + unit_mult = '1000' + if unit_mult == '-4': + unit_mult = '10000' + if unit_mult == '-5': + unit_mult = '100000' + if unit_mult == '-6': # indian rupies + unit_mult = '1000000' + unit_mult = float(unit_mult) # convert to float + # calculate the Currency to CHF: + FOREIGNvalue = 1 / CHFvalue + FOREIGNvalue *= unit_mult + CHFvalue = CHFvalue / unit_mult + # truncate it to decimal values provided by the xml: + FOREIGNvalue_round = round(FOREIGNvalue, 5) + # Print nice setup of all calculated currencys for Dev: + # print("date:", date, " 1 ", target_currency, " costs: ", + # CHFvalue, "CHF and 1 ", base_currency, " costs: ", + # FOREIGNvalue_round, target_currency) + exchange_rates = {target_currency: FOREIGNvalue_round} + # Print the Dictionary: + # print(exchange_rates) + return(exchange_rates) + else: + break + # for development its preferable to see that the for loop is done: + # print('no more fresh data!') diff --git a/django/didgeridoo/currencies/migrations/__init__.py b/django/didgeridoo/currencies/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django/didgeridoo/currencies/models.py b/django/didgeridoo/currencies/models.py new file mode 100644 index 0000000..829609d --- /dev/null +++ b/django/didgeridoo/currencies/models.py @@ -0,0 +1,20 @@ +from django.db import models +import exchange_rates + + +class ExchangeRate(models.Model): + name = models.CharField(max_length=200, unique=True) + exchange_rate_to_chf = models.FloatField(max_length=5) + + def __str__(self): + return self.name + + def exchange_rates(): + exchange_rates = currencies.get_exchange_rate() + + for i in exchange_rates: + if ExchangeRate.objects.filter( + name='exchange_rates_data[dictionary_value]'): + ExchangeRate.objects.filter( + name='exchange_rates_data[dictionary_key]', + exchange_rate_to_chf=exchange_rates.value).save() diff --git a/django/didgeridoo/currencies/tests.py b/django/didgeridoo/currencies/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/django/didgeridoo/currencies/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/django/didgeridoo/currencies/views.py b/django/didgeridoo/currencies/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/django/didgeridoo/currencies/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/django/didgeridoo/didgeridoo/settings.py b/django/didgeridoo/didgeridoo/settings.py index 682b4be..3b01f6e 100644 --- a/django/didgeridoo/didgeridoo/settings.py +++ b/django/didgeridoo/didgeridoo/settings.py @@ -39,7 +39,8 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', -] + 'currencies', + ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', diff --git a/django/didgeridoo/webshop/models.py b/django/didgeridoo/webshop/models.py index 185abd4..62fbca5 100644 --- a/django/didgeridoo/webshop/models.py +++ b/django/didgeridoo/webshop/models.py @@ -29,14 +29,6 @@ class ArticleStatus(models.Model): return self.name -class ExchangeRate(models.Model): - name = models.CharField(max_length=200, unique=True) - exchange_rate_to_chf = models.FloatField(max_length=5) - - def __str__(self): - return self.name - - # Create your models here. class Category(models.Model): name = models.CharField(max_length=200, unique=True)