Skip to content
This repository has been archived by the owner on May 14, 2021. It is now read-only.

Commit

Permalink
Merge pull request #6 from OfficineArduinoTorino/showlogdevice
Browse files Browse the repository at this point in the history
Show device last activity in the admin
  • Loading branch information
mastrolinux authored Jan 25, 2017
2 parents 28a81c0 + 03d4c22 commit 320c58d
Show file tree
Hide file tree
Showing 7 changed files with 327 additions and 76 deletions.
2 changes: 1 addition & 1 deletion labAdmin/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class CategoryAdmin(admin.ModelAdmin):


class DeviceAdmin(admin.ModelAdmin):
list_display = ('name', 'hourlyCost', 'category', 'mac',)
list_display = ('name', 'hourlyCost', 'category', 'mac', 'last_activity')
ordering = ('name',)

admin.site.register(Device, DeviceAdmin)
Expand Down
22 changes: 1 addition & 21 deletions labAdmin/functions.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
from labAdmin.models import (
Device, UserProfile
Device
)


def get_user_or_None(id):
"""
Function that return the UserProfile that has the id passed as parameter else returns None
"""
try:
u = UserProfile.objects.get(id=id)
return u
except UserProfile.DoesNotExist:
return None

def get_device_by_mac_or_None(mac):
"""
Function that return the Device that has the mac passed as parameter else returns None
Expand All @@ -22,13 +12,3 @@ def get_device_by_mac_or_None(mac):
return d
except Device.DoesNotExist:
return None

def get_device_or_None(id):
"""
Function that return the Device that has the id passed as parameter else returns None
"""
try:
d = Device.objects.get(id=id)
return d
except Device.DoesNotExist:
return None
30 changes: 21 additions & 9 deletions labAdmin/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,10 @@ def can_open_door_now(self):
).exists()

def can_use_device_now(self, device):
try:
return TimeSlot.objects.can_now().filter(role__group__user=self,role__role_kind=1, role__category_device=device.category_device, role__valid=True).exists()
except:
# Any Exception Return False
return False
roles = self.groups.values_list('roles__pk', flat=True).distinct()
return TimeSlot.objects.can_now().filter(
role__in=roles, role__role_kind=1, role__valid=True
).exists()

def displaygroups(self):
data = []
Expand Down Expand Up @@ -191,6 +190,14 @@ class Device(models.Model):
def __str__(self):
return "%010d - %s" %(self.id, self.name)

def last_activity(self):
logdevice = self.logdevice_set.order_by('-id').first()
if not logdevice:
return ''
if logdevice.inWorking:
return timezone.now()
return logdevice.finishWork

def save(self, *args, **kwargs):
if not self.token:
self.token = str(uuid.uuid4())
Expand Down Expand Up @@ -234,13 +241,18 @@ class LogDevice(models.Model):
inWorking=models.BooleanField(default=True)

def priceWork(self):
c = (finishWork-startWork)
duration = 0.01*decimal.Decimal((c.days*24+c.seconds/3600)*100)
return 'inWorking...' if self.inWorking else self.hourlyCost*duration
if self.inWorking:
return 'inWorking...'
delta = self.finishWork - self.startWork
duration = delta.total_seconds() / 3600
return round(self.hourlyCost * duration, 2)

def stop(self):
n = timezone.now()
self.finishWork = self.shutdownDevice = n
self.inWorking = False
self.finishWork = n
self.shutdownDevice = n
self.save(update_fields=['finishWork', 'shutdownDevice', 'inWorking'])

def __str__(self):
return "user: %s\ndevice: %s\nboot: %s\nstart: %s\ninWorking: %s\nHourlyCost: %f" %(self.user, self.device, self.bootDevice, self.startWork, "yes" if self.inWorking else "no\nshutdown: %s\nfinish: %s"%(self.shutdownDevice, self.finishWork), self.hourlyCost)
Expand Down
24 changes: 16 additions & 8 deletions labAdmin/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,24 @@
from .models import Device


class DeviceTokenPermission(BasePermission):
def has_permission(self, request, view):
auth = get_authorization_header(request).split()
def get_token_from_request(request):
auth = get_authorization_header(request).split()

if len(auth) != 2:
return False
if len(auth) != 2:
return None

try:
token = auth[1].decode()
except UnicodeError:
try:
token = auth[1].decode()
except UnicodeError:
return None

return token


class DeviceTokenPermission(BasePermission):
def has_permission(self, request, view):
token = get_token_from_request(request)
if not token:
return False

try:
Expand Down
201 changes: 200 additions & 1 deletion labAdmin/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from .models import (
Card, Group, LogAccess, Role, TimeSlot, UserProfile, TimeSlot,
LogCredits, Category, Device
LogCredits, Category, Device, LogDevice
)


Expand All @@ -29,6 +29,13 @@ def setUpTestData(cls):
hour_start=dateparse.parse_time("14:0:0"),
hour_end=dateparse.parse_time("20:0:0"),
)
full_timeslot = TimeSlot.objects.create(
name="any day",
weekday_start=1,
weekday_end=7,
hour_start=dateparse.parse_time("00:00:00"),
hour_end=dateparse.parse_time("23:59:59"),
)

fablab_role = Role.objects.create(
name="Fablab Access",
Expand All @@ -42,10 +49,18 @@ def setUpTestData(cls):
)
guest_role.time_slots.add(reduced_timeslot)

full_devices_role = Role.objects.create(
name="Devices Access",
role_kind=1
)
full_devices_role.time_slots.add(full_timeslot)

fab_guest_group = Group.objects.create(name="Fablab Guest")
fab_guest_group.roles.add(fablab_role, guest_role)
guest_group = Group.objects.create(name="Guest")
guest_group.roles.add(guest_role)
devices_group = Group.objects.create(name="Full Devices access")
devices_group.roles.add(full_devices_role)

card = Card.objects.create(nfc_id=123456)
user = User.objects.create(username="alessandro.monaco")
Expand All @@ -57,6 +72,17 @@ def setUpTestData(cls):
endSubscription=timezone.now()
)
u.groups.add(guest_group)
u.groups.add(devices_group)

noperm_card = Card.objects.create(nfc_id=654321)
noperm_user = User.objects.create(username="nopermission")
noperm_up = UserProfile.objects.create(
user=noperm_user,
card=noperm_card,
name="No Permission",
needSubscription=False,
endSubscription=timezone.now()
)

category = Category.objects.create(
name="category"
Expand All @@ -70,7 +96,9 @@ def setUpTestData(cls):
)

cls.card = card
cls.noperm_card = noperm_card
cls.userprofile = u
cls.noperm_userprofile = noperm_up
cls.device = device

def test_login_by_nfc(self):
Expand Down Expand Up @@ -281,3 +309,174 @@ def test_device_token_creation(self):
device.save()
device = Device.objects.get(pk=device.pk)
self.assertEqual(old_token, device.token)

def test_device_stop(self):
now = timezone.now()
logdevice = LogDevice.objects.create(
device=self.device,
user=self.userprofile,
bootDevice=now,
startWork=now,
shutdownDevice=now,
finishWork=now,
hourlyCost=self.device.hourlyCost,
)
logdevice.stop()
self.assertEqual(logdevice.startWork, logdevice.bootDevice)
self.assertTrue(logdevice.startWork < logdevice.finishWork)
self.assertEqual(logdevice.finishWork, logdevice.shutdownDevice)

def test_logdevice_pricework(self):
now = timezone.now()
logdevice = LogDevice.objects.create(
device=self.device,
user=self.userprofile,
bootDevice=now,
startWork=now,
shutdownDevice=now,
finishWork=now,
hourlyCost=self.device.hourlyCost,
)

self.assertEqual(logdevice.priceWork(), 'inWorking...')
logdevice.stop()
logdevice.finishWork = logdevice.finishWork + datetime.timedelta(seconds=60)
logdevice.save()
self.assertEqual(logdevice.priceWork(), 0.02)

def test_device_last_activity(self):
self.assertEqual(self.device.last_activity(), '')

now = timezone.now()
logdevice = LogDevice.objects.create(
device=self.device,
user=self.userprofile,
bootDevice=now,
startWork=now,
shutdownDevice=now,
finishWork=now,
hourlyCost=self.device.hourlyCost,
)

self.assertTrue(logdevice.inWorking)
self.assertTrue(self.device.last_activity() >= logdevice.startWork)

logdevice.stop()
self.assertFalse(logdevice.inWorking)
self.assertEqual(self.device.last_activity(), logdevice.finishWork)

def test_device_start_use(self):
client = Client()
auth = 'Token {}'.format(self.device.token)
url = reverse('device-use-start')

self.assertFalse(LogDevice.objects.filter(device=self.device).exists())

# not authenticated
data = {
'nfc_id': self.card.nfc_id,
}
response = client.post(url, data)
self.assertEqual(response.status_code, 403)

# invalid data
data = {
}
response = client.post(url, data, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 400)

data = {
'nfc_id': 0
}
response = client.post(url, data, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 400)

# not enough permissions
data = {
'nfc_id': self.noperm_card.nfc_id,
}
response = client.post(url, data, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 400)

# ok
data = {
'nfc_id': self.card.nfc_id,
}
response = client.post(url, data, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 201)
self.assertEqual(LogDevice.objects.count(), 1)
self.assertTrue(
LogDevice.objects.filter(device=self.device, user=self.userprofile, inWorking=True).exists()
)
self.assertJSONEqual(response.content.decode('utf-8'), {
'cost': self.device.hourlyCost
})

# ok too but the previous LogDevice is closed
data = {
'nfc_id': self.card.nfc_id,
}
response = client.post(url, data, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 201)
self.assertEqual(LogDevice.objects.count(), 2)
self.assertEqual(
LogDevice.objects.filter(device=self.device, user=self.userprofile, inWorking=True).count(), 1
)

def test_device_stop_use(self):
client = Client()
auth = 'Token {}'.format(self.device.token)
url = reverse('device-use-stop')

self.assertFalse(LogDevice.objects.filter(device=self.device).exists())

# not authenticated
data = {
'nfc_id': self.card.nfc_id,
}
response = client.post(url, data)
self.assertEqual(response.status_code, 403)

# invalid data
data = {
}
response = client.post(url, data, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 400)

data = {
'nfc_id': 0
}
response = client.post(url, data, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 400)

# no open logdevice
data = {
'nfc_id': self.card.nfc_id,
}
response = client.post(url, data, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 400)

now = timezone.now()
LogDevice.objects.create(
device=self.device,
user=self.userprofile,
startWork=now,
bootDevice=now,
shutdownDevice=now,
finishWork=now,
hourlyCost="0.0"
)

# ok
data = {
'nfc_id': self.card.nfc_id,
}
response = client.post(url, data, HTTP_AUTHORIZATION=auth)
self.assertEqual(response.status_code, 200)
self.assertEqual(LogDevice.objects.count(), 1)
self.assertTrue(
LogDevice.objects.filter(device=self.device, user=self.userprofile, inWorking=False).exists()
)
self.assertJSONEqual(response.content.decode('utf-8'), {
'cost': 0
})
3 changes: 2 additions & 1 deletion labAdmin/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
url(r'^user/identity/$', views.UserIdentity.as_view()),
url(r'^nfc/users/$', views.LoginByNFC.as_view(), name='nfc-users'),
url(r'^card/credits/$', views.CardCredits.as_view(), name='card-credits'),
url(r'^device/use/start/$', views.DeviceStartUse.as_view(), name='device-use-start'),
url(r'^device/use/stop/$', views.DeviceStopUse.as_view(), name='device-use-stop'),
# url(r'^nfc/(?P<nfc>.+)/$', views.NfcLogin.as_view()),
# url(r'^nfc/', views.NfcLogin.as_view()),
# url(r'^getpermission/', views.GetPermission.as_view()),
# url(r'^usedevice/', views.LogdeviceUse.as_view()),
# url(r'^usedevicelist/', views.LogdeviceUseList.as_view()),
# url(r'^getToken/', views.GetTokenExample.as_view()),
# url(r'^users/', views.UserList.as_view()),
Expand Down
Loading

0 comments on commit 320c58d

Please sign in to comment.