Пример #1
0
 def post_through_setup(self, cls):
     self.use_gfk = self.through is None or issubclass(self.through, GenericTaggedItemBase)
     self.rel.to = self.through._meta.get_field("tag").rel.to
     self.related = RelatedObject(self.through, cls, self)
     if self.use_gfk:
         tagged_items = GenericRelation(self.through)
         tagged_items.contribute_to_class(cls, "tagged_items")
Пример #2
0
 def post_through_setup(self, cls):
     self.use_gfk = (
         self.through is None or issubclass(self.through, GenericTaggedItemBase)
     )
     self.rel.to = self.through._meta.get_field("tag").rel.to
     if self.use_gfk:
         tagged_items = GenericRelation(self.through)
         tagged_items.contribute_to_class(cls, "%s_tagged_items" % cls.__name__.lower())
Пример #3
0
 def post_through_setup(self, cls):
     self.use_gfk = (
         self.through is None or issubclass(self.through, GenericChoiceBase)
     )
     self.rel.to = self.through._meta.get_field("poll").rel.to
     if self.use_gfk:
         poll_choices = GenericRelation(self.through)
         poll_choices.contribute_to_class(cls, "poll_choices")
Пример #4
0
 def contribute_to_class(self, cls, name):
     self.name = self.column = name
     self.model = cls
     cls._meta.add_field(self)
     setattr(cls, name, self)
     if self.use_gfk:
         tagged_items = GenericRelation(self.through)
         tagged_items.contribute_to_class(cls, "tagged_items")
Пример #5
0
 def post_through_setup(self, cls):
   self.use_gfk = (
     self.through is None
   )
   self.rel.to = self.through._meta.get_field("group").rel.to
   if RelatedObject is not None:
     self.related = RelatedObject(self.through, cls, self)
   if self.use_gfk:
     groups = GenericRelation(self.through)
     groups.contribute_to_class(cls, "groups")
Пример #6
0
 def post_through_setup(self, cls):
     self.related = RelatedObject(cls, self.model, self)
     self.use_gfk = (
         self.through is None or issubclass(self.through, GenericTaggedItemBase)
     )
     self.rel.to = self.through._meta.get_field("tag").rel.to
     self.related = RelatedObject(self.through, cls, self)
     if self.use_gfk:
         self.__class__._related_name_counter += 1
         related_name = '+%d' % self.__class__._related_name_counter
         tagged_items = GenericRelation(self.through, related_name=related_name)
         tagged_items.contribute_to_class(cls, 'tagged_items')
Пример #7
0
    def post_through_setup(self, cls):
        self.related = RelatedObject(cls, self.model, self)
        self.use_gfk = (
            self.through is None or issubclass(self.through, GenericTaggedItemBase)
        )
        self.rel.to = self.through._meta.get_field("tag").rel.to
        self.related = RelatedObject(self.through, cls, self)
        if self.use_gfk:
            tagged_items = GenericRelation(self.through)
            tagged_items.contribute_to_class(cls, 'tagged_items')

            for rel in cls._meta.local_many_to_many:
                if isinstance(rel, TaggableManager) and rel.use_gfk and rel != self:
                    raise ValueError('You can only have one TaggableManager per model'
                        ' using generic relations.')
Пример #8
0
    def post_through_setup(self, cls):
        self.related = RelatedObject(cls, self.model, self)
        self.use_gfk = (
            self.through is None or issubclass(self.through, GenericTaggedItemBase)
        )
        self.rel.to = self.through._meta.get_field("tag").rel.to
        self.related = RelatedObject(self.through, cls, self)
        if self.use_gfk:
            tagged_items = GenericRelation(self.through)
            tagged_items.contribute_to_class(cls, 'tagged_items')

        for rel in cls._meta.local_many_to_many:
            if rel == self or not isinstance(rel, TaggableManager):
                continue
            if rel.through == self.through:
                raise ValueError('You can\'t have two TaggableManagers with the'
                                 ' same through model.')
Пример #9
0
class Event(Generic):

    class Meta:
        verbose_name = _("Event")
        verbose_name_plural = _("Events")

    STATUS_CHOICES = (
        (0, _('Pending')),
        (1, _('Admitted')),
        (2, _('Refused')),
        (3, _('Deleted')),
    )

    status = models.SmallIntegerField(_('Status'), choices=STATUS_CHOICES, null=True, default=0)
    not_regional_event = models.BooleanField(_('Do not publish in the regional event directory'), default=False)

    title = models.CharField(_('Title'), max_length=455, blank=False, help_text=_("Enter the full name of the event, as it appears and in the same language. Ex: XIX Congresso Brasileiro de Arritmias Cardiacas. XVII Simposio Nacional do DECS-SBCC"))
    start_date = models.DateField(_('Start date'), help_text='DD/MM/YYYY')
    end_date = models.DateField(_('End date'), help_text='DD/MM/YYYY')

    link = models.URLField(_('Link'), max_length=255, help_text=_("Enter the link of event portal"), blank=True)

    address = models.CharField(_('Address'), max_length=255, blank=True, help_text=_("Enter full address of the local of the event to present it in a Google map"))
    city = models.CharField(_('City'), max_length=125, blank=True)
    country = models.ForeignKey(Country, verbose_name=_('Country'), blank=True, null=True)

    event_type = models.ManyToManyField(EventType, verbose_name=_("Event type"), blank=False)
    official_language = models.ManyToManyField('main.SourceLanguage', verbose_name=_("Official languages"), blank=True)

    contact_email = models.EmailField(_('Contact email'), blank=True)
    contact_info = models.TextField(_("Information for contact"), blank=True)
    observations = models.TextField(_("Observations"), help_text=_("Enter information about institutions that organize and/or sponsor the event, deadline for submission of papers, simultaneous translation service, event program, etc."), blank=True)
    target_groups = models.TextField(_("Target groups"), blank=True)

    # responsible cooperative center
    cooperative_center_code = models.CharField(_('Cooperative center'), max_length=55, blank=True)

    # relations
    error_reports = GenericRelation(ErrorReport)
    thematics = GenericRelation(ResourceThematic)

    def __unicode__(self):
        return self.title
Пример #10
0
class TaggedModel(models.Model):
    tags = GenericRelation(Tag)

    @denormalized(models.TextField)
    @depend_on_related(Tag)
    def tags_string(self):
        return ', '.join(sorted([t.name for t in self.tags.all()]))

    class Meta:
        abstract = True
Пример #11
0
class Deck(models.Model):
    #information
    title = models.CharField(max_length=128)
    creator = models.ForeignKey(User)
    tags = models.ManyToManyField(Tag, blank=True, null=True)
    text = models.TextField(blank=True, null=True)

    #record
    date_posted = models.DateField(auto_now_add=True)
    challenge = models.ForeignKey(Challenge,
                                  null=True,
                                  blank=True,
                                  on_delete=models.SET_NULL)  #just one
    is_public = models.BooleanField(blank=True, default=True)
    is_removed = models.BooleanField(blank=True, default=False)

    #data
    deck_image = models.ImageField(upload_to="img/%Y/%m/%d")
    comments = GenericRelation(Comment, object_id_field="object_pk")
    polls = GenericRelation(BinaryPoll, object_id_field="object_id")
    deck_length_coefficient = models.SmallIntegerField()
    deck_width_coefficient = models.SmallIntegerField()

    #managers
    objects = models.Manager()
    public = PublicSetManager()

    class Meta():
        get_latest_by = 'date_posted'

    #methods
    def clean(self):
        #needs to check that any attached challenges are not expired
        if self.is_public == True and self.is_removed == True:
            raise ValidationError('Removed entries cannot also be public.')
        super(Deck, self).clean()

    def __unicode__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('deck:view', kwargs={'pk': str(self.pk)})
Пример #12
0
class LegislatorDetail(models.Model):

    objects = LegislatorDetailManager()

    legislator = models.OneToOneField(Politician)

    on_bill = models.CharField(max_length=1,
                               choices=ON_BILL_CHOICES,
                               default='U')
    on_amendment = models.NullBooleanField(default=None)
    call_goal = models.SmallIntegerField(default=10)

    calls = GenericRelation(AnswerSet)

    def __unicode__(self):
        return u' '.join([
            self.legislator.get_title_display(),
            self.good_fname(), self.legislator.lastname
        ])

    def good_fname(self):
        return self.legislator.nickname or self.legislator.firstname

    def is_cosponsor(self):
        return self.on_bill == 'C'

    def supports_bill(self):
        if self.on_bill in ('C', 'S'):
            return True
        elif self.on_bill == 'O':
            return False
        else:
            return None

    def he_or_she(self):
        if self.legislator.gender == 'F':
            return 'she'
        else:
            return 'he'

    def his_or_her(self):
        if self.legislator.gender == 'F':
            return 'her'
        else:
            return 'his'

    def him_or_her(self):
        if self.legislator.gender == 'F':
            return 'her'
        else:
            return 'him'

    def needs_more_calls(self):
        return self.calls.count() < self.call_goal
Пример #13
0
class ItemInstance(ActionInstance):
    """
    An instance of a single item
    """
    owner = models.ForeignKey(Player, on_delete=models.CASCADE)
    itype = models.ForeignKey(Item, on_delete=models.CASCADE)
    attributes = GenericRelation(Attribute)

    def transfer(self, newowner):
        self.owner = newowner
        self.save()
        return "You have successfully transfered the item " + self.itype.name
Пример #14
0
class PurchaseItem(models.Model):
    invoice = models.ForeignKey(PurchaseInvoice,
                                verbose_name=_(u'Purchase invoice'))
    material = models.ForeignKey(Material, verbose_name=_(u'Material'))
    material_cluster = models.OneToOneField(
        MaterialCluster, verbose_name=_(u'Created material cluster'))
    movement = GenericRelation('MaterialMovement')
    quantity = models.PositiveIntegerField(_(u'Quantity'))
    unit_cost = models.DecimalField(_(u'Unit cost'),
                                    max_digits=20,
                                    decimal_places=2)

    @property
    def total_cost(self):
        return self.unit_cost * self.quantity

    class Meta:
        verbose_name = _(u'Purchase item')
        verbose_name_plural = _(u'Purchase items')

    def __unicode__(self):
        return _(
            u"%(quantity)s %(measure_unit)s of %(material)s (invoice nr. %(number)s-%(serie)s:)"
        ) % {
            'quantity': self.quantity,
            'measure_unit': self.material.measure_unit,
            'material': self.material.description,
            'number': self.invoice.number,
            'serie': self.invoice.serie
        }

    def save(self, *args, **kwargs):
        if self.pk is None:
            # Create a new MaterialCluster
            mc = MaterialCluster.objects.create(
                material=self.material,
                quantity=self.quantity,
                unit_cost=self.unit_cost,
                creation_date=self.invoice.input_date,
                last_change=self.invoice.input_date)
            # Links the MaterialCluster with this PurchaseItem
            self.material_cluster = mc
            # Call the super.save() method
            super(PurchaseItem, self).save(*args, **kwargs)
            # Create a new MaterialMovement
            mm = MaterialMovement.objects.create(
                material_cluster=mc,
                type='E',
                qty_before_mov=0,
                quantity=self.quantity,
                mov_date=self.invoice.input_date,
                unit_cost=self.unit_cost,
                origin=self)
Пример #15
0
class AbstractGeneric(models.Model):

    name = models.CharField(max_length=255)
    description = models.TextField()

    staff = GenericRelation(
        "Staff",
        content_type_field="content_type",
        object_id_field="object_id",
    )

    class Meta:
        abstract = True
Пример #16
0
class Company(models.Model):
    """Company model."""
    name = models.CharField(_('name'), max_length=200)
    nickname = models.CharField(_('nickname'),
                                max_length=50,
                                blank=True,
                                null=True)
    slug = models.SlugField(_('slug'), max_length=50, unique=True)
    about = models.TextField(_('about'), blank=True, null=True)
    logo = models.ImageField(_('photo'),
                             upload_to='contacts/companies/',
                             blank=True)

    phone_number = GenericRelation('PhoneNumber')
    email_address = GenericRelation('EmailAddress')
    instant_messenger = GenericRelation('InstantMessenger')
    web_site = GenericRelation('WebSite')
    street_address = GenericRelation('StreetAddress')
    special_date = GenericRelation('SpecialDate')
    note = GenericRelation(Comment, object_id_field='object_pk')

    date_added = models.DateTimeField(_('date added'), auto_now_add=True)
    date_modified = models.DateTimeField(_('date modified'), auto_now=True)

    class Meta:
        db_table = 'contacts_companies'
        ordering = ('name', )
        verbose_name = _('company')
        verbose_name_plural = _('companies')

    def __unicode__(self):
        return u"%s" % self.name

    @permalink
    def get_absolute_url(self):
        return ('contacts_company_detail', None, {
            'pk': self.pk,
            'slug': self.slug,
        })

    @permalink
    def get_update_url(self):
        return ('contacts_company_update', None, {
            'pk': self.pk,
            'slug': self.slug,
        })

    @permalink
    def get_delete_url(self):
        return ('contacts_company_delete', None, {
            'pk': self.pk,
            'slug': self.slug,
        })
Пример #17
0
class InstalledMeasure(models.Model):
    measure = models.ForeignKey(Measure)
    cost = models.IntegerField(null=True, blank=True)
    disruption = models.IntegerField(null=True, blank=True)
    house = models.ForeignKey(House,
                              null=True,
                              blank=True,
                              related_name='measures')

    report_text = models.TextField(null=True, blank=True)
    supplier = models.CharField(max_length=1024, null=True, blank=True)
    supplier_urls = GenericRelation(RelatedTrackableURL,
                                    null=True,
                                    blank=True,
                                    related_name='supplier_urls')
    product = models.CharField(max_length=1024, null=True, blank=True)
    product_urls = GenericRelation(RelatedTrackableURL,
                                   null=True,
                                   blank=True,
                                   related_name='product_urls')

    def __unicode__(self):
        return u'%s' % (self.measure.short, )
Пример #18
0
class Game(models.Model):
    """
    Defines a game within the website
    """

    name = models.CharField(max_length=200, default="Game", unique=True)
    items = models.ManyToManyField(Item, blank=True)
    abilities = models.ManyToManyField(Ability, blank=True)
    rules = models.CharField(max_length=2047, blank=True)
    attributes = GenericRelation('Attribute')
    active = models.BooleanField(default=False)

    def __str__(self):
        return self.name
Пример #19
0
class ChildModel(ParentModel):

    child_name = models.CharField(max_length=255)

    file = models.FileField(upload_to="test", blank=True)

    genericrelatedmodel_set = GenericRelation("test_app.GenericRelatedModel")

    def __str__(self):
        return "%s > %s" % (self.parent_name, self.child_name)

    class Meta:
        verbose_name = _("child model")
        verbose_name_plural = _("child models")
Пример #20
0
class TracTicketMetric(models.Model):
    name = models.CharField(max_length=300)
    slug = models.SlugField()
    query = models.TextField()
    data = GenericRelation('Datum')

    def __unicode__(self):
        return self.name

    def fetch(self):
        s = xmlrpclib.ServerProxy(settings.TRAC_RPC_URL)
        return len(s.ticket.query(self.query + "&max=0"))

    def link(self):
        return "%squery?%s" % (settings.TRAC_URL, self.query)
Пример #21
0
class Post(models.Model):
    title = models.CharField(max_length=150)
    text = models.TextField()
    author = models.ForeignKey(User)
    post_image = models.ImageField(blank=True, upload_to="postimages")
    created_on = models.DateTimeField(auto_now_add=True)
    # to get sub comments from the parent
    comments = GenericRelation('Comment')

    def __unicode__(self):
        return u"%s" % self.id

    #to order comments by date reverse
    class Meta:
        ordering = ['-created_on']
Пример #22
0
class FileStorageMixin(models.Model):
    file_set = GenericRelation(RelativeFileStorage)

    class Meta:
        abstract = True

    def get_documents(self):
        return self.file_set \
            .exclude(document__extension__in=ImageThumbnailMixin.IMAGE_EXTENSIONS) \
            .filter(languages__contains=translation.get_language())

    def get_images(self):
        return self.file_set \
            .filter(document__extension__in=ImageThumbnailMixin.IMAGE_EXTENSIONS) \
            .filter(languages__contains=translation.get_language())
Пример #23
0
class NewProject(CodelistsModel):
    title = models.CharField(max_length=500, blank=True)
    number = models.CharField(verbose_name=_('N. ID DGCS'),
                              blank=True,
                              max_length=100)
    description = models.TextField(verbose_name=_('Abstract'), blank=True)
    year = models.PositiveSmallIntegerField(null=True, blank=True)
    commitment = models.FloatField(help_text=_('Migliaia di euro'),
                                   blank=True,
                                   null=True)
    disbursement = models.FloatField(help_text=_('Migliaia di euro'),
                                     blank=True,
                                     null=True)
    photo_set = GenericRelation('attachments.Photo')

    def get_absolute_url(self):
        return reverse('projects:newproject-detail', kwargs={'pk': self.pk})
Пример #24
0
class Event (OrderedModelMixin, ModelWithSlugMixin, CloneableModelMixin, models.Model):
    label = models.TextField(help_text=_("The time label for the event, e.g. \"January 15th, 2015\", \"Spring 2015 Phase\", \"Phase II, Summer 2015\", etc."))
    slug = models.CharField(max_length=64, blank=True)
    description = models.TextField(help_text=_("A summary description of the timeline item"), default='', blank=True)
    index = models.PositiveIntegerField(help_text=_("Leave this field blank; it will be filled in automatically"))
    project = models.ForeignKey(Project, related_name='events')
    details = JSONField(blank=True, default=dict)

    datetime_label = models.TextField(blank=True, help_text=_("A description of this event's date and time, preferably in a parsable format."))
    start_datetime = models.DateTimeField(null=True, blank=True)
    end_datetime = models.DateTimeField(null=True, blank=True)

    attachments = GenericRelation('Attachment',
                                  object_id_field='attached_to_id',
                                  content_type_field='attached_to_type')

    objects = EventManager()

    class Meta:
        ordering = ('project', 'index',)
        unique_together = [('project', 'slug')]

    def __str__(self):
        if self.index is not None:
            return '%s. %s' % (self.index + 1, self.label)
        else:
            return self.label

    def natural_key(self):
        return self.project.natural_key() + (self.index,)

    def get_slug_basis(self):
        return self.label

    def get_all_slugs(self):
        return [e.slug for e in self.project.events.all()]

    def slug_exists(self, slug):
        return self.project.events.filter(slug__iexact=slug).exists()

    def get_siblings(self):
        return self.project.events.all()

    def clone_related(self, onto):
        kwargs = dict(attached_to=onto)
        for a in self.attachments.all(): a.clone(overrides=kwargs)
Пример #25
0
class Discussion(models.Model):
    """
	A new topic of discussion.
	"""

    title = models.CharField(max_length=255, default='Untitled Discussion')
    tags = models.CharField(max_length=255, blank=True)
    description = models.TextField(blank=True)
    created = models.DateTimeField(auto_now_add=True)
    hacker = models.ForeignKey('Hacker', related_name='discussions')
    comments = GenericRelation('Comment')

    class Meta:
        ordering = ['-created']

    def __unicode__(self):
        return self.title
Пример #26
0
class TabBlock(ContentBlock):
    name = _("Tabbed block")
    code = 'tabbed-block'
    group = _("Layout")
    context_object_name = "block"
    template_name = "fancypages/blocks/tabbedblockblock.html"

    tabs = GenericRelation('fancypages.OrderedContainer')

    def save(self, *args, **kwargs):
        super(TabBlock, self).save(*args, **kwargs)
        if not self.tabs.count():
            OrderedContainer.objects.create(page_object=self,
                                            display_order=0,
                                            title=_("New Tab"))

    class Meta:
        app_label = 'fancypages'
Пример #27
0
class Page(Resource):
    show_title = models.BooleanField(default=True)
    meta_summary = models.TextField(blank=True)
    text = RichTextField(blank=True)
    template = models.CharField(max_length=100,
                                blank=True,
                                choices=template_choices(),
                                default=template_default(),
                                help_text=_("Inherit if empty"))
    related_links = GenericRelation(RelatedLink)

    class Meta:
        verbose_name = _(u'Page')
        verbose_name_plural = _(u'Page')

    def get_template(self):
        if self.template == "":
            try:
                return self.parent.get_object().get_template()
            except AttributeError:  #  no parent
                return template_default() or template_choices()[0][0]
        return self.template

    def get_response(self, request):
        return render(request, self.get_template(), {'page': self})

    def resolve(self):
        return self.get_absolute_url()

    def subpages(self):
        return render_to_string("resources/subpages.html", {
            'page': self,
            'start': 2
        })

    def subnav(self):
        return render_to_string("resources/subnav.html", {
            'page': self,
            'start': 2
        })

    def get_related_links(self):
        return self.related_links.all().select_subclasses()
Пример #28
0
class Comment(models.Model):
    text = models.TextField()
    author = models.ForeignKey(User)
    entity = models.ForeignKey(Post)
    created_on = models.DateTimeField(auto_now_add=True)
    # GenericForeignKey Usage
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')
    # to get sub comments from the parent
    comments = GenericRelation('Comment')
    is_verified = models.BooleanField(default=False)
    email = models.EmailField()

    def __unicode__(self):
        return u"%s" % self.id

    #to order comments by date reverse
    class Meta:
        ordering = ['created_on']
Пример #29
0
class Votable(models.Model):
    votes = GenericRelation(Vote)

    class Meta:
        abstract = True

    def vote_count(self):
        aggregate = self.votes.aggregate(Sum('value'))
        if aggregate['value__sum'] == None:
            return 0
        else:
            return aggregate['value__sum']

    def set_vote(self, user, value):
        if (user.is_authenticated):
            v = self.votes.filter(user=user)
            if v.count() == 0:
                new_vote = self.votes.create(user=user, value=value)
                new_vote.save()
            else:
                v.update(value=value)
Пример #30
0
class Proposal(models.Model):
    """
	A proposal for idea / hack / talk.
	"""

    # TODO: Add voting.

    TYPES = (
        ('HACK', 'Hack'),
        ('TALK', 'Talk'),
    )

    title = models.CharField(max_length=255)
    slug = models.SlugField(blank=True, unique=True, max_length=150)
    type = models.CharField(max_length=4, choices=TYPES)
    tags = models.CharField(max_length=255, blank=True)
    description = models.TextField(blank=True)
    completed = models.BooleanField(default=False)
    url = models.CharField(max_length=128, blank=True)
    repo_url = models.CharField(max_length=128, blank=True)

    upvotes = models.ManyToManyField(Hacker,
                                     related_name='upvoters',
                                     blank=True)
    comments = GenericRelation('Comment')

    proposer = models.ForeignKey(Hacker, related_name='proposals')
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-created']

    def __unicode__(self):
        return self.title

    def save(self, *args, **kwargs):
        super(Proposal, self).save(*args, **kwargs)
        self.slug = '%i-%s' % (self.id, slugify(self.title[:150]))
        super(Proposal, self).save(*args, **kwargs)
Пример #31
0
class MyBaseModel (models.Model):
	# fields
	hash = models.CharField (
		max_length = 256, # we don't expect using a hash more than 256-bit long!
		null = True,
		blank = True,
		default = '',
		verbose_name = u'MD5 hash'
	)
		
	# basic value fields
	name = models.CharField(
			default = None,
			max_length = 128,
			verbose_name = u'名称'
		)
	description = models.TextField (
			null=True, 
			blank=True,
			verbose_name = u'描述'
		)
	
	# help text
	help_text = models.CharField (
			max_length = 64,
			null = True,
			blank = True,
			verbose_name = u'帮助提示'
		)

	# attachments
	attachments = GenericRelation('Attachment')
	
	# this is an Abstract model
	class Meta:
		abstract=True

	def __unicode__(self):
		return self.name
Пример #32
0
class Organisation(models.Model):
    class Meta:
        verbose_name = _('organisation')
        verbose_name_plural = _('organisations')
    name = models.CharField(_('name'), max_length=200,)
    strategy = models.TextField(_('strategy'), blank=True)
    middlemen = models.ManyToManyField('Member', related_name="middleman_organisations", blank=True,null=True,
                                      verbose_name=_("middle men"))
    representatives = models.CharField(_('Representative'), max_length=30, blank=True)

    found_via = models.CharField(_('Found via'), max_length=30, blank=True)
    contact = models.TextField(_('contact info'), blank=True)
    comment = models.TextField(_('comment'), blank=True)
    working_with = models.TextField(_('Also working with'), blank=True)
    types = models.ManyToManyField('OrganisationType', related_name="organisations", blank=True, verbose_name=_("Type of organisation"))
    updates = GenericRelation(Update, verbose_name=_("Updates"), blank=True)

    partnered_project = models.ForeignKey('Project', related_name="partners", blank=True, null=True, verbose_name=_("partnered project"))
    provided_help = models.TextField(_('Provided help'), blank=True)

    def __unicode__(self):
        return self.name
Пример #33
0
class AbstractRegistry(models.Model):
    asset = models.ForeignKey(Asset, verbose_name=_(u"Asset"))
    registry_date = models.DateTimeField(_(u"Registry date"), auto_now_add=True, editable=False)
    annotation = models.TextField(_(u"Additional annotation"))
    related_movement = GenericRelation('AssetMovement')

    class Meta:
        abstract = True
        ordering = ('asset', '-registry_date',)
    
    def pre_save(self, asset):
        """
        Hook for doing any pre save model changes has been
        called before any data saves
        """
        pass

    def post_save(self, asset):
        """
        Hook for doing any post save model actions has been
        called afetr model saves and before AssetMovement creation
        """
        pass

    @commit_on_success
    def save(self, *args, **kwargs):
        asset = self.asset
        self.pre_save(asset)
        super(AbstractRegistry, self).save(*args, **kwargs)
        self.post_save(asset)
        if not self.related_movement.exists():
            mov = AssetMovement(asset=asset, mov_date=self.registry_date, origin=self)
        else:
            mov = self.related_movement.get()
            mov.asset = asset
            mov.mov_date = self.registry_date
        mov.save()
Пример #34
0
class Resource(Generic, AuditLog):
    class Meta:
        verbose_name = _("Resource")
        verbose_name_plural = _("Resources")

    STATUS_CHOICES = (
        (0, _('Pending')),
        (1, _('Admitted')),
        (2, _('Refused')),
        (3, _('Deleted')),
    )

    # status (399)
    status = models.SmallIntegerField(_('Status'),
                                      choices=STATUS_CHOICES,
                                      null=True,
                                      default=0)
    # title (311)
    title = models.CharField(
        _('Title'),
        max_length=510,
        blank=False,
        help_text=
        _("Transcribe as it appears on the internet resource. If there is no title, provide a brief, simple but explanatory title"
          ))
    # link (351)
    link = models.TextField(_('Link'), blank=False)
    # originator (313)
    originator = models.TextField(
        _('Originator'),
        blank=False,
        help_text=
        _("Institutional or personnel name of the responsible for the existence of the internet resource. Ex. Brazilian Society for Dental Research"
          ))
    # originator_location (314)
    originator_location = models.ManyToManyField(
        Country, verbose_name=_('Originator location'), blank=False)
    # author (315)
    author = models.TextField(
        _('Authors'),
        blank=True,
        help_text=
        _("Enter one per line. Only filled if different from the originator of the resource"
          ))
    # language of resource (317)
    source_language = models.ManyToManyField(SourceLanguage,
                                             verbose_name=_("Source language"),
                                             blank=False)
    # source type (318)
    source_type = models.ManyToManyField(SourceType,
                                         verbose_name=_("Source type"),
                                         blank=False)
    # abstract (319)
    abstract = models.TextField(
        _("Abstract"),
        blank=False,
        help_text=
        _("Include information on the content and operation of the internet resource"
          ))
    # time period (341)
    time_period_textual = models.CharField(_('Temporal range'),
                                           max_length=255,
                                           blank=True)
    # objective (361)
    objective = models.TextField(_('Objective'), blank=True)
    # responsible cooperative center
    cooperative_center_code = models.CharField(_('Cooperative center'),
                                               max_length=55,
                                               blank=True)

    # relations
    error_reports = GenericRelation(ErrorReport)
    thematics = GenericRelation(ResourceThematic)
    descriptors = GenericRelation(Descriptor)

    def get_fields(self):
        return [(field.verbose_name, field.value_to_string(self))
                for field in Resource._meta.fields]

    def __unicode__(self):
        return unicode(self.title)
Пример #35
0
class TaggableBase(db.Model):
    """Provides the `tags` generic relation to prettify the API."""
    tags = GenericRelation("Tag")

    def tag(self, name, language, author):
        """Tags this object using a `name` in a specific `language`. The tag
        will be marked as authored by `author`.

        The `name` can be a list of comma-separated tags. Double quotes can be
        used to escape values with spaces or commas. One special case: if there
        are no commas in the input, spaces are treated as tag delimiters."""
        author = _tag_get_user(author)
        language = _tag_get_language(language)
        tags = parse_tag_input(name)
        for tag_name in tags:
            tag = Tag(name=tag_name, language=language, author=author,
                content_object=self)
            tag.save()

    def untag(self, name, language, author):
        """Untags this object from tags in a specific `language`, authored by
        `author`.

        The `name` can be a list of comma-separated tags. Double quotes can be
        used to escape values with spaces or commas. One special case: if there
        are no commas in the input, spaces are treated as tag delimiters."""
        author = _tag_get_user(author)
        language = _tag_get_language(language)
        ct = ContentType.objects.get_for_model(self.__class__)
        tags = parse_tag_input(name)
        for tag_name in tags:
            try:
                tag = Tag.objects.get(name=tag_name, language=language,
                    author=author, content_type=ct, object_id=self.id)
                tag.delete()
            except Tag.DoesNotExist:
                pass # okay, successfully "untagged".

    def untag_all(self, name=None, language=None, author=None):
        """untag_all([name], [language], [author])

        Untags this object from all tags in a specific `language` or authored
        by `author`."""
        author = _tag_get_user(author, default=None)
        language = _tag_get_language(language, default=None)
        ct = ContentType.objects.get_for_model(self.__class__)
        kwargs = dict(content_type=ct, object_id=self.id)
        if name is not None:
            kwargs['name__in'] = parse_tag_input(name)
        if language is not None:
            kwargs['language'] = language
        if author is not None:
            kwargs['author'] = author
        tags = Tag.objects.filter(**kwargs)
        tags.delete()


    def similar_objects(self, same_type=False, official=False):
        """similar_objects([same_type, official]) -> [(obj, distance), (obj, distance), ...]

        Returns a sorted list of similar objects in tuples (the object itself,
        the distance to the `self` object). If there are no similar objects,
        the list returned is empty. Searching for similar objects can be
        constrained to the objects of the same type (if `same_type` is
        True).

        Objects are similar when they share the same tags. Distance is the
        number of tags that are not shared by the two objects (specifically,
        the object has distance 0 to itself). Distance calculation by default
        uses all tags present on the object. If `official` is True, only the
        official tags are taken into account.
        """

        kwargs = {"official": official}
        if same_type:
            kwargs['model'] = self.__class__
        stems = TagStem.objects.get_dictionary(**kwargs)
        distance = []
        if self in stems:
            self_stems = stems[self]
            del stems[self]
        else:
            # may happen if this object is not available through Model.objects,
            # e.g. the model has a custom manager which filters it out
            self_stems = set((i[0] for i in
                TagStem.objects.get_queryset_for_model(self.__class__,
                self).values_list('name')))
        for obj, s in stems.iteritems():
            if not s & self_stems:
                # things without a single common tag are not similar at all
                continue
            distance.append((obj, len(s ^ self_stems)))
        distance.sort(key=lambda elem: elem[1])
        return distance

    def get_tags(self, official=True, author=None, language=None):
        """get_tags([official, author, language]) -> [TagStem, TagStem, ...]

        A convenience getter for tags on the current taggable. By default gets
        the `official` tags by no specific `author` and in any `language`."""
        return TagStem.objects.get_queryset_for_model(self.__class__, self,
            official=official, author=author, language=language).extra(
                select={'lname': 'lower(tags_tagstem.name)'}).order_by('lname')

    class Meta:
        abstract = True
Пример #36
0
class Trip(AdminURLMixin, models.Model):

    PLANNED = u'planned'
    APPROVED = u'approved'
    COMPLETED = u'completed'
    CANCELLED = u'cancelled'
    TRIP_STATUS = (
        (PLANNED, u"Planned"),
        (APPROVED, u"Approved"),
        (COMPLETED, u"Completed"),
        (CANCELLED, u"Cancelled"),
    )

    DUTY_TRAVEL = u'duty_travel'
    HOME_LEAVE = u'home_leave'
    FAMILY_VISIT = u'family_visit'
    EDUCATION_GRANT = u'education_grant'
    STAFF_DEVELOPMENT = u'staff_development'
    TRAVEL_TYPE = (
        (DUTY_TRAVEL, u"DUTY TRAVEL"),
        (HOME_LEAVE, u"HOME LEAVE"),
        (FAMILY_VISIT, u"FAMILY VISIT"),
        (EDUCATION_GRANT, u"EDUCATION GRANT"),
        (STAFF_DEVELOPMENT, u"STAFF DEVELOPMENT"),
    )

    status = models.CharField(
        max_length=32L,
        choices=TRIP_STATUS,
        default=PLANNED,
    )
    purpose_of_travel = models.CharField(max_length=254)
    travel_type = models.CharField(max_length=32L,
                                   choices=TRAVEL_TYPE,
                                   default=DUTY_TRAVEL)
    international_travel = models.BooleanField(
        default=False,
        help_text=
        'International travel will require approval from the representative')
    from_date = models.DateField()
    to_date = models.DateField()
    monitoring_supply_delivery = models.BooleanField(default=False)
    activities_undertaken = models.CharField(max_length=254,
                                             verbose_name='Activities')
    no_pca = models.BooleanField(
        default=False,
        verbose_name=u'Not related to a PCA',
        help_text='Tick this if this trip is not related to partner monitoring'
    )
    pcas = models.ManyToManyField(u'partners.PCA',
                                  blank=True,
                                  null=True,
                                  verbose_name=u"Related PCAs")
    partners = models.ManyToManyField(u'partners.PartnerOrganization',
                                      blank=True,
                                      null=True)
    main_observations = models.TextField(blank=True, null=True)

    ta_required = models.BooleanField(
        default=False, help_text='Is a Travel Authorisation (TA) is required?')
    programme_assistant = models.ForeignKey(
        User,
        blank=True,
        null=True,
        verbose_name='Assistant Responsible for TA',
        help_text='Needed if a Travel Authorisation (TA) is required',
        related_name='managed_trips')
    wbs = models.ForeignKey(
        WBS,
        blank=True,
        null=True,
        help_text='Needed if trip is over 10 hours and requires overnight stay'
    )
    grant = models.ForeignKey(Grant, blank=True, null=True)
    ta_approved = models.BooleanField(
        default=False, help_text='Has the TA been approved in vision?')
    ta_approved_date = models.DateField(blank=True, null=True)
    ta_reference = models.CharField(max_length=254, blank=True, null=True)

    locations = GenericRelation(LinkedLocation)

    owner = models.ForeignKey(User, verbose_name='Traveller')
    section = models.ForeignKey('reports.Sector', blank=True, null=True)

    travel_assistant = models.ForeignKey(User,
                                         blank=True,
                                         null=True,
                                         related_name='organised_trips')
    transport_booked = models.BooleanField(default=False)
    security_clearance = models.BooleanField(default=False)
    supervisor = models.ForeignKey(User, related_name='supervised_trips')
    approved_by_supervisor = models.BooleanField(default=False)
    budget_owner = models.ForeignKey(User, related_name='budgeted_trips')
    approved_by_budget_owner = models.BooleanField(default=False)
    approved_by_human_resources = models.BooleanField(default=False)
    representative_approval = models.BooleanField(default=False)
    approved_date = models.DateField(blank=True, null=True)
    created_date = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-from_date', '-to_date']

    def __unicode__(self):
        return u'{} - {}: {}'.format(self.from_date, self.to_date,
                                     self.purpose_of_travel)

    def reference(self):
        return '{}/{}'.format(self.created_date.year,
                              self.id) if self.id else None

    reference.short_description = 'Reference'

    def outstanding_actions(self):
        return self.actionpoint_set.filter(completed_date__isnull=True).count()

    @property
    def requires_hr_approval(self):
        return self.travel_type in [
            Trip.HOME_LEAVE, Trip.FAMILY_VISIT, Trip.EDUCATION_GRANT,
            Trip.STAFF_DEVELOPMENT
        ]

    @property
    def requires_rep_approval(self):
        return self.international_travel

    @property
    def can_be_approved(self):
        if not self.approved_by_supervisor\
        or not self.approved_by_budget_owner:
            return False
        if self.requires_hr_approval\
        and not self.approved_by_human_resources:
            return False
        if self.requires_rep_approval\
        and not self.representative_approval:
            return False
        return True

    @classmethod
    def get_email_template_or_default(cls, name, instance):
        try:
            template = EmailTemplate.objects.get(name=name)
        except EmailTemplate.DoesNotExist:
            template = EmailTemplate(subject='Trip {}: {}'.format(
                instance.status, instance.reference))
        return template

    @classmethod
    def send_trip_request(cls, sender, instance, created, **kwargs):
        current_site = Site.objects.get_current()
        if created:
            email_name = 'trips/trip/created'
            try:
                template = EmailTemplate.objects.get(name=email_name)
            except EmailTemplate.DoesNotExist:
                template = EmailTemplate.objects.create(
                    name=email_name,
                    description=
                    'The email that is send to the supervisor once a new trip has been created',
                    subject="New Trip Created for {{owner_name}}",
                    content="Dear {{supervisor_name}},"
                    "\r\n\r\nA new trip has been created by {{owner_name}} and awaits your approval here:"
                    "\r\n\r\n{{url}}"
                    "\r\n\r\nThank you.")
            send_mail(
                instance.owner.email, template, {
                    'owner_name':
                    instance.owner.get_full_name(),
                    'supervisor_name':
                    instance.supervisor.get_full_name(),
                    'url':
                    'http://{}{}'.format(current_site.domain,
                                         instance.get_admin_url())
                }, instance.supervisor.email)

        if instance.status == Trip.APPROVED:
            email_name = 'trips/trip/approved'
            try:
                template = EmailTemplate.objects.get(name=email_name)
            except EmailTemplate.DoesNotExist:
                template = EmailTemplate.objects.create(
                    name=email_name,
                    description=
                    'The email that is sent to the traveller if a trip has been approved',
                    subject="Trip Approved: {{trip_reference}}",
                    content=
                    "The following trip has been approved: {{trip_reference}}"
                    "\r\n\r\n{{url}}"
                    "\r\n\r\nThank you.")
            send_mail(
                instance.owner.email,
                template,
                {
                    'trip_reference':
                    instance.trip.reference(),
                    'url':
                    'http://{}{}'.format(current_site.domain,
                                         instance.get_admin_url())
                },
                instance.owner.email,
            )

        if instance.status == Trip.CANCELLED:
            email_name = 'trips/trip/cancelled'
            try:
                template = EmailTemplate.objects.get(name=email_name)
            except EmailTemplate.DoesNotExist:
                template = EmailTemplate.objects.create(
                    name=email_name,
                    description=
                    'The email that is sent to everyone if a trip has been cancelled',
                    subject="Trip Cancelled: {{trip_reference}}",
                    content=
                    "The following trip has been cancelled: {{trip_reference}}"
                    "\r\n\r\n{{url}}"
                    "\r\n\r\nThank you.")
            send_mail(
                instance.owner.email,
                template,
                {
                    'trip_reference':
                    instance.trip.reference(),
                    'url':
                    'http://{}{}'.format(current_site.domain,
                                         instance.get_admin_url())
                },
                instance.owner.email,
                instance.supervisor.email,
                instance.budget_owner.email,
                instance.travel_assistant.email,
            )

        if instance.approved_by_supervisor:
            if instance.travel_assistant and not instance.transport_booked:
                email_name = "travel/trip/travel_or_admin_assistant"
                try:
                    template = EmailTemplate.objects.get(name=email_name)
                except EmailTemplate.DoesNotExist:
                    template = EmailTemplate.objects.create(
                        name=email_name,
                        description=
                        "This e-mail will be sent when the trip is approved by the supervisor. "
                        "It will go to the travel assistant to prompt them to organise the travel "
                        "(vehicles, flights etc.) and request security clearance.",
                        subject="Travel for {{owner_name}}",
                        content="Dear {{travel_assistant}},"
                        "\r\n\r\nPlease organise the travel and security clearance (if needed) for the following trip:"
                        "\r\n\r\n{{url}}"
                        "\r\n\r\nThanks,"
                        "\r\n{{owner_name}}")
                send_mail(
                    instance.owner.email,
                    template,
                    {
                        'owner_name':
                        instance.owner.get_full_name(),
                        'travel_assistant':
                        instance.travel_assistant.get_full_name(),
                        'url':
                        'http://{}{}'.format(current_site.domain,
                                             instance.get_admin_url())
                    },
                    instance.travel_assistant.email,
                )

            if instance.ta_required and instance.programme_assistant and not instance.ta_approved:
                email_name = 'trips/trip/TA_request'
                try:
                    template = EmailTemplate.objects.get(name=email_name)
                except EmailTemplate.DoesNotExist:
                    template = EmailTemplate.objects.create(
                        name=email_name,
                        description=
                        "This email is sent to the relevant programme assistant to create "
                        "the TA for the staff in concern after the approval of the supervisor.",
                        subject=
                        "Travel Authorization request for {{owner_name}}",
                        content="Dear {{pa_assistant}},"
                        "\r\n\r\nKindly draft my Travel Authorization in Vision based on the approved trip:"
                        "\r\n\r\n{{url}}"
                        "\r\n\r\nThanks,"
                        "\r\n{{owner_name}}")
                send_mail(
                    instance.owner.email,
                    template,
                    {
                        'owner_name':
                        instance.owner.get_full_name(),
                        'pa_assistant':
                        instance.programme_assistant.get_full_name(),
                        'url':
                        'http://{}{}'.format(current_site.domain,
                                             instance.get_admin_url())
                    },
                    instance.programme_assistant.email,
                )
Пример #37
0
class Page(models.Model):

    objects = models.Manager()
    uniques = UniquePageManager()

    title = models.CharField(_("title"), max_length=255, unique=True)
    tags = models.ManyToManyField("tags.Tag", blank=True, related_name="pages")
    redirect_to = models.OneToOneField("Page", blank=True, null=True)
    #wiki_votes = GenericRelation("utils.Vote")
    #wiki_rates = GenericRelation("utils.Rate")
    wiki_views = GenericRelation("utils.View")
    view_count = models.IntegerField(default=0)
    wiki_bookmark = GenericRelation("utils.Bookmark")
    image_attachment = GenericRelation("utils.ImageAttachment")
    # count of things
    bookmark_count = models.IntegerField(default=0)
    # number of comment count, used for sorting.
    open_comment_count = models.IntegerField(default=0)
    pending_comment_count = models.IntegerField(default=0)

    current_revision = models.OneToOneField('PageRevision',
                                            blank=True,
                                            null=True,
                                            verbose_name=_('current revision'),
                                            related_name="revision_page")

    OPEN, PROTECTED = range(2)
    STATUS_CHOICE = [(OPEN, "open"), (PROTECTED, "protected")]
    status = models.IntegerField(choices=STATUS_CHOICE, default=OPEN)

    # redirect url
    def __unicode__(self):
        return self.title

    def get_title(self):
        return self.title.replace(" ", "_")

    def get_lead_section(self):
        #(\[TOC\])?\r\n#(.|\n)*$
        pattern = re.compile(u'^\s*?((.|\n)*?)\s*?(\n#(.|\n)*)?$')
        match = re.search(pattern, self.current_revision.content)
        lead_raw = match.group(1)
        toc = re.compile(u'\[TOC\]')
        lead = re.sub(toc, '', lead_raw)
        mkd_content = markdown.markdown(
            lead,
            extensions=[
                'extra',
                'wikilinks(base_url=/wiki/, end_url=/)',
            ],
            safe_mode='escape')
        pattern = re.compile(u'(<a[^>]*?wikilink)(.*?)(>(.*?)</a>)')
        mkd_content_wikilink = re.sub(pattern, replace_wikilinks, mkd_content)
        return mkd_content_wikilink

    def get_rate_average(self):
        rate_count = self.wiki_rates.count()
        rate_sum = 0
        for rate in self.wiki_rates.all():
            rate_sum += rate.rating
        if rate_count > 0:
            return float(rate_sum) / rate_count
        else:
            return rate_sum

    def get_open_comment(self):
        return self.comments.filter(status=0)

    def get_pending_comment(self):
        return self.comments.filter(status=1)

    def get_closed_comment(self):
        return self.comments.filter(status=2)

    @staticmethod
    def update_wiki_views(wiki, request, hours=24):
        "Views are updated per user session"

        # Extract the IP number from the request.
        ip1 = request.META.get('REMOTE_ADDR', '')
        ip2 = request.META.get('HTTP_X_FORWARDED_FOR',
                               '').split(",")[0].strip()
        # 'localhost' is not a valid ip address.
        ip1 = '' if ip1.lower() == 'localhost' else ip1
        ip2 = '' if ip2.lower() == 'localhost' else ip2
        ip = ip2 or ip1 or '0.0.0.0'

        now = timezone.now()
        since = now - timezone.timedelta(hours=hours)

        obj_type = ContentType.objects.get_for_model(wiki)
        obj_id = wiki.id
        # One view per time interval from each IP address.
        if not wiki.wiki_views.filter(ip=ip, date__gt=since):
            new_view = View(ip=ip, content_object=wiki, date=now)
            new_view.save()
            Page.objects.filter(id=wiki.id).update(view_count=F('view_count') +
                                                   1)
        return wiki

    @staticmethod
    def reset_comment_count():
        for wiki in Page.objects.all():
            wiki.open_comment_count = wiki.get_open_comment().count()
            wiki.pending_comment_count = wiki.get_pending_comment().count()
            wiki.save()

    @staticmethod
    def update_comment_count(sender, instance, **kwargs):
        page = instance.page
        page.open_comment_count = page.get_open_comment().count()
        page.pending_comment_count = page.get_pending_comment().count()
        page.save()

    def get_absolute_url(self):
        return reverse('wiki:wiki-detail', kwargs={'title': self.get_title()})
Пример #38
0
def negotiable(cls):
    # EXTEND NEGOTIABLE CLASS

    # add the default for mandatory method 'freeze'
    if not hasattr(cls, 'freeze') or not callable(getattr(cls, 'freeze')):
        setattr(cls, 'freeze', freeze)

    # add the mandatory 'creator' property
    if not hasattr(cls, 'creator'):
        setattr(cls, 'creator', creator)

    # add the generic relation field to negotiable class
    negotiations = GenericRelation(Negotiation, object_id_field='content_pk', content_type_field='content_type')
    negotiations.contribute_to_class(cls, 'negotiations')

    # add the negotiation property
    setattr(cls, 'negotiation', negotiation)

    # add the negotiate method
    setattr(cls, 'negotiate', negotiate)

    # add the status_for method
    setattr(cls, 'status_for', status_for)

    # add the accept method
    setattr(cls, 'accept', accept)

    # add the cancel method
    setattr(cls, 'cancel', cancel)

    # add the counter_proposal method
    setattr(cls, 'counter_proposal', counter_proposal)

    # add the modify_proposal method
    setattr(cls, 'modify_proposal', modify_proposal)

    # add the is_negotiating property
    setattr(cls, 'is_negotiating', is_negotiating)

    # add the is_accepted property
    setattr(cls, 'is_accepted', is_accepted)

    # add the is_cancelled property
    setattr(cls, 'is_cancelled', is_cancelled)

    # add the is_seller method
    setattr(cls, 'is_seller', is_seller)

    # add the is_client method
    setattr(cls, 'is_client', is_client)

    # add the last_proposal_from method
    setattr(cls, 'last_proposal_from', last_proposal_from)

    # add the last_counterpart_proposal_for method
    setattr(cls, 'last_counterpart_proposal_for', last_counterpart_proposal_for)

    # add the last_client_proposal property
    setattr(cls, 'last_client_proposal', last_client_proposal)

    # add the last_seller_proposal property
    setattr(cls, 'last_seller_proposal', last_seller_proposal)

    # add the initiator property
    setattr(cls, 'initiator', initiator)

    # add the last_updater property
    setattr(cls, 'last_updater', last_updater)

    # add the is_last_updater method
    setattr(cls, 'is_last_updater', is_last_updater)

    # add the history method
    setattr(cls, 'history', history)

    # add the negotiation_options method
    setattr(cls, 'negotiation_options', negotiation_options)

    # EXTEND NEGOTIABLE CLASS'S MANAGERS AND QUERYSETS

    cls._meta.concrete_managers.sort()
    managers = [(mgr_name, manager) for _, mgr_name, manager in cls._meta.concrete_managers]

    setattr(cls, '_default_manager', None)  # clean the default manager
    setattr(cls._meta, 'concrete_managers', [])  # clean the managers

    for mgr_name, manager in managers:

        class ExtendedNegotiableManager(ExtendedNegotiableManagerMixin, manager.__class__):

            class ExtendedNegotiableQueryset(ExtendedNegotiableQuerysetMixin, manager.get_queryset().__class__):
                pass

            def get_queryset(self):
                return self.ExtendedNegotiableQueryset(self.model, using=self._db)

        cls.add_to_class(mgr_name, ExtendedNegotiableManager())

    return cls
Пример #39
0
class Metric(models.Model):
    name = models.CharField(max_length=300)
    slug = models.SlugField()
    data = GenericRelation('Datum')
    show_on_dashboard = models.BooleanField(default=True)
    show_sparkline = models.BooleanField(default=True)
    period = models.CharField(max_length=15,
                              choices=METRIC_PERIOD_CHOICES,
                              default=METRIC_PERIOD_INSTANT)
    unit = models.CharField(max_length=100)
    unit_plural = models.CharField(max_length=100)

    class Meta:
        abstract = True

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return ("metric-detail", [self.slug])

    def gather_data(self, since):
        """
        Gather all the data from this metric since a given date.
        
        Returns a list of (timestamp, value) tuples. The timestamp is a Unix
        timestamp, coverted from localtime to UTC.
        """
        if self.period == METRIC_PERIOD_INSTANT:
            return self._gather_data_instant(since)
        elif self.period == METRIC_PERIOD_DAILY:
            return self._gather_data_periodic(since, 'day')
        elif self.period == METRIC_PERIOD_WEEKLY:
            return self._gather_data_periodic(since, 'week')
        else:
            raise ValueError("Unknown period: %s", self.period)

    def _gather_data_instant(self, since):
        """
        Gather data from an "instant" metric.
        
        Instant metrics change every time we measure them, so they're easy:
        just return every single measurement.
        """
        data = self.data.filter(timestamp__gt=since) \
                        .order_by('timestamp') \
                        .values_list('timestamp', 'measurement')
        return [(calendar.timegm(t.timetuple()), m) for (t, m) in data]

    def _gather_data_periodic(self, since, period):
        """
        Gather data from "periodic" merics.
        
        Period metrics are reset every day/week/month and count up as the period
        goes on. Think "commits today" or "new tickets this week".
        
        XXX I'm not completely sure how to deal with this since time zones wreak
        havoc, so there's right now a hard-coded offset which doesn't really
        scale but works for now.
        """
        OFFSET = "2 hours"  # HACK!
        ctid = ContentType.objects.get_for_model(self).id

        c = connections['default'].cursor()
        c.execute(
            '''SELECT 
                        DATE_TRUNC(%s, timestamp - INTERVAL %s),
                        MAX(measurement)
                     FROM dashboard_datum
                     WHERE content_type_id = %s 
                       AND object_id = %s
                       AND timestamp >= %s
                     GROUP BY 1;''', [period, OFFSET, ctid, self.id, since])
        return [(calendar.timegm(t.timetuple()), float(m))
                for (t, m) in c.fetchall()]