diff --git a/django/didgeridoo/currencies/exchange_rates.py b/django/didgeridoo/currencies/exchange_rates.py index bb12c47..173de19 100644 --- a/django/didgeridoo/currencies/exchange_rates.py +++ b/django/didgeridoo/currencies/exchange_rates.py @@ -1,14 +1,15 @@ from datetime import datetime import urllib.request import xml.etree.ElementTree as ET +import datetime as dt -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. +""" +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. """ @@ -20,16 +21,17 @@ def get_exchange_rate(): # ~~~~~~~~~~~~~~~~~~~~~ # 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) + # 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') + root = ET.ElementTree(file='rss') # ~~~~~~~~~~~~~~~~~~~~~ + # Namespaces ns = {'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', 'none': 'http://purl.org/rss/1.0/', @@ -38,43 +40,45 @@ def get_exchange_rate(): '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")) + # today = datetime.now().strftime("%Y-%m-%d") + today = "2018-01-02" exchange_rates = {} + 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 # seams like snb striked the microsecond somewhere between Nov. and - # Dez. 2017 so maybe first check time type. "%Y-%m-%dT%H:%M:%S.%f%z" - date = datetime.strptime(''.join( - datetime_str.rsplit(':', 1)), - "%Y-%m-%dT%H:%M:%S%z").strftime( - "%Y-%m-%d") + # Dez. 2017 so maybe first check time type is with milliseconds: + try: + date = datetime.strptime(''.join( + datetime_str.rsplit(':', 1)), + "%Y-%m-%dT%H:%M:%S.%f%z").strftime( + "%Y-%m-%d") + except Exception as e: + print('%s (%s)' % (e, type(e))) + try: + date = datetime.strptime(''.join( + datetime_str.rsplit(':', 1)), + "%Y-%m-%dT%H:%M:%S%z").strftime( + "%Y-%m-%d") + except Exception as e: + print('%s (%s)' % (e, type(e))) + # Print dates for development: + # print("date:", date, "today:", today) # only the values of today are used so check for date in XML: 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) + value = float(item.find(observation_path + + 'cb:value', ns).text) + value = float(value) # convert to float + foreign_value = value # copy to new value to have both. # 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. + # here and have to do something in there so i set the target to 1. if item.find(observation_path + 'cb:unit_mult', ns) is None: unit_mult = float("1.0") else: @@ -104,21 +108,21 @@ def get_exchange_rate(): 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 + foreign_value = 1 / value + foreign_value *= unit_mult + value = value / unit_mult # truncate it to decimal values provided by the xml: - FOREIGNvalue_round = round(FOREIGNvalue, 5) + foreign_value_round = round(foreign_value, 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.update( - {target_currency: FOREIGNvalue_round}) + {target_currency: foreign_value_round}) # Print the Dictionary: # print(exchange_rates) else: break - return(exchange_rates, date) + return(exchange_rates, today) # for development its preferable to see that the for loop is done: # print('no more fresh data!') diff --git a/django/didgeridoo/currencies/templates/currencies/index.html b/django/didgeridoo/currencies/templates/currencies/index.html index bddcee2..d61c474 100644 --- a/django/didgeridoo/currencies/templates/currencies/index.html +++ b/django/didgeridoo/currencies/templates/currencies/index.html @@ -6,20 +6,24 @@

Currencies in CHF

{% if currency_list %} - + +

{{ message }}


@@ -32,11 +36,81 @@ {% endfor %} +
+ + raw_data + {% else %}

- Something whent wrong, no currencies are available. + Something whent totaly wrong.

{% endif %} +
+ today + +
+ unique_dates_list + +
+ unique_currencies_list + +
+ count_date + +
+ count_currencies + +
+ currencies_list + + currency_dict + diff --git a/django/didgeridoo/currencies/views.py b/django/didgeridoo/currencies/views.py index 1128eab..b2c2b63 100644 --- a/django/didgeridoo/currencies/views.py +++ b/django/didgeridoo/currencies/views.py @@ -4,23 +4,76 @@ from currencies import exchange_rates def currencies(request): - # return HttpResponse("exchange_rates") - raw_data, date = exchange_rates.get_exchange_rate() - message = "" + # this function fetches the data from exchange_rates.py + # evaluates if the values are already stored and + # prepares the view all dynamicaly. + # It can grow in terms of more Currencies over time automaticaly. + raw_data, today = exchange_rates.get_exchange_rate() + message_no = "Already querried today: " + message_yes = " Updated successfully: " for currency, rate in raw_data.items(): - if ExchangeRate.objects.filter(date=date): - message = "already querried today" + if ExchangeRate.objects.filter(date=today, name=currency)[:1]: + message_no += currency + ", " else: e = ExchangeRate.objects.create( name=currency, exchange_rate_to_chf=rate, - date=date + date=today ) e.save() - message = "updated successfully" - currency_list = ExchangeRate.objects.all() + message_yes += currency + ", " + + # prepare messages: + message_no = message_no[::-1] # invert the string + message_no = message_no.replace(",", "!", 1) # replace first , with ! + message_no = message_no[::-1] # invert the string back + message_yes = message_yes[::-1] # invert the string + message_yes = message_yes.replace(",", "!", 1) # replace first , with ! + message_yes = message_yes[::-1] # invert the string back + + if len(message_no) > 24 and len(message_yes) > 23: + message = message_no + message_yes + elif len(message_no) > 24: + message = message_no + elif len(message_yes) > 23: + message = message_yes + else: + message = "something whent wrong" + + # prepare data to be displayed in a html table: + # https://stackoverflow.com/questions/8749158/removing-duplicates-from-dictionary#8749473 + # atomar_dates + # A: https://stackoverflow.com/questions/37205793/django-values-list-vs-values#37205928 + # B: https://stackoverflow.com/questions/6521892/how-to-access-a-dictionary-key-value-present-inside-a-list + unique_dates_list = ExchangeRate.objects.values_list('date', flat=True).distinct() + # atomar_currenies + unique_currencies_list = ExchangeRate.objects.values_list('name', flat=True).distinct() + # search for currencies in a date and apend them to the list + currency_list = [] + count_date = 0 + count_currencies = 0 + for unique_date in unique_dates_list: + count_date += 1 + currency_dict = {} + currency_dict['date'] = unique_date + for unique_currency in unique_currencies_list: + count_currencies += 1 + try: + temp = ExchangeRate.objects.filter(date=unique_date, name=unique_currency).values() #A + exchange_rate_to_chf = temp[0]['exchange_rate_to_chf'] + currency_dict = currency_dict.update({unique_currency: exchange_rate_to_chf}) #B + except Exception as e: + print('%s (%s)' % (e, type(e))) + currency_list.append(currency_dict) + assert False return render(request, 'currencies/index.html', {'currency_list': currency_list, - 'date': date, + 'raw_data': raw_data, + 'today': today, + 'unique_dates_list': unique_dates_list, + 'unique_currencies_list': unique_currencies_list, + 'count_date': count_date, + 'count_currencies': count_currencies, + 'currency_dict': currency_dict, 'message': message}) diff --git a/django/didgeridoo/didgeridoo/settings.py b/django/didgeridoo/didgeridoo/settings.py index 61bc7e1..f142821 100644 --- a/django/didgeridoo/didgeridoo/settings.py +++ b/django/didgeridoo/didgeridoo/settings.py @@ -23,7 +23,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) SECRET_KEY = '(#4#-$$&mx7(%q+6&&@-c&g%i0dc4)zfks1%sy8b%lsxspou&%' # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = False +DEBUG = True ALLOWED_HOSTS = [ 'localhost', diff --git a/django/didgeridoo/rss b/django/didgeridoo/rss index af36b76..009f10e 100644 --- a/django/didgeridoo/rss +++ b/django/didgeridoo/rss @@ -37,7 +37,7 @@ CH: 1.3081 CHF = 1 GBP 2017-11-27 Tägliche Kurse (11:00)https://www.snb.ch1 GBP = 1.3081 CHF (Tägliche Kurse (11:00); 2017-11-27T12:16:53.767+01:00) - 2017-12-19T12:16:53.767+01:00 + 2018-01-02T12:16:53.767+01:00de @@ -66,7 +66,7 @@ CH: 0.8813 CHF = 100 JPY 2017-11-27 Tägliche Kurse (11:00) https://www.snb.ch 100 JPY = 0.8813 CHF (Tägliche Kurse (11:00); 2017-11-27T12:16:53.760+01:00) - 2017-12-19T12:16:53.760+01:00 + 2018-01-02T12:16:53.760+01:00 de @@ -96,7 +96,7 @@ CH: 1.1697 CHF = 1 EUR 2017-11-27 Tägliche Kurse (11:00) https://www.snb.ch 1 EUR = 1.1697 CHF (Tägliche Kurse (11:00); 2017-11-27T12:16:53.750+01:00) - 2017-12-19T12:16:53.750+01:00 + 2018-01-02T12:16:53.750+01:00 de @@ -125,7 +125,7 @@ CH: 0.9803 CHF = 1 USD 2017-11-27 Tägliche Kurse (11:00) https://www.snb.ch 1 USD = 0.9803 CHF (Tägliche Kurse (11:00); 2017-11-27T12:16:53.737+01:00) - 2017-11-29T12:16:53.737+01:00 + 2018-01-02T12:16:53.737+01:00 de