Commit c634caa8846537b73dcae80f8a6d33e7943c1d95
1 parent
4adb7f10
Exists in
master
and in
3 other branches
Adding Log app
Showing
6 changed files
with
210 additions
and
2 deletions
Show diff stats
log/admin.py
| 1 | 1 | from django.contrib import admin |
| 2 | 2 | |
| 3 | -# Register your models here. | |
| 3 | +from .models import Log | |
| 4 | + | |
| 5 | +class LogAdmin(admin.ModelAdmin): | |
| 6 | + list_display = ['datetime', 'user', 'action', 'resource', 'context'] | |
| 7 | + search_fields = ['user', 'action', 'resource'] | |
| 8 | + | |
| 9 | +admin.site.register(Log, LogAdmin) | |
| 4 | 10 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,78 @@ |
| 1 | +import json | |
| 2 | +import time | |
| 3 | +from functools import wraps | |
| 4 | +from django.shortcuts import get_object_or_404 | |
| 5 | + | |
| 6 | +from .models import Log | |
| 7 | + | |
| 8 | +def log_decorator(log_component = '', log_action = '', log_resource = ''): | |
| 9 | + | |
| 10 | + def _log_decorator(view_function): | |
| 11 | + | |
| 12 | + def _decorator(request, *args, **kwargs): | |
| 13 | + | |
| 14 | + response = view_function(request, *args, **kwargs) | |
| 15 | + | |
| 16 | + if request.user.is_authenticated: | |
| 17 | + | |
| 18 | + log = Log() | |
| 19 | + log.user = request.user | |
| 20 | + log.component = log_component | |
| 21 | + log.context = request.log_context | |
| 22 | + log.action = log_action | |
| 23 | + log.resource = log_resource | |
| 24 | + | |
| 25 | + log.save() | |
| 26 | + | |
| 27 | + return response | |
| 28 | + | |
| 29 | + return wraps(view_function)(_decorator) | |
| 30 | + | |
| 31 | + return _log_decorator | |
| 32 | + | |
| 33 | +def log_decorator_ajax(log_component = '', log_action = '', log_resource = ''): | |
| 34 | + | |
| 35 | + def _log_decorator_ajax(view_function): | |
| 36 | + | |
| 37 | + def _decorator(request, *args, **kwargs): | |
| 38 | + view_action = request.GET.get("action") | |
| 39 | + | |
| 40 | + if view_action == 'open': | |
| 41 | + if request.user.is_authenticated: | |
| 42 | + | |
| 43 | + log = Log() | |
| 44 | + log.user = request.user | |
| 45 | + log.component = log_component | |
| 46 | + log.context = "" | |
| 47 | + log.action = log_action | |
| 48 | + log.resource = log_resource | |
| 49 | + | |
| 50 | + log.save() | |
| 51 | + | |
| 52 | + response = view_function(request, *args, **kwargs) | |
| 53 | + | |
| 54 | + log = Log.objects.latest('id') | |
| 55 | + log.context = request.log_context | |
| 56 | + log.save() | |
| 57 | + elif view_action == 'close': | |
| 58 | + if request.user.is_authenticated: | |
| 59 | + log = get_object_or_404(Log, id = request.GET.get('log_id')) | |
| 60 | + | |
| 61 | + if type(log.context) == dict: | |
| 62 | + log_context = log.context | |
| 63 | + else: | |
| 64 | + log_context = json.loads(log.context) | |
| 65 | + | |
| 66 | + log_context['timestamp_end'] = str(int(time.time())) | |
| 67 | + | |
| 68 | + log.context = log_context | |
| 69 | + | |
| 70 | + log.save() | |
| 71 | + | |
| 72 | + response = view_function(request, *args, **kwargs) | |
| 73 | + | |
| 74 | + return response | |
| 75 | + | |
| 76 | + return wraps(view_function)(_decorator) | |
| 77 | + | |
| 78 | + return _log_decorator_ajax | |
| 0 | 79 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,47 @@ |
| 1 | +import time | |
| 2 | +import json | |
| 3 | +from django.core.urlresolvers import resolve | |
| 4 | +from django.shortcuts import get_object_or_404 | |
| 5 | + | |
| 6 | +from .models import Log | |
| 7 | + | |
| 8 | +class TimeSpentMiddleware(object): | |
| 9 | + def __init__(self, get_response = None): | |
| 10 | + self.get_response = get_response | |
| 11 | + | |
| 12 | + def process_request(self, request): | |
| 13 | + app_names = resolve(request.path).app_names | |
| 14 | + | |
| 15 | + if not 'admin' in app_names: | |
| 16 | + if not request.is_ajax(): | |
| 17 | + log_id = request.session.get('log_id', None) | |
| 18 | + | |
| 19 | + if not log_id is None: | |
| 20 | + log = get_object_or_404(Log, id = log_id) | |
| 21 | + | |
| 22 | + if type(log.context) == dict: | |
| 23 | + log_context = log.context | |
| 24 | + else: | |
| 25 | + log_context = json.loads(log.context) | |
| 26 | + | |
| 27 | + log_context['timestamp_end'] = str(int(time.time())) | |
| 28 | + | |
| 29 | + log.context = log_context | |
| 30 | + | |
| 31 | + log.save() | |
| 32 | + | |
| 33 | + request.session['log_id'] = None | |
| 34 | + | |
| 35 | + oppened_logs = Log.objects.filter(user = request.user, context__contains={'timestamp_end': '-1'}) | |
| 36 | + | |
| 37 | + for op_log in oppened_logs: | |
| 38 | + if type(op_log.context) == dict: | |
| 39 | + log_context = op_log.context | |
| 40 | + else: | |
| 41 | + log_context = json.loads(op_log.context) | |
| 42 | + | |
| 43 | + log_context['timestamp_end'] = str(int(time.time())) | |
| 44 | + | |
| 45 | + op_log.context = log_context | |
| 46 | + | |
| 47 | + op_log.save() | |
| 0 | 48 | \ No newline at end of file | ... | ... |
| ... | ... | @@ -0,0 +1,36 @@ |
| 1 | +# -*- coding: utf-8 -*- | |
| 2 | +# Generated by Django 1.10 on 2016-12-29 20:07 | |
| 3 | +from __future__ import unicode_literals | |
| 4 | + | |
| 5 | +from django.conf import settings | |
| 6 | +import django.contrib.postgres.fields.jsonb | |
| 7 | +from django.db import migrations, models | |
| 8 | +import django.db.models.deletion | |
| 9 | + | |
| 10 | + | |
| 11 | +class Migration(migrations.Migration): | |
| 12 | + | |
| 13 | + initial = True | |
| 14 | + | |
| 15 | + dependencies = [ | |
| 16 | + migrations.swappable_dependency(settings.AUTH_USER_MODEL), | |
| 17 | + ] | |
| 18 | + | |
| 19 | + operations = [ | |
| 20 | + migrations.CreateModel( | |
| 21 | + name='Log', | |
| 22 | + fields=[ | |
| 23 | + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |
| 24 | + ('component', models.TextField(verbose_name='Component (Module / App)')), | |
| 25 | + ('context', django.contrib.postgres.fields.jsonb.JSONField(blank=True, verbose_name='Context')), | |
| 26 | + ('action', models.TextField(verbose_name='Action')), | |
| 27 | + ('resource', models.TextField(verbose_name='Resource')), | |
| 28 | + ('datetime', models.DateTimeField(auto_now_add=True, verbose_name='Date and Time of action')), | |
| 29 | + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Actor')), | |
| 30 | + ], | |
| 31 | + options={ | |
| 32 | + 'verbose_name_plural': 'Logs', | |
| 33 | + 'verbose_name': 'Log', | |
| 34 | + }, | |
| 35 | + ), | |
| 36 | + ] | ... | ... |
| ... | ... | @@ -0,0 +1,24 @@ |
| 1 | +import json | |
| 2 | + | |
| 3 | +from .models import Log | |
| 4 | + | |
| 5 | +from users.models import User | |
| 6 | + | |
| 7 | +class LogMixin(object): | |
| 8 | + log_component = "" | |
| 9 | + log_context = {} | |
| 10 | + log_action = "" | |
| 11 | + log_resource = "" | |
| 12 | + | |
| 13 | + def createLog(self, actor = None, component = '', log_action = '', log_resource = '', context = {}): | |
| 14 | + log = Log() | |
| 15 | + log.user = actor | |
| 16 | + log.context = context | |
| 17 | + log.component = component | |
| 18 | + log.action = log_action | |
| 19 | + log.resource = log_resource | |
| 20 | + | |
| 21 | + log.save() | |
| 22 | + | |
| 23 | + def dispatch(self, request, *args, **kwargs): | |
| 24 | + return super(LogMixin, self).dispatch(request, *args, **kwargs) | |
| 0 | 25 | \ No newline at end of file | ... | ... |
log/models.py
| 1 | 1 | from django.db import models |
| 2 | +from django.contrib.postgres.fields import JSONField | |
| 3 | +from django.utils.translation import ugettext_lazy as _ | |
| 2 | 4 | |
| 3 | -# Create your models here. | |
| 5 | +from users.models import User | |
| 6 | + | |
| 7 | +class Log(models.Model): | |
| 8 | + component = models.TextField(_('Component (Module / App)')) | |
| 9 | + context = JSONField(_('Context'), blank = True) | |
| 10 | + action = models.TextField(_('Action')) | |
| 11 | + resource = models.TextField(_('Resource')) | |
| 12 | + user = models.ForeignKey(User, verbose_name = _('Actor')) | |
| 13 | + datetime = models.DateTimeField(_("Date and Time of action"), auto_now_add = True) | |
| 14 | + | |
| 15 | + class Meta: | |
| 16 | + verbose_name = _('Log') | |
| 17 | + verbose_name_plural = _('Logs') | |
| 18 | + | |
| 19 | + def __str__(self): | |
| 20 | + return str(self.user) + ' / ' + self.component | |
| 4 | 21 | \ No newline at end of file | ... | ... |