from datetime import * from dateutil import relativedelta from django.db import models from django.db.models import permalink from django.utils.translation import ugettext_lazy as _ from django.core.urlresolvers import reverse from django.contrib.auth.models import User from django.contrib.localflavor.us.models import PhoneNumberField, USStateField from fields import ZipCodeField from django_extensions.db.models import TimeStampedModel import os import csv import urllib #import pbp_com.settings as settings from django.conf import settings def get_lat_long(location): key = settings.GOOGLE_API_KEY output = "csv" location = urllib.quote_plus(location) request = "http://maps.google.com/maps/geo?q=%s&output=%s&key=%s" % (location, output, key) data = urllib.urlopen(request).read() dlist = data.split(',') if dlist[0] == '200': return "%s, %s" % (dlist[2], dlist[3]) else: return '' class Person(TimeStampedModel): """Person model.""" GENDER_CHOICES=( (1, 'Male'), (2, 'Female'), ) title=models.CharField(_('title'), blank=True, null=True, max_length=20) first_name=models.CharField(_('first name'), blank=True, max_length=100) middle_name=models.CharField(_('middle name'), blank=True, null=True, max_length=100) last_name=models.CharField(_('last name'), blank=True, max_length=100) nickname=models.CharField(_('nickname'), blank=True, null=True, max_length=100) suffix=models.CharField(_('suffix'), blank=True, null=True, max_length=20) slug=models.SlugField(_('slug'), unique=True) user=models.ForeignKey(User, blank=True, null=True, help_text='If the person is an existing user of your site.') gender=models.PositiveSmallIntegerField(_('gender'), choices=GENDER_CHOICES, blank=True, null=True) birth_date=models.DateField(_('birth date'), blank=True, null=True) death_date=models.DateField(_('death date'), blank=True, null=True) phone=PhoneNumberField(blank=True) email=models.EmailField(blank=True) town=models.ForeignKey('Town', blank=True, null=True) class Meta: verbose_name=_('person') verbose_name_plural=_('people') ordering=('last_name', 'first_name') def __unicode__(self): return u'%s' % self.full_name @property def full_name(self): return u'%s %s' % (self.first_name, self.last_name) @property def age(self): if self.death_date: DELTA=self.death_date else: DELTA=datetime.today() return u'%s' % relativedelta.relativedelta(DELTA, self.birth_date).years @permalink def get_absolute_url(self): return ('di-person-detail', None, {'slug': self.slug}) class Town(TimeStampedModel): '''Town model.''' name=models.CharField(_('name'), max_length=100) state=USStateField(_('state')) slug=models.SlugField(_('slug'), unique=True) in_coverage=models.BooleanField(_('in coverage'), default=False) zipcode=ZipCodeField(_('Zipcode'), blank=True, null=True, help_text='Use for a primary zipcode when town has multiple.', max_length=5) class Meta: unique_together=(('name','state',),) ordering=('state', 'name',) def __unicode__(self): return u'%s, %s' % (self.name, self.state) @permalink def get_absolute_url(self): return ('di-town-detail', None, {'slug': self.slug}) class PopulationYear(TimeStampedModel): ''' Population yaer model. Keeps track of a population count for a town in a given (usually census) year. ''' town=models.ForeignKey(Town) year=models.IntegerField(_('year'), max_length=4) population=models.IntegerField(_('population'), max_length=7) def __unicode__(self): return u'%s %s population' % (self.town, self.year) class TownInfo(TimeStampedModel): ''' Town info model. Keeps track of various pieces of town info for our register. We create a separate model so that we can use a really simple setup for our legacy website and just rewrite this whole class when we're ready to implement some higher-level town info stuff. This way we do not have to delete town ids and mess up all related_name applications. ''' town=models.ForeignKey(Town) office=models.ForeignKey("Place") po_box=models.IntegerField(_('PO Box')) map=models.FileField(_('Town map'), blank=True, null=True, upload_to='directory/maps/') time_info=models.TextField(_('Contact info')) description=models.TextField(_('Description')) officials=models.TextField(_('Officials')) tax_info=models.TextField(_('Tax info')) permits=models.TextField(_('Permits')) town_ordinances=models.TextField(_('Town ordinances')) post_offices=models.TextField(_('Post offices')) total_area=models.IntegerField(_('Total area'), help_text='In acres') land_area=models.IntegerField(_('Land'), help_text='In acres') bog_area=models.IntegerField(_('Bog'), help_text='In acres', default=0) flood_plain_area=models.IntegerField(_('Flood plain'), help_text='In acres', default=0) inland_water_area=models.IntegerField(_('Inland water'), help_text='In acres', default=0) shoreline=models.IntegerField(_('Shoreline'), help_text='In miles', default=0) populations=models.ManyToManyField(PopulationYear, blank=True, null=True) edu_contact=models.TextField(_('Education contact')) enrollment=models.TextField(_('Enrollment numbers')) fire_dept_info=models.TextField(_('Fire department')) cemetery_info=models.TextField(_('Cemeteries'), blank=True, null=True) trash_recycle_info=models.TextField(_('Trash & recycling'), blank=True, null=True) public_restrooms=models.TextField(_('Public restrooms'), blank=True, null=True) walking_trails=models.TextField(_('Walking trails'), blank=True, null=True) public_landings=models.TextField(_('Public landings'), blank=True, null=True) def __unicode__(self): return u'%s information' % (self.town) @permalink def get_absolute_url(self): return ('di-town-info', None, {'slug': self.town.slug}) class Committee(TimeStampedModel): '''Committee model.''' title=models.CharField(_('title'), max_length=100) slug=models.SlugField(_('slug'), unique=True) town=models.ForeignKey(Town, related_name="town_committee") members=models.ManyToManyField(Person, blank=True, null=True) def __unicode__(self): return u'%s %s' % (self.town, self.title) def get_absolute_url(self): args = self.slug return reverse('di-committee-detail', args=args) class Point(TimeStampedModel): lat_lon=models.CharField(_('coordinates'), blank=True, null=True, max_length=255) address=models.CharField(_('address'), max_length=255) town=models.ForeignKey(Town) zipcode=models.CharField(_('zip'), max_length=10, blank=True) def __unicode__(self): return u'%s, %s' % (self.address, self.town) class Meta: verbose_name=(_('point')) verbose_name_plural=(_('points')) def save(self, *args, **kwargs): if not self.lat_lon: location = "%s +%s +%s +%s" % (self.address, self.town, self.town.state, self.zipcode) self.lat_lon = get_lat_long(location) if not self.lat_lon: location = "%s +%s +%s" % (self.town, self.town.state, self.zipcode) self.lat_lon = get_lat_long(location) super(Point, self).save(*args, **kwargs) class Place(TimeStampedModel): '''Place model for Directory application.''' STATUS_CHOICES = ( (0, 'Inactive'), (1, 'Active'), ) point=models.ForeignKey(Point, blank=True, null=True) title=models.CharField(_('Title'), max_length=255) slug=models.SlugField(_('Slug')) description=models.TextField(_('Description'), blank=True, null=True) status=models.IntegerField(_('Status'), choices=STATUS_CHOICES, default=1) po_box=models.IntegerField(_('P.O. Box'), blank=True, null=True, max_length=5) po_box_town=models.ForeignKey(Town, blank=True, null=True) phone=PhoneNumberField(_('Phone'), blank=True, null=True) fax=PhoneNumberField(_('Fax'), blank=True, null=True) email=models.EmailField(_('Email'), blank=True, null=True) website=models.URLField(_('Website'), blank=True, null=True, verify_exists=False) def __unicode__(self): return self.title @permalink def get_absolute_url(self): return ('di-place-detail', None, {'slug': self.slug}) class SchoolAdministrativeUnit(TimeStampedModel): ''' An SAU, as defined by the state of Maine. ''' name=models.CharField(_('name'), max_length=100) slug=models.SlugField(_('slug'), unique=True) union=models.IntegerField(_('union'), max_length=2, blank=True, null=True) # governor=models.ForeignKey(Board, blank=True, null=True) def __unicode__(self): return self.name @permalink def get_absolute_url(self): return ('di-sau-detail', None, {'slug': self.slug}) class School(Place): ''' School model. A school derives from the Place model, adding a few school-specific fields ''' TYPE_CHOICES = ( ('E', 'Elementary School'), ('H', 'High School'), ('C', 'Combined School'), ('U', 'College/University'), ('O', 'Other'), ) CLASS_CHOICES = ( ('N', 'None'), ('A', 'A'), ('B', 'B'), ('C', 'C'), ('D', 'D'), ) REGION_CHOICES = ( ('N', 'None'), ('W', 'West'), ('E', 'East'), ) short_title=models.CharField(_('short title'), max_length=30) type=models.CharField(_('type'), choices=TYPE_CHOICES, default="O", max_length=1) #enrollment=models.ManyToMany(Enrollment?) administration=models.ForeignKey(SchoolAdministrativeUnit) title_one_eligible=models.BooleanField(_('title one eligible'), default=False) title_one_recipient=models.BooleanField(_('title one recipient'), default=False) school_class=models.CharField(_('class'), max_length=1, choices=CLASS_CHOICES, default='N') region=models.CharField(_('region'), max_length=2, choices=REGION_CHOICES, default='N') mascot=models.CharField(_('mascot'), max_length=50, blank=True, null=True) athletic_director=models.ForeignKey(Person, related_name='athletic_director', blank=True, null=True) principal=models.ForeignKey(Person, related_name='principal', blank=True, null=True) @permalink def get_absolute_url(self): return ('di-school-detail', None, {'slug': self.slug}) class PhoneBookEntry(TimeStampedModel): entry=models.CharField(_('entry'), max_length=100) phone=PhoneNumberField() town=models.ForeignKey(Town) owner=models.ForeignKey(Person, blank=True, null=True) related_place=models.ForeignKey(Place, blank=True, null=True) def __unicode__(self): return u'%s: %s' % (self.entry, self.phone) class Meta: verbose_name=(_('phone book entry')) verbose_name_plural=(_('phone book entries')) class PhoneBookEntryUpload(models.Model): data_file = models.FileField(_('data file (.csv)'), upload_to="temp", help_text=_('Select a .csv file of phone book data to upload.')) town = models.ForeignKey(Town) class Meta: verbose_name = _('phone book entry upload') verbose_name_plural = _('phone book entry uploads') def save(self): super(PhoneBookEntryUpload, self).save() self.process_datafile() super(PhoneBookEntryUpload, self).delete() def process_datafile(self): if os.path.isfile(self.data_file.path): entry_data = csv.reader(open(self.data_file.path), delimiter='\t') for row in entry_data: args={} args['town'] = self.town args['entry'] = row[0] if len(row[1]) > 8 or len(row[1]) < 4: args['phone'] = row[1] else: args['phone'] = '207-'+row[1] entry = PhoneBookEntry.objects.create(**args) try: entry.save() except: pass