382 lines
12 KiB
Python
382 lines
12 KiB
Python
# encoding: utf-8
|
|
#
|
|
# Copyright (C) 2020 willipink.eu
|
|
# Author Moritz Münch moritzmuench@mailbox.org
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
from datetime import datetime, date
|
|
from json import dumps
|
|
|
|
from django.conf import settings
|
|
from django.http import HttpResponse, Http404
|
|
from django.template import loader
|
|
from django.template.defaultfilters import register
|
|
from django.views.decorators.http import condition
|
|
from django.utils.datastructures import MultiValueDictKeyError
|
|
|
|
from .cache import (get_last_modified_coin, set_last_modified_coin,
|
|
get_last_modified_country, set_last_modified_country)
|
|
from .models import Country, Stamp, Coin, User
|
|
from .helper import total_coin_sum, coin_sum_of_
|
|
|
|
|
|
@condition(last_modified_func=get_last_modified_coin)
|
|
def index(request):
|
|
''' index view '''
|
|
|
|
template = loader.get_template('coinc/index.html')
|
|
countrys = Country.objects.order_by('name')
|
|
users = User.objects.order_by('id')
|
|
coin_sum = total_coin_sum()
|
|
recent_coins = Coin.objects.order_by('-found_on')[:10]
|
|
for coin in range(len(recent_coins)):
|
|
recent_coins[coin].value /= 100
|
|
context = {
|
|
'countrys': countrys,
|
|
'users': users,
|
|
'coin_sum': f'{coin_sum:.2f} €',
|
|
'recent_coins': recent_coins,
|
|
}
|
|
|
|
return HttpResponse(template.render(context, request))
|
|
|
|
|
|
@condition(last_modified_func=get_last_modified_country)
|
|
def detail_country(request, name_iso):
|
|
''' wrapper_view for a *single* country '''
|
|
|
|
template = loader.get_template('coinc/country.html')
|
|
try:
|
|
country = Country.objects.get(name_iso=name_iso)
|
|
except Country.DoesNotExist:
|
|
raise Http404(f"Das Land '{name_iso}' existiert nicht.")
|
|
|
|
context = show_country(country, single_country=True)
|
|
|
|
return HttpResponse(template.render(context, request))
|
|
|
|
|
|
@register.inclusion_tag('coinc/country.html')
|
|
def show_country(country, single_country=False):
|
|
''' detail_view for a country '''
|
|
|
|
c = {
|
|
'name_iso': country.name_iso,
|
|
'name': country.name,
|
|
'comment': country.comment,
|
|
'years': {}
|
|
}
|
|
coin_sum = coin_sum_of_(country)
|
|
|
|
irregular_stamps = {}
|
|
stamps = Stamp.objects.filter(country=country.name_iso).values(
|
|
'name_short', 'years')
|
|
|
|
if stamps:
|
|
temp_stamps = {}
|
|
|
|
for stamp in stamps:
|
|
stamp_name_short = stamp['name_short']
|
|
|
|
if stamp['years'] == "":
|
|
temp_stamps[stamp_name_short] = {}
|
|
else:
|
|
for year in stamp['years'].split(","):
|
|
irregular_stamps[year] = {}
|
|
irregular_stamps[year][stamp_name_short] = {}
|
|
temp_stamps[''] = {}
|
|
|
|
stamps = temp_stamps
|
|
else:
|
|
stamps = {'': {}}
|
|
|
|
year_now = datetime.now().year
|
|
for year in [str(i) for i in range(country.euro_member_since, year_now + 1)]:
|
|
stamps_per_year = stamps
|
|
|
|
if irregular_stamps and year in irregular_stamps:
|
|
for irregular_stamp, value in irregular_stamps[year].items():
|
|
stamps_per_year[irregular_stamp] = {}
|
|
|
|
# TODO this is not a fix, when more stamps with uniqe years get added
|
|
elif country.name_iso == 'gr':
|
|
stamps_per_year = {'': {}}
|
|
|
|
c['years'][year] = {}
|
|
|
|
for stamp in stamps_per_year:
|
|
c['years'][year][stamp] = {
|
|
1: {},
|
|
2: {},
|
|
5: {},
|
|
10: {},
|
|
20: {},
|
|
50: {},
|
|
100: {},
|
|
200: {},
|
|
201: {},
|
|
202: {},
|
|
203: {}
|
|
}
|
|
|
|
stamps_per_year = {}
|
|
|
|
coins = Coin.objects.all().filter(country=country)
|
|
for coin in coins:
|
|
|
|
td_class = ''
|
|
if not coin.exists:
|
|
td_class = 'noexist'
|
|
elif coin.buy_only:
|
|
td_class = 'buy_only'
|
|
elif coin.circulation and coin.circulation <= 1500000:
|
|
td_class = 'rare'
|
|
elif coin.value in [10, 20, 50]:
|
|
td_class = 'brass'
|
|
elif coin.found_by:
|
|
td_class = 'found'
|
|
else:
|
|
td_class = 'exist'
|
|
|
|
if coin.in_collector:
|
|
td_class += ' ec'
|
|
elif coin.checked:
|
|
td_class += ' checked'
|
|
|
|
div_class = ''
|
|
marker = ''
|
|
if coin.found_by:
|
|
div_class = f"found {coin.found_by}"
|
|
marker = '✔'
|
|
|
|
name = coin.name if coin.name else ''
|
|
special_class = ''
|
|
special_name = ''
|
|
if name:
|
|
if coin.value == 201:
|
|
special_name = 'special1_name'
|
|
elif coin.value == 202:
|
|
special_name = 'special2_name'
|
|
elif coin.value == 203:
|
|
special_name = 'special3_name'
|
|
|
|
if len(name) >= 18 and len(name) <= 42:
|
|
special_class = 'two_lines'
|
|
elif len(name) > 42:
|
|
special_class = 'three_lines'
|
|
|
|
stamp = coin.stamp.name_short if coin.stamp else ''
|
|
|
|
c['years'][str(coin.year)][stamp][coin.value] = {
|
|
'marker': marker,
|
|
'name': name,
|
|
'date_modified': coin.date_modified,
|
|
'td_class': td_class,
|
|
'div_class': div_class,
|
|
'special_class': special_class,
|
|
'special_name': special_name
|
|
}
|
|
|
|
return {
|
|
'country': c,
|
|
'single_country': single_country,
|
|
'users': User.objects.order_by('id').values('name','color'),
|
|
'coin_sum': f"{coin_sum:.2f} €"
|
|
}
|
|
|
|
|
|
@register.inclusion_tag('coinc/year.html')
|
|
def show_year(country, year):
|
|
''' show a year '''
|
|
return {
|
|
'stamps': country['years'][year],
|
|
'year_short': year[2:4],
|
|
}
|
|
|
|
|
|
@register.inclusion_tag('coinc/coin.html')
|
|
def show_coin(coin, value):
|
|
''' show a coin '''
|
|
if coin:
|
|
return {
|
|
'value': value,
|
|
'marker': coin['marker'],
|
|
'name': coin['name'],
|
|
'date_modified': coin['date_modified'],
|
|
'td_class': coin['td_class'],
|
|
'div_class': coin['div_class'],
|
|
'special_class': coin['special_class'],
|
|
'special_name': coin['special_name']}
|
|
else:
|
|
return { 'value': value }
|
|
|
|
|
|
def response(status=0, message=''):
|
|
''' return generic json-formatted status output with http-headers '''
|
|
return HttpResponse(dumps({ 'status': status, 'message': message }))
|
|
|
|
|
|
def add_user(request, username, color):
|
|
''' add a user '''
|
|
|
|
try:
|
|
existing_user = User.objects.get(name=username)
|
|
return response(1, f"'{username}' ist schon vergeben.")
|
|
|
|
except User.DoesNotExist:
|
|
User.objects.create(name=username, color=color)
|
|
|
|
return response()
|
|
|
|
|
|
def edit_coin(request):
|
|
return response()
|
|
|
|
|
|
def add_coin(request, country, year, value):
|
|
''' add or update a coin
|
|
@params request.POST[field]
|
|
|
|
*field* mandatory default data type (internal) with limits
|
|
------------------------------------------------------------------------------------
|
|
value yes - int [1, 2, 5, 10, 20, 50, 100, 200, 201, 202, 203]
|
|
year yes - int [1999; 2098]
|
|
country yes - obj Country
|
|
stamp no None obj Stamp
|
|
exists no False bool
|
|
name no - str
|
|
found_by no None obj User
|
|
found_on no None str %Y-%m-%d
|
|
date-added no auto str %Y-%m-%d %H:%M:%S.%s
|
|
date-modified no auto str %Y-%m-%d %H:%M:%S.%s
|
|
circulation no 0 int [0; 1000000000]
|
|
buy_only no False bool
|
|
checked no False bool
|
|
ec no False bool
|
|
|
|
'''
|
|
|
|
# mandatory fields value, year, country
|
|
value = int(value)
|
|
year = int(year)
|
|
country = str(country)
|
|
try:
|
|
country = Country.objects.get(name_iso=country)
|
|
except Country.DoesNotExist:
|
|
return response(1, f"Das Land mit ISO-Kürzel '{country}' existiert nicht")
|
|
|
|
# optional fields stamp, exists, name, found_by, found_on, circulation, buy_only, ec, checked
|
|
stamp = request.POST.get('stamp')
|
|
stamp = str(stamp) if stamp else None
|
|
if stamp:
|
|
if len(stamp) > 10:
|
|
return response(1, f'Die Prägerei darf max. 10 Zeichen lang sein')
|
|
try:
|
|
stamp = Stamp.objects.get(name_short=stamp)
|
|
except Stamp.DoesNotExist:
|
|
return response(1, f"Die Prägerei '{stamp}' existiert nicht.")
|
|
|
|
exists = request.POST.get('exists', False)
|
|
exists = True if exists == 'true' else False
|
|
if not exists:
|
|
name = ''
|
|
found_by = None
|
|
found_on = date.today().strftime('%Y-%m-%d')
|
|
circulation = 0
|
|
buy_only = False
|
|
checked = False
|
|
ec = False
|
|
|
|
else:
|
|
|
|
name = request.POST.get('name')
|
|
name = str(name) if name else None
|
|
|
|
found_by = request.POST.get('found_by')
|
|
found_by = str(found_by) if found_by else None
|
|
if found_by:
|
|
try:
|
|
found_by = User.objects.get(name=found_by)
|
|
except User.DoesNotExist:
|
|
return response(1, f"Der Nutzer '{found_by}' existiert nicht.")
|
|
|
|
found_on = request.POST.get('found_on')
|
|
if found_on:
|
|
try:
|
|
found_on = datetime.strptime(found_on, '%d.%m.%Y')
|
|
found_on = found_on.strftime('%Y-%m-%d')
|
|
except ValueError:
|
|
return response(1, f"Das Datum '{found_on}' entspricht nicht dem Format 'DD.MM.YYYY'.")
|
|
else:
|
|
found_on = date.today().strftime('%Y-%m-%d')
|
|
|
|
circulation = request.POST.get('circulation', 0)
|
|
circulation = 0 if circulation == '' else circulation
|
|
try:
|
|
circulation = int(circulation.replace('.', ''))
|
|
except ValueError:
|
|
return response(1, f"Die Münzauflage '{circulation}' muss eine Zahl sein.")
|
|
if circulation < 0:
|
|
return response(1, f"Die Münzauflage '{circulation}' muss 0 oder positiv sein.")
|
|
elif circulation > 1000000000:
|
|
return response(1, f"Die Münzauflage '{circulation}' ist unrealistisch.")
|
|
|
|
buy_only = True if request.POST.get('buy_only') == 'true' else False
|
|
checked = True if request.POST.get('checked') == 'true' else False
|
|
ec = True if request.POST.get('ec') == 'true' else False
|
|
|
|
try:
|
|
coin = Coin.objects.get(
|
|
value=value,
|
|
year=year,
|
|
country=country,
|
|
stamp=stamp)
|
|
coin.name = name
|
|
coin.found_by = found_by
|
|
coin.found_on = found_on
|
|
coin.circulation = circulation
|
|
coin.buy_only = buy_only
|
|
coin.checked = checked
|
|
coin.in_collector = ec
|
|
coin.exists = exists
|
|
coin.save(force_update=True)
|
|
|
|
except Coin.DoesNotExist:
|
|
Coin.objects.create(
|
|
value = value,
|
|
year = year,
|
|
country = country,
|
|
stamp = stamp,
|
|
name = name,
|
|
found_by = found_by,
|
|
found_on = found_on,
|
|
circulation = circulation,
|
|
buy_only = buy_only,
|
|
checked = checked,
|
|
in_collector = ec,
|
|
exists = exists)
|
|
|
|
set_last_modified_coin()
|
|
set_last_modified_country(country.name_iso)
|
|
return response()
|
|
|
|
|
|
def statistic(request):
|
|
''' show statistics '''
|
|
|
|
return HttpResponse('Statistik')
|