Skip to content
This repository was archived by the owner on Feb 8, 2019. It is now read-only.
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
2 changes: 1 addition & 1 deletion project/api/admin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django.contrib import admin
from simple_history.admin import SimpleHistoryAdmin
from .models import *
from .models import Territory, PoliticalEntity, DiplomaticRelation

# Register your models here.
admin.site.register(Territory, SimpleHistoryAdmin)
Expand Down
2 changes: 2 additions & 0 deletions project/api/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ class TerritoryFilter(FilterSet):
)

def filter_bounds(self, queryset, field_name, value):
"""Filters geometries that intersect @bounds."""
geom = Polygon(make_tuple(value), srid=4326)
return queryset.filter(geo__intersects=geom)

def filter_date(self, queryset, field_name, value):
"""Filters territories that exist during @Date."""
return queryset.filter(start_date__lte=value, end_date__gte=value)

class Meta:
Expand Down
28 changes: 28 additions & 0 deletions project/api/migrations/0005_auto_20181014_0009.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 2.1.2 on 2018-10-14 00:09

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0004_auto_20181011_0231'),
]

operations = [
migrations.AlterField(
model_name='entity',
name='name',
field=models.TextField(help_text='Canonical name, which should not include any epithets and must be unique', max_length=100, unique=True),
),
migrations.AlterField(
model_name='historicalentity',
name='name',
field=models.TextField(db_index=True, help_text='Canonical name, which should not include any epithets and must be unique', max_length=100),
),
migrations.AlterField(
model_name='historicalpoliticalentity',
name='name',
field=models.TextField(db_index=True, help_text='Canonical name, which should not include any epithets and must be unique', max_length=100),
),
]
56 changes: 28 additions & 28 deletions project/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,24 @@


class EntityManager(PolymorphicManager):
"""
Manager for the Nation model to handle lookups by url_id
"""
"""Manager for the Nation model to handle lookups by url_id."""

def get_by_natural_key(self, url_id):
def get_by_natural_key(self, url_id): # noqa
return self.get(url_id=url_id)


class Entity(PolymorphicModel):
"""
Cultural/governmental entity. Serves as foreign key for most Territories
"""Cultural/governmental entity.

Serves as foreign key for most Territories.
"""

objects = EntityManager()

name = models.TextField(
max_length=100,
help_text="Canonical name, should not include any epithets, must be unique",
help_text="Canonical name, which should not include any epithets and"
" must be unique",
unique=True,
)
url_id = models.SlugField(
Expand All @@ -52,15 +52,17 @@ class Entity(PolymorphicModel):
)

def natural_key(self):
"""Return the ID for lookups."""
return self.url_id

def __str__(self):
return self.name


class PoliticalEntity(Entity):
"""
Cultural/governmental entity. Serves as foreign key for most Territories
"""Cultural/governmental entity.

Serves as foreign key for most Territories.
"""

color = ColorField(
Expand All @@ -79,16 +81,15 @@ class PoliticalEntity(Entity):

# History fields

# Foreign key to auth.User which will be updated every time the model is changed,
# and is this stored in history as the user to update a specific revision
# Consider other metadata (DateTime) for the revision (may be handled by django-simple-history)
# Foreign key to auth.User which we update every time the model changes,
# and store in history as the user to update a specific revision.
# Consider other metadata (DateTime) for the revision
# (may be handled by django-simple-history).
# TODO: implement this


class Territory(models.Model):
"""
Defines the borders and controlled territories associated with an Entity.
"""
"""Defines the borders and territories associated with an Entity."""

class Meta:
verbose_name_plural = "territories"
Expand All @@ -103,16 +104,17 @@ class Meta:
history = HistoricalRecords()

def clean(self, *args, **kwargs):
"""Ensure that our geometry is a polygon and our dates do not intersect
with those of another Territory of the same Entity."""
if self.start_date > self.end_date:
raise ValidationError("Start date cannot be later than end date")
if (
loads(self.geo.json)["type"] != "Polygon"
and loads(self.geo.json)["type"] != "MultiPolygon"
loads(self.geo.json)["type"] != "Polygon" and
loads(self.geo.json)["type"] != "MultiPolygon"
):
raise ValidationError(
"Only Polygon and MultiPolygon objects are acceptable geometry types."
)

"Only Polygon and MultiPolygon objects are acceptable geometry"
" types.")
try:
# This date check is inculsive.
if Territory.objects.filter(
Expand All @@ -121,14 +123,15 @@ def clean(self, *args, **kwargs):
entity__exact=self.entity,
).exists():
raise ValidationError(
"Another territory of this PoliticalEntity exists during this timeframe."
"Another territory of this PoliticalEntity exists during"
" this timeframe."
)
except Entity.DoesNotExist:
pass

super(Territory, self).clean(*args, **kwargs)

def save(self, *args, **kwargs):
def save(self, *args, **kwargs): # noqa
self.full_clean()
super(Territory, self).save(*args, **kwargs)

Expand All @@ -141,10 +144,7 @@ def __str__(self):


class DiplomaticRelation(models.Model):
"""
Defines political and diplomatic interactions between PoliticalEntitys.
"""

"""Defines interactions between PoliticalEntitys."""
start_date = models.DateField(help_text="When this relation takes effect")
end_date = models.DateField(help_text="When this relation ceases to exist")
parent_parties = models.ManyToManyField(
Expand Down Expand Up @@ -172,13 +172,13 @@ class DiplomaticRelation(models.Model):

history = HistoricalRecords()

def clean(self, *args, **kwargs):
def clean(self, *args, **kwargs): # noqa
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disable the rule thats necessitating these noqa?

if self.start_date > self.end_date:
raise ValidationError("Start date cannot be later than end date")

super(DiplomaticRelation, self).clean(*args, **kwargs)

def save(self, *args, **kwargs):
def save(self, *args, **kwargs): # noqa
self.full_clean()
super(DiplomaticRelation, self).save(*args, **kwargs)

Expand Down
19 changes: 10 additions & 9 deletions project/api/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,25 @@

class IsStaffOrSpecificUser(permissions.BasePermission):
"""
Permission to detect whether to user in question is staff or the target user
Permission to detect whether the user is staff or the target user.
Example:
John (regular user) should be able to access John's account
Alice (staff) should be able to access John's account
Jane (regular user) should not be able to access John's account
"""

def has_permission(self, request, view):
# allow user to list all users if logged in user is staff
return view.action == "retrieve" or request.user.is_staff
"""Allow user to list all users if logged in user is staff."""
return view.action == 'retrieve' or request.user.is_staff

def has_object_permission(self, request, view, obj):
# allow all users to view specific user information
"""Allow all users to view specific user information."""
# TODO: Actually implement this.
return True


def get_token_auth_header(request):
"""
Obtains the Access Token from the Authorization Header
"""
"""Obtains the Access Token from the Authorization Header."""
auth = request.META.get("HTTP_AUTHORIZATION", None)
parts = auth.split()
token = parts[1]
Expand All @@ -55,9 +54,11 @@ def decorated(*args, **kwargs):
"https://" + settings.AUTH0_DOMAIN + "/.well-known/jwks.json"
)
jwks = json.loads(jsonurl.read())
body = re.sub("(.{64})", "\\1\n", jwks["keys"][0]["x5c"][0], 0, re.DOTALL)
body = re.sub(
"(.{64})", "\\1\n", jwks["keys"][0]["x5c"][0], 0, re.DOTALL)
cert = (
"-----BEGIN CERTIFICATE-----\n" + body + "\n-----END CERTIFICATE-----"
"-----BEGIN CERTIFICATE-----\n" + body +
"\n-----END CERTIFICATE-----"
)
certificate = load_pem_x509_certificate(
cert.encode("utf-8"), default_backend()
Expand Down
32 changes: 12 additions & 20 deletions project/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,32 @@


class PoliticalEntitySerializer(serializers.ModelSerializer):
"""
Serializes the PoliticalEntity model
"""

"""Serializes the PoliticalEntity model."""
class Meta:
model = PoliticalEntity
exclude = ("polymorphic_ctype",)


class GeoField(serializers.RelatedField):
"""
Field Serializer for Territories
"""
"""Field Serializer for Territories."""

@classmethod
def to_representation(self, value):
# Compress geojson to geobuf and return as hexadecimal
def to_representation(cls, value):
"""Compress geojson to geobuf and return as hexadecimal."""
gbuf = geobuf.encode(loads(value.geojson))
return gbuf.hex()


class TerritorySerializer(serializers.ModelSerializer):
"""
Serializes the Territory model as GeoJSON compatible data
"""

entity = serializers.SlugRelatedField(read_only=True, slug_field="url_id")

"""Serializes the Territory model as GeoJSON compatible data."""
entity = serializers.SlugRelatedField(
read_only=True,
slug_field='url_id'
)
geo = GeoField(read_only=True)

def to_internal_value(self, data):
"""Return a dictionary of territory data."""
ret = {}

# Update ret to include passed in data
Expand Down Expand Up @@ -72,11 +67,8 @@ class Meta:


class DiplomaticRelationSerializer(serializers.ModelSerializer):
"""
Serializes the DiplomaticRelation model
"""

entity = serializers.SlugRelatedField(read_only=True, slug_field="url_id")
"""Serializes the DiplomaticRelation model."""
entity = serializers.SlugRelatedField(read_only=True, slug_field='url_id')

class Meta:
model = DiplomaticRelation
Expand Down
Loading