Skip to content

Commit

Permalink
import refactored with logging
Browse files Browse the repository at this point in the history
  • Loading branch information
guglielmo committed Jun 15, 2012
1 parent ca7eca4 commit 5e25a95
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 60 deletions.
2 changes: 1 addition & 1 deletion open_municipio/acts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from open_municipio.taxonomy.managers import TopicableManager
from open_municipio.taxonomy.models import Category, TaggedAct
from open_municipio.locations.models import Location, TaggedActByLocation
from open_municipio.monitoring.models import MonitorizedItem
from open_municipio.monitoring.models import MonitorizedItem, Monitoring


#
Expand Down
103 changes: 56 additions & 47 deletions open_municipio/om/management/commands/importvotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

from open_municipio.people.models import Sitting, Institution, Person
from open_municipio.votations.models import Votation, ChargeVote, InstitutionCharge

import traceback
from open_municipio import settings_import as settings

import logging



# configure xml namespaces
NS = {
Expand Down Expand Up @@ -39,45 +40,32 @@ class Command(LabelCommand):
help = "Import the voting information contained in the specified XML documents"
label = 'filename'

logger = logging.getLogger('import')

people_tree = None

def lookupCharge(self, xml_chargevote, institution, **options):
def lookupCharge(self, om_id, **options):
"""
look for the correct open municipio charge, or return None
"""
try:
# this is done through component_id,
# making the whole ChargeXRef stuff unused
# TODO: see if there's a more flexible way to do it, using ChargeXRef
component_id = xml_chargevote.get("componentId")
people_charges = self.people_tree.xpath(
'//om:Person[@id=%s]' % component_id,
namespaces={'om': "http://www.openmunicipio.it"}
)
if len(people_charges):
om_id = people_charges[0].get('om_id')
if om_id is None:
if int(options['verbosity']) > 0:
self.stderr.write("Warning: charge with id %s has no om_id (past charge?). Skipping.\n" % component_id)
return None
try:
person = Person.objects.get(pk=int(om_id))
charge = person.current_institution_charge(institution)
return charge
except ObjectDoesNotExist:
if int(options['verbosity']) > 1:
self.stderr.write("Warning: could not find person or charge for id = %s in open municipio DB. Skipping.\n" % component_id)
return None
except MultipleObjectsReturned:
self.stderr.write("Error: found more than one person or charge for id %s in open municipio db. Skipping.\n" % component_id)
return None
else:
people_charges = self.people_tree.xpath(
'//om:Person[@om_id=%s]' % om_id,
namespaces={'om': "http://www.openmunicipio.it"}
)
if len(people_charges) == 1:
id = people_charges[0].get('id')
if id is None:
if int(options['verbosity']) > 0:
self.stderr.write("Warning: could not find person for id %s in peopkle XML file. Skipping.\n" % component_id)
self.logger.error(" charge with om_id %s has no id in people XML file. Skipping.\n" % om_id)
return None
except ObjectDoesNotExist:
return id
elif len(people_charges) > 1:
if int(options['verbosity']) > 0:
self.stderr.write("Warning: could not find charge with id %s in Open Municipio DB. Skipping.\n" % component_id)
self.logger.error(" more than one person for om_id %s in people XML file. Skipping.\n" % om_id)
return None
else:
if int(options['verbosity']) > 0:
self.logger.error(" no person for om_id %s in people XML file. Skipping.\n" % om_id)
return None


Expand All @@ -88,7 +76,7 @@ def handle_label(self, filename, **options):
tree = etree.parse(filename)

sittings = tree.xpath("/om:Sitting",namespaces=NS)
self.stdout.write("%d Sittings to import\n" % len(sittings))
self.logger.debug("%d Sittings to import\n" % len(sittings))
for xml_sitting in sittings:

# map the sitting site code into an Institution
Expand All @@ -104,6 +92,7 @@ def handle_label(self, filename, **options):
# get or create the sitting object
curr_inst = Institution.objects.get(name=settings.XML_TO_OM_INST[site])
council_inst = Institution.objects.get(name=settings.XML_TO_OM_INST['SCN'])
self.logger.debug("Working in institution %s" % curr_inst)

sitting_date = xml_sitting.get("date")[0:10]
om_sitting, created = Sitting.objects.get_or_create(
Expand All @@ -113,13 +102,13 @@ def handle_label(self, filename, **options):
)

if not created:
self.stdout.write("\n\nFound sitting %s - %s\n" % (om_sitting.number, sitting_date))
self.logger.debug("Found sitting %s - %s" % (om_sitting.number, sitting_date))
else:
self.stdout.write("\n\nCreated sitting %s - %s\n" % (om_sitting.number, sitting_date))
self.logger.debug("Created sitting %s - %s" % (om_sitting.number, sitting_date))

# fetch all votations for the sitting in the XML
votations = xml_sitting.xpath("./om:Votation", namespaces=NS)
self.stdout.write("%d Votations to import\n" % len(votations))
self.logger.debug("%d Votations to import\n" % len(votations))
for xml_votation in votations:

vot_num = xml_votation.get("seq_n")
Expand All @@ -135,9 +124,9 @@ def handle_label(self, filename, **options):
sitting=om_sitting
)
if not created:
self.stdout.write("Found votation %s\n" % om_votation.idnum)
self.logger.debug("Found votation %s\n" % om_votation.idnum)
else:
self.stdout.write("Created votation %s\n" % om_votation.idnum)
self.logger.debug("Created votation %s\n" % om_votation.idnum)

# new votations get statistics (or overwrite)
if created or options['overwrite']:
Expand All @@ -154,20 +143,40 @@ def handle_label(self, filename, **options):
# om_votation.outcome = xml_votation.get("outcome") # decode
om_votation.save()

self.stdout.write("title: %s\n" % om_votation.act_descr.encode('utf-8'))
self.logger.debug("title: %s\n" % om_votation.act_descr.encode('utf-8'))

# build a ChargeVote for every single vote
chargevotes = xml_votation.xpath("./om:Votes/om:ChargeVote", namespaces=NS)
self.stdout.write("Votation contains %d ChargeVotes\n" % len(chargevotes))

self.logger.debug("Votation in XML contains %d ChargeVotes\n" % len(chargevotes))

# loop over all members of the institution
# at the moment of the sitting
for m in curr_inst.charge_set.current(moment=sitting_date):
om_id = m.person.id
xml_id = self.lookupCharge(om_id)
self.logger.debug("Member: %s (om_id:%s => xml_id:%s)" % (m, om_id, xml_id ))
chargevote = xml_votation.xpath("./om:Votes/om:ChargeVote[@componentId=%s]" % xml_id, namespaces=NS)
if len(chargevote):
vote = chargevote[0].get('vote')
self.logger.debug("Vote: %s" % vote)
else:
self.logger.error("Absent!")

"""
# remove all votes in this votation if overwriting
if options['overwrite']:
ChargeVote.objects.filter(votation=om_votation).delete()
ChargeVote.objects.filter (votation=om_votation).delete()
for xml_cv in chargevotes:
for n, xml_cv in enumerate(chargevotes, start=1):
self.logger.debug(
"%s) ComponentId: %s " % (n, xml_cv.get('componentId'))
)
# lookup council charges to match with ChargeVote
om_charge = self.lookupCharge(xml_cv, council_inst, **options)
if om_charge is None:
self.logger.debug(
"charge not found. Skipping \n"
)
continue
# get or create ChargeVote
Expand All @@ -193,12 +202,12 @@ def handle_label(self, filename, **options):
om_cv.vote = settings.XML_TO_OM_VOTE[xml_vote]
om_cv.save()
self.stdout.write("Person: %s - %s\n" % (om_charge.person.last_name.encode('utf8'), om_cv.vote))

self.logger.debug("Person: %s - %s\n" % (om_charge.person.last_name.encode('utf8'), om_cv.vote))
"""

# update votation caches
om_votation.update_caches()
self.stdout.write("caches for this votation updated.\n")
self.logger.debug("caches for this votation updated.\n")

def handle(self, *labels, **options):

Expand Down
27 changes: 17 additions & 10 deletions open_municipio/people/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,6 @@ class TimeFramedQuerySet(QuerySet):
We assume that the time range is described by two ``Date`` (or ``DateTime``) fields
named ``start_date`` and ``end_date``, respectively.
"""
def current(self):
"""
Return a QuerySet containing the *current* instances of the model
(i.e. those for which the current date-time lies within their associated time range).
"""
now = datetime.now()
return self.filter(Q(start_date__lte=now) &
(Q(end_date__gte=now) | Q(end_date__isnull=True)))

def past(self):
"""
Return a QuerySet containing the *past* instances of the model
Expand All @@ -36,4 +27,20 @@ def future(self):
(i.e. those having a start date which is in the future).
"""
now = datetime.now()
return self.filter(start_date__gte=now)
return self.filter(start_date__gte=now)

def current(self, moment=None):
"""
Return a QuerySet containing the *current* instances of the model
at the given moment in time, if the parameter is spcified
now if it is not
@moment - is a datetime, expressed in the YYYY-MM-DD format
(i.e. those for which the moment date-time lies within their associated time range).
"""
if moment is None:
moment = datetime.now()
else:
moment = datetime.strptime(moment, "%Y-%m-%d")

return self.filter(Q(start_date__lte=moment) &
Q(end_date__gte=moment) | Q(end_date__isnull=True))
4 changes: 2 additions & 2 deletions open_municipio/people/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Person(models.Model, MonitorizedItem):

img = ImageField(upload_to="person_images", blank=True, null=True)

# manager to handle the list of monitoring having as content_object this instance
# manager to handle the list of monitoring having as content_object this instance
#monitoring_set = generic.GenericRelation(Monitoring, object_id_field='object_pk')

class Meta:
Expand Down Expand Up @@ -705,7 +705,7 @@ def get_absolute_url(self):
def charges(self):
"""
The QuerySet of all *current* charges (``InstitutionCharge`` instances)
associated with this institution.
associated with this institution.
"""
return self.charge_set.current()

Expand Down

0 comments on commit 5e25a95

Please sign in to comment.