Compare commits

...

2 Commits

2 changed files with 46 additions and 23 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
__pycache__ __pycache__
cache.json

View File

@ -1,34 +1,55 @@
#!/usr/bin/python3 #!/usr/bin/python3
import requests import requests, json, os.path
from datetime import datetime from datetime import datetime
from dateutil import relativedelta from dateutil import relativedelta
from dateutil import parser as dparser from dateutil import parser as dparser
from dateutil.parser._parser import ParserError as DateParserError from dateutil.parser._parser import ParserError as DateParserError
# Ugly code thats outside of any function _years = None
url = 'https://sdw.ecb.europa.eu/quickviewexport.do?SERIES_KEY=122.ICP.M.U2.N.000000.4.ANR&type=csv'
resp = requests.get(url)
lines = resp.text.split('\n')[6:]
years = {} # Will later contain the monthly factor of inflation (~1.0016667) for every month
for line in lines:
vals = line.split(',')
year = int(vals[0][:4])
month = datetime.strptime(vals[0][4:],'%b').month
inflation = float(vals[1])
if not year in years:
years[year] = {}
years[year][month] = 1 + (inflation/100)/12
for year in years: def _loadYearsTable(maxCacheSeconds=3600):
months = years[year] global _years
for month in range(1,13): if os.path.isfile('cache.json'):
if month not in months: with open('cache.json', 'r') as f:
years[year][month] = 1 + 0.02/12 # Lets say the ECB archives their target cacheUpdate, cacheYears = json.loads(f.read())
if (datetime.now() - dparser.isoparse(cacheUpdate)).total_seconds() < maxCacheSeconds:
# JSON does not allow integers as keys; so we convert them back here...
cacheYears = {int(y):{int(m):float(n) for m,n in ms.items()} for y,ms in cacheYears.items()}
_years = cacheYears
return
_years = _loadYearsTableWeb()
def _loadYearsTableWeb():
print('[i] Fetching new data from ECB-Servers...')
url = 'https://sdw.ecb.europa.eu/quickviewexport.do?SERIES_KEY=122.ICP.M.U2.N.000000.4.ANR&type=csv'
resp = requests.get(url)
lines = resp.text.split('\n')[6:]
years = {} # Will later contain the monthly factor of inflation (~1.0016667) for every month
for line in lines:
vals = line.split(',')
year = int(vals[0][:4])
month = datetime.strptime(vals[0][4:],'%b').month
inflation = float(vals[1])
if not year in years:
years[year] = {}
years[year][month] = 1 + (inflation/100)/12
for year in years:
months = years[year]
for month in range(1,13):
if month not in months:
years[year][month] = 1 + 0.02/12 # Lets say the ECB archives their target
with open('cache.json', 'w') as f:
f.write(json.dumps([datetime.now().isoformat(),years]))
return years
# Gives you the exchange rate between euros and meuros for the given date. # Gives you the exchange rate between euros and meuros for the given date.
# (Should always be a float < 1) # (Should always be a float < 1)
# date should be either a datetime-object or None (= current date) # date should be either a datetime-object or None (= current date)
def exchangeRate(date=None): def exchangeRate(date=None):
global _years
if _years==None:
_loadYearsTable()
if date==None: if date==None:
date = datetime.now() date = datetime.now()
month, year = date.month, date.year month, year = date.month, date.year
@ -37,23 +58,24 @@ def exchangeRate(date=None):
akk = 1 akk = 1
for fullYear in range(2001, year): for fullYear in range(2001, year):
yearlyInf = 1 yearlyInf = 1
for m in years[fullYear]: for m in _years[fullYear]:
monthlyInf = years[fullYear][m] monthlyInf = _years[fullYear][m]
yearlyInf *= monthlyInf yearlyInf *= monthlyInf
akk *= yearlyInf akk *= yearlyInf
for fullMonth in range(1, month): for fullMonth in range(1, month):
monthlyInf = years[year][fullMonth] monthlyInf = _years[year][fullMonth]
akk *= monthlyInf akk *= monthlyInf
beginningOfMonth = date.replace(hour=0, minute=0, second=0, microsecond=0, day=1) beginningOfMonth = date.replace(hour=0, minute=0, second=0, microsecond=0, day=1)
endOfMonth = beginningOfMonth + relativedelta.relativedelta(months=1) endOfMonth = beginningOfMonth + relativedelta.relativedelta(months=1)
fracOfMonth = (date - beginningOfMonth).total_seconds() / (endOfMonth - beginningOfMonth).total_seconds() fracOfMonth = (date - beginningOfMonth).total_seconds() / (endOfMonth - beginningOfMonth).total_seconds()
inflationThisMonth = 1 + fracOfMonth * (years[year][month]-1) inflationThisMonth = 1 + fracOfMonth * (_years[year][month]-1)
akk *= inflationThisMonth akk *= inflationThisMonth
return 1/akk return 1/akk
# Converts the given amount of euros to meuros for the given date. (wholeCents means it rounds to two decimal places) # Converts the given amount of euros to meuros for the given date. (wholeCents means it rounds to two decimal places)
# date should be either a datetime-object or None (= current date) # date should be either a datetime-object or None (= current date)
def euroToMeuro(eur,date=None,wholeCents=True): def euroToMeuro(eur,date=None,wholeCents=True):