models.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. from datetime import *
  2. from dateutil import relativedelta
  3. from django.db import models
  4. from django.db.models import permalink
  5. from django.utils.translation import ugettext_lazy as _
  6. from django.core.urlresolvers import reverse
  7. from django.contrib.auth.models import User
  8. from django.contrib.localflavor.us.models import PhoneNumberField, USStateField
  9. from fields import ZipCodeField
  10. from django_extensions.db.models import TimeStampedModel
  11. import os
  12. import csv
  13. import urllib
  14. #import pbp_com.settings as settings
  15. from django.conf import settings
  16. def get_lat_long(location):
  17. key = settings.GOOGLE_API_KEY
  18. output = "csv"
  19. location = urllib.quote_plus(location)
  20. request = "http://maps.google.com/maps/geo?q=%s&output=%s&key=%s" % (location, output, key)
  21. data = urllib.urlopen(request).read()
  22. dlist = data.split(',')
  23. if dlist[0] == '200':
  24. return "%s, %s" % (dlist[2], dlist[3])
  25. else:
  26. return ''
  27. class Person(TimeStampedModel):
  28. """Person model."""
  29. GENDER_CHOICES=(
  30. (1, 'Male'),
  31. (2, 'Female'),
  32. )
  33. title=models.CharField(_('title'), blank=True, null=True, max_length=20)
  34. first_name=models.CharField(_('first name'), blank=True, max_length=100)
  35. middle_name=models.CharField(_('middle name'), blank=True, null=True, max_length=100)
  36. last_name=models.CharField(_('last name'), blank=True, max_length=100)
  37. nickname=models.CharField(_('nickname'), blank=True, null=True, max_length=100)
  38. suffix=models.CharField(_('suffix'), blank=True, null=True, max_length=20)
  39. slug=models.SlugField(_('slug'), unique=True)
  40. user=models.ForeignKey(User, blank=True, null=True, help_text='If the person is an existing user of your site.')
  41. gender=models.PositiveSmallIntegerField(_('gender'), choices=GENDER_CHOICES, blank=True, null=True)
  42. birth_date=models.DateField(_('birth date'), blank=True, null=True)
  43. death_date=models.DateField(_('death date'), blank=True, null=True)
  44. phone=PhoneNumberField(blank=True)
  45. email=models.EmailField(blank=True)
  46. town=models.ForeignKey('Town', blank=True, null=True)
  47. class Meta:
  48. verbose_name=_('person')
  49. verbose_name_plural=_('people')
  50. ordering=('last_name', 'first_name')
  51. def __unicode__(self):
  52. return u'%s' % self.full_name
  53. @property
  54. def full_name(self):
  55. return u'%s %s' % (self.first_name, self.last_name)
  56. @property
  57. def age(self):
  58. if self.death_date:
  59. DELTA=self.death_date
  60. else:
  61. DELTA=datetime.today()
  62. return u'%s' % relativedelta.relativedelta(DELTA, self.birth_date).years
  63. @permalink
  64. def get_absolute_url(self):
  65. return ('di-person-detail', None, {'slug': self.slug})
  66. class Town(TimeStampedModel):
  67. '''Town model.'''
  68. name=models.CharField(_('name'), max_length=100)
  69. state=USStateField(_('state'))
  70. slug=models.SlugField(_('slug'), unique=True)
  71. in_coverage=models.BooleanField(_('in coverage'), default=False)
  72. zipcode=ZipCodeField(_('Zipcode'), blank=True, null=True, help_text='Use for a primary zipcode when town has multiple.', max_length=5)
  73. class Meta:
  74. unique_together=(('name','state',),)
  75. ordering=('state', 'name',)
  76. def __unicode__(self):
  77. return u'%s, %s' % (self.name, self.state)
  78. @permalink
  79. def get_absolute_url(self):
  80. return ('di-town-detail', None, {'slug': self.slug})
  81. class PopulationYear(TimeStampedModel):
  82. ''' Population yaer model.
  83. Keeps track of a population count for a town in a given (usually census) year.
  84. '''
  85. town=models.ForeignKey(Town)
  86. year=models.IntegerField(_('year'), max_length=4)
  87. population=models.IntegerField(_('population'), max_length=7)
  88. def __unicode__(self):
  89. return u'%s %s population' % (self.town, self.year)
  90. class TownInfo(TimeStampedModel):
  91. ''' Town info model.
  92. Keeps track of various pieces of town info for our register.
  93. We create a separate model so that we can use a really simple
  94. setup for our legacy website and just rewrite this whole class
  95. when we're ready to implement some higher-level town info stuff.
  96. This way we do not have to delete town ids and mess up all related_name
  97. applications.
  98. '''
  99. town=models.ForeignKey(Town)
  100. office=models.ForeignKey("Place")
  101. po_box=models.IntegerField(_('PO Box'))
  102. map=models.FileField(_('Town map'), blank=True, null=True, upload_to='directory/maps/')
  103. time_info=models.TextField(_('Contact info'))
  104. description=models.TextField(_('Description'))
  105. officials=models.TextField(_('Officials'))
  106. tax_info=models.TextField(_('Tax info'))
  107. permits=models.TextField(_('Permits'))
  108. town_ordinances=models.TextField(_('Town ordinances'))
  109. post_offices=models.TextField(_('Post offices'))
  110. total_area=models.IntegerField(_('Total area'), help_text='In acres')
  111. land_area=models.IntegerField(_('Land'), help_text='In acres')
  112. bog_area=models.IntegerField(_('Bog'), help_text='In acres', default=0)
  113. flood_plain_area=models.IntegerField(_('Flood plain'), help_text='In acres', default=0)
  114. inland_water_area=models.IntegerField(_('Inland water'), help_text='In acres', default=0)
  115. shoreline=models.IntegerField(_('Shoreline'), help_text='In miles', default=0)
  116. populations=models.ManyToManyField(PopulationYear, blank=True, null=True)
  117. edu_contact=models.TextField(_('Education contact'))
  118. enrollment=models.TextField(_('Enrollment numbers'))
  119. fire_dept_info=models.TextField(_('Fire department'))
  120. cemetery_info=models.TextField(_('Cemeteries'), blank=True, null=True)
  121. trash_recycle_info=models.TextField(_('Trash & recycling'), blank=True, null=True)
  122. public_restrooms=models.TextField(_('Public restrooms'), blank=True, null=True)
  123. walking_trails=models.TextField(_('Walking trails'), blank=True, null=True)
  124. public_landings=models.TextField(_('Public landings'), blank=True, null=True)
  125. def __unicode__(self):
  126. return u'%s information' % (self.town)
  127. @permalink
  128. def get_absolute_url(self):
  129. return ('di-town-info', None, {'slug': self.town.slug})
  130. class Committee(TimeStampedModel):
  131. '''Committee model.'''
  132. title=models.CharField(_('title'), max_length=100)
  133. slug=models.SlugField(_('slug'), unique=True)
  134. town=models.ForeignKey(Town, related_name="town_committee")
  135. members=models.ManyToManyField(Person, blank=True, null=True)
  136. def __unicode__(self):
  137. return u'%s %s' % (self.town, self.title)
  138. def get_absolute_url(self):
  139. args = self.slug
  140. return reverse('di-committee-detail', args=args)
  141. class Point(TimeStampedModel):
  142. lat_lon=models.CharField(_('coordinates'), blank=True, null=True, max_length=255)
  143. address=models.CharField(_('address'), max_length=255)
  144. town=models.ForeignKey(Town)
  145. zipcode=models.CharField(_('zip'), max_length=10, blank=True)
  146. def __unicode__(self):
  147. return u'%s, %s' % (self.address, self.town)
  148. class Meta:
  149. verbose_name=(_('point'))
  150. verbose_name_plural=(_('points'))
  151. def save(self, *args, **kwargs):
  152. if not self.lat_lon:
  153. location = "%s +%s +%s +%s" % (self.address, self.town, self.town.state, self.zipcode)
  154. self.lat_lon = get_lat_long(location)
  155. if not self.lat_lon:
  156. location = "%s +%s +%s" % (self.town, self.town.state, self.zipcode)
  157. self.lat_lon = get_lat_long(location)
  158. super(Point, self).save(*args, **kwargs)
  159. class Place(TimeStampedModel):
  160. '''Place model for Directory application.'''
  161. STATUS_CHOICES = (
  162. (0, 'Inactive'),
  163. (1, 'Active'),
  164. )
  165. point=models.ForeignKey(Point, blank=True, null=True)
  166. title=models.CharField(_('Title'), max_length=255)
  167. slug=models.SlugField(_('Slug'))
  168. description=models.TextField(_('Description'), blank=True, null=True)
  169. status=models.IntegerField(_('Status'), choices=STATUS_CHOICES, default=1)
  170. po_box=models.IntegerField(_('P.O. Box'), blank=True, null=True, max_length=5)
  171. po_box_town=models.ForeignKey(Town, blank=True, null=True)
  172. phone=PhoneNumberField(_('Phone'), blank=True, null=True)
  173. fax=PhoneNumberField(_('Fax'), blank=True, null=True)
  174. email=models.EmailField(_('Email'), blank=True, null=True)
  175. website=models.URLField(_('Website'), blank=True, null=True, verify_exists=False)
  176. def __unicode__(self):
  177. return self.title
  178. @permalink
  179. def get_absolute_url(self):
  180. return ('di-place-detail', None, {'slug': self.slug})
  181. class SchoolAdministrativeUnit(TimeStampedModel):
  182. '''
  183. An SAU, as defined by the state of Maine.
  184. '''
  185. name=models.CharField(_('name'), max_length=100)
  186. slug=models.SlugField(_('slug'), unique=True)
  187. union=models.IntegerField(_('union'), max_length=2, blank=True, null=True)
  188. # governor=models.ForeignKey(Board, blank=True, null=True)
  189. def __unicode__(self):
  190. return self.name
  191. @permalink
  192. def get_absolute_url(self):
  193. return ('di-sau-detail', None, {'slug': self.slug})
  194. class School(Place):
  195. '''
  196. School model.
  197. A school derives from the Place model, adding a few school-specific fields
  198. '''
  199. TYPE_CHOICES = (
  200. ('E', 'Elementary School'),
  201. ('H', 'High School'),
  202. ('C', 'Combined School'),
  203. ('U', 'College/University'),
  204. ('O', 'Other'),
  205. )
  206. CLASS_CHOICES = (
  207. ('N', 'None'),
  208. ('A', 'A'),
  209. ('B', 'B'),
  210. ('C', 'C'),
  211. ('D', 'D'),
  212. )
  213. REGION_CHOICES = (
  214. ('N', 'None'),
  215. ('W', 'West'),
  216. ('E', 'East'),
  217. )
  218. short_title=models.CharField(_('short title'), max_length=30)
  219. type=models.CharField(_('type'), choices=TYPE_CHOICES, default="O", max_length=1)
  220. #enrollment=models.ManyToMany(Enrollment?)
  221. administration=models.ForeignKey(SchoolAdministrativeUnit)
  222. title_one_eligible=models.BooleanField(_('title one eligible'), default=False)
  223. title_one_recipient=models.BooleanField(_('title one recipient'), default=False)
  224. school_class=models.CharField(_('class'), max_length=1, choices=CLASS_CHOICES, default='N')
  225. region=models.CharField(_('region'), max_length=2, choices=REGION_CHOICES, default='N')
  226. mascot=models.CharField(_('mascot'), max_length=50, blank=True, null=True)
  227. athletic_director=models.ForeignKey(Person, related_name='athletic_director', blank=True, null=True)
  228. principal=models.ForeignKey(Person, related_name='principal', blank=True, null=True)
  229. @permalink
  230. def get_absolute_url(self):
  231. return ('di-school-detail', None, {'slug': self.slug})
  232. class PhoneBookEntry(TimeStampedModel):
  233. entry=models.CharField(_('entry'), max_length=100)
  234. phone=PhoneNumberField()
  235. town=models.ForeignKey(Town)
  236. owner=models.ForeignKey(Person, blank=True, null=True)
  237. related_place=models.ForeignKey(Place, blank=True, null=True)
  238. def __unicode__(self):
  239. return u'%s: %s' % (self.entry, self.phone)
  240. class Meta:
  241. verbose_name=(_('phone book entry'))
  242. verbose_name_plural=(_('phone book entries'))
  243. class PhoneBookEntryUpload(models.Model):
  244. data_file = models.FileField(_('data file (.csv)'), upload_to="temp",
  245. help_text=_('Select a .csv file of phone book data to upload.'))
  246. town = models.ForeignKey(Town)
  247. class Meta:
  248. verbose_name = _('phone book entry upload')
  249. verbose_name_plural = _('phone book entry uploads')
  250. def save(self):
  251. super(PhoneBookEntryUpload, self).save()
  252. self.process_datafile()
  253. super(PhoneBookEntryUpload, self).delete()
  254. def process_datafile(self):
  255. if os.path.isfile(self.data_file.path):
  256. entry_data = csv.reader(open(self.data_file.path), delimiter='\t')
  257. for row in entry_data:
  258. args={}
  259. args['town'] = self.town
  260. args['entry'] = row[0]
  261. if len(row[1]) > 8 or len(row[1]) < 4:
  262. args['phone'] = row[1]
  263. else:
  264. args['phone'] = '207-'+row[1]
  265. entry = PhoneBookEntry.objects.create(**args)
  266. try:
  267. entry.save()
  268. except:
  269. pass