Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions labAdmin/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
UserProfile,
)

from .arp import get_neighbours


class CardAdmin(admin.ModelAdmin):
list_display = ('nfc_id', 'user', 'credits')
Expand Down Expand Up @@ -66,6 +68,22 @@ class CategoryAdmin(admin.ModelAdmin):
class DeviceAdmin(admin.ModelAdmin):
list_display = ('name', 'hourlyCost', 'category', 'mac', 'last_activity')
ordering = ('name',)
change_form_template = 'labadmin/admin/device_change_form.html'
add_form_template = 'labadmin/admin/device_change_form.html'

def change_view(self, request, object_id, form_url='', extra_context=None):
extra_context = extra_context or {}
extra_context['labadmin_available_devices'] = get_neighbours()
return super(DeviceAdmin, self).change_view(
request, object_id, form_url, extra_context=extra_context
)

def add_view(self, request, form_url='', extra_context=None):
extra_context = extra_context or {}
extra_context['labadmin_available_devices'] = get_neighbours()
return super(DeviceAdmin, self).add_view(
request, form_url, extra_context=extra_context
)

admin.site.register(Device, DeviceAdmin)

Expand Down
20 changes: 20 additions & 0 deletions labAdmin/arp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
IP_INDEX = 0
MAC_INDEX = 3
NUM_FIELDS = 6


def get_neighbours():
"""
Returns a generator of ip address, mac address tuples.
Empty mac addresses are filtered out.
"""
with open('/proc/net/arp', 'r') as f:
# skip header
next(f)
for row in f:
fields = row.split()
if len(fields) < NUM_FIELDS:
continue
if fields[MAC_INDEX] == '00:00:00:00:00:00':
continue
yield fields[IP_INDEX], fields[MAC_INDEX]
43 changes: 43 additions & 0 deletions labAdmin/templates/labadmin/admin/device_change_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{% extends "admin/change_form.html" %}
{% load i18n admin_urls %}

{% block object-tools %}
{% if not is_popup %}
<ul class="object-tools">
{% block object-tools-items %}
{% if change %}
<li>
{% url opts|admin_urlname:'history' original.pk|admin_urlquote as history_url %}
<a href="{% add_preserved_filters history_url %}" class="historylink">{% trans "History" %}</a>
</li>
{% if has_absolute_url %}<li><a href="{{ absolute_url }}" class="viewsitelink">{% trans "View on site" %}</a></li>{% endif %}
{% endif %}
{% if labadmin_available_devices %}<li><a id="labadmin-available-devices-toggle" href="" class="viewsitelink">{% trans "Available Devices" %}</a></li>
<div id="labadmin-available-devices" style="display: none">
<table>
<tr>
<th>IP</th>
<th>MAC</th>
</tr>
{% for ip, mac in labadmin_available_devices %}
<tr>
<td>{{ ip }}</td>
<td>{{ mac }}</td>
</tr>
{% endfor %}
</table>
</div>
{% endif %}
{% endblock %}
</ul>
{% endif %}
{% endblock %}

{% block admin_change_form_document_ready %}
<script type="text/javascript">
django.jQuery('#labadmin-available-devices-toggle').click(function(event) {
event.preventDefault();
django.jQuery('#labadmin-available-devices').toggle();
});
</script>
{% endblock %}
18 changes: 18 additions & 0 deletions labAdmin/tests.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import datetime
import json
import io

from unittest.mock import mock_open, patch

from django.contrib.auth.models import User
from django.test import TestCase, Client, override_settings
Expand All @@ -13,6 +16,7 @@
Card, Group, LogAccess, Role, TimeSlot, UserProfile,
LogCredits, Category, Device, LogDevice, LogError
)
from .arp import get_neighbours


class TestLabAdmin(TestCase):
Expand Down Expand Up @@ -518,3 +522,17 @@ def test_timeslot_manager_now(self):
self.assertTrue(ts_now.exists())
self.assertEqual(ts_now.count(), 1)
self.assertEqual(ts_now.first().pk, open_ts.pk)


class ArpTests(TestCase):
def test_read_neighbours(self):
data = io.StringIO('\n'.join([
'IP address HW type Flags HW address Mask Device',
'10.120.0.124 0x1 0x2 55:54:00:4a:b0:35 * wlan0',
'10.120.71.14 0x1 0x2 e4:2d:8c:5e:05:18 *',
'169.254.52.147 0x1 0x0 00:00:00:00:00:00 * virbr0'
]))
with patch('builtins.open', return_value=data, create=True) as m:
result = list(get_neighbours())

self.assertEqual(result, [('10.120.0.124', '55:54:00:4a:b0:35')])