1
# -*- coding: utf-8 -*-
7
from urllib import urlopen
8
from django.core import management
9
from django.db.models.signals import post_syncdb
10
from models import EarlyVotingStation, VotingStation, ZipCode, County, Municipality, Region
11
from regions import update_regions
12
import models as site_app
13
from transversemercator import RT90
16
EARLY_VOTING_STATIONS_URL = \
17
"http://www.val.se/val/ep2009/rostmottagning/fortidsrostning/rostlokal.xml"
19
VOTING_STATIONS_URL = \
20
"http://www.val.se/val/ep2009/rostmottagning/vallokal/vallokal.xml"
22
def load_zipcodes(sender, created_models, verbosity, **kwargs):
24
Load zip codes into database
26
if not ZipCode in created_models:
28
ZipCode.objects.all().delete()
29
management.call_command('loaddata', 'zipcodes_fixture.json')
31
def municipality_name_to_region(mname):
33
Return the Region object that matches the given municipality name.
36
# Sometimes mname is a tuple instead of a string. Why?
37
new_name = '%s' % mname
40
if new_name == u'Gotland':
41
return Region.objects.get(name=u'Gotlands valkrets')
42
if new_name == u'Malm\xf6':
43
return Region.objects.get(name=u'Malm\xf6 valkrets')
44
if new_name == u'G\xf6teborg':
45
return Region.objects.get(name=u'G\xf6teborgs valkrets')
48
consonant_list = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm',
49
'n', 'p', 'q', 'r', 't', 'v', 'w'] # except s and x
50
if new_name[-1] in consonant_list:
51
new_name += 's kommun'
54
return Region.objects.get(name=new_name)
57
def fetch_earlyvotingstations(sender, created_models, verbosity, **kwargs):
59
Fetch current early voting stations from Swedish Election Authority
61
if not EarlyVotingStation in created_models:
64
print "Fetching " + EARLY_VOTING_STATIONS_URL
66
# TransverseMercator object for converting RT90 coordinates to WGS84
69
doc = xml.dom.minidom.parse(urlopen(EARLY_VOTING_STATIONS_URL))
74
print "Parsing data..."
75
for county in doc.getElementsByTagName(u'LÄN'):
76
current_county = County(id=int(county.getAttribute(u'KOD')),
77
name=county.getAttribute(u'NAMN'))
78
counties.append(current_county)
79
for municipality in county.getElementsByTagName(u'KOMMUN'):
80
m_name = municipality.getAttribute(u'NAMN')
81
current_municipality = Municipality(
82
id=(current_county.id*100) + int(municipality.getAttribute(u'KOD')),
84
county=current_county,
85
region=municipality_name_to_region(m_name))
86
municipalities.append(current_municipality)
87
for station in municipality.getElementsByTagName(u'RÖSTNINGSLOKAL'):
88
rt90x = float(station.getAttribute(u'X') or '0')
89
rt90y = float(station.getAttribute(u'Y') or '0')
90
if rt90x != 0 and rt90y != 0:
91
# Yes, it's Y, X instead of X, Y. RT90 is backwards.
92
(wgs84n, wgs84e) = tmerc.inverse_project_d(rt90y, rt90x)
94
(wgs84n, wgs84e) = (0, 0)
95
newstation = EarlyVotingStation(
96
county = current_county,
97
municipality = current_municipality,
98
region = current_municipality.region,
99
code = int(station.getAttribute(u'KOD') or '0'),
100
name = station.getAttribute(u'NAMN'),
101
address1 = station.getAttribute(u'ADRESS1'),
102
address2 = station.getAttribute(u'ADRESS2'),
103
address3 = station.getAttribute(u'ADRESS3'),
104
city = station.getAttribute(u'POSTORT'),
105
opening_hours = station.getAttribute(u'ÖPPETTIDER'),
106
available = station.getAttribute(u'TILLGÄNGL'),
107
status = station.getAttribute(u'STATUS'),
110
earlystations.append(newstation)
112
print "Counties: " + str(len(counties))
113
print "Municipalities: " + str(len(municipalities))
114
print "Early voting stations: " + str(len(earlystations))
116
print "Storing in models..."
117
County.objects.all().delete()
118
for county in counties:
120
Municipality.objects.all().delete()
121
for municipality in municipalities:
123
EarlyVotingStation.objects.all().delete()
124
for station in earlystations:
127
print "Early voting stations update done!"
129
def fetch_votingstations(sender, created_models, verbosity, **kwargs):
131
Fetch current voting stations from Swedish Election Authority
133
if len(VotingStation.objects.all()) > 0:
136
print "Fetching " + VOTING_STATIONS_URL
137
doc = xml.dom.minidom.parse(urlopen(VOTING_STATIONS_URL))
139
# TransverseMercator object for converting RT90 coordinates to WGS84
144
print "Parsing data..."
145
for county in doc.getElementsByTagName(u'LÄN'):
146
current_county = County(id=int(county.getAttribute(u'KOD')),
147
name=county.getAttribute(u'NAMN'))
148
for municipality in county.getElementsByTagName(u'KOMMUN'):
149
m_name = municipality.getAttribute(u'NAMN'),
150
current_municipality = Municipality(
151
id=(current_county.id*100) + int(municipality.getAttribute(u'KOD')),
153
county=current_county,
154
region=municipality_name_to_region(m_name))
155
for constituency in municipality.getElementsByTagName(u'VALKRETS'):
156
for station in constituency.getElementsByTagName(u'VALDISTRIKT'):
157
rt90x = float(station.getAttribute(u'X') or '0')
158
rt90y = float(station.getAttribute(u'Y') or '0')
159
if rt90x != 0 and rt90y != 0:
160
# Yes, it's Y, X instead of X, Y. RT90 is backwards.
161
(wgs84n, wgs84e) = tmerc.inverse_project_d(rt90y, rt90x)
163
(wgs84n, wgs84e) = (0, 0)
165
county = current_county,
166
municipality = current_municipality,
167
region = current_municipality.region,
168
code = int(station.getAttribute(u'KOD') or '0'),
169
name = station.getAttribute(u'NAMN'),
170
local = station.getAttribute(u'LOKAL'),
171
address1 = station.getAttribute(u'ADRESS1'),
172
address2 = station.getAttribute(u'ADRESS2'),
173
address3 = station.getAttribute(u'ADRESS3'),
174
city = station.getAttribute(u'POSTORT'),
175
available = station.getAttribute(u'TILLGÄNGL'),
176
status = station.getAttribute(u'STATUS'),
177
done = station.getAttribute(u'KLAR'),
182
print "Voting stations: " + str(len(stations))
184
print "Storing in models..."
185
VotingStation.objects.all().delete()
186
for station in stations:
189
print "Voting stations update done!"
192
def load_voter_count(**kwargs):
194
if len(VotingStation.objects.filter(voters=0)) == 0:
197
print "Loading number of voters per station..."
198
sourcefile = os.path.join(os.path.dirname(__file__), "rostberattigade.skv")
199
fd = open(sourcefile)
200
# Skip the header line.
204
fields = line.split(';')
207
county_id = int(fields[11])
208
municipality_id = county_id * 100 + int(fields[23])
209
station_id = int(fields[35])
210
voters = int(fields[37])
211
station = VotingStation.objects.get(municipality__id=municipality_id,
213
station.voters = voters
217
def update_region_statistics(**kwargs):
218
print "Updating region statistics..."
219
root = Region.objects.get(shortname='root')
220
root.update_statistics()
223
post_syncdb.connect(load_zipcodes, sender=site_app)
224
post_syncdb.connect(update_regions, sender=site_app)
225
post_syncdb.connect(fetch_earlyvotingstations, sender=site_app)
226
post_syncdb.connect(fetch_votingstations, sender=site_app)
227
post_syncdb.connect(load_voter_count, sender=site_app)
228
post_syncdb.connect(testdata.generate_testdata, sender=site_app)
229
post_syncdb.connect(update_region_statistics, sender=site_app)