def test_IntervalField_db_type(self): f = IntervalField() self.assertEqual(f.db_type(connection=FakeConnection('postgresql')), 'INTERVAL') self.assertEqual(f.db_type(connection=FakeConnection('mysql')), 'BIGINT')
def test_IntervalField_db_type(self): f = IntervalField() self.assertEquals( f.db_type(connection=FakeConnection('postgresql')), 'INTERVAL') self.assertEquals( f.db_type(connection=FakeConnection('mysql')), 'BIGINT')
def do_some_tests(): valid_strings = ["00:00:00", "00:00:00.0", "10:10:10", "10:10:10.10", "5 days, 22:22:22.22", "5 days, 22:22:22", "1 day, 0:00:00", "00:00:00.22", "00:00:00.222", "00:00:00.2222", "00:00:00.22222", "00:00:00.22222", "00:00:00.222222"] invalid_strings = ["10:-10:10", "10:10:-10", "00:00:00.-100", "00:62:00", "00:00:61", "xx days, 12:12:12.123", "12 dayz, 00:00:00", "00:00:00.12345672930923890"] a = IntervalField() for s in valid_strings: a.to_python(s) for s in invalid_strings: self.assertRaises(ValueError, a.to_python, s) for value, should_be in [ (timedelta(seconds=5), timedelta(seconds=5)), ("00:00:05.1", timedelta(seconds=5, microseconds=100000)), ("2 days, 00:00:05.1", timedelta(days=2, seconds=5, microseconds=100000)), ("2 days, 00:00:05.01", timedelta(days=2, seconds=5, microseconds=10000)), ("2 days, 00:00:05.001", timedelta(days=2, seconds=5, microseconds=1000)), ("2 days, 00:00:05.0001", timedelta(days=2, seconds=5, microseconds=100)), ("2 days, 00:00:05.00001", timedelta(days=2, seconds=5, microseconds=10)), ("2 days, 00:00:05.000001", timedelta(days=2, seconds=5, microseconds=1)), ]: self.assertEquals(a.to_python(value), should_be)
def test_IntervalField_get_db_prep_value(self): f = IntervalField() for value, should_be in [ (f.get_db_prep_value(None, connection=FakeConnection('none')), None), (f.get_db_prep_value(timedelta(1), connection=FakeConnection('postgresql')), '1 DAYS'), (f.get_db_prep_value(timedelta(1), connection=FakeConnection('mysql')), 1 * 3600 * 24 * microseconds) ]: self.assertEqual(value, should_be)
class Topic(CommonModel): def __unicode__(self): out = self.title if self.presentors.count(): out += " By: %s" % self.presentors.all()[0].name return out title = models.CharField( max_length=MAX_LENGTH) presentors = models.ManyToManyField( Presentor, blank=True) meeting = models.ForeignKey( Meeting, blank=True, null=True, related_name='topics') experience_level = models.CharField( "Audience Experience Level", max_length=15, blank=True, null=True, choices=EXPERIENCE_LEVELS) license = models.CharField( max_length=50, choices=LICENSE_CHOISES, default='CC BY') length = IntervalField( format="M", blank=True, null=True) embed_video = models.TextField(blank=True, null=True) description = models.TextField(blank=True, null=True) slides_link = models.URLField(blank=True, null=True) start_time = models.DateTimeField(blank=True, null=True) approved = models.BooleanField(default=False) objects = TopicsQuerySet.as_manager()
class ActualTime(models.Model): item = models.ForeignKey(Item, null=False, db_column='iid') resolver = models.ForeignKey(User, db_column='resolver') actual_time = IntervalField(null=True, blank=True) completed = models.DateTimeField(primary_key=True) class Meta: db_table = u'actual_times'
def test_IntervalField_get_db_prep_value(self): f = IntervalField() for value, should_be in [ (f.get_db_prep_value(None, connection=FakeConnection('none')), None), (f.get_db_prep_value(timedelta(1), connection=FakeConnection('postgresql')), '1 DAYS'), (f.get_db_prep_value(timedelta(1), connection=FakeConnection('mysql')), 1 * 3600 * 24 * microseconds) ]: self.assertEquals(value, should_be)
class TestModel(models.Model): not_required_interval = IntervalField('I am not required', null=True, blank=True, format='DH') required_interval = IntervalField(format='H', default=timedelta(hours=3)) required_interval_with_limits = IntervalField(min_value=timedelta(hours=1), max_value=timedelta(days=5), format='DHMSX') def __unicode__(self): return ", ".join([ unicode(self.not_required_interval), unicode(self.required_interval), unicode(self.required_interval_with_limits) ])
class SiteSlice(models.Model): # dict """Maintains a list of addresses, used for site-crawling process.""" class Meta: app_label = 'crawler' objects = models.Manager() active = SiteSliceManager() enabled = models.BooleanField(default=True) parser = models.ForeignKey( Parser, help_text=_('Select the parser engine')) # related_name='site', label = models.CharField(max_length=255, help_text=_('Human-readable name'), blank=False, null=False) domains = models.CharField(max_length=255, help_text=_('Allowed domains'), blank=True) urls = models.TextField(help_text=_('Crawling address list'), blank=False) rotate_time = IntervalField(format='DH', help_text=_('Rotate time interval'), default=timedelta(days=1)) tagline = TaggableManager(blank=True, verbose_name=_( "Tags")) # %(app_label)_%(class), related_name='urlset_tags', def __unicode__(self): return self.label @property def short_summary(self): """Get the summary stat""" return "Articles count: %s, last parsed at: %s" % ( self.summary.parsed_n_articles, self.summary.last_parse_time) @property def domains_list(self): return (self.domains and self.domains.split(',')) or [] @property def urls_list(self): return (self.urls and self.urls.split(',')) or [] def update_summary(self): pass # todo: use "defer" argument def deactivate(self): self.enabled = False self.save() def activate(self): self.enabled = True self.save()
def do_some_tests(): valid_strings = [ "00:00:00", "00:00:00.0", "10:10:10", "10:10:10.10", "5 days, 22:22:22.22", "5 days, 22:22:22", "1 day, 0:00:00", "00:00:00.22", "00:00:00.222", "00:00:00.2222", "00:00:00.22222", "00:00:00.22222", "00:00:00.222222" ] invalid_strings = [ "10:-10:10", "10:10:-10", "00:00:00.-100", "00:62:00", "00:00:61", "xx days, 12:12:12.123", "12 dayz, 00:00:00", "00:00:00.12345672930923890" ] a = IntervalField() for s in valid_strings: a.to_python(s) for s in invalid_strings: self.assertRaises(ValueError, a.to_python, s) for value, should_be in [ (timedelta(seconds=5), timedelta(seconds=5)), ("00:00:05.1", timedelta(seconds=5, microseconds=100000)), ("2 days, 00:00:05.1", timedelta(days=2, seconds=5, microseconds=100000)), ("2 days, 00:00:05.01", timedelta(days=2, seconds=5, microseconds=10000)), ("2 days, 00:00:05.001", timedelta(days=2, seconds=5, microseconds=1000)), ("2 days, 00:00:05.0001", timedelta(days=2, seconds=5, microseconds=100)), ("2 days, 00:00:05.00001", timedelta(days=2, seconds=5, microseconds=10)), ("2 days, 00:00:05.000001", timedelta(days=2, seconds=5, microseconds=1)), ]: self.assertEqual(a.to_python(value), should_be)
class TestModel(models.Model): not_required_interval = IntervalField('I am not required', null=True, blank=True, format='DH') required_interval = IntervalField(format='H', default=timedelta(hours=3)) required_interval_with_limits = IntervalField(min_value=timedelta(hours=1), max_value=timedelta(days=5), format='DHMSX') def __str__(self): return ", ".join([ six.text_type(self.not_required_interval), six.text_type(self.required_interval), six.text_type(self.required_interval_with_limits) ]) def get_absolute_url(self): return reverse("detail_model", args=[str(self.pk)])
class Topic(CommonModel): def __unicode__(self): out = self.title if self.presentor: out += " By: %s" % self.presentor.name return out title = models.CharField(max_length=MAX_LENGTH) presentor = models.ForeignKey(Presentor, blank=True, null=True) meeting = models.ForeignKey(Meeting, blank=True, null=True, related_name='topics') length = IntervalField(format="M", blank=True, null=True) embed_video = models.TextField(blank=True, null=True) description = models.TextField(blank=True, null=True) slides_link = models.URLField(verify_exists=True, blank=True, null=True) start_time = models.DateTimeField(blank=True, null=True) approved = models.BooleanField(default=False)
class Topic(CommonModel): def __unicode__(self): out = self.title if self.presentors.count(): out += " By: %s" % self.presentors.all()[0].name return out title = models.CharField( help_text="This will be the public title for your talk.", max_length=MAX_LENGTH) presentors = models.ManyToManyField(Presentor, blank=True) meeting = models.ForeignKey( Meeting, blank=True, null=True, related_name='topics', help_text=("Please select the meeting that you'd like to " "target your talk for.")) experience_level = models.CharField("Audience Experience Level", max_length=15, blank=True, null=True, choices=EXPERIENCE_LEVELS) license = models.CharField(max_length=50, choices=LICENSE_CHOISES, default='CC BY') length = IntervalField(format="M", blank=True, null=True) embed_video = models.TextField(blank=True, null=True) description = models.TextField( "Public Description", blank=True, null=True, help_text="This will be the public talk description.") notes = models.TextField( "Private Submission Notes", blank=True, null=True, help_text=("Additional non-public information or context " "you want us to know about the talk submission."), ) slides_link = models.URLField(blank=True, null=True) start_time = models.DateTimeField(blank=True, null=True) approved = models.BooleanField(default=False) objects = TopicsQuerySet.as_manager()
class SportSession(models.Model): day = models.ForeignKey('SportDay', related_name="sessions") sport = models.ForeignKey(Sport) time = IntervalField(format='DHMSX', null=True, blank=True) distance = models.FloatField(null=True, blank=True) name = models.CharField(max_length=255, null=True, blank=True) comment = models.TextField(_('session comment'), null=True, blank=True) type = models.CharField(max_length=12, default='training', choices=SESSION_TYPES) race_category = models.ForeignKey('RaceCategory', verbose_name=_('Race category'), null=True, blank=True) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) # Comments comments_public = models.OneToOneField('messages.Conversation', null=True, blank=True, related_name='session_public') comments_private = models.OneToOneField('messages.Conversation', null=True, blank=True, related_name='session_private') class Meta: db_table = 'sport_session' app_label = 'sport' def save(self, *args, **kwargs): # No race category when we are not in race if self.type != 'race': self.race_category = None # Only allow depth 1 sports if self.sport.depth != 1: raise Exception( "Invalid sport '%s', only level 1 authorized for SportSession" % self.sport) super(SportSession, self).save(*args, **kwargs) def build_conversation(self, type): ''' Init a conversation private|public ''' if type not in ('public', 'private'): raise Exception('Invalid conversation name') name = 'comments_%s' % type if getattr(self, name, None): raise Exception('Conversation already exists') conversation = Conversation.objects.create( type=name, session_user=self.day.week.user) setattr(self, name, conversation) self.save() return conversation
def add_to_query(self, query, alias, col, source, is_summary): aggregate = AvgSQL(col, source=IntervalField(), is_summary=is_summary, **self.extra) query.aggregates[alias] = aggregate
class Item(models.Model): iid = models.AutoField(primary_key=True) type = models.CharField(max_length=12, choices=[('bug', 'bug'), ('action item', 'action item')]) owner = models.ForeignKey(User, db_column='owner', related_name='owned_items') assigned_to = models.ForeignKey(User, db_column='assigned_to', related_name='assigned_items') title = models.CharField(max_length=255) milestone = models.ForeignKey(Milestone, db_column='mid') status = models.CharField(max_length=16, choices=[('OPEN', 'OPEN'), ('INPROGRESS', 'IN PROGRESS'), ('RESOLVED', 'RESOLVED'), ('VERIFIED', 'VERIFIED')]) description = models.TextField(blank=True) priority = models.IntegerField(null=True, blank=True, choices=[(0, 'ICING'), (1, 'LOW'), (2, 'MEDIUM'), (3, 'HIGH'), (4, 'CRITICAL')]) r_status = models.CharField(max_length=16, blank=True) last_mod = models.DateTimeField(null=True, blank=True) target_date = models.DateField(null=True, blank=True) estimated_time = IntervalField(blank=True, null=True) url = models.TextField(blank=True) tags = TaggableManager() class Meta: db_table = u'items' def get_absolute_url(self): return "/item/%d/" % self.iid def status_class(self): return self.status.lower() def priority_label(self): return priority_label_f(self.priority) def status_display(self): if self.status == 'RESOLVED': return self.r_status return self.status def target_date_status(self): overdue = (datetime.now().date() - self.target_date).days return overdue_days_to_string(overdue) def is_bug(self): return self.type == "bug" def history(self): """ interleave comments and events into one stream """ comments = [HistoryComment(c) for c in self.comment_set.all()] events = [HistoryEvent(e) for e in self.events_set.all()] merged = comments + events merged.sort() return merged def add_resolve_time(self, user, time): completed = datetime.now() ActualTime.objects.create(item=self, resolver=user, actual_time=time, completed=completed) def add_clients(self, clients): for c in clients: ItemClient.objects.create(item=self, client=c) def resolvable(self): return self.status in ['OPEN', 'INPROGRESS', 'NEW'] def inprogressable(self): return self.status == 'OPEN' def verifiable(self): return self.status == 'RESOLVED' def reopenable(self): return self.status in ['RESOLVED', 'INPROGRESS', 'VERIFIED', 'CLOSED'] def touch(self): self.last_mod = datetime.now() self.save() def add_comment(self, user, body): Comment.objects.create(item=self, username=user.username, comment=body, add_date_time=datetime.now()) def resolve(self, user, r_status, comment): self.status = "RESOLVED" self.r_status = r_status self.save() e = Events.objects.create(status="RESOLVED", event_date_time=datetime.now(), item=self) Comment.objects.create(event=e, username=user.username, comment="<b>resolved %s</b><br />\n%s" % (r_status, comment), add_date_time=datetime.now()) def verify(self, user, comment): self.status = 'VERIFIED' self.r_status = '' self.save() e = Events.objects.create(status="VERIFIED", event_date_time=datetime.now(), item=self) Comment.objects.create(event=e, username=user.username, comment="<b>verified</b><br />\n%s" % comment, add_date_time=datetime.now()) def mark_in_progress(self, user, comment): self.status = 'INPROGRESS' self.r_status = '' self.save() e = Events.objects.create(status="INPROGRESS", event_date_time=datetime.now(), item=self) Comment.objects.create( event=e, username=user.username, comment="<b>marked as in progress</b><br />\n%s" % comment, add_date_time=datetime.now()) def reopen(self, user, comment): self.status = 'OPEN' self.r_status = '' self.save() e = Events.objects.create(status="OPEN", event_date_time=datetime.now(), item=self) Comment.objects.create(event=e, username=user.username, comment="<b>reopened</b><br />\n%s" % comment, add_date_time=datetime.now()) def reassign(self, user, assigned_to, comment): self.assigned_to = assigned_to self.save() e = Events.objects.create(status="OPEN", event_date_time=datetime.now(), item=self) Comment.objects.create(event=e, username=user.username, comment="<b>reassigned to %s</b><br />\n%s" % (assigned_to.fullname, comment), add_date_time=datetime.now()) def change_owner(self, user, owner, comment): self.owner = owner self.save() e = Events.objects.create(status="OPEN", event_date_time=datetime.now(), item=self) Comment.objects.create( event=e, username=user.username, comment="<b>ownership changed to %s</b><br />\n%s" % (owner.fullname, comment), add_date_time=datetime.now()) def set_priority(self, priority, user): old_priority = self.priority self.priority = priority self.save() self.add_event( self.status, user, "<b>changed priority from %s to %s</b>" % (priority_label_f(old_priority), priority_label_f(priority))) def add_event(self, status, user, comment): e = Events.objects.create(status=status, event_date_time=datetime.now(), item=self) Comment.objects.create(event=e, username=user.username, comment=comment, add_date_time=datetime.now()) def setup_default_notification(self): self.add_cc(self.owner) self.add_cc(self.assigned_to) def add_project_notification(self): for n in NotifyProject.objects.filter(pid=self.milestone.project): self.add_cc(n.username) def add_cc(self, user): if user.status == "inactive": # don't bother with inactive users return Notify.objects.get_or_create(item=self, username=user) def update_email(self, comment, user): body = comment.replace("<b>", "").replace("</b>", "").replace("<br />", "\n") body = textwrap.fill(body, replace_whitespace=False) # TODO: handle no user specified email_subj = "[PMT:%s] Attn:%s-%s" % (truncate_string( self.milestone.project.name), self.assigned_to.fullname, truncate_string(self.title)) email_body = """ project:\t%s by:\t\t%s %s:\t%d title:\t\t%s %s %s URL: https://dmt.ccnmtl.columbia.edu%s Please do not reply to this message. """ % (self.milestone.project.name, user.fullname, self.type, self.iid, self.title, body, self.type, self.get_absolute_url()) addresses = [u.email for u in self.users_to_email(user)] send_mail(email_subj, email_body, user.email, addresses, fail_silently=settings.DEBUG) statsd.incr('main.email_sent') def users_to_email(self, skip=None): return [ n.username for n in Notify.objects.filter(item=self) if (n.username.status == 'active' and not n.username.grp and n.username != skip) ] def copy_clients_to_new_item(self, new_item): for ic in self.itemclient_set.all(): ItemClient.objects.create(item=new_item, client=ic.client) def clone_to_new_item(self, new_title, user): new_item = Item.objects.create(type=self.type, owner=self.owner, assigned_to=self.assigned_to, title=new_title, milestone=self.milestone, status='OPEN', r_status='', description='', priority=self.priority, target_date=self.target_date, estimated_time=self.estimated_time, url=self.url) new_item.add_event('OPEN', user, ("<b>%s added</b>" "<p>Split from <a href='%s'>#%d</a></p>" % (self.type, self.get_absolute_url(), self.iid))) new_item.touch() new_item.setup_default_notification() new_item.add_project_notification() self.copy_clients_to_new_item(new_item) return new_item
def test_IntervalField_formfield(self): f = IntervalField() f.formfield()
class PlanSession(models.Model): # Organisation plan = models.ForeignKey(Plan, related_name='sessions') week = models.IntegerField() day = models.IntegerField() # Dummy data, should be later specified # using a collections of PlanPart name = models.CharField(max_length=250) time = IntervalField(format='DHMSX', null=True, blank=True) distance = models.FloatField(null=True, blank=True) # Mappings to SportSession sport = models.ForeignKey(Sport) type = models.CharField(max_length=12, default='training', choices=SESSION_TYPES) # Conversation comments = models.OneToOneField('messages.Conversation', null=True, blank=True, related_name='plan_session') # Dates created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) @property def date(self): return self.plan.calc_date(self.week, self.day) def delete(self, *args, **kwargs): plan = self.plan # backup plan reference out = super(PlanSession, self).delete(*args, **kwargs) # actually delete the session plan.update_weeks() # Check weeks are still consecutive return out def copy(self, plan): ''' Copy this session and attach it to new plan ''' data = { 'plan': plan, } copy_fields = ( 'week', 'day', 'name', 'sport', 'type', ) for f in copy_fields: data[f] = getattr(self, f) return PlanSession.objects.create(**data) def apply(self, application): ''' Apply this plan session to a user ''' if not self.date: raise Exception('No date to apply this session') # Load week w, year = date_to_week(self.date) week, _ = SportWeek.objects.get_or_create(year=year, week=w, user=application.user) # Load day day, _ = SportDay.objects.get_or_create(week=week, date=self.date) # Check a session does not already have this plan session try: psa = PlanSessionApplied.objects.get(plan_session=self, sport_session__day=day) except PlanSessionApplied.DoesNotExist: psa = None if psa: # retrieve sport session session = psa.sport_session else: # Load session defaults = { 'name': self.name, 'distance': self.distance, 'time': self.time, } session, _ = SportSession.objects.get_or_create(sport=self.sport, day=day, type=self.type, defaults=defaults) # Apply plan session PlanSessionApplied.objects.create(plan_session=self, sport_session=session, application=application) # Copy all comments if self.comments: # Build conversation if needed if not session.comments_private: session.build_conversation('private') for c in self.comments.messages.all(): c.copy(session.comments_private)