diff --git a/netbox/extras/migrations/0005_auto_20160524_1324.py b/netbox/extras/migrations/0005_auto_20160524_1324.py
new file mode 100644
index 000000000..d1c214a75
--- /dev/null
+++ b/netbox/extras/migrations/0005_auto_20160524_1324.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.5 on 2016-05-24 13:24
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('extras', '0004_useraction'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='useraction',
+ name='user',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='actions', to=settings.AUTH_USER_MODEL),
+ ),
+ ]
diff --git a/netbox/extras/models.py b/netbox/extras/models.py
index 9dba10bd4..a3396124e 100644
--- a/netbox/extras/models.py
+++ b/netbox/extras/models.py
@@ -3,6 +3,7 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.http import HttpResponse
from django.template import Template, Context
+from django.utils.safestring import mark_safe
from dcim.models import Site
@@ -156,7 +157,7 @@ class UserAction(models.Model):
A record of an action (add, edit, or delete) performed on an object by a User.
"""
time = models.DateTimeField(auto_now_add=True, editable=False)
- user = models.ForeignKey(User, on_delete=models.CASCADE)
+ user = models.ForeignKey(User, related_name='actions', on_delete=models.CASCADE)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField(blank=True, null=True)
action = models.PositiveSmallIntegerField(choices=ACTION_CHOICES)
@@ -166,3 +167,18 @@ class UserAction(models.Model):
class Meta:
ordering = ['-time']
+
+ def __unicode__(self):
+ if self.message:
+ return ' '.join([self.user, self.message])
+ return ' '.join([self.user, self.get_action_display(), self.content_type])
+
+ def icon(self):
+ if self.action in [ACTION_CREATE, ACTION_IMPORT]:
+ return mark_safe('')
+ elif self.action in [ACTION_EDIT, ACTION_BULK_EDIT]:
+ return mark_safe('')
+ elif self.action in [ACTION_DELETE, ACTION_BULK_DELETE]:
+ return mark_safe('')
+ else:
+ return ''
diff --git a/netbox/netbox/views.py b/netbox/netbox/views.py
index e0ce6803c..0197a7dd5 100644
--- a/netbox/netbox/views.py
+++ b/netbox/netbox/views.py
@@ -36,7 +36,7 @@ def home(request):
return render(request, 'home.html', {
'stats': stats,
- 'recent_activity': UserAction.objects.all()[:20]
+ 'recent_activity': UserAction.objects.all()[:15]
})
diff --git a/netbox/templates/home.html b/netbox/templates/home.html
index ccdb2cbd2..9609c9023 100644
--- a/netbox/templates/home.html
+++ b/netbox/templates/home.html
@@ -47,100 +47,104 @@
-
-
-
-
DCIM
+
+
+
+
+
+ DCIM
+
+
+
+
{{ stats.site_count }}
+
+
Geographic locations
+
+
+
{{ stats.rack_count }}
+
+
Equipment racks, optionally organized by group
+
+
+
{{ stats.device_count }}
+
+
Rack-mounted network equipment, servers, and other devices
+
+
+
Connections
+
{{ stats.interface_connections_count }}
+
Interfaces
+
{{ stats.console_connections_count }}
+
Console
+
{{ stats.power_connections_count }}
+
Power
+
+
+
+ {% if perms.secrets %}
+
+
+ Secrets
+
+
+
+
{{ stats.secret_count }}
+
+
Sensitive data (such as passwords) which has been stored securely
+
+
+
+ {% endif %}
-
-
-
{{ stats.site_count }}
-
-
Geographic locations
+
+
+
+ IPAM
+
+
+
+
{{ stats.aggregate_count }}
+
+
Top-level IP allocations
+
+
+
{{ stats.prefix_count }}
+
+
IPv4 and IPv6 network assignments
+
+
+
{{ stats.ipaddress_count }}
+
+
Individual IPv4 and IPv6 addresses
+
+
+
{{ stats.vlan_count }}
+
+
Layer two domains, identified by VLAN ID
+
+
-
-
{{ stats.rack_count }}
-
-
Equipment racks, optionally organized by group
-
-
-
{{ stats.device_count }}
-
-
Rack-mounted network equipment, servers, and other devices
-
-
-
Connections
-
{{ stats.interface_connections_count }}
-
Interfaces
-
{{ stats.console_connections_count }}
-
Console
-
{{ stats.power_connections_count }}
-
Power
-
-
-
- {% if perms.secrets %}
-
-
- Secrets
-
-
-
-
{{ stats.secret_count }}
-
-
Sensitive data (such as passwords) which has been stored securely
+
+
+ Circuits
+
+
+
+
{{ stats.provider_count }}
+
+
Organizations which provide circuit connectivity
+
+
+
{{ stats.circuit_count }}
+
+
Communication links for Internet transit, peering, and other services
+
- {% endif %}
-
-
-
-
- IPAM
-
-
-
-
{{ stats.aggregate_count }}
-
-
Top-level IP allocations
-
-
-
{{ stats.prefix_count }}
-
-
IPv4 and IPv6 network assignments
-
-
-
{{ stats.ipaddress_count }}
-
-
Individual IPv4 and IPv6 addresses
-
-
-
{{ stats.vlan_count }}
-
-
Layer two domains, identified by VLAN ID
-
-
-
-
-
- Circuits
-
-
-
-
{{ stats.provider_count }}
-
-
Organizations which provide circuit connectivity
-
-
-
{{ stats.circuit_count }}
-
-
Communication links for Internet transit, peering, and other services
-
-
-
+
Recent Activity
@@ -150,7 +154,7 @@
{{ a.time|date:"Y-m-d H:i" }} |
{{ a.user }} |
- {{ a.message|safe }} |
+ {{ a.icon }} {{ a.message|safe }} |
{% endfor %}
diff --git a/netbox/templates/users/inc/profile_nav.html b/netbox/templates/users/inc/profile_nav.html
index f21db3e1d..c5b1791bb 100644
--- a/netbox/templates/users/inc/profile_nav.html
+++ b/netbox/templates/users/inc/profile_nav.html
@@ -2,4 +2,5 @@
Profile
Change Password
User Key
+
Recent Activity
diff --git a/netbox/templates/users/recent_activity.html b/netbox/templates/users/recent_activity.html
new file mode 100644
index 000000000..76b8c3f54
--- /dev/null
+++ b/netbox/templates/users/recent_activity.html
@@ -0,0 +1,35 @@
+{% extends '_base.html' %}
+{% load form_helpers %}
+
+{% block title %}Recent Activity{% endblock %}
+
+{% block content %}
+
+
+
+ {% include 'users/inc/profile_nav.html' with active_tab="recent_activity" %}
+
+
+
+
+
+ Time |
+ Action |
+
+
+
+ {% for action in recent_activity %}
+
+ {{ action.time|date:"Y-m-d H:i" }} |
+ {{ action.icon }} {{ action.message|safe }} |
+
+ {% endfor %}
+
+
+
+
+{% endblock %}
diff --git a/netbox/users/urls.py b/netbox/users/urls.py
index 4e38050f1..d33d14beb 100644
--- a/netbox/users/urls.py
+++ b/netbox/users/urls.py
@@ -10,5 +10,6 @@ urlpatterns = [
url(r'^profile/password/$', views.change_password, name='change_password'),
url(r'^profile/user-key/$', views.userkey, name='userkey'),
url(r'^profile/user-key/edit/$', views.userkey_edit, name='userkey_edit'),
+ url(r'^profile/recent-activity/$', views.recent_activity, name='recent_activity'),
]
diff --git a/netbox/users/views.py b/netbox/users/views.py
index 0337833b8..7a01539b7 100644
--- a/netbox/users/views.py
+++ b/netbox/users/views.py
@@ -116,3 +116,11 @@ def userkey_edit(request):
'userkey': userkey,
'form': form,
})
+
+
+@login_required()
+def recent_activity(request):
+
+ return render(request, 'users/recent_activity.html', {
+ 'recent_activity': request.user.actions.all()[:50]
+ })