~speakman/ppvalbok/trunk

« back to all changes in this revision

Viewing changes to ballot_system/management.py

  • Committer: Daniel Nyström
  • Date: 2009-05-24 21:35:17 UTC
  • Revision ID: daniel@nystrom.st-20090524213517-q6d1t2d235k5wugu
MAJOR VotingLocal refactoring

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
from models import RegionData, EVSData, VSData
2
 
from swevote.models import Region, EarlyVotingStation, VotingStation
3
 
from django.db.models.signals import post_save
4
 
 
 
1
from swevote.utils import slugify
 
2
from models import RegionData, EVSData, VSData, LocalData
 
3
from utils import distance
 
4
from swevote.models import Region, EarlyVotingStation, VotingStation, VotingLocal, LocalTypes
 
5
from django.db.models.signals import post_save, post_syncdb
 
6
import re
5
7
 
6
8
def create_data_for_region(sender, instance, **kwargs):
7
9
    """
12
14
    if len(RegionData.objects.filter(region=instance)) == 0:
13
15
        data = RegionData(region=instance)
14
16
        data.save()
 
17
post_save.connect(create_data_for_region, sender=Region)
15
18
 
16
19
 
17
20
def create_data_for_evs(sender, instance, **kwargs):
23
26
    if len(EVSData.objects.filter(earlyvotingstation=instance)) == 0:
24
27
        data = EVSData(earlyvotingstation=instance)
25
28
        data.save()
 
29
post_save.connect(create_data_for_evs, sender=EarlyVotingStation)
26
30
 
27
31
 
28
32
def create_data_for_vs(sender, instance, **kwargs):
34
38
    if len(VSData.objects.filter(votingstation=instance)) == 0:
35
39
        data = VSData(votingstation=instance)
36
40
        data.save()
37
 
 
38
 
 
39
 
post_save.connect(create_data_for_region, sender=Region)
40
 
post_save.connect(create_data_for_evs, sender=EarlyVotingStation)
41
41
post_save.connect(create_data_for_vs, sender=VotingStation)
 
42
 
 
43
#
 
44
# Utilities for migration 0001 -> 0002
 
45
#
 
46
REMOVAL_PATTERN = r'[ s,.:;-_]'
 
47
 
 
48
def _find_existing_local(station):
 
49
    for local in VotingLocal.objects.filter(municipality=station.municipality):
 
50
        if re.sub(REMOVAL_PATTERN, '', local.name.lower())  == re.sub(REMOVAL_PATTERN, '', station.local.lower()):
 
51
            if distance(local,station) < 25:
 
52
                return local
 
53
            if station.address1 != "" and local.address1 == station.address1 and distance(local,station) < 300:
 
54
                return local
 
55
    return None
 
56
 
 
57
def _generate_slug(name, municipality):
 
58
    count = 0
 
59
    while True:
 
60
        if count > 0:
 
61
            slug = slugify(name + ' ' + str(count))
 
62
        else:
 
63
            slug = slugify(name)
 
64
 
 
65
        if VotingLocal.objects.filter(municipality=municipality,
 
66
                                     slug=slug).count() == 0:
 
67
            return slug
 
68
 
 
69
        count += 1
 
70
        
 
71
 
 
72
def copy_bookings(localdata, vsdata):
 
73
    altered = False
 
74
 
 
75
    localdata.ballots += vsdata.ballots
 
76
    #localdata.ballots_locked = vsdata.ballots_locked
 
77
 
 
78
    if vsdata.distributor:
 
79
        if localdata.distributor and \
 
80
                localdata.distributor.email != \
 
81
                vsdata.distributor.email:
 
82
            raise Exception("%s already has distributor!" % localdata.votinglocal.name)
 
83
        localdata.distributor = vsdata.distributor
 
84
        altered = True
 
85
        
 
86
    if vsdata.first_watch:
 
87
        if localdata.first_watch and \
 
88
                localdata.first_watch.email != \
 
89
                vsdata.first_watch.email:
 
90
            raise Exception("%s already has first_watch!" % localdata.votinglocal.name)
 
91
        localdata.first_watch = vsdata.first_watch
 
92
        altered = True
 
93
 
 
94
    if vsdata.second_watch:
 
95
        if localdata.second_watch and \
 
96
                localdata.second_watch.email != \
 
97
                vsdata.second_watch.email:
 
98
            raise Exception("%s already has second_watch!" % localdata.votinglocal.name)
 
99
        localdata.second_watch = vsdata.second_watch
 
100
        altered = True
 
101
 
 
102
    if vsdata.third_watch:
 
103
        if localdata.third_watch and \
 
104
                localdata.third_watch.email != \
 
105
                vsdata.third_watch.email:
 
106
            raise Exception("%s already has third_watch!" % localdata.votinglocal.name)
 
107
        localdata.third_watch = vsdata.third_watch
 
108
        altered = True
 
109
 
 
110
    if altered:
 
111
        localdata.save()
 
112
 
 
113
def generate_locals():
 
114
    if VotingLocal.objects.count() > 0:
 
115
        print "VotingLocal already existing. Remove all and try again. Exiting."
 
116
        return
 
117
 
 
118
    print "Calculating VotingLocal (this might take a while)..."
 
119
    for station in VotingStation.objects.order_by('municipality'):
 
120
        local = _find_existing_local(station)
 
121
        if local:
 
122
            local.voters += station.voters
 
123
            local.save()
 
124
        else:
 
125
            local = VotingLocal(
 
126
                localtype=LocalTypes.ELECTION,
 
127
                municipality=station.municipality,
 
128
                region=station.region,
 
129
                name=station.local.strip(),
 
130
                slug=_generate_slug(station.local, station.municipality),
 
131
                address1=station.address1.strip(),
 
132
                address2=station.address2.strip(),
 
133
                address3=station.address3.strip(),
 
134
                city=station.city.strip(),
 
135
                voters=station.voters,
 
136
                lat=station.lat,
 
137
                lon=station.lon,
 
138
                )
 
139
            local.save()
 
140
            local.localdata = LocalData(votinglocal=local)
 
141
            local.localdata.save()
 
142
            local.save()
 
143
        station.votinglocal = local
 
144
        station.save()
 
145
 
 
146
    print "found %d locals" % VotingLocal.objects.count()
 
147
 
 
148
 
 
149
def merge_bookings():
 
150
    for station in VotingStation.objects.all():
 
151
        copy_bookings(station.votinglocal.data, station.vsdata)
 
152
 
 
153
def postsync_votinglocal_handler(sender, app, created_models,
 
154
                                 verbosity, interactive, **kwargs):
 
155
    if LocalData in created_models:
 
156
        if VotingLocal.objects.count() == 0:
 
157
            generate_locals()
 
158
            merge_bookings()
 
159
    
 
160
post_syncdb.connect(postsync_votinglocal_handler)