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