Skip to content

Commit

Permalink
PWA Revision and migration to django-bootstrap-datepicker-plus (#34)
Browse files Browse the repository at this point in the history
* PWA

* django-bootstrap-datepicker-plus==3.0.5

* refactored {% csrf_token %}

* PWA

* django 2.2.11 and removed django-datetime-widget

* black format

* bootstrap_datepicker_plus

* removed check for organisation

* verbose names

* removed forced inputs

* service worker

* rename site title to ANGA UTM

* removed forced static files

* Organisation documentation
  • Loading branch information
geoffreynyaga committed Mar 10, 2020
1 parent 185a22a commit cf9aa7a
Show file tree
Hide file tree
Showing 26 changed files with 515 additions and 162 deletions.
55 changes: 21 additions & 34 deletions ANGA_UTM/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url,include
from django.conf.urls import url, include
from django.contrib import admin

from django.conf import settings
Expand All @@ -28,49 +28,36 @@
from applications.views import view_airspace

urlpatterns = [
url(r'^admin/', admin.site.urls),
url('', include('pwa.urls')), # You MUST use an empty string as the URL prefix
url(r'^webpush/', include('webpush.urls')),

url(r'^home$', views.home,name='home' ),

url(r'^$', view_airspace, name='view_airspace'),

url(r'^rpas/', include('rpas.urls')),

url(r'^account/', include("accounts.urls", namespace ='accounts') ),
url(r'^account/', include('django.contrib.auth.urls')),
url(r'^maps/', include('maps.urls')),
url(r'^flight_plans/', include('flight_plans.urls')),
url(r'^weather/', include('weather.urls')),
url(r'^applications/', include('applications.urls')),
url(r'^messages/', include('utm_messages.urls', namespace ='messages')),

url(r'^notams/', include('notams.urls')),
url(r'^organizations/', include('organizations.urls')),

url(r'^notifications/', include('notifications.urls', namespace ='notifications')),

url(r'^api/maps/', include('maps.api.urls')),

url(r"^admin/", admin.site.urls),
url("", include("pwa.urls")), # You MUST use an empty string as the URL prefix
url(r"^webpush/", include("webpush.urls")),
url(r"^home$", views.home, name="home"),
url(r"^$", view_airspace, name="view_airspace"),
url(r"^rpas/", include("rpas.urls")),
url(r"^account/", include("accounts.urls", namespace="accounts")),
url(r"^account/", include("django.contrib.auth.urls")),
url(r"^maps/", include("maps.urls")),
url(r"^flight_plans/", include("flight_plans.urls")),
url(r"^weather/", include("weather.urls")),
url(r"^applications/", include("applications.urls")),
url(r"^messages/", include("utm_messages.urls", namespace="messages")),
url(r"^notams/", include("notams.urls")),
url(r"^organizations/", include("organizations.urls")),
url(r"^notifications/", include("notifications.urls", namespace="notifications")),
url(r"^api/maps/", include("maps.api.urls")),
]


if settings.DEBUG:
urlpatterns += [

url(r'^static/(?P<path>.*)$', serve, {'document_root': settings.STATIC_ROOT,}),

url(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT,}),

url(r"^static/(?P<path>.*)$", serve, {"document_root": settings.STATIC_ROOT,}),
url(r"^media/(?P<path>.*)$", serve, {"document_root": settings.MEDIA_ROOT,}),
]

if settings.DEBUG:
import debug_toolbar
urlpatterns = [
url(r'^__debug__/', include(debug_toolbar.urls)),

] + urlpatterns
urlpatterns = [url(r"^__debug__/", include(debug_toolbar.urls)),] + urlpatterns

handler404 = error_404
handler500 = error_500
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

> `This is a LAANC (Low Altitude Authorization and Notification Capability) to UTM (UAV Traffic Management) implemetation for drones / UAS / RPAS. It includes drone Registrations, drone flight plans, drone Geofences and drone approvals`
`It is a PWA (Progressive Web App) purely done in Django/python`

![Anga UTM](docs/screenshots/main.png)

## Overview
Expand Down Expand Up @@ -123,3 +125,9 @@ python manage.py migrate
```javascript
bounds = new L.LatLngBounds(new L.LatLng(<northEastLatitude>,<northEastLongitude>), new L.LatLng(<southWestlattitude>, <southWestLongitude>));
```

> Now the app should be working well. However, you will realise that you can not create a reserve airspace yet, and that you have to have an RPAS registered, which when you attempt does not go through because you are not registered to any organisation.
>
> This is a deliberate design choice, you have to register an organisation on the admin page `http://localhost:8000/admin` and add the user to that organisation. This is the supposed role that Civil Aviation bodies will have to play.
>
> Finally, you can create a user in the admin page and make sure to assign them to the `CAA` group that we created in on of the steps above. If you now login with this user on the site, you should have additional features such as `Approve Flight Plans`, `Create Notams` etc.
10 changes: 5 additions & 5 deletions accounts/templates/accounts/signup.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<div class="panel-body">
<h4>Sign Up</h4>
<form class="" action="" method="POST">
{% csrf_token %}

{% bootstrap_form_errors form %}

Expand All @@ -24,14 +25,13 @@ <h4>Sign Up</h4>
<span>{% bootstrap_field form.username %}</span>
</div>
<div class="col-sm-2">

</div>
<div class="col-sm-3">
{% bootstrap_field form.email %}
</div>

</div>
{% csrf_token %}
<br>
<div class="row">
<div class="col-sm-6">
Expand All @@ -41,10 +41,10 @@ <h4>Sign Up</h4>
<!-- {{form.password1}} -->
{% bootstrap_field form.password2 %}
</div>

</div>


<button type="submit" class="btn btn-primary btn-lg btn-block">Sign Me Up!</button>

</form>
Expand Down
44 changes: 31 additions & 13 deletions applications/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
from django.core.exceptions import ValidationError
from django.forms import widgets

from datetimewidget.widgets import TimeWidget
from bootstrap_datepicker_plus import (
DateTimePickerInput,
DatePickerInput,
TimePickerInput,
)

# from datetimewidget.widgets import TimeWidget
from leaflet.forms.widgets import LeafletWidget

from rpas.models import Rpas
Expand All @@ -17,16 +23,22 @@ class ExtLeafletWidget(LeafletWidget):


class ReserveAirspaceForm(forms.ModelForm):
start_time = forms.TimeField(widget=TimeWidget(usel10n=True, bootstrap_version=3))
end = forms.TimeField(widget=TimeWidget(usel10n=True, bootstrap_version=3))
# start_time = forms.TimeField(widget=TimeWidget(usel10n=True, bootstrap_version=3))
# end = forms.TimeField(widget=TimeWidget(usel10n=True, bootstrap_version=3))

class Meta:
model = ReserveAirspace

# rpas = forms.ModelMultipleChoiceField(queryset=Rpas.objects.filter(user=request.user).order_by('-id'))

fields = ("rpas", "start_day", "start_time", "end", "geom", "log")
widgets = {"geom": ExtLeafletWidget(), "start_day": widgets.SelectDateWidget()}
widgets = {
"geom": ExtLeafletWidget(),
# "start_day": widgets.SelectDateWidget(),
"start_day": widgets.SelectDateWidget(),
"start_time": TimePickerInput(),
"end": TimePickerInput(),
}

def __init__(self, *args, **kwargs):
# apparently i'm popping the user from kwargs dictionary
Expand All @@ -45,6 +57,8 @@ def __init__(self, *args, **kwargs):
# org = Organization.objects.filter(users=user)
# print(org,"this is xxxxxxxxxxxxxxxxxxx")
""" Come up with proper queryset for all rpas in the organization for the dropdown
NB: ALways do `filter(organization=org)` as this helps us in frontend to deny people not registered to any organisation
"""
self.fields["rpas"] = forms.ModelChoiceField(
queryset=Rpas.objects.filter(organization=org).order_by("-id")
Expand All @@ -56,7 +70,7 @@ def __init__(self, *args, **kwargs):
Also fixed the amount of flights somebody can book in a day
#TODO: Settings DASHBOARD FOR CAA TO SET Max number of flights, max un-approved flights,max area,
max
"""

def clean(self, *args, **kwargs):
Expand Down Expand Up @@ -103,20 +117,22 @@ def clean(self, *args, **kwargs):


class AppliedReserveAirspaceUpdateForm(forms.ModelForm):

# start_time = forms.TimeField(widget=TimeWidget(usel10n=True, bootstrap_version=3))

# end = forms.TimeField(widget=TimeWidget(usel10n=True, bootstrap_version=3))
class Meta:
model = ReserveAirspace
fields = ("rpas", "start_day", "start_time", "end", "geom", "log")
widgets = {
"geom": LeafletWidget(),
"start_day": widgets.SelectDateWidget(),
"start_time": TimePickerInput(),
"end": TimePickerInput(),
# 'rpas': forms.widgets.Select(attrs={'readonly': True,
# 'disabled': True})
}

start_time = forms.TimeField(widget=TimeWidget(usel10n=True, bootstrap_version=3))

end = forms.TimeField(widget=TimeWidget(usel10n=True, bootstrap_version=3))

def __init__(self, *args, **kwargs):
user = kwargs.pop("user", None)
super(AppliedReserveAirspaceUpdateForm, self).__init__(*args, **kwargs)
Expand All @@ -127,6 +143,10 @@ def __init__(self, *args, **kwargs):


class CAAAppliedReserveAirspaceUpdateForm(forms.ModelForm):
# start_time = forms.TimeField(widget=TimeWidget(usel10n=True, bootstrap_version=3))

# end = forms.TimeField(widget=TimeWidget(usel10n=True, bootstrap_version=3))

class Meta:
model = ReserveAirspace
fields = (
Expand All @@ -141,14 +161,12 @@ class Meta:
widgets = {
"geom": LeafletWidget(),
"start_day": widgets.SelectDateWidget(),
"start_time": TimePickerInput(),
"end": TimePickerInput(),
# 'rpas': forms.widgets.Select(attrs={'readonly': True,
# 'disabled': True})
}

start_time = forms.TimeField(widget=TimeWidget(usel10n=True, bootstrap_version=3))

end = forms.TimeField(widget=TimeWidget(usel10n=True, bootstrap_version=3))


# class LogsUploadForm(forms.ModelForm):
# class Meta:
Expand Down
24 changes: 12 additions & 12 deletions applications/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,8 @@ def save(self, *args, **kwargs):
if self.geom:
self.centroid = self.geom.centroid


super(ReserveAirspace, self).save(*args, **kwargs)




if self.log:
from django.contrib.gis.geos import LineString, MultiLineString

Expand Down Expand Up @@ -202,16 +198,20 @@ def clean(self):
"""

# Checking to see if user is registered to any organisation before allowing creation

# FIXED: This is solved in the forms.py as the rpas dropdown is filtered by the users organisation first
# Recreational users will have to be registered by a Club

try:
organization = self.created_by.userprofile.organization
print(organization,"organization in save()")
except Exception as e:
print(e, "user is not attached to any organisation")
raise ValidationError(
"You are not registered under any organisation, you can not apply for reserve airspace"
)
# try:
# organization = self.created_by.userprofile.organization
# print(organization, "organization in save()")
# except Exception as e:
# print(e, "user is not attached to any organisation")
# print(self.created_by, "xxxxxxxxxxxxxx")

# raise ValidationError(
# "You are not registered under any organisation, you can not apply for reserve airspace"
# )

if not (self.geom or self.log):
raise ValidationError(
Expand Down
41 changes: 32 additions & 9 deletions applications/templates/applications/approve.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,20 @@
{% block head %}
<title>Update Reserve</title>

<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}" type="text/css">


{% comment %} <script src="{% static 'js/datepicker-widget.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/datepicker-widget.css' %}"> {% endcomment %}


{% load bootstrap3 %}
{% bootstrap_css %}
{% bootstrap_javascript jquery='full' %}
{% load leaflet_tags %}
{% leaflet_js plugins="ALL" %}
{% leaflet_css plugins="ALL" %}
{{ form.media }}

{%endblock%}

Expand All @@ -23,19 +37,12 @@
{% endcomment %}




{% load bootstrap3 %}

{% load leaflet_tags %}
{% leaflet_js plugins="forms" %}
{% leaflet_css plugins="forms" %}


{{ form.media }}



{% comment %} {{ form.media }} {% endcomment %}

<form method="POST">
{% csrf_token %}
Expand All @@ -60,7 +67,9 @@ <h3 class="panel-title">Flight Times</h3>
{% bootstrap_field form.start_day %}
<br>
<span class="label label-primary">Change Start Time :</span>
{{ form.start_time }}
{% comment %} {{ form.start_time }} {% endcomment %}
{% bootstrap_field form.start_time %}

<br>
<span class="label label-primary">Change End Time: :</span>
{{ form.end }}
Expand Down Expand Up @@ -153,4 +162,18 @@ <h3 class="panel-title">APPROVE/REJECT/IGNORE APPLICATION</h3>
{% endif %}
</section>

<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>

{% comment %} <!-- Bootstrap 3.3.7 --> {% endcomment %}
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}" />
{% comment %} <!-- jQuery 3 --> {% endcomment %}
<script src="{% static 'adminlite/bower_components/jquery/dist/jquery.min.js' %}">


{% comment %} <!-- jQuery UI 1.11.4 --> {% endcomment %}
<script src="{% static 'adminlite/bower_components/jquery-ui/jquery-ui.min.js' %}"></script>

{%endblock%}
Loading

0 comments on commit cf9aa7a

Please sign in to comment.