Commit 81f3772d authored by luxcem's avatar luxcem

tastypie to DRF

parent ea41823d
......@@ -65,7 +65,6 @@
// either we have membership date or only if it's the current one
"begin_date": "", // optinional
"end_date": "", // optinional
"current": false, // optinional
}
]
}]
# coding: utf-8
# This file is part of compotista.
#
# compotista is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or any later version.
#
# compotista is distributed in the hope that it will
# be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU General Affero Public
# License along with django-representatives.
# If not, see <http://www.gnu.org/licenses/>.
#
# Copyright (C) 2013 Laurent Peuch <cortex@worlddomination.be>
# Copyright (C) 2015 Arnaud Fabre <af@laquadrature.net>
import sys
from django.db import transaction
from datetime import datetime
from representatives.models import Representative, Country, Group, Constituency
PERSONAL_FIELDS = ("first_name", "last_name", "full_name", "birth_place", "cv", "photo")
GENDER_DICT = dict(Representative.GENDER)
def export_a_representative(representative):
reps = {"id": representative.remote_id}
reps["personal"] = {field: getattr(representative, field) for field in PERSONAL_FIELDS}
reps["personal"]["gender"] = GENDER_DICT[representative.gender]
reps["personal"]["birth_date"] = representative.birth_date.isoformat().split('T')[0] if representative.birth_date else None
reps["contact"] = {}
reps["contact"]["emails"] = [{
"email": email.email,
"type": email.kind
} for email in representative.email_set.all()]
reps["contact"]["websites"] = [{
"website": website.url,
"type": website.kind
} for website in representative.website_set.all()]
reps["contact"]["phones"] = [{
"phone": phone.number,
"type": phone.kind, "address":
phone.address_id,
"id": phone.id
} for phone in representative.phone_set.all()]
reps["contact"]["address"] = [{
"id": address.id,
"country": {"name": address.country.name, "code": address.country.code},
"city": address.city,
"street": address.street,
"number": address.number,
"postcode": address.postcode,
"floor": address.floor,
"office_number": address.office_number,
"type": address.kind,
"geo": None,
"phones": [phone.id for phone in address.phone_set.all()],
} for address in representative.address_set.all()]
reps["mandates"] = [{
"name": mandate.group.name,
"type": mandate.group.kind,
"short_id": mandate.group.abbreviation,
"url_official": mandate.url,
"constituency": mandate.constituency.name,
"role": mandate.role,
"begin_date": mandate.begin_date.isoformat().split('T')[0] if mandate.begin_date else None,
"end_date": mandate.end_date.isoformat().split('T')[0] if mandate.end_date else None,
# "current": mandate.active,
} for mandate in representative.mandate_set.all()]
return reps
def export_all_representatives():
return [export_a_representative(representative) for representative in Representative.objects.all()]
def export_active_representatives():
return [export_a_representative(representative) for representative in Representative.objects.filter(active=True)]
def import_representatives_from_format(data, verbose=False):
reverted_gender_dict = {x[1]: x[0] for x in Representative.GENDER}
a = 0
end = len(data)
with transaction.atomic():
for reps in data:
a += 1
if verbose:
sys.stdout.write("%s/%s\r" % (a, end))
sys.stdout.flush()
remote_id = reps["id"]
representative = Representative.objects.filter(remote_id=remote_id)
if representative:
representative = representative[0]
else:
representative = Representative()
representative.remote_id = remote_id
representative.first_name = reps["personal"]["first_name"]
representative.last_name = reps["personal"]["last_name"]
representative.full_name = reps["personal"]["full_name"]
representative.birth_place = reps["personal"]["birth_place"]
representative.cv = reps["personal"]["cv"]
representative.photo = reps["personal"]["photo"]
if reps["personal"]["birth_date"]:
representative.birth_date = datetime.strptime(reps["personal"]["birth_date"], "%Y-%m-%d")
else:
representative.birth_date = None
representative.gender = reverted_gender_dict[reps["personal"]["gender"]]
representative.save()
representative.email_set.all().delete()
for email in reps["contact"]["emails"]:
representative.email_set.create(
email=email["email"],
kind=email["type"],
)
representative.website_set.all().delete()
for website in reps["contact"]["websites"]:
representative.website_set.create(
url=website["website"],
kind=website["type"],
)
addresses = {}
representative.address_set.all().delete()
for address in reps["contact"]["address"]:
country = Country.objects.filter(code=address["country"]["code"])
if not country:
country = Country.objects.create(
name=address["country"]["name"],
code=address["country"]["code"]
)
else:
country = country[0]
address_in_db = representative.address_set.create(
city=address["city"],
street=address["street"],
number=address["number"],
postcode=address["postcode"],
floor=address["floor"],
office_number=address["office_number"],
kind=address["type"],
country=country
)
for phone in address["phones"]:
addresses[phone] = address_in_db
representative.phone_set.all().delete()
for phone in reps["contact"]["phones"]:
representative.phone_set.create(
number=phone["phone"],
kind=phone["type"],
address=addresses[phone["id"]]
)
representative.mandate_set.all().delete()
for mandate in reps["mandates"]:
constituency, created = Constituency.objects.get_or_create(
name=mandate['constituency']
)
group, created = Group.objects.get_or_create(
name=mandate['name'],
abbreviation=mandate['short_id'],
kind=mandate['type']
)
representative.mandate_set.create(
group=group,
constituency=constituency,
url=mandate["url_official"],
role=mandate["role"],
begin_date=mandate["begin_date"],
end_date=mandate["end_date"],
# active=mandate["current"],
)
representative.save()
if verbose:
sys.stdout.write("\n")
......@@ -19,10 +19,10 @@
# Copyright (C) 2013 Laurent Peuch <cortex@worlddomination.be>
# Copyright (C) 2015 Arnaud Fabre <af@laquadrature.net>
import json
from django.core.management.base import BaseCommand
from representatives.utils import export_all_representatives
from rest_framework.renderers import JSONRenderer
class Command(BaseCommand):
def handle(self, *args, **options):
print json.dumps(export_all_representatives(), indent=4)
print(JSONRenderer().render(export_all_representatives()))
......@@ -19,27 +19,23 @@
# Copyright (C) 2013 Laurent Peuch <cortex@worlddomination.be>
# Copyright (C) 2015 Arnaud Fabre <af@laquadrature.net>
import json
from urllib2 import urlopen
from django.core.management.base import BaseCommand
from django.conf import settings
from representatives.utils import import_representatives_from_format
from urllib2 import urlopen
from django.utils.six import BytesIO
from rest_framework.parsers import JSONParser
from representatives.utils import import_representatives
class Command(BaseCommand):
def handle(self, *args, **options):
if args and args[0] == 'q':
verbose = False
else:
verbose = True
compotista_server = getattr(settings,
'REPRESENTATIVES_COMPOTISTA_SERVER',
'http://compotista.mm.staz.be')
url = compotista_server + "/latest/"
import_representatives_from_format(
json.load(urlopen(url)),
verbose=verbose)
stream = BytesIO(urlopen(url))
import_representatives(JSONParser().parse(stream))
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('representatives', '0009_auto_20150428_0455'),
]
operations = [
migrations.RenameField(
model_name='mandate',
old_name='url',
new_name='link',
),
]
......@@ -48,16 +48,15 @@ class Representative(models.Model):
birth_date = models.DateField(blank=True, null=True)
cv = models.TextField(blank=True, null=True)
photo = models.CharField(max_length=512, null=True)
active = models.BooleanField(default=False)
def __unicode__(self):
return self.full_name
def gender_as_str(self):
genders = {0: 'N/A', 1: 'F', 2: 'M'}
return genders[self.gender]
def __unicode__(self):
return self.full_name
# Contact related models
class Contact(models.Model):
......@@ -70,7 +69,7 @@ class Contact(models.Model):
class Email(Contact):
email = models.EmailField()
kind = models.CharField(max_length=255, blank=True, null=True)
class WebSite(Contact):
url = models.URLField()
......@@ -93,7 +92,7 @@ class Address(Contact):
class Phone(Contact):
number = models.CharField(max_length=255)
kind = models.CharField(max_length=255, blank=True, null=True)
address = models.ForeignKey(Address)
address = models.ForeignKey(Address, null=True)
# Mandate related models
......@@ -133,4 +132,5 @@ class Mandate(models.Model):
)
begin_date = models.DateField(blank=True, null=True)
end_date = models.DateField(blank=True, null=True)
url = models.URLField()
link = models.URLField()
import representatives.models as models
from rest_framework import serializers
from django.db import transaction
class CountrySerializer(serializers.ModelSerializer):
class Meta:
model = models.Country
fields = ('name', 'code')
class EmailSerializer(serializers.ModelSerializer):
class Meta:
model = models.Email
fields = ('email', 'kind')
class WebsiteSerializer(serializers.ModelSerializer):
class Meta:
model = models.WebSite
fields = ('url', 'kind')
class PhoneSerializer(serializers.ModelSerializer):
class Meta:
model = models.Phone
fields = ('id', 'number', 'kind')
class AddressSerializer(serializers.ModelSerializer):
country = CountrySerializer()
phones = PhoneSerializer(many=True, source='phone_set')
class Meta:
model = models.Address
fields = ('country', 'city', 'street', 'number', 'postcode', 'floor', 'office_number', 'kind', 'phones')
class ContactField(serializers.Serializer):
emails = EmailSerializer(many=True)
phones = PhoneSerializer(many=True)
websites = WebsiteSerializer(many=True)
address = AddressSerializer(many=True)
def get_attribute(self, obj):
return {
'emails': obj.email_set.all(),
'websites': obj.website_set.all(),
'phones': obj.phone_set.all(),
'address': obj.address_set.all(),
}
class MandateSerializer(serializers.ModelSerializer):
name = serializers.CharField(source='group.name')
short_id = serializers.CharField(source='group.abbreviation', allow_null=True)
kind = serializers.CharField(source='group.kind')
constituency = serializers.CharField(source='constituency.name')
class Meta:
model = models.Mandate
fields = (
'id',
'name',
'short_id',
'kind',
'constituency',
'representative',
'role',
'representative',
'begin_date',
'end_date',
)
class MandateHyperLinkedSerializer(MandateSerializer):
class Meta(MandateSerializer.Meta):
fields = MandateSerializer.Meta.fields + ('url',)
class RepresentativeSerializer(serializers.ModelSerializer):
class Meta:
model = models.Representative
fields = (
'id',
'slug',
'remote_id',
'first_name',
'last_name',
'full_name',
'gender',
'birth_place',
'birth_date',
'photo',
'active',
)
class RepresentativeHyperLinkedSerializer(RepresentativeSerializer):
class Meta(RepresentativeSerializer.Meta):
fields = RepresentativeSerializer.Meta.fields + ('url',)
class RepresentativeDetailSerializer(RepresentativeSerializer):
contacts = ContactField()
mandates = MandateSerializer(many=True, source='mandate_set')
class Meta(RepresentativeSerializer.Meta):
fields = RepresentativeSerializer.Meta.fields + (
'cv',
'contacts',
'mandates'
)
# Nested creation is not implemented yet in DRF, it sucks
# TODO : fix this code when it will be implemented
@transaction.atomic
def create(self, validated_data):
contacts_data = validated_data.pop('contacts')
mandates_data = validated_data.pop('mandate_set')
representative = models.Representative.objects.create(**validated_data)
self._create_mandates(mandates_data, representative)
self._create_contacts(contacts_data, representative)
return representative
def _create_contacts(self, contacts_data, representative):
for contact_data in contacts_data['emails']:
contact = models.Email(**contact_data)
contact.representative = representative
contact.save()
for contact_data in contacts_data['websites']:
contact = models.WebSite(**contact_data)
contact.representative = representative
contact.save()
for contact_data in contacts_data['address']:
country, _ = models.Country.objects.get_or_create(
**contact_data.pop('country')
)
phone_set = contact_data.pop('phone_set')
contact = models.Address(**contact_data)
contact.country = country
contact.representative = representative
contact.save()
for phone_data in phone_set:
phone = models.Phone(**phone_data)
phone.address = contact
phone.representative = representative
phone.save()
def _create_mandates(self, mandates_data, representative):
for mandate_data in mandates_data:
constituency, _ = models.Constituency.objects.get_or_create(
**mandate_data.pop('constituency')
)
group, _ = models.Group.objects.get_or_create(
**mandate_data.pop('group')
)
mandate = models.Mandate(**mandate_data)
mandate.representative = representative
mandate.constituency = constituency
mandate.group = group
mandate.save()
......@@ -19,185 +19,28 @@
# Copyright (C) 2013 Laurent Peuch <cortex@worlddomination.be>
# Copyright (C) 2015 Arnaud Fabre <af@laquadrature.net>
import sys
from representatives.models import Representative
from representatives.serializers import RepresentativeDetailSerializer
from django.db import transaction
from datetime import datetime
from representatives.models import Representative, Country, Group, Constituency
PERSONAL_FIELDS = ("first_name", "last_name", "full_name", "birth_place", "cv", "photo")
GENDER_DICT = dict(Representative.GENDER)
# Import a representative
def import_a_representative(data):
serializer = RepresentativeDetailSerializer(data=data)
serializer.is_valid()
return serializer.save()
def import_representatives(data):
return [import_a_representative(r_data) for r_data in data]
# Export
def export_a_representative(representative):
reps = {"id": representative.remote_id}
reps["personal"] = {field: getattr(representative, field) for field in PERSONAL_FIELDS}
reps["personal"]["gender"] = GENDER_DICT[representative.gender]
reps["personal"]["birth_date"] = representative.birth_date.isoformat().split('T')[0] if representative.birth_date else None
reps["contact"] = {}
reps["contact"]["emails"] = [{
"email": email.email,
"type": email.kind
} for email in representative.email_set.all()]
reps["contact"]["websites"] = [{
"website": website.url,
"type": website.kind
} for website in representative.website_set.all()]
reps["contact"]["phones"] = [{
"phone": phone.number,
"type": phone.kind, "address":
phone.address_id,
"id": phone.id
} for phone in representative.phone_set.all()]
reps["contact"]["address"] = [{
"id": address.id,
"country": {"name": address.country.name, "code": address.country.code},
"city": address.city,
"street": address.street,
"number": address.number,
"postcode": address.postcode,
"floor": address.floor,
"office_number": address.office_number,
"type": address.kind,
"geo": None,
"phones": [phone.id for phone in address.phone_set.all()],
} for address in representative.address_set.all()]
reps["mandates"] = [{
"name": mandate.group.name,
"type": mandate.group.kind,
"short_id": mandate.group.abbreviation,
"url_official": mandate.url,
"constituency": mandate.constituency.name,
"role": mandate.role,
"begin_date": mandate.begin_date.isoformat().split('T')[0] if mandate.begin_date else None,
"end_date": mandate.end_date.isoformat().split('T')[0] if mandate.end_date else None,
# "current": mandate.active,
} for mandate in representative.mandate_set.all()]
return reps
serialized = RepresentativeDetailSerializer(representative)
return serialized.data
def export_representatives(filters={}):
return [export_a_representative(representative) for representative in Representative.objects.filter(**filters)]
def export_all_representatives():
return [export_a_representative(representative) for representative in Representative.objects.all()]
return export_representatives()
def export_active_representatives():
return [export_a_representative(representative) for representative in Representative.objects.filter(active=True)]
def import_representatives_from_format(data, verbose=False):
reverted_gender_dict = {x[1]: x[0] for x in Representative.GENDER}
a = 0
end = len(data)
with transaction.atomic():
for reps in data:
a += 1
if verbose:
sys.stdout.write("%s/%s\r" % (a, end))
sys.stdout.flush()
remote_id = reps["id"]
representative = Representative.objects.filter(remote_id=remote_id)
if representative:
representative = representative[0]
else:
representative = Representative()
representative.remote_id = remote_id
representative.first_name = reps["personal"]["first_name"]
representative.last_name = reps["personal"]["last_name"]
representative.full_name = reps["personal"]["full_name"]
representative.birth_place = reps["personal"]["birth_place"]