Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/usnistgov/NEMO
Browse files Browse the repository at this point in the history
  • Loading branch information
sbonaime committed May 13, 2020
2 parents 17a87d9 + 2149b25 commit c77667b
Show file tree
Hide file tree
Showing 62 changed files with 1,667 additions and 683 deletions.
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
venv
NEMO/settings.py
documentation
2 changes: 2 additions & 0 deletions Dockerfile.splash_pad
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ WORKDIR /nemo
COPY resources/icons/* /nemo/media/
COPY resources/people/* /nemo/media/
COPY resources/sounds/* /nemo/media/
COPY resources/images/* /nemo/media/
COPY resources/splash_pad_rates.json /nemo/media/rates.json
COPY resources/splash_pad_settings.py /nemo/
COPY NEMO/fixtures/splash_pad.json /nemo/

Expand Down
45 changes: 38 additions & 7 deletions NEMO/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.contrib.admin import register
from django.contrib.admin.widgets import FilteredSelectMultiple
from django.contrib.auth.models import Permission
from django.db.models.fields.files import FieldFile

from NEMO.actions import lock_selected_interlocks, synchronize_with_tool_usage, unlock_selected_interlocks, \
duplicate_tool_configuration
Expand All @@ -13,7 +14,7 @@
News, Notification, PhysicalAccessLevel, PhysicalAccessLog, Project, Reservation, Resource, ResourceCategory, \
SafetyIssue, ScheduledOutage, ScheduledOutageCategory, StaffCharge, Task, TaskCategory, TaskHistory, TaskStatus, \
Tool, TrainingSession, UsageEvent, User, UserType, UserPreferences, TaskImages, InterlockCardCategory, \
record_remote_many_to_many_changes_and_save, record_local_many_to_many_changes, record_active_state
record_remote_many_to_many_changes_and_save, record_local_many_to_many_changes, record_active_state, AlertCategory

admin.site.site_header = "NEMO"
admin.site.site_title = "NEMO"
Expand Down Expand Up @@ -81,7 +82,8 @@ def clean(self):
primary_owner = cleaned_data.get("_primary_owner")
image = cleaned_data.get("_image")

if image:
# only resize if an image is present and has changed
if image and not isinstance(image, FieldFile):
from NEMO.utilities import resize_image
# resize image to 500x500 maximum
cleaned_data['_image'] = resize_image(image, 500)
Expand Down Expand Up @@ -124,7 +126,7 @@ def clean(self):

@register(Tool)
class ToolAdmin(admin.ModelAdmin):
list_display = ('name_display', '_category', 'visible', 'operational_display', 'problematic', 'is_configurable')
list_display = ('name_display', 'id', '_category', 'visible', 'operational_display', 'problematic', 'is_configurable')
search_fields = ('name', '_description', '_serial')
list_filter = ('visible', '_operational', '_category', '_location')
actions = [duplicate_tool_configuration]
Expand Down Expand Up @@ -318,11 +320,26 @@ def clean(self):
@register(InterlockCard)
class InterlockCardAdmin(admin.ModelAdmin):
form = InterlockCardAdminForm
list_display = ('server', 'port', 'number', 'category', 'even_port', 'odd_port')
list_display = ('name', 'server', 'port', 'number', 'category', 'even_port', 'odd_port')


class InterlockAdminForm(forms.ModelForm):
class Meta:
model = Interlock
fields = '__all__'

def clean(self):
if any(self.errors):
return
super(InterlockAdminForm, self).clean()
from NEMO import interlocks
category = self.cleaned_data['card'].category
interlocks.get(category, False).clean_interlock(self)


@register(Interlock)
class InterlockAdmin(admin.ModelAdmin):
form = InterlockAdminForm
list_display = ('id', 'card', 'channel', 'state', 'tool', 'door')
actions = [lock_selected_interlocks, unlock_selected_interlocks, synchronize_with_tool_usage]
readonly_fields = ['state', 'most_recent_reply']
Expand Down Expand Up @@ -369,8 +386,8 @@ def get_tool(self, task_image: TaskImages):

@register(Comment)
class CommentAdmin(admin.ModelAdmin):
list_display = ('id', 'tool', 'author', 'creation_date', 'expiration_date', 'visible', 'hidden_by', 'hide_date')
list_filter = ('visible', 'creation_date', 'tool')
list_display = ('id', 'tool', 'author', 'creation_date', 'expiration_date', 'visible', 'staff_only', 'hidden_by', 'hide_date')
list_filter = ('visible', 'creation_date', 'tool', 'staff_only')
date_hierarchy = 'creation_date'
search_fields = ('content',)

Expand Down Expand Up @@ -452,9 +469,23 @@ class DoorAdmin(admin.ModelAdmin):
list_display = ('name', 'area', 'interlock', 'get_absolute_url')


@register(AlertCategory)
class AlertCategoryAdmin(admin.ModelAdmin):
list_display = ('name',)


class AlertAdminForm(forms.ModelForm):
contents = forms.CharField(widget=forms.Textarea(attrs={'rows':3, 'cols': 50}),)

class Meta:
model = Alert
fields = '__all__'


@register(Alert)
class AlertAdmin(admin.ModelAdmin):
list_display = ('title', 'creation_time', 'creator', 'debut_time', 'expiration_time', 'user', 'dismissible')
list_display = ('title', 'category', 'creation_time', 'creator', 'debut_time', 'expiration_time', 'user', 'dismissible', 'expired', 'deleted')
form = AlertAdminForm


@register(PhysicalAccessLevel)
Expand Down
12 changes: 10 additions & 2 deletions NEMO/apps/area_access/templates/area_access/occupancy.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@
<thead>
<tr>
<th colspan="4">
<span class="primary-highlight">{{ area }} occupancy</span>
{% if area.list|length > 1 %}<span class="light-grey pull-right">{{ area.list|length }} people</span>{% endif %}
<span class="primary-highlight">{{ area.name }} occupancy</span>
{% if occupants|length > 1 %}
<span class="pull-right">
{% if area.maximum_capacity != 0 and occupants|length >= area.danger_capacity %}<span style="color:red"><span class="glyphicon glyphicon-alert" style="margin-right: 10px"></span>
{% elif area.maximum_capacity != 0 and occupants|length >= area.warning_capacity %}<span style="color:orange"><span class="glyphicon glyphicon-alert" style="margin-right: 10px"></span>
{% else %}<span>{% endif %}
{{ occupants|length }}
</span>{% if area.maximum_capacity != 0 %} / {{ area.maximum_capacity }}{% endif %} people
</span>
{% endif %}
</th>
</tr>
<tr>
Expand Down
26 changes: 21 additions & 5 deletions NEMO/apps/area_access/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

from NEMO.decorators import disable_session_expiry_refresh
from NEMO.exceptions import InactiveUserError, NoActiveProjectsForUserError, PhysicalAccessExpiredUserError, \
NoPhysicalAccessUserError, NoAccessiblePhysicalAccessUserError, UnavailableResourcesUserError
NoPhysicalAccessUserError, NoAccessiblePhysicalAccessUserError, UnavailableResourcesUserError, \
MaximumCapacityReachedError
from NEMO.models import AreaAccessRecord, Door, PhysicalAccessLog, PhysicalAccessType, Project, User, UsageEvent, Area
from NEMO.tasks import postpone
from NEMO.views.policy import check_policy_to_enter_this_area, check_policy_to_enter_any_area
Expand Down Expand Up @@ -76,6 +77,7 @@ def login_to_area(request, door_id):
message = "You have not been granted physical access to any NanoFab area. Please visit the User Office if you believe this is an error."
return render(request, 'area_access/physical_access_denied.html', {'message': message})

max_capacity_reached = False
# Check policy to enter this area
try:
check_policy_to_enter_this_area(area=door.area, user=user)
Expand All @@ -92,12 +94,22 @@ def login_to_area(request, door_id):
log.save()
return render(request, 'area_access/resource_unavailable.html', {'unavailable_resources': unavailable_resources})

except MaximumCapacityReachedError:
# deal with this error after checking if the user is already logged in
max_capacity_reached = True

current_area_access_record = user.area_access_record()
if current_area_access_record and current_area_access_record.area == door.area:
# No log entry necessary here because all validation checks passed.
# The log entry is captured when the subsequent choice is made by the user.
return render(request, 'area_access/already_logged_in.html', {'area': door.area, 'project': current_area_access_record.project, 'badge_number': user.badge_number})

if max_capacity_reached:
log.details = f"This area has reached its maximum capacity of {door.area} people at a time."
log.save()
message = "This area has reached its maximum capacity. Please wait for somebody to leave and try again."
return render(request, 'area_access/physical_access_denied.html', {'message': message})

previous_area = None
if user.active_project_count() >= 1:
if user.active_project_count() == 1:
Expand Down Expand Up @@ -190,11 +202,15 @@ def open_door(request, door_id):
@require_GET
@disable_session_expiry_refresh
def area_access_occupancy(request):
area = request.GET.get('occupancy')
if area is None or not Area.objects.filter(name=area).exists():
area_name = request.GET.get('occupancy')
if area_name is None:
return HttpResponse()
try:
area = Area.objects.get(name=area_name)
except Area.DoesNotExist:
return HttpResponse()
dictionary = {
'area': area,
'occupants': AreaAccessRecord.objects.filter(area__name=area, end=None, staff_charge=None).prefetch_related('customer'),
'occupants': AreaAccessRecord.objects.filter(area__name=area.name, end=None, staff_charge=None).prefetch_related('customer'),
}
return render(request, 'kiosk/occupancy.html', dictionary)
return render(request, 'area_access/occupancy.html', dictionary)
3 changes: 3 additions & 0 deletions NEMO/apps/kiosk/templates/kiosk/category_choices.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ <h1>{{ category }}</h1>
{% if tool.delayed_logoff_in_progress %}
<span style="font-size:x-large; margin-right:10px" class="glyphicon glyphicon-time primary-highlight"></span>
{% endif %}

{% if tool.scheduled_outages %}
<span style="font-size:x-large; margin-right:10px" class="glyphicon glyphicon-time danger-highlight"></span>
{% elif tool.scheduled_partial_outages %}
<span style="font-size:x-large; margin-right:10px" class="glyphicon glyphicon-time warning-highlight"></span>
{% endif %}

{% if tool.required_resource_is_unavailable %}
Expand Down
12 changes: 10 additions & 2 deletions NEMO/apps/kiosk/templates/kiosk/occupancy.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,16 @@
<thead>
<tr>
<th colspan="4">
<span class="primary-highlight">{{ area }} occupancy</span>
{% if area.list|length > 1 %}<span class="light-grey pull-right">{{ area.list|length }} people</span>{% endif %}
<span class="primary-highlight">{{ area.name }} occupancy</span>
{% if occupants|length > 1 %}
<span class="pull-right">
{% if area.maximum_capacity != 0 and occupants|length >= area.danger_capacity %}<span style="color:red"><span class="glyphicon glyphicon-alert" style="margin-right: 10px"></span>
{% elif area.maximum_capacity != 0 and occupants|length >= area.warning_capacity %}<span style="color:orange"><span class="glyphicon glyphicon-alert" style="margin-right: 10px"></span>
{% else %}<span>{% endif %}
{{ occupants|length }}
</span>{% if area.maximum_capacity != 0 %} / {{ area.maximum_capacity }}{% endif %} people
</span>
{% endif %}
</th>
</tr>
<tr>
Expand Down
Loading

0 comments on commit c77667b

Please sign in to comment.