Update login system to support the multiple threads of UWSGI

This commit is contained in:
Skia 2016-08-26 20:56:16 +02:00
parent b33c3b20bb
commit 9927310f6e
6 changed files with 134 additions and 44 deletions

View File

@ -291,6 +291,12 @@ label {
#user_edit img { #user_edit img {
width: 100px; width: 100px;
} }
#cash_summary_form label {
display: inline;
}
.inline {
display: inline;
}
.form_button { .form_button {
width: 150px; width: 150px;
height: 120px; height: 120px;

View File

@ -0,0 +1,54 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
from django.conf import settings
import accounting.models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('counter', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='CashRegisterSummary',
fields=[
('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)),
('date', models.DateTimeField(verbose_name='date')),
('comment', models.TextField(null=True, verbose_name='comment', blank=True)),
('emptied', models.BooleanField(default=False, verbose_name='emptied')),
('counter', models.ForeignKey(to='counter.Counter', related_name='cash_summaries', verbose_name='counter')),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='cash_summaries', verbose_name='user')),
],
options={
'verbose_name': 'cash register summary',
},
),
migrations.CreateModel(
name='CashRegisterSummaryItem',
fields=[
('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, auto_created=True)),
('value', accounting.models.CurrencyField(max_digits=12, verbose_name='value', decimal_places=2)),
('quantity', models.IntegerField(default=0, verbose_name='quantity')),
('check', models.BooleanField(default=False, verbose_name='check')),
('cash_summary', models.ForeignKey(to='counter.CashRegisterSummary', related_name='items', verbose_name='cash summary')),
],
options={
'verbose_name': 'cash register summary item',
},
),
migrations.AlterField(
model_name='permanency',
name='counter',
field=models.ForeignKey(to='counter.Counter', related_name='permanencies', verbose_name='counter'),
),
migrations.AlterField(
model_name='permanency',
name='user',
field=models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='permanencies', verbose_name='user'),
),
]

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import datetime
from django.utils.timezone import utc
class Migration(migrations.Migration):
dependencies = [
('counter', '0002_auto_20160826_1342'),
]
operations = [
migrations.AddField(
model_name='permanency',
name='activity',
field=models.DateTimeField(verbose_name='activity time', auto_now=True, default=datetime.datetime(2016, 8, 26, 17, 5, 31, 202824, tzinfo=utc)),
preserve_default=False,
),
]

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('counter', '0003_permanency_activity'),
]
operations = [
migrations.AlterField(
model_name='permanency',
name='end',
field=models.DateTimeField(verbose_name='end date', null=True),
),
]

View File

@ -109,15 +109,14 @@ class Product(models.Model):
class Counter(models.Model): class Counter(models.Model):
name = models.CharField(_('name'), max_length=30) name = models.CharField(_('name'), max_length=30)
club = models.ForeignKey(Club, related_name="counters") club = models.ForeignKey(Club, related_name="counters", verbose_name=_("club"))
products = models.ManyToManyField(Product, related_name="counters", blank=True) products = models.ManyToManyField(Product, related_name="counters", verbose_name=_("products"), blank=True)
type = models.CharField(_('counter type'), type = models.CharField(_('counter type'),
max_length=255, max_length=255,
choices=[('BAR',_('Bar')), ('OFFICE',_('Office')), ('EBOUTIC',_('Eboutic'))]) choices=[('BAR',_('Bar')), ('OFFICE',_('Office')), ('EBOUTIC',_('Eboutic'))])
sellers = models.ManyToManyField(Subscriber, verbose_name=_('sellers'), related_name='counters', blank=True) sellers = models.ManyToManyField(Subscriber, verbose_name=_('sellers'), related_name='counters', blank=True)
edit_groups = models.ManyToManyField(Group, related_name="editable_counters", blank=True) edit_groups = models.ManyToManyField(Group, related_name="editable_counters", blank=True)
view_groups = models.ManyToManyField(Group, related_name="viewable_counters", blank=True) view_groups = models.ManyToManyField(Group, related_name="viewable_counters", blank=True)
barmen_session = {}
class Meta: class Meta:
verbose_name = _('counter') verbose_name = _('counter')
@ -144,31 +143,21 @@ class Counter(models.Model):
sub = get_subscriber(request.user) sub = get_subscriber(request.user)
return user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) or sub in self.sellers return user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) or sub in self.sellers
def add_barman(counter_id, user_id): def add_barman(self, user):
""" """
Logs a barman in to the given counter Logs a barman in to the given counter
A user is stored as a tuple with its login time A user is stored as a tuple with its login time
""" """
counter_id = int(counter_id) Permanency(user=user, counter=self, start=timezone.now(), end=None).save()
user_id = int(user_id)
if counter_id not in Counter.barmen_session.keys():
Counter.barmen_session[counter_id] = {'users': {(user_id, timezone.now())}, 'time': timezone.now()}
else:
Counter.barmen_session[counter_id]['users'].add((user_id, timezone.now()))
def del_barman(counter_id, user_id): def del_barman(self, user):
""" """
Logs a barman out and store its permanency Logs a barman out and store its permanency
""" """
counter_id = int(counter_id) perm = Permanency.objects.filter(counter=self, user=user, end=None).all()
user_id = int(user_id) for p in perm:
user_tuple = None p.end = p.activity
for t in Counter.barmen_session[counter_id]['users']: p.save()
if t[0] == user_id: user_tuple = t
Counter.barmen_session[counter_id]['users'].remove(user_tuple)
u = User.objects.filter(id=user_id).first()
c = Counter.objects.filter(id=counter_id).first()
Permanency(user=u, counter=c, start=user_tuple[1], end=Counter.barmen_session[counter_id]['time']).save()
def get_barmen_list(self): def get_barmen_list(self):
""" """
@ -176,19 +165,15 @@ class Counter(models.Model):
Also handle the timeout of the barmen Also handle the timeout of the barmen
""" """
pl = Permanency.objects.filter(counter=self, end=None).all()
bl = [] bl = []
counter_id = self.id for p in pl:
if counter_id in list(Counter.barmen_session.keys()): if timezone.now() - p.activity < timedelta(minutes=settings.SITH_BARMAN_TIMEOUT):
for b in Counter.barmen_session[counter_id]['users']: p.save() # Update activity
# Reminder: user is stored as a tuple with its login time bl.append(p.user)
bl.append(User.objects.filter(id=b[0]).first())
if (timezone.now() - Counter.barmen_session[counter_id]['time']) < timedelta(minutes=settings.SITH_BARMAN_TIMEOUT):
Counter.barmen_session[counter_id]['time'] = timezone.now()
else: else:
for b in bl: p.end = p.activity
Counter.del_barman(counter_id, b.id) p.save()
bl = []
Counter.barmen_session[counter_id]['users'] = set()
return bl return bl
def get_random_barman(self): def get_random_barman(self):
@ -292,10 +277,11 @@ class Permanency(models.Model):
""" """
This class aims at storing a traceability of who was barman where and when This class aims at storing a traceability of who was barman where and when
""" """
user = models.ForeignKey(User, related_name="permanencies") user = models.ForeignKey(User, related_name="permanencies", verbose_name=_("user"))
counter = models.ForeignKey(Counter, related_name="permanencies") counter = models.ForeignKey(Counter, related_name="permanencies", verbose_name=_("counter"))
start = models.DateTimeField(_('start date')) start = models.DateTimeField(_('start date'))
end = models.DateTimeField(_('end date')) end = models.DateTimeField(_('end date'), null=True)
activity = models.DateTimeField(_('last activity date'), auto_now=True)
class Meta: class Meta:
verbose_name = _("permanency") verbose_name = _("permanency")

View File

@ -19,9 +19,10 @@ from ajax_select import make_ajax_form, make_ajax_field
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, CanCreateMixin
from core.views.forms import SelectUser from core.views.forms import SelectUser
from core.models import User
from subscription.models import Subscriber from subscription.models import Subscriber
from subscription.views import get_subscriber from subscription.views import get_subscriber
from counter.models import Counter, Customer, Product, Selling, Refilling, ProductType from counter.models import Counter, Customer, Product, Selling, Refilling, ProductType, CashRegisterSummary, CashRegisterSummaryItem
class GetUserForm(forms.Form): class GetUserForm(forms.Form):
""" """
@ -212,7 +213,7 @@ class CounterClick(DetailView):
product = self.get_product(pid) product = self.get_product(pid)
can_buy = False can_buy = False
for g in product.buying_groups.all(): for g in product.buying_groups.all():
if request.user.is_in_group(g.name): if self.customer.user.is_in_group(g.name):
can_buy = True can_buy = True
if not can_buy: if not can_buy:
request.session['not_allowed'] = True request.session['not_allowed'] = True
@ -343,12 +344,13 @@ class CounterLogin(RedirectView):
Register the logged user as barman for this counter Register the logged user as barman for this counter
""" """
self.counter_id = kwargs['counter_id'] self.counter_id = kwargs['counter_id']
self.counter = Counter.objects.filter(id=kwargs['counter_id']).first()
form = AuthenticationForm(request, data=request.POST) form = AuthenticationForm(request, data=request.POST)
self.errors = [] self.errors = []
if form.is_valid(): if form.is_valid():
user = Subscriber.objects.filter(username=form.cleaned_data['username']).first() user = User.objects.filter(username=form.cleaned_data['username']).first()
if user.is_subscribed(): if user.is_in_group(settings.SITH_MAIN_MEMBERS_GROUP) and not user in self.counter.get_barmen_list():
Counter.add_barman(self.counter_id, user.id) self.counter.add_barman(user)
else: else:
self.errors += ["subscription"] self.errors += ["subscription"]
else: else:
@ -364,8 +366,9 @@ class CounterLogout(RedirectView):
""" """
Unregister the user from the barman Unregister the user from the barman
""" """
self.counter_id = kwargs['counter_id'] self.counter = Counter.objects.filter(id=kwargs['counter_id']).first()
Counter.del_barman(self.counter_id, request.POST['user_id']) user = User.objects.filter(id=request.POST['user_id']).first()
self.counter.del_barman(user)
return super(CounterLogout, self).post(request, *args, **kwargs) return super(CounterLogout, self).post(request, *args, **kwargs)
def get_redirect_url(self, *args, **kwargs): def get_redirect_url(self, *args, **kwargs):
@ -384,8 +387,8 @@ class CounterEditForm(forms.ModelForm):
class Meta: class Meta:
model = Counter model = Counter
fields = ['sellers', 'products'] fields = ['sellers', 'products']
sellers = make_ajax_field(Counter, 'sellers', 'users', show_help_text=False) sellers = make_ajax_field(Counter, 'sellers', 'users', help_text="")
products = make_ajax_field(Counter, 'products', 'products') products = make_ajax_field(Counter, 'products', 'products', help_text="")
class CounterEditView(CanEditMixin, UpdateView): class CounterEditView(CanEditMixin, UpdateView):
""" """
@ -394,7 +397,7 @@ class CounterEditView(CanEditMixin, UpdateView):
model = Counter model = Counter
form_class = CounterEditForm form_class = CounterEditForm
pk_url_kwarg = "counter_id" pk_url_kwarg = "counter_id"
template_name = 'counter/counter_edit.jinja' template_name = 'core/edit.jinja'
def get_success_url(self): def get_success_url(self):
return reverse_lazy('counter:admin', kwargs={'counter_id': self.object.id}) return reverse_lazy('counter:admin', kwargs={'counter_id': self.object.id})