Merge branch 'master' of ssh://willipink.eu:3456/moritz/coinmanager
This commit is contained in:
commit
5ee77597ba
55
coinmanager/coinc/cache.py
Normal file
55
coinmanager/coinc/cache.py
Normal file
@ -0,0 +1,55 @@
|
||||
# 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 hashlib import sha256
|
||||
from random import random
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.http import Http404
|
||||
|
||||
from .models import Coin
|
||||
|
||||
|
||||
def get_last_modified_index(request):
|
||||
return cache.get(f'last_modified_index', set_last_modified_index())
|
||||
|
||||
|
||||
def set_last_modified_index():
|
||||
''' set and return the datetime of the last coin added '''
|
||||
try:
|
||||
last_modified = Coin.objects.latest('date_modified').date_modified
|
||||
except Coin.DoesNotExist:
|
||||
raise Http404(f'Das Land "{name_iso}" existiert nicht')
|
||||
cache.set(f'last_modified_index', last_modified)
|
||||
return last_modified
|
||||
|
||||
|
||||
def get_last_modified_country(request, name_iso):
|
||||
return cache.get(f'last_modified_{name_iso}', set_last_modified_country(name_iso))
|
||||
|
||||
|
||||
def set_last_modified_country(name_iso):
|
||||
''' return the datetime of the last coin added to a country '''
|
||||
try:
|
||||
last_modified = Coin.objects.filter(country=name_iso).latest('date_modified').date_modified
|
||||
except Coin.DoesNotExist:
|
||||
raise Http404(f'Das Land "{name_iso}" existiert nicht')
|
||||
cache.set(f'last_modified_{name_iso}', last_modified)
|
||||
return last_modified
|
54
coinmanager/coinc/helper.py
Normal file
54
coinmanager/coinc/helper.py
Normal file
@ -0,0 +1,54 @@
|
||||
# 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 .models import Country, Coin
|
||||
|
||||
def total_coin_sum():
|
||||
''' add each coin_sum from each country and return the result
|
||||
>>> total_coin_sum()
|
||||
173.57
|
||||
'''
|
||||
|
||||
total_coin_sum = 0
|
||||
for country in Country.objects.order_by('name'):
|
||||
total_coin_sum += coin_sum_of_(country)
|
||||
|
||||
return total_coin_sum
|
||||
|
||||
|
||||
def coin_sum_of_(country):
|
||||
''' calculate the sum of all coins from a country
|
||||
>>> coin_sum_of_(germany)
|
||||
346.82
|
||||
'''
|
||||
|
||||
coin_count = {'total': 0}
|
||||
for value in [1, 2, 5, 10, 20, 50, 100, 200, 201, 202, 203]:
|
||||
|
||||
coin_count[value] = Coin.objects.filter(
|
||||
country=country,
|
||||
value=value
|
||||
).exclude(found_by__isnull=True).count()
|
||||
|
||||
if value > 200:
|
||||
coin_count['total'] += 200 * coin_count[value]
|
||||
else:
|
||||
coin_count['total'] += value * coin_count[value]
|
||||
|
||||
return coin_count['total'] / 100
|
@ -20,7 +20,7 @@
|
||||
|
||||
from datetime import datetime, date
|
||||
|
||||
from django.db.models import BooleanField, CASCADE, CharField, DateField, ForeignKey, Model, PositiveIntegerField, PositiveSmallIntegerField, TextField
|
||||
from django.db.models import BooleanField, CASCADE, CharField, DateField, DateTimeField, ForeignKey, Model, PositiveIntegerField, PositiveSmallIntegerField, TextField
|
||||
|
||||
|
||||
year_now = int(datetime.now().year)
|
||||
@ -85,6 +85,10 @@ class Coin(Model):
|
||||
|
||||
found_on = DateField('Eingetragen am', default=date.today)
|
||||
|
||||
date_added = DateTimeField('Hinzugefügt', auto_now_add=True)
|
||||
|
||||
date_modified = DateTimeField('Geändert', auto_now=True)
|
||||
|
||||
circulation = PositiveIntegerField('Auflage', default=0)
|
||||
|
||||
buy_only = BooleanField('Kursmünze', default=False)
|
||||
|
@ -1,9 +1,11 @@
|
||||
{% load cache %}
|
||||
{% csrf_token %}
|
||||
{% cache None controlbar user %}
|
||||
<style type="text/css">{% for user in users %}
|
||||
div.{{ user.name }} { background-color: {{ user.color }} !important; }{% endfor %}
|
||||
</style>
|
||||
|
||||
<div id="button_control">
|
||||
{% csrf_token %}
|
||||
{% if user.is_authenticated %}
|
||||
<button id="begin_edit" class="btn btn-info" title="Hinzufügen"><i class="fas fa-plus"></i><span> Hinzufügen</span></button>
|
||||
<button id="do_logout" class="btn btn-info" title="Abmelden"><i class="fas fa-sign-out-alt"></i></button>
|
||||
@ -14,7 +16,6 @@
|
||||
|
||||
<!-- navbar -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
{% csrf_token %}
|
||||
|
||||
<!-- advanced options -->
|
||||
<div id="advanced_options">
|
||||
@ -114,7 +115,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endcache %}
|
||||
<!-- modal login -->
|
||||
{% if not user.is_authenticated %}
|
||||
<div id="login" class="modal-container">
|
||||
|
@ -1,3 +1,5 @@
|
||||
{% load cache %}
|
||||
{% cache None header %}
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
|
||||
@ -53,3 +55,4 @@
|
||||
<title>{{ title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
{% endcache %}
|
||||
|
@ -17,6 +17,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
from datetime import datetime, date
|
||||
from json import dumps
|
||||
|
||||
@ -24,32 +25,15 @@ 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 .cache import (get_last_modified_index, set_last_modified_index,
|
||||
get_last_modified_country, set_last_modified_country)
|
||||
from .models import Country, Stamp, Coin, User
|
||||
from .helper import total_coin_sum, coin_sum_of_
|
||||
|
||||
|
||||
def total_coin_sum():
|
||||
total_coin_sum = 0
|
||||
for country in Country.objects.order_by('name'):
|
||||
total_coin_sum += coin_sum_of_(country)
|
||||
return total_coin_sum
|
||||
|
||||
|
||||
def coin_sum_of_(country):
|
||||
coin_count = {'total': 0}
|
||||
for value in [1, 2, 5, 10, 20, 50, 100, 200, 201, 202, 203]:
|
||||
coin_count[value] = Coin.objects.filter(
|
||||
country=country,
|
||||
value=value
|
||||
).exclude(found_by__isnull=True).count()
|
||||
if value > 200:
|
||||
coin_count['total'] += 200 * coin_count[value]
|
||||
else:
|
||||
coin_count['total'] += value * coin_count[value]
|
||||
coin_count['total'] /= 100
|
||||
return coin_count['total']
|
||||
|
||||
|
||||
@condition(last_modified_func=get_last_modified_index)
|
||||
def index(request):
|
||||
''' index view '''
|
||||
|
||||
@ -60,12 +44,13 @@ def index(request):
|
||||
context = {
|
||||
'countrys': countrys,
|
||||
'users': users,
|
||||
'coin_sum': f"{coin_sum:.2f} €"
|
||||
'coin_sum': f'{coin_sum:.2f} €'
|
||||
}
|
||||
|
||||
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 '''
|
||||
|
||||
@ -194,6 +179,7 @@ def show_country(country, single_country=False):
|
||||
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,
|
||||
@ -225,6 +211,7 @@ def show_coin(coin, value):
|
||||
'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'],
|
||||
@ -268,6 +255,8 @@ def add_coin(request):
|
||||
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
|
||||
@ -385,6 +374,8 @@ def add_coin(request):
|
||||
in_collector = ec,
|
||||
exists = exists)
|
||||
|
||||
set_last_modified_index()
|
||||
set_last_modified_country(country.name_iso)
|
||||
return response()
|
||||
|
||||
|
||||
|
@ -44,10 +44,11 @@ INSTALLED_APPS = [
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.cache.UpdateCacheMiddleware',
|
||||
# 'django.middleware.cache.UpdateCacheMiddleware', # per-site cache
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.cache.FetchFromCacheMiddleware',
|
||||
# 'django.middleware.cache.FetchFromCacheMiddleware', # per-site cache
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
# 'django.middleware.http.ConditionalGetMiddleware', # set 'ETag' and 'Last Modified' headers
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
@ -129,6 +130,18 @@ MAINTENANCE_MODE_READ_ONLY = False
|
||||
# do not redirect after login
|
||||
LOGIN_REDIRECT_URL = './'
|
||||
|
||||
# caching
|
||||
CACHE_MIDDLEWARE_ALIAS = willipink_coinc
|
||||
CACHE_MIDDLEWARE_SECONDS = 600
|
||||
# caching modes, i.e. file based, memcached, or other fancy stuff
|
||||
# https://docs.djangoproject.com/en/3.1/topics/cache/#cache-arguments
|
||||
CACHES = {
|
||||
'default': {
|
||||
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
|
||||
'LOCATION': '/var/tmp/django_cache',
|
||||
'TIMEOUT': None,
|
||||
}
|
||||
}
|
||||
|
||||
# per-site cache
|
||||
# updatecachemiddleware: adds 'Expires' and 'Cache-Control' headers to give the
|
||||
# page a maximum age CACHE_MIDDLEWARE_SECONDS
|
||||
# CACHE_MIDDLEWARE_ALIAS = 'default'
|
||||
# CACHE_MIDDLEWARE_SECONDS = 600
|
||||
|
Loading…
x
Reference in New Issue
Block a user