class Snipet(models.Model): LANGUAGE_CHOICES = (('python', u'Python'), ('javascript', u'JavaScript')) title = models.CharField(_(u'title'), max_length=255) description = models.TextField(_(u'description'), blank=True) language = models.CharField(_(u'language'), default='python', choices=LANGUAGE_CHOICES, max_length=100, help_text=_(u'Main snippet language')) author = models.ForeignKey(User, verbose_name=_(u'author')) created = models.DateTimeField(_(u'created'), auto_now_add=True) tags = TagAutocompleteField(verbose_name=_(u'tags')) rating = models.PositiveIntegerField(_(u'rating'), default=0) rated_by = models.ManyToManyField(User, verbose_name=_(u'rated by'), editable=False, related_name='rated_snippets') class Meta: ordering = ['-created'] def __unicode__(self): return self.title @models.permalink def get_absolute_url(self): return ('code_review:details', [self.pk], {}) def can_rate(self, user): if not user.is_authenticated(): return False return not self.rated_by.filter(pk=user.pk).exists()
class Publicacion(models.Model): titulo = models.CharField(max_length=200) slug = models.SlugField(max_length=200, editable=False) fecha = models.DateField() foto = ImageField(upload_to=utils.get_file_path, blank=True, null=True) archivo = models.FileField(upload_to=utils.get_file_path, blank=True, null=True) categoria= TagAutocompleteField(help_text='Separar elementos con "," ', null=True, blank=True) fileDir = 'publicaciones/' autor = models.ForeignKey(User) def __unicode__(self): return self.titulo def save(self, *args, **kwargs): self.slug = (slugify(self.titulo)) super(Publicacion, self).save(*args, **kwargs) def get_absolute_url(self): return '/publicaciones/%s/' % (self.slug) class Meta: verbose_name = "Publicacion" verbose_name_plural = "Publicaciones"
class Eventos(models.Model): titulo = models.CharField(max_length=200) slug = models.SlugField(max_length=200, editable=False) fecha_inicio = models.DateField() fecha_finalizacion = models.DateField() descripcion = RichTextField('Descripción') position = GeopositionField(null=True, blank=True) fotos = generic.GenericRelation(Fotos) categoria = TagAutocompleteField("Tags", help_text='Separar elementos con "," ', null=True, blank=True) autor = models.ForeignKey(User) def save(self, *args, **kwargs): self.slug = (slugify(self.titulo)) super(Eventos, self).save(*args, **kwargs) def get_absolute_url(self): return reverse('eventos_detalle', kwargs={'slug': self.slug}) class Meta: verbose_name = 'Evento' verbose_name_plural = 'Eventos' ordering = ('-fecha_inicio', ) def __unicode__(self): return u'%s' % self.titulo
class Publicaciones(models.Model): titulo = models.CharField(max_length=200) slug = models.SlugField(max_length=200, editable=False) fecha = models.DateField('Fecha de publicación') descripcion = RichTextField('Descripción') adjunto = models.FileField(upload_to=get_file_path, null=True, blank=True) portada = ImageField(upload_to=get_file_path, blank=True, null=True) categoria = TagAutocompleteField(help_text='Separar elementos con "," ', null=True, blank=True) fileDir = 'publicaciones/' autor = models.ForeignKey(User) def save(self, *args, **kwargs): self.slug = (slugify(self.titulo)) super(Publicaciones, self).save(*args, **kwargs) def get_absolute_url(self): return reverse('publicaciones_detalles', kwargs={'slug': self.slug}) class Meta: verbose_name = u'Publicación' verbose_name_plural = u'Publicaciones' ordering = ('-id', ) def __unicode__(self): return u'%s' % self.titulo
class Question(models.Model): question = models.CharField(max_length=300, verbose_name='Titulo') description = models.TextField() date_created = models.DateTimeField(default=datetime.datetime.now()) tags = TagAutocompleteField(verbose_name='Palabras Claves',help_text='Separar elementos con "," ') last_answer_date = models.DateTimeField(default=datetime.datetime.now()) views = models.IntegerField() user = models.ForeignKey(User) def __unicode__(self): return u'%s' % self.question class Meta: verbose_name = u'Pregunta' verbose_name_plural = u'Preguntas' #Para jalar las tags def set_tags(self, tags): Tag.objects.update_tags(self, tags) def get_tags(self): return Tag.objects.get_for_object(self) def get_answer_count(self): if self.answer_set.all().count() == 0: return 0 return self.answer_set.all().count() def last_answer(self): return self.answer_set.latest('fecha')
class Documentos(models.Model): ''' Modelo generico para subir los documentos en distintos app''' content_type = models.ForeignKey(ContentType) object_id = models.IntegerField(db_index=True) content_object = generic.GenericForeignKey('content_type', 'object_id') nombre_doc = models.CharField("Nombre", max_length=200, null=True, blank=True) adjunto = models.FileField("Adjunto", upload_to=get_file_path, null=True, blank=True) tags_doc = TagAutocompleteField("Tags", help_text='Separar elementos con "," ', null=True, blank=True) fileDir = 'documentos/' class Meta: verbose_name_plural = "Documentos" def __unicode__(self): return self.nombre_doc
class Imagen(models.Model): ''' Modelo generico para subir imagenes en todos los demas app :)''' content_type = models.ForeignKey(ContentType) object_id = models.IntegerField(db_index=True) content_object = generic.GenericForeignKey('content_type', 'object_id') nombre_img = models.CharField("Nombre", max_length=200, null=True, blank=True) foto = ImageWithThumbsField("Foto", upload_to=get_file_path, sizes=((220, 160), (80, 80), (380, 250), (640, 480)), null=True, blank=True) tags_img = TagAutocompleteField("Tags", help_text='Separar elementos con "," ', null=True, blank=True) fileDir = 'fotos/' class Meta: verbose_name_plural = "Imágenes" def __unicode__(self): return self.nombre_img
class Noticias(models.Model): titulo = models.CharField(max_length=200) slug = models.SlugField(max_length=200, editable=False) fecha = models.DateField() descripcion = RichTextField('Descripción') fotos = generic.GenericRelation(Fotos) categoria = TagAutocompleteField("Tags", help_text='Separar elementos con "," ', null=True, blank=True) destacada = models.BooleanField() adjunto = generic.GenericRelation(Adjuntos) autor = models.ForeignKey(User) def save(self, *args, **kwargs): self.slug = (slugify(self.titulo)) super(Noticias, self).save(*args, **kwargs) def get_absolute_url(self): return reverse('noticias_detalle', kwargs={'slug': self.slug}) def get_tags(self): return Tag.objects.get_for_object(self) class Meta: verbose_name = 'Noticia' verbose_name_plural = 'Noticias' ordering = ('-id', ) def __unicode__(self): return u'%s' % self.titulo
class Videos(models.Model): nombre = models.CharField(max_length=200, null=True, blank=True) url = models.URLField(null=True, blank=True) tags_video = TagAutocompleteField(help_text='Separar elementos con "," ', null=True, blank=True) def __unicode__(self): return self.nombre class Meta: verbose_name_plural = "Videos" ordering = ('-id', )
class Audio(models.Model): nombre = models.CharField(max_length=150) audio = models.FileField(upload_to=get_file_path, null=True, blank=True) tags_audio = TagAutocompleteField("Tags", help_text='Separar elementos con "," ', null=True, blank=True) fileDir = 'audios/' def __unicode__(self): return self.nombre class Meta: verbose_name_plural = "Audios" ordering = ('-id', )
class NamedUpload(Upload): file_name_new = models.CharField(max_length=255) name = models.CharField(max_length=255, blank=True, null=True) description = models.TextField(blank=True, null=True) tags = TagAutocompleteField(blank=True, null=True) created_timestamp = models.DateTimeField(blank=True, null=True, verbose_name="Date Created") def get_name(self): if self.name is not None and len(self.name) > 0: return self.name elif self.file_name_orig is not None and len(self.file_name_orig) > 0: return self.file_name_orig return 'Untitled' def to_dict(self, **kwargs): d = { 'id': self.id, 'name': self.get_name(), 'content_type': self.content_type, 'path': self.absolute_virtual_path(), 'file_name_orig': self.file_name_orig, 'tags': self.tags, 'project_id': self.project.id } #add turned_on flag (only exists for views) try: d.update(dict(turned_on=self.turned_on)) except AttributeError: pass #add marker (if exists) try: if self.source_marker is not None: d.update(dict(markerID=self.source_marker.id)) except AttributeError: pass #add lat/lng ( not applicable for scans & attachments) try: if self.point is not None: d.update(dict(lat=self.point.y, lng=self.point.x)) except AttributeError: pass return d class Meta: abstract = True
class Videos(models.Model): ''' Modelo generico para subir videos en todos los app''' content_type = models.ForeignKey(ContentType) object_id = models.IntegerField(db_index=True) content_object = generic.GenericForeignKey('content_type', 'object_id') nombre_video = models.CharField(max_length=200, null=True, blank=True) url = models.URLField(null=True, blank=True) tags_vid = TagAutocompleteField(help_text='Separar elementos con "," ', null=True, blank=True) class Meta: verbose_name_plural = "Videos" def __unicode__(self): return self.nombre_video
class Page(models.Model): category = models.ForeignKey(Category) postby = models.ForeignKey(User) title = models.CharField(max_length=50) data = models.TextField() views = models.IntegerField(default=0) date = models.DateTimeField(default=datetime.now()) like = models.IntegerField(default=0) tags = TagAutocompleteField( null=True, blank=True, ) #slug = models.SlugField(default='', unique=True) def __str__(self): return self.title
class Imagem(models.Model): criador = models.ForeignKey(User, related_name='imagem', verbose_name=_(u"Criador")) image = models.ImageField(upload_to=settings.BANCO_IMAGE_UPLOAD_DIR, verbose_name=_(u"Imagem")) slug = models.SlugField(max_length=65, unique=True, blank=True, verbose_name=_(u"Slug")) nome = models.CharField(max_length=60, verbose_name=_(u"Titulo")) desc = models.TextField(verbose_name=_(u"Descrição")) tags = TagAutocompleteField(verbose_name=_(u"Tags")) data_criacao = models.DateTimeField(default=datetime.now, verbose_name=_(u"Data de Criação")) def pontos(self): return Ponto.objects.filter(imagem=self) def __unicode__(self): return self.nome def get_absolute_url(self): return reverse('bi_imagem', kwargs={'slug': self.slug})
class Fotos(models.Model): nombre = models.CharField(max_length=150) imagen = ImageField(upload_to=get_file_path, blank=True, null=True) tags_fotos = TagAutocompleteField("Tags", help_text='Separar elementos con "," ', null=True, blank=True) content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id') fileDir = 'fotos/' def __unicode__(self): return self.nombre class Meta: verbose_name_plural = "Fotos"
class Audios(models.Model): '''' Modelo generico para subir audios en todos los demas app ''' content_type = models.ForeignKey(ContentType) object_id = models.IntegerField(db_index=True) content_object = generic.GenericForeignKey('content_type', 'object_id') nombre_audio = models.CharField(max_length=200, null=True, blank=True) audio = models.FileField(upload_to=get_file_path, null=True, blank=True) tags_aud = TagAutocompleteField(help_text='Separar elementos con "," ', null=True, blank=True) fileDir = 'audios/' class Meta: verbose_name_plural = "Audios" def __unicode__(self): return self.nombre_audio
class Event(CommonSettings): """ A log event is a constituent of an experiment. """ author = models.ForeignKey(User) timestamp = models.DateTimeField(auto_now_add=True) event_type = models.ForeignKey(Event_Type, verbose_name="Event type") text_field = models.TextField(blank=True, null=True, max_length=2048, help_text="what did you do?", verbose_name="Event") flag_box = models.BooleanField( verbose_name="On / Off", help_text= "Please be careful with correctly setting this flag. Leave unckecked for 'On', check for 'Off'" ) time = models.TimeField() date = models.DateField() experiment = models.ForeignKey(Experiment) SCHEDULE_PAST = 1 SCHEDULE_FUTURE = 2 SCHEDULE_PARTIAL = 3 SCHEDULE_CHOICES = ( (SCHEDULE_PAST, 'Event in the past (default)'), (SCHEDULE_FUTURE, 'Future event: ToDo'), (SCHEDULE_PARTIAL, 'Future event: partially started'), ) schedule = models.PositiveIntegerField( choices=SCHEDULE_CHOICES, verbose_name="Schedule Event", blank=False, help_text="Is this a past or a future event?") tags = TagAutocompleteField() def __unicode__(self): return u"%s" % (self.timestamp)
class Posts(models.Model): fecha = models.DateField() titulo = models.CharField(max_length=200) slug = models.CharField(max_length=200) contenido = models.TextField() autor = models.ForeignKey(User) categoria = models.ForeignKey(Categoria) tag = TagAutocompleteField('Tags', help_text='Separa con comas', null=True, blank=True) def __unicode__(self): return self.titulo def adjunto(self): adjunto = Archivos.objects.filter(fk_post_id=self.id) return adjunto def get_absolute_url(self): return '/blog/%s/' % (self.slug)
class Device(models.Model): """ Records for devices referenced in report configuration pages. Actual instantiations of Device objects handled through DeviceManager class in devicemanager.py module. """ name = models.CharField(max_length=200) module = models.CharField(max_length=200) host = models.CharField(max_length=200) port = models.IntegerField(default=443, validators=[validate_port]) username = models.CharField(max_length=100, blank=True) password = models.CharField(max_length=100, blank=True) tags = TagAutocompleteField(blank=True) objects = DevManager() auth = models.IntegerField(default=Auth.NONE, choices=((Auth.NONE, 'None'), (Auth.BASIC, 'Basic'), (Auth.OAUTH, 'OAuth2'))) access_code = models.TextField(blank=True) # only enabled devices will require field validation enabled = models.BooleanField(default=True) class Meta: unique_together = (("host", "port")) def __unicode__(self): return '%s (%s:%s)' % (self.name, self.host, self.port) def save(self, *args, **kwargs): super(Device, self).save(*args, **kwargs) create_device_fixture(settings.APPFWK_STRIP_DEVICE_PASSWORDS) def tags_as_list(self): return [tag.strip() for tag in self.tags.split(',') if tag.strip()]
class Video(models.Model): title = models.CharField(_(u'title'), max_length=500) video = models.URLField(_(u'video URL')) description = models.TextField() tags = TagAutocompleteField(verbose_name=_(u'tags')) created = models.DateTimeField(_(u'created'), auto_now_add=True) class Meta: ordering = ['-created'] verbose_name = _(u'video') verbose_name_plural = _(u'videos') def __unicode__(self): return self.title @models.permalink def get_absolute_url(self): return ('videos:index', ) def video_embed_code(self, maxwidth=300, maxheight=225): try: resource = oembed.site.embed(self.video, maxwidth=maxwidth, maxheight=maxheight) return resource.get_data()['html'] except (oembed.exceptions.OEmbedException, KeyError): return '' def video_preview_code(self): try: resource = oembed.site.embed(self.video, maxwidth=348, maxheight=261) return resource.get_data()['html'] except (oembed.exceptions.OEmbedException, KeyError): return ''
class Bird(CommonStuff): ''' The model for a database bird. Note: -> date_of_birth and age_uncertainty are stored with every bird individually, rather than with the brood -> there are functions that return mother and father of the bird if possible TODO: we do not enforce uniqueness of names of living birds at all right now -> for data consistency this has to be done though!!! maybe this could be of help: http://djangosnippets.org/snippets/1830/ ''' JUVENILE_PREFIX = 'J' name_help_text = 'Birdnames have to consist of alphabetic letters, numbers, hyphens or underscores.' name = models.CharField(max_length=255, validators=[validate_slug], help_text=name_help_text) SEX_UNKNOWN_JUVENILE = 'u' SEX_UNKNOWN_NOT_VISIBLE = 'v' SEX_MALE = 'm' SEX_FEMALE = 'f' SEX_CHOICES = ( (SEX_UNKNOWN_JUVENILE, 'unknown - juvenile'), (SEX_UNKNOWN_NOT_VISIBLE, 'unknown - not visible'), (SEX_MALE, 'male'), (SEX_FEMALE, 'female'), ) sex = models.CharField(max_length=1, choices=SEX_CHOICES) SPECIES_ZEBRAFINCH = 'ZF' SPECIES_BENGALESEFINCH = 'BF' SPECIES_CHOICES = ( (SPECIES_ZEBRAFINCH, 'zebra finch'), (SPECIES_BENGALESEFINCH, 'bengalese finch'), ) date_of_birth = models.DateField(auto_now_add=False, blank=True, null=True) AGE_UNCERTAINTY_CHOICES = ( (0, 'zero days'), (-1, 'one day'), (-2, 'two days'), (-3, 'three days'), (-4, 'four days'), (-5, 'five days'), (-6, 'six days'), (-7, 'seven days'), (-8, 'more than seven days'), ) age_uncertainty = models.IntegerField(choices=AGE_UNCERTAINTY_CHOICES) species = models.CharField(max_length=10, choices=SPECIES_CHOICES) brood = models.ForeignKey(Brood, blank=True, null=True) cage = models.ForeignKey(Cage) reserved_until = models.DateField(blank=True, null=True) reserved_by = models.ForeignKey(User, blank=True, null=True) missing_since = models.DateField(blank=True, null=True) COUPLING_NEVER_USED = 0 COUPLING_DO_NOT_COUPLE = 1 COUPLING_BREEDER = 2 COUPLING_TRY_BREEDING_AGAIN = 3 COUPLING_CHOICES = ( (COUPLING_NEVER_USED, 'never used for breeding'), (COUPLING_DO_NOT_COUPLE, 'do not couple'), (COUPLING_BREEDER, 'good breeder'), (COUPLING_TRY_BREEDING_AGAIN, 'semi-ok breeder'), ) coupling_status = models.PositiveIntegerField(choices=COUPLING_CHOICES, default=COUPLING_NEVER_USED) comment = models.TextField(blank=True, null=True) exit_date = models.DateField(blank=True, null=True) # name_unique declares whether a birds name has to be unique # generally birds alive in our breeding colony have to be unique # the NullBooleanField has three possible entries: Null, False, True # birds to be unique will need entry yes, birds whose name can be used # MULTIPLE times HAVE TO USE NULL, False is not to be used # TODO : enforce not using False name_unique = models.NullBooleanField(default=True, null=True) # don't use magic numbers! # see also: http://www.b-list.org/weblog/2007/nov/02/handle-choices-right-way/ EXIT_NONE = 0 EXIT_SLEEP = 1 EXIT_SURGERY = 2 EXIT_PERISHED = 3 EXIT_NONEXPERIMENTAL = 4 EXIT_GIVENAWAY = 5 EXIT_MISSING = 6 CAUSE_OF_EXIT_CHOICES = ( (EXIT_NONE, '-----'), (EXIT_SLEEP, 'end of experiment (chronic / acute sleep)'), (EXIT_SURGERY, 'end of experiment (surgery / under anesthesia)'), (EXIT_PERISHED, 'perished'), (EXIT_NONEXPERIMENTAL, 'not experimental'), (EXIT_GIVENAWAY, 'given away'), (EXIT_MISSING, 'missing'), ) cause_of_exit = models.PositiveIntegerField( choices=CAUSE_OF_EXIT_CHOICES, blank=True, null=True, verbose_name="Reason for removal") tags = TagAutocompleteField() name.alphabetic_filter = True class Meta: ordering = [ 'name', ] unique_together = ('name', 'name_unique') def __unicode__(self): return u'%s' % (self.name) @models.permalink def get_absolute_url(self): return ('bird_overview', [str(self.id)]) @models.permalink def get_edit_url(self): return ('bird_edit', [str(self.id)]) # function to return the age of the bird def get_phd(self, relative_to_day=None, return_empty=None): # only calculate the age if the field is set - for old birds or # outbreeders there might be no birthday if self.date_of_birth: if relative_to_day: age = relative_to_day - self.date_of_birth else: age = datetime.date.today() - self.date_of_birth age = age.days.__str__() age = age # + ' phd' printing 'phd' in all forms is a space issue else: if return_empty == True: age = None else: age = '?' return age def get_father(self): try: if self.brood.origin == Brood.ORIGIN_BREEDING: return self.brood.coupling.couple.get_male() except: return def get_sex_display(self): ''' if sex is unknown, show only the 'unknown', otherwise show the short sex names (f, m) ''' try: if self.sex in (Bird.SEX_UNKNOWN_NOT_VISIBLE, Bird.SEX_UNKNOWN_JUVENILE): return 'unknown' else: return self.sex except: return self.sex def get_mother(self): try: if self.brood.origin == Brood.ORIGIN_BREEDING: return self.brood.coupling.couple.get_female() except: return def get_mother_and_father(self): try: if self.brood.origin == Brood.ORIGIN_BREEDING: # slow way #return self.brood.coupling.couple.get_female_and_male() # fast way couplelookup = CoupleLookup.objects.get( couple__coupling__brood__bird=self) return couplelookup.mother, couplelookup.father except: return None, None def get_couple_ids(self): ''' get all couple IDs that this bird was part of ''' couples = [] if self.sex not in (Bird.SEX_MALE, Bird.SEX_FEMALE): return couples if self.sex == Bird.SEX_MALE: couples = self.father_set.all().values_list('couple', flat=True) else: couples = self.mother_set.all().values_list('couple', flat=True) return couples def get_couplings(self): ''' get all couplings that this bird was involved in ''' couple_ids = self.get_couple_ids() couples = Couple.objects.filter(id__in=couple_ids) # for all couples, find all couplings couplinglists = [] for clui in couples: couplinglists.append(clui.coupling_set.all().select_related( 'couple').order_by('coupling_date')) # this code is doing the same, but doesn't group couplings that belong # to the same couple #Coupling.objects.filter(couple__id__in = couple_ids).select_related('couple').order_by('coupling_date') return couplinglists def get_offspring(self): ''' returns all offspring of current bird this function takes roughly 3ms ''' couple_ids = self.get_couple_ids() # the following code is doing the same, but is ~ 10% slower #from django.db.models import Q #couple_ids = CoupleLookup.objects.filter(Q(Q(father = self.id) | Q(mother = self.id))).values_list('couple', flat = True) # return only birds that were part of a 'breeding couple' return Bird.objects.filter(brood__coupling__couple__in=couple_ids, brood__origin=Brood.ORIGIN_BREEDING) def get_mates_string(self): ''' returns a string with the mates of a bird, how successful they were and when they were separated. ''' mates = '' # all couplings that this bird was involved in couplinglists = self.get_couplings() if couplinglists == []: return mates # now we have a list of lists of couplings for a bird / couple for couplinglist in couplinglists: # now we go through the couples mates += couplinglist[0].couple.get_partner(self.sex).name # and count its offspring over several couplings offcount = 0 for coupling in couplinglist: offcount += coupling.brood_set.all().count() # put offspring and separation_date of last coupling into string mates += '(' + str(offcount) + ' - ' + str( coupling.separation_date) + '), ' mates = mates[:-2] return mates def get_mates_dict(self): mates = [] last_separation = None # all couplings that this bird was involved in couplinglists = self.get_couplings() if couplinglists == []: return {'mates': mates, 'last_separation': last_separation} # now we have a list of lists of couplings for a bird / couple for couplinglist in couplinglists: # now we go through the couples # and count its offspring over several couplings broodcount = 0 juvcount = 0 partner = couplinglist[0].couple.get_partner(self.sex) for coupling in couplinglist: broods = coupling.brood_set.all() broodcount += broods.__len__() for brood in broods: juvcount += brood.bird_set.all().__len__() coupling_list_len = couplinglist.__len__() # put info into dict mate_dict = { 'bird': partner, 'AvgNoBroods': float(broodcount) / float(coupling_list_len), 'AvgNoJuvs': float(juvcount) / float(coupling_list_len), 'last_separation': coupling.separation_date, 'NoCouplings': coupling_list_len, } if last_separation: if last_separation < coupling.separation_date: last_separation = coupling.separation_date else: last_separation = coupling.separation_date # append dict to mates list mates.append(mate_dict) return {'mates': mates, 'last_separation': last_separation} def build_family_tree(self): family = [] mother, father = self.get_mother_and_father() # all couplings that this bird was involved in couplinglists = self.get_couplings() if couplinglists == []: return { 'family': family, 'mother': mother, 'father': father, } # now we have a list of lists of couplings for a bird / couple for couplinglist in couplinglists: partner = couplinglist[0].couple.get_partner(self.sex) partner_mother, partner_father = partner.get_mother_and_father() for coupling in couplinglist: offspring_this_coupling = [] broods = coupling.brood_set.all() for brood in broods: offspring_this_coupling = brood.bird_set.all() offspring_this_coupling_with_offspring = [] for j in offspring_this_coupling: this_offspring = j.get_offspring() has_offspring = False if this_offspring.__len__() > 0: has_offspring = True offspring_this_coupling_with_offspring.append( [j, has_offspring]) # put info into dict generation_dict = { 'partner': partner, 'partner_father': partner_father, 'partner_mother': partner_mother, 'coupling_date': coupling.coupling_date, 'separation_date': coupling.separation_date, 'offspring_with_offspring': offspring_this_coupling_with_offspring, } # append dict family.append(generation_dict) return { 'family': family, 'mother': mother, 'father': father, } def is_breeding(self): # current couples from birdlist.utils.bird import find_birds_currently_breeding males, females = find_birds_currently_breeding() if self.id in males or self.id in females: return True else: return False def is_juvenile_to_be_transferred(self): from birdlist.utils.bird import get_juveniles lower_datethreshold = datetime.date.today() - datetime.timedelta(60) juveniles = get_juveniles().filter( date_of_birth__lte=lower_datethreshold).filter( cage__function=Cage.FUNCTION_BREEDING) if self in juveniles: return True else: return False def get_current_partner(self): try: couple_in_cage = Coupling.objects.get(cage__name=self.cage.name, separation_date=None) partner = couple_in_cage.couple.get_partner(self.sex) return partner except: return None
class Project(models.Model): """ A project is a group of translatable resources. """ private = models.BooleanField( default=False, verbose_name=_('Private'), help_text=_( 'A private project is visible only by you and your team. ' 'Moreover, private projects are limited according to billing ' 'plans for the user account.')) slug = models.SlugField( _('Slug'), max_length=30, unique=True, validators=[ validate_slug_not_in_blacklisted, validate_slug, ], help_text=_('A short label to be used in the URL, containing only ' 'letters, numbers, underscores or hyphens.')) name = models.CharField( _('Name'), max_length=50, help_text=_('A short name or very short description.')) description = models.CharField( _('Description'), blank=False, max_length=255, help_text=_('A sentence or two describing the object.')) long_description = models.TextField( _('Long description'), blank=True, max_length=1000, help_text=_('A longer description (optional). Use Markdown syntax.')) homepage = models.URLField(_('Homepage'), blank=True, verify_exists=False) feed = models.CharField( _('Feed'), blank=True, max_length=255, help_text=_('An RSS feed with updates to the project.')) bug_tracker = models.URLField( _('Bug tracker'), blank=True, help_text=_('The URL for the bug and tickets tracking system ' '(Bugzilla, Trac, etc.)')) trans_instructions = models.URLField( _('Translator Instructions'), blank=True, help_text=_("A web page containing documentation or instructions for " "translators, or localization tips for your community.")) anyone_submit = models.BooleanField( _('Anyone can submit'), default=False, blank=False, help_text=_('Can anyone submit files to this project?')) hidden = models.BooleanField( _('Hidden'), default=False, editable=False, help_text=_('Hide this object from the list view?')) enabled = models.BooleanField( _('Enabled'), default=True, editable=False, help_text=_('Enable this object or disable its use?')) created = models.DateTimeField(auto_now_add=True, editable=False) modified = models.DateTimeField(auto_now=True, editable=False) tags = TagAutocompleteField(verbose_name=_('Tags'), blank=True, null=True) logo = ThumbnailerImageField( _('Logo'), blank=True, null=True, upload_to=upload_to_mugshot, resize_source=PROJECT_LOGO_SETTINGS, help_text=_('A logo image displayed for the project.')) # Relations maintainers = models.ManyToManyField(User, verbose_name=_('Maintainers'), related_name='projects_maintaining', blank=False, null=True) outsource = models.ForeignKey( 'Project', blank=True, null=True, verbose_name=_('Outsource project'), related_name="outsourcing", help_text=_( 'Project hub that owns the access control of this project.')) owner = models.ForeignKey(User, blank=True, null=True, verbose_name=_('Owner'), related_name='projects_owning', help_text=_('The user who owns this project.')) source_language = models.ForeignKey( Language, verbose_name=_('Source Language'), blank=False, null=False, db_index=False, help_text=_("The source language of this Resource.")) # Denormalized fields is_hub = models.BooleanField( _('Project Hub?'), default=False, blank=True, help_text=_('Is it a project hub that other regular projects can ' 'use to outsource teams to receive translations?')) # Normalized fields long_description_html = models.TextField( _('HTML Description'), blank=True, max_length=1000, help_text=_('Description in HTML.'), editable=False) # Reverse Relation for LogEntry GenericForeignkey # Allows to access LogEntry objects for a given project actionlogs = generic.GenericRelation(LogEntry, object_id_field="object_id", content_type_field="content_type") # Managers objects = ChainerManager(DefaultProjectQuerySet) public = PublicProjectManager() def __unicode__(self): return self.name def __repr__(self): return repr(u'<Project: %s>' % self.name) class Meta: verbose_name = _('project') verbose_name_plural = _('projects') db_table = 'projects_project' ordering = ('name', ) get_latest_by = 'created' def save(self, *args, **kwargs): """Save the object in the database.""" long_desc = escape(self.long_description) self.long_description_html = markdown.markdown(long_desc) if self.id is None: is_new = True else: is_new = False super(Project, self).save(*args, **kwargs) if is_new: project_created.send(sender=self) def delete(self, *args, **kwargs): self.resources.all().delete() project_deleted.send(sender=self) super(Project, self).delete(*args, **kwargs) @permalink def get_absolute_url(self): return ('project_detail', None, {'project_slug': self.slug}) @property def hub_request(self): """ Return a HubRequest object if a request to join a project hub exists. Otherwise it returns None. """ try: return self.hub_requesting.all()[0] except IndexError: return None @property def wordcount(self): return self.resources.aggregate( Sum('wordcount'))['wordcount__sum'] or 0 @property def num_languages(self): return Language.objects.filter( rlstats__resource__project=self).distinct().count() @property def max_hostable_wordcount(self): return self.num_languages * self.wordcount @property def entities(self): return self.resources.aggregate( Sum('total_entities'))['total_entities__sum'] or 0 @property def team_members(self): """Return a queryset of all memebers of a project.""" return User.objects.filter( Q(team_members__project=self) | Q(team_coordinators__project=self) |\ Q(team_reviewers__project=self) | Q(projects_owning=self) |\ Q(projects_maintaining=self) ).distinct() @property def team_member_count(self): return User.objects.filter( Q(team_members__project=self) | Q(team_coordinators__project=self) |\ Q(projects_owning=self) | Q(projects_maintaining=self) ).distinct().count() def languages(self): """ The languages this project's resources are being translated into excluding the source language, ordered by number of translations. """ return Language.objects.filter( rlstats__resource__in=self.resources.all()).exclude( code=self.source_language.code).order_by( '-rlstats__translated').distinct() def get_logo_url(self): """ Returns the image containing the mugshot for the user. The mugshot can be a uploaded image or a Gravatar. :return: ``None`` when no default image is supplied by ``PROJECT_LOGO_DEFAULT``. """ # First check for a uploaded logo image and if any return that. if self.logo: return self.logo.url # Check for a default image. elif getattr(settings, 'PROJECT_LOGO_DEFAULT', None): return os.path.join(settings.STATIC_URL, settings.PROJECT_LOGO_DEFAULT) else: return None def get_action_logs(self): """ Return actionlog entries for the given project plus the actionlogs of the hub projects, in case it's a hub. """ ids = [self.id] if self.is_hub: ids += self.outsourcing.all().values_list('id', flat=True) return LogEntry.objects.filter( content_type=ContentType.objects.get_for_model(Project), object_id__in=ids)