Permalink
Browse files

data import now may delete superseded collections

  • Loading branch information...
1 parent 03f58c9 commit 69f66c3c264026f1da7b510aebaa6185034835d5 @davewhiteland davewhiteland committed May 9, 2011
View
8 INSTALL.txt
@@ -11,10 +11,16 @@ databases.
Please use South for future binalerts migrations too.
You can load collection time data in with one of these, a small sample used by
-the test code, or a large full file:
+the test code:
./manage.py loadpdf garden_sample_pdf.xml
+
+... or a large full file: (this is Garden Waste, but includes postcodes)
./manage.py loadpdf garden-and-kitchen-waste-collection-streets.xml
+...then load the Domestic waste (lacks postcodes):
+ ./manage.py loadcvs refuse_rounds_road_day.csv
+
+
For me only the binalerts app tests work (not the Django core ones). So I run
tests like this:
./manage.py test binalerts
View
8 pylib/djangoproj/binalerts/admin.py
@@ -9,7 +9,13 @@
from django.contrib import admin
-admin.site.register(BinCollection)
+class BinCollectionAdmin(admin.ModelAdmin):
+ date_hierarchy = 'last_updated'
+ readonly_fields = ('last_updated',)
+ list_display = ('street', 'collection_day', 'collection_type', 'last_updated')
+ list_display_links = ('street', 'collection_day', 'collection_type')
+
+admin.site.register(BinCollection, BinCollectionAdmin)
admin.site.register(BinCollectionType)
admin.site.register(CollectionAlert)
admin.site.register(EmailConfirmation)
View
68 pylib/djangoproj/binalerts/migrations/0003_auto__add_field_bincollection_last_updated.py
@@ -0,0 +1,68 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Adding field 'BinCollection.last_updated'
+ db.add_column('binalerts_bincollection', 'last_updated', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, auto_now_add=True, null=True, blank=True), keep_default=False)
+
+
+ def backwards(self, orm):
+
+ # Deleting field 'BinCollection.last_updated'
+ db.delete_column('binalerts_bincollection', 'last_updated')
+
+
+ models = {
+ 'binalerts.bincollection': {
+ 'Meta': {'object_name': 'BinCollection'},
+ 'collection_day': ('django.db.models.fields.IntegerField', [], {}),
+ 'collection_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['binalerts.BinCollectionType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}),
+ 'street': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bin_collections'", 'to': "orm['binalerts.Street']"})
+ },
+ 'binalerts.bincollectiontype': {
+ 'Meta': {'object_name': 'BinCollectionType'},
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'detail_text': ('django.db.models.fields.TextField', [], {'default': "''", 'max_length': '1024', 'blank': 'True'}),
+ 'friendly_id': ('django.db.models.fields.CharField', [], {'max_length': '4'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ },
+ 'binalerts.collectionalert': {
+ 'Meta': {'ordering': "('email',)", 'object_name': 'CollectionAlert'},
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_checked_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.date(2000, 1, 1)'}),
+ 'street': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['binalerts.Street']", 'null': 'True'})
+ },
+ 'binalerts.street': {
+ 'Meta': {'object_name': 'Street'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'partial_postcode': ('django.db.models.fields.CharField', [], {'max_length': '5'}),
+ 'url_name': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'db_index': 'True'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'emailconfirmation.emailconfirmation': {
+ 'Meta': {'object_name': 'EmailConfirmation'},
+ 'confirmed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'page_after': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ }
+ }
+
+ complete_apps = ['binalerts']
View
28 pylib/djangoproj/binalerts/models.py
@@ -9,6 +9,8 @@
import xml.dom.minidom
import re
+from djangoproj.settings import BINS_ALLOW_MULTIPLE_COLLECTIONS_PER_WEEK
+
from django.db import models
from django.contrib.contenttypes import generic
@@ -44,15 +46,26 @@ class Street(models.Model):
url_name = models.SlugField(max_length=50)
partial_postcode = models.CharField(max_length=5) # e.g. NW4
+ def add_collection(self, collection_type, collection_day):
+ if not BINS_ALLOW_MULTIPLE_COLLECTIONS_PER_WEEK:
+ # delete all other collections (of this type), on all days, then create a new one
+ for bc in self.bin_collections.filter(collection_type=collection_type):
+ bc.delete()
+ # find the single bin collection of this type on this day, and mark it as modified
+ bin_collection, was_created = BinCollection.objects.get_or_create(street=self, collection_type=collection_type, collection_day=collection_day )
+ if not was_created:
+ bin_collection.last_update = datetime.datetime.now()
+ bin_collection.save()
+
objects = StreetManager()
def __unicode__(self):
return "%s, %s" % (self.name, self.partial_postcode)
class BinCollectionManager(models.Manager):
def find_by_street_name(self, street_name):
- return self.filter(street__name__icontains=street_name)
-
+ return self.filter(street__name__icontains=street_name)
+
# Convert from day of week string e.g. Sunday, to number, e.g. 0
def day_of_week_string_to_number(self, day_of_week):
for row in DAY_OF_WEEK_CHOICES:
@@ -127,10 +140,10 @@ def _yield_rows_from_pdf(self, doc):
# loads http://www.barnet.gov.uk/garden-and-kitchen-waste-collection-streets.pdf
# after it has been converted with "pdftohtml -xml"
- def load_from_pdf_xml(self, xml_file_name):
+ def load_from_pdf_xml(self, xml_file_name, collection_type_id='G'):
doc = xml.dom.minidom.parse(xml_file_name)
- this_type = BinCollectionType.objects.get(friendly_id='G')
+ this_type = BinCollectionType.objects.get(friendly_id=collection_type_id)
rows = self._yield_rows_from_pdf(doc)
started = False
@@ -176,18 +189,15 @@ def load_from_pdf_xml(self, xml_file_name):
url_name = slug,
partial_postcode = checked_partial_postcode,
)
- bin_collection = BinCollection.objects.create(
- street = street,
- collection_day = day_of_week_as_number,
- collection_type = this_type, # NB defaulting to a single type at the moment
- )
+ street.add_collection(this_type, day_of_week_as_number)
# Represents when a type of bin is collected for a particular street.
class BinCollection(models.Model):
street = models.ForeignKey(Street, null=False, related_name='bin_collections')
collection_day = models.IntegerField(choices=DAY_OF_WEEK_CHOICES)
collection_type = models.ForeignKey(BinCollectionType, null=False)
+ last_updated = models.DateTimeField(auto_now=True, auto_now_add=True, null=True) # allow tracking of change data
objects = BinCollectionManager()
View
5 pylib/djangoproj/settings.py
@@ -49,6 +49,11 @@
DATABASE_HOST = config.get('BINS_DB_HOST')
DATABASE_PORT = config.get('BINS_DB_PORT')
+# True if the *same type of collection* can occur at a given address more than once a week
+# (the default, False, is common: e.g., recycling is only collected once a week)
+# If false, it means if the a new collection day is read from the import, the old one will be deleted
+BINS_ALLOW_MULTIPLE_COLLECTIONS_PER_WEEK = config.get('BINS_ALLOW_MULTIPLE_COLLECTIONS_PER_WEEK', False)
+
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.

0 comments on commit 69f66c3

Please sign in to comment.