Commit 9eaea806 authored by Arnaud Fabre's avatar Arnaud Fabre

better api

parent 1361a192
......@@ -34,6 +34,6 @@ class Command(BaseCommand):
def handle(self, *args, **options):
fingerprint = options['fingerprint']
if options['celery']:
import_a_dossier_from_toutatis.delay(fingerprint, delay=True)
import_a_dossier_from_toutatis.delay(fingerprint)
else:
import_a_dossier_from_toutatis(fingerprint, delay=False)
import_a_dossier_from_toutatis(fingerprint)
......@@ -43,7 +43,9 @@ class Proposal(HashableModel, TimeStampedModel):
total_against = models.IntegerField()
total_for = models.IntegerField()
hashable_fields = ['dossier', 'title', 'reference', 'kind']
hashable_fields = ['dossier', 'title', 'reference',
'kind', 'total_abstain', 'total_against',
'total_for']
def __unicode__(self):
return unicode(self.title)
......
......@@ -25,27 +25,39 @@ from django.db import transaction
class VoteSerializer(serializers.ModelSerializer):
'''
Serializer for votes
'''
proposal = serializers.CharField(
source='proposal.fingerprint'
)
class Meta:
model = models.Vote
fields = (
'id',
'proposal',
'representative_name',
'representative_remote_id',
'position'
)
def to_internal_value(self, data):
data = super(VoteSerializer, self).to_internal_value(data)
data['proposal'] = models.Proposal.objects.get(
fingerprint=data['proposal']['fingerprint']
)
return data
class ProposalSerializer(serializers.ModelSerializer):
'''
Base Proposal Serializer
'''
dossier = serializers.CharField(
source='dossier.fingerprint'
)
class Meta:
model = models.Proposal
fields = (
'id',
'fingerprint',
'dossier',
'title',
'description',
'reference',
......@@ -56,63 +68,47 @@ class ProposalSerializer(serializers.ModelSerializer):
'total_for',
)
class ProposalHyperLinkedSerializer(ProposalSerializer):
'''
Proposal Serializer with hyperlink to dossier (used for listing)
'''
dossier = serializers.HyperlinkedRelatedField(
read_only = True,
view_name = 'dossier-detail',
)
dossier_title = serializers.CharField(
read_only = True,
source = 'dossier.title'
)
dossier_reference = serializers.CharField(
read_only = True,
source = 'dossier.reference'
)
class Meta(ProposalSerializer.Meta):
fields = ProposalSerializer.Meta.fields + (
'dossier',
'dossier_title',
'dossier_reference',
'url',
def to_internal_value(self, data):
validated_data = super(ProposalSerializer, self).to_internal_value(data)
validated_data['dossier'] = models.Dossier.objects.get(
fingerprint=validated_data['dossier']['fingerprint']
)
validated_data['votes'] = data['votes']
return validated_data
def _create_votes(self, votes_data, proposal):
for vote in votes_data:
vote['proposal'] = proposal
models.Vote.objects.create(
**vote
)
class ProposalDetailSerializer(ProposalSerializer):
'''
Proposal Serializer with votes detail (used in Dossier Detail)
'''
votes = VoteSerializer(many=True)
class Meta(ProposalSerializer.Meta):
fields = ProposalSerializer.Meta.fields + (
'votes',
def create(self, validated_data):
votes_data = validated_data.pop('votes')
proposal = models.Proposal.objects.create(
**validated_data
)
self._create_votes(votes_data, proposal)
return proposal
def update(self, instance, validated_data):
validated_data.pop('votes')
for attr, value in validated_data.iteritems():
setattr(instance, attr, value)
instance.save()
return instance
class ProposalDetailHyperLinkedSerializer(ProposalDetailSerializer, ProposalHyperLinkedSerializer):
'''
Proposal Serializer combined Detail Serializer and Hyperlinked Serializer
'''
class ProposalDetailSerializer(ProposalSerializer):
votes = VoteSerializer(many=True)
class Meta(ProposalSerializer.Meta):
fields = ProposalSerializer.Meta.fields + (
'dossier',
'dossier_title',
'dossier_reference',
'votes',
)
class DossierSerializer(serializers.ModelSerializer):
'''
Base Dossier Serializer
'''
class Meta:
model = models.Dossier
fields = (
......@@ -122,30 +118,7 @@ class DossierSerializer(serializers.ModelSerializer):
'reference',
'text',
'link',
)
class DossierListSerializer(DossierSerializer):
'''
Dossier Serializer with short description of proposals
'''
class ProposalSerializer(ProposalSerializer):
class Meta(ProposalSerializer.Meta):
fields = (
'id',
'url',
) + ProposalSerializer.Meta.fields
proposals = ProposalSerializer(
many = True,
read_only = True
)
class Meta(DossierSerializer.Meta):
fields = DossierSerializer.Meta.fields + (
'url',
'proposals',
)
......@@ -162,26 +135,3 @@ class DossierDetailSerializer(DossierSerializer):
fields = DossierSerializer.Meta.fields + (
'proposals',
)
@transaction.atomic
def create(self, validated_data):
proposals_data = validated_data.pop('proposals')
dossier, _ = models.Dossier.objects.get_or_create(**validated_data)
for proposal_data in proposals_data:
proposal, created = self._create_proposal(
proposal_data,
dossier
)
return dossier
def _create_proposal(self, proposal_data, dossier):
votes_data = proposal_data.pop('votes')
proposal_data['dossier'] = dossier
proposal, created = models.Proposal.objects.get_or_create(**proposal_data)
if created:
for vote_data in votes_data:
vote_data['proposal'] = proposal
models.Vote.objects.create(**vote_data)
return (proposal, created)
......@@ -29,43 +29,22 @@ import redis
from celery import shared_task
from urllib2 import urlopen
from representatives_votes.models import Dossier
from representatives_votes.serializers import DossierDetailSerializer
from representatives_votes.models import Dossier, Proposal, Vote
from representatives.tasks import import_a_model
from representatives_votes.serializers import DossierSerializer, ProposalSerializer, VoteSerializer
logger = logging.getLogger(__name__)
@shared_task
def import_a_dossier(data):
'''
Import a dossier from serialized
'''
with redis.Redis().lock('import_a_dossier'):
try:
dossier = Dossier.objects.get(
fingerprint=data['fingerprint']
)
serializer = DossierDetailSerializer(
instance=dossier,
data=data
)
except:
serializer = DossierDetailSerializer(data=data)
if serializer.is_valid():
return serializer.save()
else:
raise Exception(serializer.errors)
@shared_task
def import_a_dossier_from_toutatis(fingerprint, delay=False):
def import_a_dossier_from_toutatis(fingerprint):
'''
Import a complete dossier from a toutatis server
'''
toutatis_server = settings.TOUTATIS_SERVER
search_url = '{server}/api/dossiers/?fingerprint={fingerprint}'.format({
'server': toutatis_server,
'fingerprint': fingerprint
})
search_url = '{}/api/dossiers/?fingerprint={}'.format(
toutatis_server,
fingerprint
)
logger.info('Import dossier with fingerprint {} from {}'.format(
fingerprint,
search_url
......@@ -75,10 +54,10 @@ def import_a_dossier_from_toutatis(fingerprint, delay=False):
raise Exception('Search should return one and only one result')
detail_url = data['results'][0]['url']
data = json.load(urlopen(detail_url))
if delay:
import_a_dossier.delay(data)
else:
import_a_dossier(data)
import_a_model(data, Dossier, DossierSerializer)
for proposal in data['proposals']:
logger.info('Import proposal {}'.format(proposal['title']))
import_a_model(proposal, Proposal, ProposalSerializer)
@shared_task
def import_a_proposal_from_toutatis(fingerprint, delay=False):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment