Merge branch 'currency' into frontendstyling

* currency: (25 commits)
  changed view and deleted the database unique filed
  add tableview in /currencies
  checkout the production branch on the production server
  add a registration
  disable debugging for production
  add a user profile
  extend the base template with login, profile and logout links
  add templates to support user authentication
  add url patterns to support user authentication
  remove an unnecessary shebang
  remove unnecessary attributes from the Person model
  redirect logins back to the index
  make imports more explicit
  remove an unnecessary configuration
  remove an old file
  change the article status to active
  change the content include because the org-mode file is called doku
  add a python package to the ansible role
  add fixtures with test data
  Add date to currencies list
  ...

# Conflicts:
#	Vagrantfile
#	ansible/roles/web_AI-5/tasks/main.yml
#	django/didgeridoo/didgeridoo/settings.py
#	django/didgeridoo/webshop/templates/webshop/base.html
This commit is contained in:
Ivan Hörler 2017-12-29 19:43:16 +01:00
commit dc083d9c5e
39 changed files with 1242 additions and 54 deletions

3
Vagrantfile vendored
View File

@ -30,7 +30,8 @@ Vagrant.configure("2") do |config|
#zu installierende Pakete
apt-get install -y apache2 python3-django mariadb-server avahi-daemon \
libnss-mdns libapache2-mod-wsgi-py3 python3-mysqldb python3-pip
pip3 install django-extensions Pillow django-bootstrap3
pip3 install django-extensions Pillow pyaml django-bootstrap3
/vagrant/ansible/roles/web_AI-5/tasks/setup_script.sh
SHELL

View File

@ -15,6 +15,7 @@
git: repo=https://git.2li.ch/ibz/web_AI-5.git
dest="/vagrant"
force=yes
version=production
- name: Set Permissions on the repository
file:
@ -27,6 +28,7 @@
name:
- django-extensions
- Pillow
- pyaml
- django-bootstrap3
executable: pip3

View File

@ -17,3 +17,5 @@ echo "from django.contrib.auth.models import User; \
User.objects.filter(email='admin@example.com').delete(); \
User.objects.create_superuser('admin', 'admin@example.com', 'password')" |
python3 /vagrant/django/didgeridoo/manage.py shell
python3 /vagrant/django/didgeridoo/manage.py loaddata webshop

View File

@ -2,7 +2,7 @@
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="jdk" jdkName="Python 3.6.3 (/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/bin/python3.6)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6.3 (/usr/bin/python3.6)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6.3 (/usr/local/Cellar/python3/3.6.3/Frameworks/Python.framework/Versions/3.6/bin/python3.6)" project-jdk-type="Python SDK" />
</project>

View File

View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class CurrenciesConfig(AppConfig):
name = 'currencies'

View File

@ -0,0 +1,124 @@
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')
# ~~~~~~~~~~~~~~~~~~~~~
# 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/'
}
# 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"))
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")
# 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)
# 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.update(
{target_currency: FOREIGNvalue_round})
# Print the Dictionary:
# print(exchange_rates)
else:
break
return(exchange_rates, date)
# for development its preferable to see that the for loop is done:
# print('no more fresh data!')

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-18 18:01
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='ExchangeRate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200, unique=True)),
('exchange_rate_to_chf', models.FloatField(max_length=5)),
],
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-27 10:05
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('currencies', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='exchangerate',
name='date',
field=models.DateField(null=True),
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-27 10:19
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('currencies', '0002_exchangerate_date'),
]
operations = [
migrations.AlterField(
model_name='exchangerate',
name='date',
field=models.DateField(null=True, verbose_name='%Y-%m-%d'),
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-29 16:08
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('currencies', '0003_auto_20171227_1119'),
]
operations = [
migrations.AlterField(
model_name='exchangerate',
name='name',
field=models.CharField(max_length=200),
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-29 16:35
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('currencies', '0004_auto_20171229_1708'),
]
operations = [
migrations.AlterField(
model_name='exchangerate',
name='date',
field=models.DateField(null=True, verbose_name='%Y-%m-%dT%H:%M:%S'),
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-29 16:47
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('currencies', '0005_auto_20171229_1735'),
]
operations = [
migrations.AlterField(
model_name='exchangerate',
name='date',
field=models.DateTimeField(null=True, verbose_name='%Y-%m-%dT%H:%M:%S'),
),
]

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2017-12-29 17:06
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('currencies', '0006_auto_20171229_1747'),
]
operations = [
migrations.AlterField(
model_name='exchangerate',
name='date',
field=models.DateField(null=True, verbose_name='%Y-%m-%d'),
),
]

View File

@ -0,0 +1,10 @@
from django.db import models
class ExchangeRate(models.Model):
name = models.CharField(max_length=200)
date = models.DateField('%Y-%m-%d', null=True)
exchange_rate_to_chf = models.FloatField(max_length=5)
def __str__(self):
return self.name

View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="{{ STATIC_URL }}/static/admin/css/base.css" />
</head>
<body>
<div id="content" class="flex">
<h1>Currencies in CHF</h1>
{% if currency_list %}
<table>
<tr>
<th scope="col">DATE</th>
{% for currency in currency_list %}
<th scope="col">{{ currency.name }}</th>
{% endfor %}
</tr>
<tr>
<td>{{ date }}</td>
{% for currency in currency_list %}
<td>{{ currency.exchange_rate_to_chf }}</td>
{% endfor %}
</tr>
</table>
<br>
<p> {{ message }} </p>
<br>
<ul>
{% for currency in currency_list %}
<li>
{{ currency.date }} :
{{ currency.name }} :
{{ currency.exchange_rate_to_chf }}
</li>
{% endfor %}
</ul>
{% else %}
<p class="alert">
Something whent wrong, no currencies are available.
</p>
{% endif %}
</div>
</body>
</html>

View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

View File

@ -0,0 +1,7 @@
from django.conf.urls import url
from currencies.views import currencies
urlpatterns = [
url(r'^currencies/$', currencies),
]

View File

@ -0,0 +1,26 @@
from django.shortcuts import render
from currencies.models import ExchangeRate
from currencies import exchange_rates
def currencies(request):
# return HttpResponse("exchange_rates")
raw_data, date = exchange_rates.get_exchange_rate()
message = ""
for currency, rate in raw_data.items():
if ExchangeRate.objects.filter(date=date):
message = "already querried today"
else:
e = ExchangeRate.objects.create(
name=currency,
exchange_rate_to_chf=rate,
date=date
)
e.save()
message = "updated successfully"
currency_list = ExchangeRate.objects.all()
return render(request,
'currencies/index.html',
{'currency_list': currency_list,
'date': date,
'message': message})

View File

@ -23,9 +23,13 @@ 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 = True
DEBUG = False
ALLOWED_HOSTS = []
ALLOWED_HOSTS = [
'localhost',
'127.0.0.1',
'didgeridoo.ml'
]
# Application definition
@ -39,8 +43,9 @@ INSTALLED_APPS = [
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bootstrap3'
]
'currencies',
'bootstrap3',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
@ -131,9 +136,4 @@ STATIC_URL = '/static/'
STATIC_ROOT = '/vagrant/django/didgeridoo/static/'
MEDIA_ROOT = '/vagrant/django/didgeridoo/media/'
ALLOWED_HOSTS = [
'localhost',
'127.0.0.1',
'didgeridoo.ml'
]
LOGIN_REDIRECT_URL = '/'

View File

@ -18,6 +18,6 @@ from django.contrib import admin
urlpatterns = [
url(r'', include('webshop.urls')),
url(r'^admin/', admin.site.urls),
url(r'', include('currencies.urls')),
url(r'^admin/', admin.site.urls),
]

621
django/didgeridoo/rss Normal file
View File

@ -0,0 +1,621 @@
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.2/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/">
<channel rdf:about="https://www.snb.ch/de/ifor/media/id/media_rss">
<title>SNB Devisenkurse</title>
<link>https://www.snb.ch/de/ifor/media/id/media_rss</link>
<description>Schweizerische Nationalbank (SNB): Devisenkurse (Ankauf Zürich 11 Uhr)</description>
<items>
<rdf:Seq>
<rdf:li rdf:resource="https://www.snb.ch#GBP_6ec827d359194a0a002581e5003df8a5"/>
<rdf:li rdf:resource="https://www.snb.ch#JPY_6ec827d359194a0a002581e5003df8a5"/>
<rdf:li rdf:resource="https://www.snb.ch#EUR_6ec827d359194a0a002581e5003df8a5"/>
<rdf:li rdf:resource="https://www.snb.ch#USD_6ec827d359194a0a002581e5003df8a5"/>
<rdf:li rdf:resource="https://www.snb.ch#GBP_f4a6fbc20fb0403d002581e2003e3d67"/>
<rdf:li rdf:resource="https://www.snb.ch#JPY_f4a6fbc20fb0403d002581e2003e3d67"/>
<rdf:li rdf:resource="https://www.snb.ch#EUR_f4a6fbc20fb0403d002581e2003e3d67"/>
<rdf:li rdf:resource="https://www.snb.ch#USD_f4a6fbc20fb0403d002581e2003e3d67"/>
<rdf:li rdf:resource="https://www.snb.ch#GBP_6568365cd292474b002581e1003fca55"/>
<rdf:li rdf:resource="https://www.snb.ch#JPY_6568365cd292474b002581e1003fca55"/>
<rdf:li rdf:resource="https://www.snb.ch#EUR_6568365cd292474b002581e1003fca55"/>
<rdf:li rdf:resource="https://www.snb.ch#USD_6568365cd292474b002581e1003fca55"/>
<rdf:li rdf:resource="https://www.snb.ch#GBP_0d6cfaf1d11a41f8002581e0003ea07c"/>
<rdf:li rdf:resource="https://www.snb.ch#JPY_0d6cfaf1d11a41f8002581e0003ea07c"/>
<rdf:li rdf:resource="https://www.snb.ch#EUR_0d6cfaf1d11a41f8002581e0003ea07c"/>
<rdf:li rdf:resource="https://www.snb.ch#USD_0d6cfaf1d11a41f8002581e0003ea07c"/>
<rdf:li rdf:resource="https://www.snb.ch#GBP_d101d729279f41cd002581df003e31f1"/>
<rdf:li rdf:resource="https://www.snb.ch#JPY_d101d729279f41cd002581df003e31f1"/>
<rdf:li rdf:resource="https://www.snb.ch#EUR_d101d729279f41cd002581df003e31f1"/>
<rdf:li rdf:resource="https://www.snb.ch#USD_d101d729279f41cd002581df003e31f1"/>
</rdf:Seq>
</items>
<dc:publisher>SNB</dc:publisher>
<dc:rights>Copyright © Schweizerische Nationalbank, Zürich (Schweiz) 2017</dc:rights>
<dcterms:license>https://www.snb.ch/de/srv/id/disclaimer</dcterms:license>
<dcterms:created>2017-11-28T07:50:22+01:00</dcterms:created>
</channel>
<item rdf:about="https://www.snb.ch#GBP_6ec827d359194a0a002581e5003df8a5">
<title>CH: 1.3081 CHF = 1 GBP 2017-11-27 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 GBP = 1.3081 CHF (Tägliche Kurse (11:00); 2017-11-27T12:16:53.767+01:00)</description>
<dc:date>2017-12-19T12:16:53.767+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>1.3081</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>GBP</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-27</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#JPY_6ec827d359194a0a002581e5003df8a5">
<title>CH: 0.8813 CHF = 100 JPY 2017-11-27 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>100 JPY = 0.8813 CHF (Tägliche Kurse (11:00); 2017-11-27T12:16:53.760+01:00)</description>
<dc:date>2017-12-19T12:16:53.760+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>10000.8813</cb:value>
<cb:unit>CHF</cb:unit>
<cb:unit_mult>-2</cb:unit_mult>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>JPY</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-27</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#EUR_6ec827d359194a0a002581e5003df8a5">
<title>CH: 1.1697 CHF = 1 EUR 2017-11-27 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 EUR = 1.1697 CHF (Tägliche Kurse (11:00); 2017-11-27T12:16:53.750+01:00)</description>
<dc:date>2017-12-19T12:16:53.750+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>1.1697</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>EUR</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-27</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#USD_6ec827d359194a0a002581e5003df8a5">
<title>CH: 0.9803 CHF = 1 USD 2017-11-27 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 USD = 0.9803 CHF (Tägliche Kurse (11:00); 2017-11-27T12:16:53.737+01:00)</description>
<dc:date>2017-11-29T12:16:53.737+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>0.9803</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>USD</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-27</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#GBP_f4a6fbc20fb0403d002581e2003e3d67">
<title>CH: 1.3072 CHF = 1 GBP 2017-11-24 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 GBP = 1.3072 CHF (Tägliche Kurse (11:00); 2017-11-24T12:19:49.733+01:00)</description>
<dc:date>2017-11-24T12:19:49.733+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>1.3072</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>GBP</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-24</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#JPY_f4a6fbc20fb0403d002581e2003e3d67">
<title>CH: 0.8806 CHF = 100 JPY 2017-11-24 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>100 JPY = 0.8806 CHF (Tägliche Kurse (11:00); 2017-11-24T12:19:49.717+01:00)</description>
<dc:date>2017-11-24T12:19:49.717+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>0.8806</cb:value>
<cb:unit>CHF</cb:unit>
<cb:unit_mult>-2</cb:unit_mult>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>JPY</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-24</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#EUR_f4a6fbc20fb0403d002581e2003e3d67">
<title>CH: 1.1644 CHF = 1 EUR 2017-11-24 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 EUR = 1.1644 CHF (Tägliche Kurse (11:00); 2017-11-24T12:19:49.710+01:00)</description>
<dc:date>2017-11-24T12:19:49.710+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>1.1644</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>EUR</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-24</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#USD_f4a6fbc20fb0403d002581e2003e3d67">
<title>CH: 0.9809 CHF = 1 USD 2017-11-24 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 USD = 0.9809 CHF (Tägliche Kurse (11:00); 2017-11-24T12:19:49.703+01:00)</description>
<dc:date>2017-11-24T12:19:49.703+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>0.9809</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>USD</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-24</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#GBP_6568365cd292474b002581e1003fca55">
<title>CH: 1.3052 CHF = 1 GBP 2017-11-23 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 GBP = 1.3052 CHF (Tägliche Kurse (11:00); 2017-11-23T12:36:46.040+01:00)</description>
<dc:date>2017-11-23T12:36:46.040+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>1.3052</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>GBP</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-23</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#JPY_6568365cd292474b002581e1003fca55">
<title>CH: 0.8816 CHF = 100 JPY 2017-11-23 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>100 JPY = 0.8816 CHF (Tägliche Kurse (11:00); 2017-11-23T12:36:46.030+01:00)</description>
<dc:date>2017-11-23T12:36:46.030+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>0.8816</cb:value>
<cb:unit>CHF</cb:unit>
<cb:unit_mult>-2</cb:unit_mult>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>JPY</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-23</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#EUR_6568365cd292474b002581e1003fca55">
<title>CH: 1.1617 CHF = 1 EUR 2017-11-23 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 EUR = 1.1617 CHF (Tägliche Kurse (11:00); 2017-11-23T12:36:46.027+01:00)</description>
<dc:date>2017-11-23T12:36:46.027+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>1.1617</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>EUR</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-23</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#USD_6568365cd292474b002581e1003fca55">
<title>CH: 0.9811 CHF = 1 USD 2017-11-23 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 USD = 0.9811 CHF (Tägliche Kurse (11:00); 2017-11-23T12:36:46.017+01:00)</description>
<dc:date>2017-11-23T12:36:46.017+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>0.9811</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>USD</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-23</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#GBP_0d6cfaf1d11a41f8002581e0003ea07c">
<title>CH: 1.3109 CHF = 1 GBP 2017-11-22 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 GBP = 1.3109 CHF (Tägliche Kurse (11:00); 2017-11-22T12:24:04.110+01:00)</description>
<dc:date>2017-11-22T12:24:04.110+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>1.3109</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>GBP</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-22</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#JPY_0d6cfaf1d11a41f8002581e0003ea07c">
<title>CH: 0.8827 CHF = 100 JPY 2017-11-22 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>100 JPY = 0.8827 CHF (Tägliche Kurse (11:00); 2017-11-22T12:24:04.103+01:00)</description>
<dc:date>2017-11-22T12:24:04.103+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>0.8827</cb:value>
<cb:unit>CHF</cb:unit>
<cb:unit_mult>-2</cb:unit_mult>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>JPY</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-22</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#EUR_0d6cfaf1d11a41f8002581e0003ea07c">
<title>CH: 1.1633 CHF = 1 EUR 2017-11-22 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 EUR = 1.1633 CHF (Tägliche Kurse (11:00); 2017-11-22T12:24:04.090+01:00)</description>
<dc:date>2017-11-22T12:24:04.090+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>1.1633</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>EUR</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-22</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#USD_0d6cfaf1d11a41f8002581e0003ea07c">
<title>CH: 0.9894 CHF = 1 USD 2017-11-22 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 USD = 0.9894 CHF (Tägliche Kurse (11:00); 2017-11-22T12:24:04.083+01:00)</description>
<dc:date>2017-11-22T12:24:04.083+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>0.9894</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>USD</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-22</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#GBP_d101d729279f41cd002581df003e31f1">
<title>CH: 1.3151 CHF = 1 GBP 2017-11-21 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 GBP = 1.3151 CHF (Tägliche Kurse (11:00); 2017-11-21T12:19:20.370+01:00)</description>
<dc:date>2017-11-21T12:19:20.370+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>1.3151</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>GBP</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-21</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#JPY_d101d729279f41cd002581df003e31f1">
<title>CH: 0.8832 CHF = 100 JPY 2017-11-21 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>100 JPY = 0.8832 CHF (Tägliche Kurse (11:00); 2017-11-21T12:19:20.363+01:00)</description>
<dc:date>2017-11-21T12:19:20.363+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>0.8832</cb:value>
<cb:unit>CHF</cb:unit>
<cb:unit_mult>-2</cb:unit_mult>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>JPY</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-21</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#EUR_d101d729279f41cd002581df003e31f1">
<title>CH: 1.1647 CHF = 1 EUR 2017-11-21 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 EUR = 1.1647 CHF (Tägliche Kurse (11:00); 2017-11-21T12:19:20.360+01:00)</description>
<dc:date>2017-11-21T12:19:20.360+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>1.1647</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>EUR</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-21</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
<item rdf:about="https://www.snb.ch#USD_d101d729279f41cd002581df003e31f1">
<title>CH: 0.9930 CHF = 1 USD 2017-11-21 Tägliche Kurse (11:00)</title>
<link>https://www.snb.ch</link>
<description>1 USD = 0.9930 CHF (Tägliche Kurse (11:00); 2017-11-21T12:19:20.343+01:00)</description>
<dc:date>2017-11-21T12:19:20.343+01:00</dc:date>
<dc:language>de</dc:language>
<cb:statistics rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Statistics"/>
<cb:country>CH</cb:country>
<cb:institutionAbbrev>SNB</cb:institutionAbbrev>
<cb:exchangeRate rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ExchangeRate"/>
<cb:observation rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#Observation"/>
<cb:value>0.9930</cb:value>
<cb:unit>CHF</cb:unit>
<cb:decimals>4</cb:decimals>
</cb:observation>
<cb:baseCurrency>CHF</cb:baseCurrency>
<cb:targetCurrency>USD</cb:targetCurrency>
<cb:rateType>Tägliche Kurse (11:00)</cb:rateType>
<cb:observationPeriod rdf:parseType="Resource">
<rdf:type rdf:resource="http://www.cbwiki.net/wiki/index.php/RSS-CB_1.2_RDF_Schema#ObservationPeriod"/>
<cb:frequency>daily</cb:frequency>
<cb:period>2017-11-21</cb:period>
</cb:observationPeriod>
</cb:exchangeRate>
</cb:statistics>
</item>
</rdf:RDF>

View File

@ -3,8 +3,9 @@ from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
# Register your models here.
from .models import (Article, Order, OrderPosition, Person, City, Picture,
OrderOfGoods, Category, Option, Setting)
from webshop.models import (Article, Order, OrderPosition,
Person, City, Picture, OrderOfGoods,
Category, Option, Setting)
class PersonInline(admin.StackedInline):

View File

@ -0,0 +1,97 @@
- model: webshop.Category
fields:
name: "First Parent Category"
parent_category:
- model: webshop.Category
fields:
name: "Second Parent Category"
parent_category:
- model: webshop.Category
fields:
name: "Third Parent Category"
parent_category:
- model: webshop.Category
fields:
name: "Fourth Parent Category"
parent_category:
- model: webshop.Category
fields:
name: "Child Category 1"
parent_category: 1
- model: webshop.Category
fields:
name: "Child Category 2"
parent_category: 2
- model: webshop.Category
fields:
name: "Child Category 3"
parent_category: 3
- model: webshop.Category
fields:
name: "Child Category 4"
parent_category: 4
- model: webshop.Article
fields:
name: "Article of First Parent Category"
category: 1
description: "An article sorted under the First Parent Category."
stock: 10
status: 3
price_in_chf: 10.1
- model: webshop.Article
fields:
name: "Article of Second Parent Category"
category: 2
description: "An article sorted under the Second Parent Category."
stock: 20
status: 3
price_in_chf: 20.2
- model: webshop.Article
fields:
name: "Article of Third Parent Category"
category: 3
description: "An article sorted under the Third Parent Category."
stock: 30
status: 3
price_in_chf: 30.3
- model: webshop.Article
fields:
name: "Article of Fourth Parent Category"
category: 4
description: "An article sorted under the Fourth Parent Category."
stock: 40
status: 3
price_in_chf: 40.4
- model: webshop.Article
fields:
name: "Article of Child Category 1"
category: 5
description: "An article sorted under the Child Category 1."
stock: 11
status: 3
price_in_chf: 11.1
- model: webshop.Article
fields:
name: "Article of Child Category 2"
category: 6
description: "An article sorted under the Child Category 2."
stock: 22
status: 3
price_in_chf: 21.2
- model: webshop.Article
fields:
name: "Article of Child Category 3"
category: 7
description: "An article sorted under the Child Category 3."
stock: 33
status: 3
price_in_chf: 31.3
- model: webshop.Article
fields:
name: "Article of Child Category 4"
category: 8
description: "An article sorted under the Child Category 4."
stock: 44
status: 3
price_in_chf: 41.4

View File

@ -0,0 +1,24 @@
from django import forms
from webshop.models import Salutation, City
class RegistrationForm(forms.Form):
email = forms.EmailField()
salutation = forms.ModelChoiceField(queryset=Salutation.objects.all())
first_name = forms.CharField()
last_name = forms.CharField()
street_name = forms.CharField()
street_number = forms.CharField()
zip_code = forms.IntegerField(min_value=1000, max_value=9999)
city = forms.CharField()
def clean_city(self):
# Check that the two password entries match
city = self.cleaned_data['city']
zip_code = self.cleaned_data['zip_code']
try:
City.objects.get(name=city, zip_code=zip_code)
except City.DoesNotExist:
raise forms.ValidationError(
"The zip code and the city don't match.")
return city

View File

@ -1,5 +1,3 @@
#!/usr/bin/python3
from decimal import Decimal
from django.core.validators import MinValueValidator
from django.db import models
@ -30,14 +28,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)
@ -138,8 +128,6 @@ class Salutation(models.Model):
class Person(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
salutation = models.ForeignKey(Salutation)
city = models.ForeignKey(City)
street_name = models.CharField(max_length=200)
@ -147,4 +135,4 @@ class Person(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
def __str__(self):
return self.last_name
return self.user.username

View File

@ -0,0 +1,6 @@
{% extends 'webshop/base.html' %}
{% block section_title %}You have been successfully logged out.{% endblock %}
{% block content %}
{% endblock %}

View File

@ -0,0 +1,12 @@
{% extends 'webshop/base.html' %}
{% block section_title %}Login{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
<p><a href="{% url 'registration' %}">Go to registration.</a></p>
</form>
{% endblock %}

View File

@ -0,0 +1,17 @@
{% extends 'webshop/base.html' %}
{% block section_title %}User Profile{% endblock %}
{% block content %}
<p><b>Username: </b>{{ request.user.username }}</p>
<p><b>Salutation: </b>{{ person.salutation }}</p>
<p><b>Firstname: </b>{{ request.user.first_name }}</p>
<p><b>Lastname: </b>{{ request.user.last_name }}</p>
<p><b>City: </b>{{ person.city }}</p>
<p><b>Street: </b>{{ person.street_name }}</p>
<p><b>Streetnumber: </b>{{ person.street_number }}</p>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
</form>
{% endblock %}

View File

@ -0,0 +1,19 @@
{% extends 'webshop/base.html' %}
{% block section_title %}Registration{% endblock %}
{% block content %}
{% if profile_form.errors %}
<p style="color: red;">
Please correct the error{{ form.errors|pluralize }} below.
</p>
{% endif %}
<form action="" method="post" novalidate>
<table>
{{ user_form.as_table }}
{{ profile_form.as_table }}
</table>
{% csrf_token %}
<button type="submit">Register</button>
</form>
{% endblock %}

View File

@ -16,6 +16,16 @@
{% endblock %}
</head>
<body>
<div id="content" class="flex">
<a href="{% url 'index' %}">Home</a> |
{% if user.is_authenticated %}
<a href="{% url 'profile' %}">Profile</a> | <a href="{% url 'logout' %}">Logout</a>
{% else %}
<a href="{% url 'login' %}">Login</a>
{% endif %}
<h1>{% block section_title %}Music Instrument Shop{% endblock %}</h1>
{% block content %}{% endblock %}
</div>
<div class="container-fluid">
<div class="row">
<div class="col-sm-12">

View File

@ -1,6 +1,6 @@
from django.conf.urls import url
from django.conf.urls import url, include
from . import views
from webshop import views
urlpatterns = [
url(r'^$', views.index, name='index'),
@ -10,4 +10,7 @@ urlpatterns = [
url(r'^category/(?P<category_id>[0-9]+)/$',
views.articles_in_category,
name='category'),
url('^', include('django.contrib.auth.urls')),
url(r'^profile/$', views.profile, name='profile'),
url(r'^registration/$', views.registration, name='registration'),
]

View File

@ -1,5 +1,10 @@
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from .models import Article, Category, ArticleStatus
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from webshop.models import Article, Category, ArticleStatus, Person, City
from webshop.forms import RegistrationForm
# Create your views here.
@ -33,3 +38,39 @@ def article_details(request, article_id):
article = get_object_or_404(Article, pk=article_id)
return render(request, 'webshop/article_details.html',
{'article': article})
@login_required
def profile(request):
person = Person.objects.get(user=request.user)
return render(request, 'registration/profile.html',
{'person': person})
def registration(request):
if request.method == 'POST':
profile_form = RegistrationForm(request.POST)
user_form = UserCreationForm(request.POST)
if (profile_form.is_valid() and user_form.is_valid()):
pf = profile_form.cleaned_data
uf = user_form.cleaned_data
user = User.objects.create_user(uf['username'],
pf['email'],
uf['password2'])
user.last_name = pf['last_name']
user.first_name = pf['first_name']
user.save()
person = Person.objects.create(
salutation=pf['salutation'],
city=City.objects.get(zip_code=pf['zip_code'],
name=pf['city']),
street_name=pf['street_name'],
street_number=pf['street_number'],
user=user)
return HttpResponseRedirect('/login/')
else:
profile_form = RegistrationForm
user_form = UserCreationForm
return render(request, 'registration/register.html',
{'profile_form': profile_form,
'user_form': user_form})

View File

@ -11,7 +11,7 @@
\microtypesetup{protrusion=true} % enables protrusion
\newpage
\include{content}
\include{doku}
\newpage
\nocite{*}

View File

@ -1,20 +0,0 @@
<!DOCTYPE HTML>
<meta charset="UTF-8">
<html>
<head></head>
<body>
<header>
<h1>audioguide</h1>
<h3>a mobile offline audioguide</h3>
noop
noop
noop
noop
noop
noop
<p>the audioguide that makes a offline usage possible.</p>
</header>
<nav>
</nav>
</body>
</html>

View File

@ -24,7 +24,7 @@ use webshopdb;
insert into webshop_articlestatus (name)
values ('out of stock'),
('hidden'),
('on sale');
('active');
use webshopdb;
insert into webshop_city (zip_code, name)