added new generic rss fetch and parse functions and setup to store not only today value but all values in file and update if new are available.

This commit is contained in:
Ivan Hörler 2018-01-21 21:31:26 +01:00
parent b53f52cac1
commit dba76057b3
6 changed files with 184 additions and 190 deletions

View File

@ -11,61 +11,30 @@ Key:Value pairs of new currencys.
""" """
def get_exchange_rate(): def get_rss(url):
# zweitweise kann die resource nicht geladen werden.
# https://stackoverflow.com/a/43523497/4061870
# 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:
# ~~~~~~~~~~~~~~~~~~~~~
today = datetime.now().strftime("%Y-%m-%d")
SNB_URL = 'https://www.snb.ch/selector/de/mmr/exfeed/rss'
urlsocket = '' urlsocket = ''
try: try:
urlsocket = urllib.request.urlopen(SNB_URL) urlsocket = urllib.request.urlopen(url)
return(urlsocket)
except urllib.error.URLError as e: except urllib.error.URLError as e:
print('err: urllib.request.urlopen: ', e.reason) print('err: urllib.request.urlopen: ', e.reason)
def parse_rss(urlsocket):
if urlsocket: if urlsocket:
root = ET.parse(urlsocket) root = ET.parse(urlsocket)
root = ET.ElementTree(root) rss_tree = ET.ElementTree(root)
# ~~~~~~~~~~~~~~~~~~~~~ return(rss_tree)
# development block:
# ~~~~~~~~~~~~~~~~~~~~~
# today = "2018-01-08"
# try:
# root = ET.ElementTree(file='rss')
# except Exception as e:
# print('exchange_rates.py_urlsocket failed %s (
# %s) on date: %s for %s'
# % (e, type(e), root))
# ~~~~~~~~~~~~~~~~~~~~~
# Namespaces
ns = {'rdf': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', def get_exchange_rate(rss_tree, ns):
'none': 'http://purl.org/rss/1.0/', # Pathvariables to XML Namespaces with
'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
rate_path = 'cb:statistics/cb:exchangeRate/' rate_path = 'cb:statistics/cb:exchangeRate/'
observation_path = 'cb:statistics/cb:exchangeRate/cb:observation/' observation_path = 'cb:statistics/cb:exchangeRate/cb:observation/'
exchange_rates = {} exchange_rates = []
for item in root.findall('none:item', ns):
# for eatch item n the list we grab the release date
# to evaluate if its fresh data or old:
# THE CURRENCY DATE: for item in rss_tree.findall('none:item', ns):
datetime_str = item.find('dc:date', ns).text 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 is with milliseconds:
try: try:
date = datetime.strptime(''.join( date = datetime.strptime(''.join(
datetime_str.rsplit(':', 1)), datetime_str.rsplit(':', 1)),
@ -82,10 +51,6 @@ def get_exchange_rate():
except Exception as e: except Exception as e:
print('%s (%s)' % (e, type(e))) print('%s (%s)' % (e, type(e)))
continue continue
# 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:
# now search for the currency exchange rate: # now search for the currency exchange rate:
target_currency = item.find(rate_path + target_currency = item.find(rate_path +
'cb:targetCurrency', ns).text 'cb:targetCurrency', ns).text
@ -135,10 +100,10 @@ def get_exchange_rate():
# print("date:", date, " 1 ", target_currency, " costs: ", # print("date:", date, " 1 ", target_currency, " costs: ",
# CHFvalue, "CHF and 1 ", base_currency, " costs: ", # CHFvalue, "CHF and 1 ", base_currency, " costs: ",
# FOREIGNvalue_round, target_currency) # FOREIGNvalue_round, target_currency)
exchange_rates.update( data = [{'date': date,
{target_currency: foreign_value_round}) 'currency': target_currency,
'exchangerate': foreign_value_round}]
exchange_rates.append(data)
# Print the Dictionary: # Print the Dictionary:
# print(exchange_rates) print(exchange_rates)
else: return(exchange_rates)
continue
return(exchange_rates, today)

View File

@ -6,6 +6,7 @@ register = template.Library()
@register.filter() @register.filter()
def boldcoffee(value): def boldcoffee(value):
# currency_of_customer = request.session['currency']
return '%s !!gefiltert!!' % value return '%s !!gefiltert!!' % value
# excample filter: {{ article.price_in_chf|boldcoffee }} # excample filter: {{ article.price_in_chf|boldcoffee }}

View File

@ -1,5 +1,5 @@
from django.shortcuts import render from django.shortcuts import render
import datetime from datetime import datetime
from django.views.generic.edit import UpdateView from django.views.generic.edit import UpdateView
from django.core.urlresolvers import reverse_lazy from django.core.urlresolvers import reverse_lazy
from currencies.models import (ExchangeRate, from currencies.models import (ExchangeRate,
@ -25,48 +25,74 @@ def currency_update(request):
def currencies(request): def currencies(request):
# this function fetches the data from exchange_rates.py
# evaluates if the values are already stored and """this function fetches the data from swiss national bank
# prepares the view all dynamicaly. evaluates if the values are already stored and
# It can grow in terms of more Currencies over time automaticaly. prepares a view all dynamicaly.
today = '' It can grow in terms of more Currencies over time automaticaly."""
raw_data = []
# Namespaces
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/'
}
SNB_URL = 'https://www.snb.ch/selector/de/mmr/exfeed/rss'
try: try:
raw_data, today = exchange_rates.get_exchange_rate() urlsocket = exchange_rates.get_rss(SNB_URL)
except Exception as e: except Exception as e:
print('views raw_data: ', raw_data, 'error:', e) # assert False print('currencies/views get_rss(): ', urlsocket, 'error:', e)
message_no = "Already querried today: " try:
rss_tree = exchange_rates.parse_rss(urlsocket)
except Exception as e:
print('currencies/views parse_rss(): ', rss_tree, 'error:', e)
try:
raw_data = exchange_rates.get_exchange_rate(rss_tree, ns)
except Exception as e:
print('currencies/views get_exchange_rate(): ', raw_data, 'error:', e)
today = datetime.now().strftime("%Y-%m-%d")
message_no = "Already querried: "
length_of_message_no = len(message_no)
message_yes = " Updated successfully: " message_yes = " Updated successfully: "
length_of_message_yes = len(message_yes)
# raw_data can be empty. In this case skip: # raw_data can be empty. In this case skip:
if raw_data: if raw_data:
# if raw_data is not empty iterate over items in it: for one_obj_of_list in raw_data:
for currency, rate in raw_data.items(): for exchange_rate_of_one_day in one_obj_of_list:
date = exchange_rate_of_one_day['date']
currency = exchange_rate_of_one_day['currency']
exchangerate = exchange_rate_of_one_day['exchangerate']
# check for already existing exrates per day and add # check for already existing exrates per day and add
# to message that its already been saved. # to message that its already been saved.
if ExchangeRate.objects.filter( if ExchangeRate.objects.filter(
date__date=today, date__date=date,
name__name=currency): name__name=currency):
message_no += currency + ", " message_no += currency + ' on ' + date + ", "
else: else:
if ExchangeRate_date.objects.filter(date=today)[:1]: if ExchangeRate_date.objects.filter(date=date)[:1]:
# if data and currency is not yet present, save it. # if data and currency is not yet present, save it.
try: try:
# A: https://stackoverflow.com/a/27802801/4061870 # A: https://stackoverflow.com/a/27802801/4061870
# lustigerweise gibt .values() den value und die id # lustigerweise gibt .values() den value und die id
# zurück. Ohne .values() gibts nur den "value" # zurück. Ohne .values() gibts nur den "value"
date_dict = ExchangeRate_date.objects.filter( date_dict = ExchangeRate_date.objects.filter(
date=today).values() date=date).values()
except Exception as e: except Exception as e:
print('exdate_exists %s (%s) on %s' print('currencies/views/exdate_exists \
%s (%s) on %s'
% (e, type(e), today)) % (e, type(e), today))
else: else:
try: try:
exdate = ExchangeRate_date.objects.create( exdate = ExchangeRate_date.objects.create(
date=today) date=date)
exdate.save() exdate.save()
except Exception as e: except Exception as e:
print('exdate_not_exists %s (%s) for %s' print('currencies/views/exdate_not_exists \
% (e, type(e), today)) %s (%s) for %s'
% (e, type(e), date))
if ExchangeRate_name.objects.filter( if ExchangeRate_name.objects.filter(
name=currency)[:1]: name=currency)[:1]:
# if data and currency is not yet present, save it. # if data and currency is not yet present, save it.
@ -74,7 +100,8 @@ def currencies(request):
name_dict = ExchangeRate_name.objects.filter( name_dict = ExchangeRate_name.objects.filter(
name=currency).values() name=currency).values()
except Exception as e: except Exception as e:
print('exname_exists %s (%s) on %s' print('currencies/views/exname_exists \
%s (%s) on %s'
% (e, type(e), currency)) % (e, type(e), currency))
else: else:
try: try:
@ -82,7 +109,8 @@ def currencies(request):
name=currency) name=currency)
exname.save() exname.save()
except Exception as e: except Exception as e:
print('exname_not_exists %s (%s) on %s' print('currencies/views/exname_not_exists \
%s (%s) on %s'
% (e, type(e), currency)) % (e, type(e), currency))
try: try:
# save item to where id's match. # save item to where id's match.
@ -92,15 +120,16 @@ def currencies(request):
name=currency).id, name=currency).id,
# date_id=date_id, # date_id=date_id,
date_id=ExchangeRate_date.objects.get( date_id=ExchangeRate_date.objects.get(
date=today).id, date=date).id,
exchange_rate_to_chf=rate, exchange_rate_to_chf=exchangerate,
) )
exrate.save() exrate.save()
message_yes += currency + ", " message_yes += currency + ' on ' + date + ", "
except Exception as e: except Exception as e:
print('exrate_create %s (%s) on %s for %s' print('currencies/views/exrate_create \
% (e, type(e), currency, today)) %s (%s) on %s for %s'
% (e, type(e), currency, date))
# prepare messages: # prepare messages:
# python can not swap a char insinde a sting so i have # python can not swap a char insinde a sting so i have
@ -112,11 +141,12 @@ def currencies(request):
message_yes = message_yes.replace(",", "!", 1) # replace f. , with ! message_yes = message_yes.replace(",", "!", 1) # replace f. , with !
message_yes = message_yes[::-1] # invert the string back message_yes = message_yes[::-1] # invert the string back
# here we evaluate what kind of message is valid: # here we evaluate what kind of message is valid:
if len(message_no) > 24 and len(message_yes) > 23: if len(message_no) > length_of_message_no\
and len(message_yes) > length_of_message_yes:
message = message_no + message_yes message = message_no + message_yes
elif len(message_no) > 24: elif len(message_no) > 24:
message = message_no message = message_no
elif len(message_yes) > 23: elif len(message_yes) > 18:
message = message_yes message = message_yes
elif datetime.datetime.today().isoweekday() == 6: elif datetime.datetime.today().isoweekday() == 6:
message = """Die Abfrage wurde ohne ergebniss beendet. message = """Die Abfrage wurde ohne ergebniss beendet.
@ -130,8 +160,6 @@ def currencies(request):
""" """
else: else:
message = """Die Abfrage wurde ohne ergebniss beendet. message = """Die Abfrage wurde ohne ergebniss beendet.
Kann es sein dass die SNB aufgrund eines Feiertages
geschlossen ist?
""" """
# know we can query our data for presentaton: # know we can query our data for presentaton:
currency_list = ExchangeRate.objects.all() currency_list = ExchangeRate.objects.all()

View File

@ -22,7 +22,7 @@
</td> </td>
<td scope="col">{{ article.category }}</td> <td scope="col">{{ article.category }}</td>
<td scope="col">{{ article.stock }}</td> <td scope="col">{{ article.stock }}</td>
<td scope="col">{{ article.price_in_chf|boldcoffee }}</td> <td scope="col">{{ article.price_in_chf }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>