Exemple #1
0
class Problem(models.Model):
    underlying_problems = models.ManyToManyField('Problem', blank=True)

    affected_locations = GM2MField() #TODO: Restrict to place derivatives
    affected_resources = GM2MField() #TODO: Restrict to resource derivatives

    associated_trouble_tickets = models.ManyToManyField(
        TroubleTicket, blank=True)

    originating_system = models.CharField(max_length=100)
    # impactImportanceFactor
    # priority
    description = models.TextField()
    # firstAlert
    # category
    # responsibleParty
    # problemEscalation
    # comments
    time_raised = models.DateTimeField(auto_now_add=True)
    time_changed = models.DateTimeField(auto_now=True)
    reason = models.CharField(max_length=200)
    # ackStatus
    # clearStatus
    # activityStatus
    # impactPattterns

    def __str__(self):
        return "{}:{} at {}".format(self.originating_system, self.reason, self.time_raised)
Exemple #2
0
class Usage(models.Model):
    usage_date = models.DateTimeField()
    usage_status = models.CharField(max_length=100)
    party_roles = GM2MField(related_name="usage_party_roles")
    usage_specification = GM2MField(related_name="usage_usage_specification")
    product_prices = models.ManyToManyField(ProductPrice, blank=True)

    #TODO: place

    class Meta:
        abstract = True
Exemple #3
0
class AlarmEvent(models.Model):
    # Alarm types

    USER = '******'
    DEVICE = 'DV'
    NO_DEVICE = 'ND'

    ALARM_CHOICES = (
        (USER, 'User'),
        (DEVICE, 'Device'),
        (NO_DEVICE, 'No-Device')
    )

    alarm = models.ForeignKey(Alarm, on_delete=models.CASCADE, null=True)
    alarm_type = models.CharField(max_length=2, choices=ALARM_CHOICES, default=USER)
    created = models.DateTimeField(auto_now_add=True)
    finished = models.DateTimeField(null=True)
    device = models.ForeignKey(settings.DEVICE_MODEL, on_delete=models.CASCADE, null=True)
    variables = models.ForeignKey(settings.VAR_MODEL, on_delete=models.CASCADE, null=True)
    content_type = GM2MField(blank=True)
    description = models.CharField(max_length=255, default='description', null=True)

    def get_contents_type(self):
        return "\n".join(obj.__str__() + '|' for obj in self.content_type.all())

    def __str__(self):
        return self.alarm_type + '-' + str(self.pk)
Exemple #4
0
class Thesis(ScienceElement):
    GRADE = (
        ('S', 'Superior'),
        ('MSc', 'Master'),
        ('Dr', 'Doctorado'),
    )

    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()

    grade = models.CharField(max_length=10, choices=GRADE)
    field = models.ForeignKey(Field, on_delete=models.DO_NOTHING)
    study_center = models.ForeignKey(StudyCenter, on_delete=models.DO_NOTHING)
    start_date = models.DateField(default=django.utils.timezone.now)
    end_date = models.DateField(null=True, blank=True)
    end_date_tutor = models.DateField(null=True, blank=True)
    student = GenericForeignKey('content_type', 'object_id')
    tutors = GM2MField(Worker, ExternalPerson, related_name='thesis_tutoradas')

    @property
    def type(self):
        return 'Tesis'

    @property
    def in_process(self):
        return True if not self.end_date_tutor else False

    @property
    def degree_title(self):
        return self.grade + ' en ' + self.field.name
Exemple #5
0
class Service(models.Model):
    TIPO = (
        ('EST', 'Estatal'),
        ('COM', 'Comercial'),
        ('EXP', 'Exportación'),
    )

    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()

    start_date = models.DateField(default=django.utils.timezone.now())
    end_date = models.DateField()
    name = models.CharField(max_length=50, blank=True, null=True)
    type_of = models.CharField(max_length=20, choices=TIPO, blank=True, null=True)
    dim = models.CharField(max_length=50, blank=True, null=True)
    cost_center = models.ForeignKey(CostCenter, on_delete=models.DO_NOTHING)
    participants = GM2MField(Worker, ExternalPerson, related_name='services')
    responsible = GenericForeignKey('content_type', 'object_id')
    client = models.ForeignKey(Client, on_delete=models.CASCADE, blank=True, null=True)
    mont = models.FloatField(default=0.0)
    entity = models.ForeignKey(Entity, on_delete=models.CASCADE, null=True, blank=True)
    results = models.ManyToManyField(Result, null=True, blank=True)
    tasks = models.ManyToManyField(Task, null=True, blank=True)

    def __str__(self):
        return self.name

    @property
    def type(self):
        return 'Service'
Exemple #6
0
class MachineTag(models.Model):
    namespace = models.CharField(max_length=100, blank=True, default='')
    namespace_slug = models.SlugField(max_length=100, editable=False, default='')
    predicate = models.CharField(max_length=100, blank=True, default='')
    predicate_slug = models.SlugField(max_length=100, editable=False, default='')
    value = models.CharField(max_length=300, blank=True, default='')
    value_slug = models.SlugField(max_length=100, editable=False,  default='')
    label = models.CharField(
        max_length=600, editable=False, blank=True, default='')
    tagged = GM2MField(Link, Feed)
    objects = models.Manager()
    class Meta:
        verbose_name = 'Machine tag'
        verbose_name_plural = 'Machine tags'
        unique_together = (
            ('namespace', 'predicate', 'value')
        )
    def __str__(self):
        return '{0.namespace}:{0.predicate}={0.value}'.format(self)

    def save(self, *args, **kwargs):
        if not self.namespace_slug:
            self.namespace_slug = slugify(self.namespace)
        if not self.predicate_slug:
            self.predicate_slug = slugify(self.predicate)
        if not self.value_slug:
            self.value_slug = slugify(self.value)
        if not self.label:
            self.label = '{0.namespace_slug}:{0.predicate_slug}={0.value_slug}'.format(
                self)
        return super().save(*args, **kwargs)
Exemple #7
0
class Tribunal(models.Model):
    date = models.DateField()
    thesis = models.ForeignKey(Thesis, on_delete=models.CASCADE)
    members = GM2MField(Worker, ExternalPerson, related_name='tribunals')

    def __str__(self):
        return self.thesis.title
Exemple #8
0
class Comision(models.Model):
    creation_date = models.DateField()
    integrants = GM2MField(Worker, ExternalPerson, related_name='comisiones')

    @property
    def type(self):
        return 'Comision'

    def __str__(self):
        return 'Comision ' + str(self.pk)
Exemple #9
0
class Ponency(models.Model):
    title = models.CharField(max_length=100)
    authors = GM2MField(Worker, ExternalPerson, related_name='ponencys')

    def __str__(self):
        return self.title

    @property
    def type(self):
        return 'Ponencia'
Exemple #10
0
class Oponency(models.Model):
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()

    date = models.DateField()
    element = GenericForeignKey('content_type', 'object_id') # Articulo, Tesis, Resultado, Proyecto
    opponents = GM2MField(Worker, ExternalPerson, related_name='oponencys')

    def __str__(self):
        return self.element.title
Exemple #11
0
class TestModel(models.Model):
    name = models.CharField(max_length=200)

    test = GM2MField()

    for_inline = models.ForeignKey('self',
                                   null=True,
                                   blank=True,
                                   related_name='inline_test_models')

    def __str__(self):
        return self.name
Exemple #12
0
class Book(ScienceElement):
    isbn = models.CharField(max_length=50)
    authors = GM2MField(Worker, ExternalPerson, related_name='books')
    data_base = models.CharField(max_length=100, null=True, blank=True) # que es esto?
    pages = models.CharField(max_length=50) # cant de pages?
    pub_date = models.DateField(default=django.utils.timezone.now)
    web_url = models.URLField(null=True, blank=True)
    editorial = models.CharField(max_length=50)
    country = models.CharField(max_length=50)
    chapter = models.CharField(max_length=50) # cant de capitulos?
    total_pages = models.CharField(max_length=50) # no deberia ser entero?
    gray_literature = models.BooleanField(default=False)

    @property
    def type(self):
        return 'Libro'
Exemple #13
0
class Result(ScienceElement):
    LEVEL = (
        ('1', 'Primer Nivel'),
        ('2', 'Segundo Nivel'),
        ('3', 'Tercer Nivel'),
    )
    date = models.DateField(default=django.utils.timezone.now)
    manager_by_cfa = models.BooleanField(default=True)
    approved_by_cc = models.BooleanField(default=False)
    prize = models.ManyToManyField(Prize, null=True, blank=True)
    level = models.CharField(max_length=40, choices=LEVEL)
    integrants = GM2MField(Worker, ExternalPerson, related_name='results')

    @property
    def type(self):
        return 'Resultado'
Exemple #14
0
class Project(ScienceElement):
    LEVEL = (
        ('PP', 'Programa Priorizado'),
        ('PE', 'Proyecto Empresarial'),
        ('INF', 'Institucional ft'),
        ('IN', 'Institucional'),
    )

    TYPE = (
        ('N', 'Nacional'),
        ('I', 'Internacional'),
    )
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()

    cost_center = models.ForeignKey(CostCenter, on_delete=models.DO_NOTHING)
    program = models.ForeignKey(Program, on_delete=models.DO_NOTHING, null=True, blank=True)
    boss = GenericForeignKey('content_type', 'object_id')
    participants = GM2MField(Worker, ExternalPerson, related_name='projects')
    manager_by_cfa = models.BooleanField(default=False)
    type = models.CharField(max_length=40, choices=TYPE)
    level = models.CharField(max_length=40, choices=LEVEL, blank=True, null=True)
    aproved_date = models.DateField(default=datetime.datetime.now())
    start_date = models.DateField(default=datetime.datetime.now())
    end_plan_date = models.DateField()
    end_date = models.DateField(null=True, blank=True)
    executor_entity = models.ForeignKey(Entity, on_delete=models.DO_NOTHING, null=True, blank=True)
    description = models.CharField(max_length=500, null=True, blank=True)
    results = models.ManyToManyField(Result, null=True, blank=True)
    entity = models.ManyToManyField(Entity, related_name="entities", null=True, blank=True)
    #manager = ProyectoManager()

    @property
    def type(self):
        return 'Proyecto'

    @property
    def en_desarrollo(self):
        return True if not self.end_date else False

    @property
    def en_atraso(self):
        return True if not self.end_date and self.end_date > datetime.date.now() else False

    def for_next_year(self):
        return True if self.aproved_date.year > datetime.date.now().year else False
Exemple #15
0
class Group(ExchangeProperty):
    manager = models.ForeignKey(User, related_name='groups')
    username = models.CharField(max_length=255)
    members = models.ManyToManyField(User, related_name='+')
    delivery_members = GM2MField()
    senders_out = models.BooleanField(
        default=False,
        help_text='Delivery management for senders outside organizational unit'
    )

    tracker = FieldTracker()

    @property
    def email(self):
        return '{}@{}'.format(self.username, self.tenant.domain)

    def get_log_fields(self):
        return super(Group, self).get_log_fields() + ('username', 'email')
Exemple #16
0
class PhysicalResource(Resource):
    power_state = models.CharField(max_length=100,
                                   null=True,
                                   blank=True,
                                   choices=POWER_STATES)
    physcial_objects = GM2MField(
        related_name="objects")  #TODO: Restrict to physical_object derivatives

    place_content_type = models.ForeignKey(
        ContentType,
        null=True,
        blank=True,
        related_name="%(app_label)s_%(class)s_ownership")
    place_object_id = models.PositiveIntegerField(null=True, blank=True)
    place = GenericForeignKey('place_content_type', 'place_object_id')

    def __str__(self):
        return "%s at %s" % (self.name, self.place)
Exemple #17
0
class PartyRole(models.Model):
    valid_from = models.DateTimeField(auto_now_add=True)
    valid_to = models.DateTimeField(null=True, blank=True)

    name = models.CharField(max_length=200)
    party_content_type = models.ForeignKey(
        ContentType, related_name="%(app_label)s_%(class)s_ownership")
    party_object_id = models.PositiveIntegerField()
    party = GenericForeignKey('party_content_type', 'party_object_id')

    contact_mediums = GM2MField()

    class Meta:
        abstract = True

    @property
    def individual(self):
        if type(self.party) is Individual:
            return self.party

    @individual.setter
    def individual(self, value):
        if type(value) is Individual or value == None:
            self.party = value
        else:
            raise Exception(
                "Invalid type of party provided as individual to PartyRole: %s" % type(value))

    @property
    def organisation(self):
        if type(self.party) is Organisation:
            return self.party

    @organisation.setter
    def organisation(self, value):
        if type(value) is Organisation or value == None:
            self.party = value
        else:
            raise Exception(
                "Invalid type of party provided as organisation to PartyRole: %s" % type(value))

    def __str__(self):
        return "%s as a %s" % (self.party, self.name)
Exemple #18
0
class Reserva(models.Model):
    ESTADO_CHOICES = (
        ('P', 'Pendiente'),
        ('A', 'Aceptada'),
        ('R', 'Rechazada'),
    )
    TIPO_CHOICES = (
        ('A', 'Artículo'),
        ('E', 'Espacio'),
    )
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True)

    fh_reserva = models.DateTimeField()
    fh_ini_reserva = models.DateTimeField()
    fh_fin_reserva = models.DateTimeField()
    estado_reserva = models.CharField(max_length=50,
                                      choices=ESTADO_CHOICES,
                                      default='P')
    tipo = models.CharField(max_length=50, choices=TIPO_CHOICES)
    related = GM2MField()
Exemple #19
0
class Prestamo(models.Model):
    ESTADO_CHOICES = (
        ('V', 'Vigente'),
        ('C', 'Caducado'),
        ('P', 'Perdido'),
        ('R', 'Recibido'),
    )
    TIPO_CHOICES = (
        ('A', 'Artículo'),
        ('E', 'Espacio'),
    )
    profile = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True)

    fh_ini_prestamo = models.DateTimeField()
    fh_fin_prestamo = models.DateTimeField()
    estado_prestamo = models.CharField(max_length=50,
                                       choices=ESTADO_CHOICES,
                                       default='V')
    tipo = models.CharField(max_length=50, choices=TIPO_CHOICES)
    related = GM2MField()
Exemple #20
0
    def test_deconstruct(self):
        # this test will run on *all* testcases having no subclasses

        if self.__class__.__subclasses__():
            return skip('not an end test class')

        try:
            field = self.links.__class__._meta.get_field('related_objects')
        except AttributeError:
            return

        __, __, args, kwargs = field.deconstruct()
        new_field = GM2MField(*args, **kwargs)

        # just checking the strings output, as for an attr to attr comparison
        # we would need to run contribute_to_class
        self.assertSetEqual(set(['%s.%s' % (r.model._meta.app_label,
                                            r.model._meta.object_name)
                                 for r in field.remote_field.rels
                                 if not getattr(r, '_added', False)]),
                            set(args))
Exemple #21
0
class UserProfile(models.Model):
    user = models.OneToOneField(User)
    sex = models.CharField(null=True,
                           max_length=1,
                           default=None,
                           choices=SEX,
                           verbose_name=u'Are you male or female?')
    city = models.CharField(null=True, default=None, max_length=100)
    timezone = models.CharField(null=True, default=None, max_length=100)
    avatar = models.ImageField(
        upload_to='imagesandvideos/imageorvideos/avatars',
        default='avatars/no_avatar.jpg',
        blank=True,
        null=True)
    saved_items = GM2MField()
    private_saved_items = models.BooleanField(default=False)
    follows = models.ManyToManyField('self',
                                     related_name='followers',
                                     symmetrical=False)

    def __unicode__(self):
        return u'%s' % self.user
Exemple #22
0
class Article(ScienceElement):
    LEVEL = (
        ('I',  'Grupo I'),
        ('II', 'Grupo II'),
        ('III', 'Grupo III'),
        ('IV', 'Grupo IV'),
    )

    PARTICIPATION = (
        ('AP', 'Autor Principal'),
        ('OA', 'Otro Autor'),
    )

    STATUS = (
        ('1', 'Enviado'),
        ('2', 'En revision'),
        ('3', 'Aceptado'),
        ('4', 'Publicado'),
    )

    doi = models.CharField(max_length=50, unique=True)
    authors = GM2MField(Worker, ExternalPerson, related_name='articles')
    database = models.CharField(max_length=100, null=True, blank=True)
    pages = models.CharField(max_length=50)
    pub_date = models.DateField(default=django.utils.timezone.now, null=True)
    web_url = models.URLField(null=True, blank=True)
    magazine = models.CharField(max_length=200, null=True, blank=True)
    issn = models.CharField(max_length=50, unique=True, null=True, blank=True)
    volume = models.PositiveSmallIntegerField(null=True, blank=True)
    number = models.PositiveSmallIntegerField(null=True, blank=True)
    impact_level = models.CharField(max_length=50, choices=LEVEL, null=True, blank=True)
    participation = models.CharField(max_length=50, choices=PARTICIPATION)
    indexed = models.BooleanField(default=False)
    refereed = models.BooleanField(default=False)
    gray_literature = models.BooleanField(default=False)

    @property
    def type(self):
        return 'Artículo'
Exemple #23
0
class QuickBlock(SmartModel):
    """
    A QuickBlock is just a block of content, organized by type and priority.  All fields are optional
    letting you use them for different things.
    """
    quickblock_type = models.ForeignKey(
        QuickBlockType,
        verbose_name="Content Type",
        help_text="The category, or type for this content block")

    title = models.CharField(
        max_length=255,
        blank=True,
        null=True,
        help_text="The title for this block of content, optional")
    summary = models.TextField(
        blank=True,
        null=True,
        help_text="The summary for this item, should be short")
    content = models.TextField(
        blank=True,
        null=True,
        help_text="The body of text for this content block, optional")
    image = models.ImageField(
        blank=True,
        null=True,
        upload_to='quickblocks',
        help_text=
        "Any image that should be displayed with this content block, optional")
    color = models.CharField(
        blank=True,
        null=True,
        max_length=16,
        help_text=
        "A background color to use for the image, in the format: #rrggbb")
    link = models.CharField(
        blank=True,
        null=True,
        max_length=255,
        help_text=
        "Any link that should be associated with this content block, optional")
    video_id = models.CharField(
        blank=True,
        null=True,
        max_length=255,
        help_text=
        "The id of the YouTube video that should be linked to this item")
    tags = models.CharField(
        blank=True,
        null=True,
        max_length=255,
        help_text=
        "Any tags for this content block, separated by spaces, can be used to do more advanced filtering, optional"
    )
    priority = models.IntegerField(
        default=0,
        help_text=
        "The priority for this block, higher priority blocks come first")
    items = GM2MField(related_name='stories',
                      help_text="The items this story is all about")

    def space_tags(self):
        """
        If we have tags set, then adds spaces before and after to allow for SQL querying for them.
        """
        if self.tags and self.tags.strip():
            self.tags = " " + self.tags.strip().lower() + " "

    def sorted_images(self):
        return self.images.filter(is_active=True).order_by('-priority')

    def __unicode__(self):
        return self.title
Exemple #24
0
class Export(AbstractExport):
    STATUS_PENDING = 'PENDING'
    STATUS_PROCESSING = 'PROCESSING'
    STATUS_FAILED = 'FAILED'
    STATUS_FINISHED = 'FINISHED'
    STATUSES = [(STATUS_PENDING, _('pending')),
                (STATUS_PROCESSING, _('processing')),
                (STATUS_FAILED, _('failed')), (STATUS_FINISHED, _('finished'))]
    status = models.CharField(_('status'),
                              choices=STATUSES,
                              max_length=10,
                              default=STATUS_PENDING)
    items = GM2MField(*related_models, related_name='exports_where_item')
    total = models.PositiveIntegerField(_('total items'), default=0)
    emails = ArrayField(
        verbose_name=_('emails'),
        base_field=models.EmailField(),
        default=list,
    )
    objects = ExportQuerySet.as_manager()
    history = AuditlogHistoryField()

    class Meta:
        verbose_name = _('export')
        verbose_name_plural = _('exports')
        ordering = ('created', )
        default_permissions = settings.DEFAULT_PERMISSIONS

    def __str__(self):
        model = self.content_type.model_class()
        name = model._meta.verbose_name_plural if model else self.content_type.model
        return '{} #{} ({})'.format(_('Export'), self.pk, name)

    def _get_base_url(self):
        app_label = self.get_app_label()
        url = reverse(f'{app_label}:{self.content_type.model}_list')
        return url

    def get_items_url(self):
        return f'{self._get_base_url()}?export={self.pk}'

    def get_absolute_url(self):
        return f'{self._get_base_url()}?{self.query_string}'

    def get_app_label(self):
        if self.context in [self.CONTEXT_LIST, self.CONTEXT_DETAIL]:
            app_label = self.content_type.app_label if self.content_type.app_label != 'invoicing' else 'billing'
        else:
            module = exporters_module_mapping[self.model_class._meta.label][
                self.context]
            app_label = module.split('.')[-2]

        return app_label

    def send_mail(self, language, filename=None):
        export_class_name = f'{self.__class__.__module__}.{self.__class__.__name__}'
        jobs.mail_export.delay(self.pk, export_class_name, language, filename)

    @property
    def object_list(self):
        ids = list(self.items.all().values_list('gm2m_pk', flat=True))
        # ids = list(map(int, ids))
        model = self.content_type.model_class()
        return model.objects.filter(id__in=ids)

    @property
    def exporter_params(self):
        return {
            'params': self.params,
            'items': self.
            object_list,  # this is required as we want to send identically same export (not currently available filtered data)
            'user': self.creator,
            'recipients': self.recipients.all(),
            'selected_fields': self.fields
        }
Exemple #25
0
class Character(models.Model):
    """
    This is the information for a character.

    ***NOTE: This is the specific model a Member will be interacting with the most.***
    """

    username = models.ForeignKey('accounts.Member', related_name='characters', editable=False)

    accessed = models.DateTimeField(auto_now=True,)

    # Flair
    char_name = models.CharField(max_length=1024, blank=True, null=True,)
    description = models.TextField(blank=True, null=True,)

    portrait = models.ImageField(blank=True, null=True,)
    char_age = models.SmallIntegerField(blank=True, null=True,)
    char_height = models.SmallIntegerField(blank=True, null=True,)
    char_weight = models.SmallIntegerField(blank=True, null=True,)
    char_skin_color = models.CharField(max_length=128, blank=True, null=True,)
    char_hair_color = models.CharField(max_length=128, blank=True, null=True,)
    char_eye_color = models.CharField(max_length=128, blank=True, null=True,)

    personality = models.TextField(blank=True, null=True,)
    ideals = models.TextField(blank=True, null=True,)
    bonds = models.TextField(blank=True, null=True,)
    flaws = models.TextField(blank=True, null=True,)

    allies = models.CharField(max_length=512, blank=True, null=True,)
    organizations = models.CharField(max_length=512, blank=True, null=True,)

    # General traits such as languages.
    char_traits = GM2MField()

    # Basics
    char_classes = models.ManyToManyField('rules.Class', related_name='character_classes', through='ClassLevel', blank=True,)
    char_prestige_classes = models.ManyToManyField('rules.PrestigeClass', related_name='character_prestiges', blank=True,)
    char_race = models.ForeignKey('rules.Race', related_name='character_races', blank=True, null=True,)
    char_subrace = models.ForeignKey('rules.Subrace', related_name='character_subraces', blank=True, null=True)
    char_background = models.ForeignKey('rules.Background', related_name='character_backgrounds', blank=True, null=True)
    alignment = models.ForeignKey('rules.Alignment', related_name='character_alignments', blank=True, null=True,)
    char_xp = models.IntegerField(default=0, blank=True, null=True,)

    # Ability Scores
    STR_score = IntegerMinMaxField(min_value=1, max_value=20, blank=True, null=True,)
    DEX_score = IntegerMinMaxField(min_value=1, max_value=20, blank=True, null=True,)
    CON_score = IntegerMinMaxField(min_value=1, max_value=20, blank=True, null=True,)
    INT_score = IntegerMinMaxField(min_value=1, max_value=20, blank=True, null=True,)
    WIS_score = IntegerMinMaxField(min_value=1, max_value=20, blank=True, null=True,)
    CHA_score = IntegerMinMaxField(min_value=1, max_value=20, blank=True, null=True,)

    # Saving Throws
    STR_saving_throw = models.BooleanField(default=False)
    DEX_saving_throw = models.BooleanField(default=False)
    CON_saving_throw = models.BooleanField(default=False)
    INT_saving_throw = models.BooleanField(default=False)
    WIS_saving_throw = models.BooleanField(default=False)
    CHA_saving_throw = models.BooleanField(default=False)

    # Actions >> May not need to use if just pulling through races and etc.
    features = models.ManyToManyField('rules.Feature', related_name='character_features', blank=True,)

    # Combat
    conditions = models.ManyToManyField('rules.Condition', related_name='character_conditions', blank=True,)
    death_fails = models.SmallIntegerField(default=0)
    death_successes = models.SmallIntegerField(default=0)
    max_health = models.SmallIntegerField(default=0)
    current_health = models.SmallIntegerField(default=0)
    temp_addtl_hp = models.SmallIntegerField(default=0)
    hit_dice_current = models.SmallIntegerField(default=1)
    speed = models.SmallIntegerField(default=30)
    inspiration = models.SmallIntegerField(blank=True, null=True,)

    # Spells
    spell_casting = models.BooleanField(default=False)
    spell_book = models.ManyToManyField('spells.Spell', related_name='character_spells', through='SpellsReady', blank=True,)
    spell_slots_1_current = models.SmallIntegerField(blank=True, null=True,)
    spell_slots_2_current = models.SmallIntegerField(blank=True, null=True,)
    spell_slots_3_current = models.SmallIntegerField(blank=True, null=True,)
    spell_slots_4_current = models.SmallIntegerField(blank=True, null=True,)
    spell_slots_5_current = models.SmallIntegerField(blank=True, null=True,)
    spell_slots_6_current = models.SmallIntegerField(blank=True, null=True,)
    spell_slots_7_current = models.SmallIntegerField(blank=True, null=True,)
    spell_slots_8_current = models.SmallIntegerField(blank=True, null=True,)
    spell_slots_9_current = models.SmallIntegerField(blank=True, null=True,)

    spell_slots_1_maximum = models.SmallIntegerField(blank=True, null=True, )
    spell_slots_2_maximum = models.SmallIntegerField(blank=True, null=True, )
    spell_slots_3_maximum = models.SmallIntegerField(blank=True, null=True, )
    spell_slots_4_maximum = models.SmallIntegerField(blank=True, null=True, )
    spell_slots_5_maximum = models.SmallIntegerField(blank=True, null=True, )
    spell_slots_6_maximum = models.SmallIntegerField(blank=True, null=True, )
    spell_slots_7_maximum = models.SmallIntegerField(blank=True, null=True, )
    spell_slots_8_maximum = models.SmallIntegerField(blank=True, null=True, )
    spell_slots_9_maximum = models.SmallIntegerField(blank=True, null=True, )

    # Special Point Tracking (Rage, Inspiration, Etc.): # TODO: Add field to check which feature they have for points and base tracking off of that.
    has_point_tracking = models.BooleanField(default=False)
    max_points = models.SmallIntegerField(blank=True, null=True)
    current_points = models.SmallIntegerField(blank=True, null=True)

    # Inventory
    tools_inv = models.ManyToManyField('equipment.Tool', related_name='character_tools_inv', blank=True,)
    items_inv = models.ManyToManyField('equipment.Item', related_name='character_items_inv', blank=True,)
    armor_inv = models.ManyToManyField('equipment.Armor', related_name='character_armor_inv', blank=True,)
    weapons_inv = models.ManyToManyField('equipment.Weapon', related_name='character_weapons_inv', blank=True,)
    char_copper = models.IntegerField(blank=True, null=True)
    char_silver = models.IntegerField(blank=True, null=True)
    char_gold = models.IntegerField(blank=True, null=True)
    char_platinum = models.IntegerField(blank=True, null=True)

    slug = models.SlugField(editable=False, blank=True, null=False)

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.char_name)
        super().save(*args, **kwargs)

    def get_prof_bonus(self):
        """
        Gets the proficiency bonus for a character based on their character level.
        :return: int()
        """

        return int(math.ceil(self.get_char_level() / 4) + 1)

    def get_ability_bonus(self, ability):
        """
        Gets the bonus for a given ability score.
        :return: int()
        """

        score_conversion = {
            'STR': self.STR_score,
            'DEX': self.DEX_score,
            'CON': self.CON_score,
            'INT': self.INT_score,
            'WIS': self.WIS_score,
            'CHA': self.CHA_score,
        }

        return (score_conversion[ability] - 10) // 2

    def get_passive_score(self, ability):
        """
        Gets the passive check for a given ability score.
        :return: int()
        """

        return self.get_ability_bonus(ability) + 10

    def get_char_level(self):
        """
        Adds all class levels to get the character level.

        :return: an int()
        """

        class_levels = self.classlevels.all()

        level = 0

        for class_level in class_levels:
            level += class_level.class_level

        return level

    def get_saving_throw_bonus(self, ability):
        """
        Checks if character is proficient in saving throw and returns amount of bonus either way.
        :return: int()
        """

        bonus = 0

        score_conversion = {
            'STR': self.STR_saving_throw,
            'DEX': self.DEX_saving_throw,
            'CON': self.CON_saving_throw,
            'INT': self.INT_saving_throw,
            'WIS': self.WIS_saving_throw,
            'CHA': self.CHA_saving_throw,
        }

        if score_conversion[ability]:
            bonus += self.get_prof_bonus()
            bonus += self.get_ability_bonus(ability)
        else:
            bonus += self.get_ability_bonus(ability)

        return bonus

    def get_initiative_bonus(self):
        """
        Returns the total initiative bonus for a character.
        :return: int()
        """
        from rules.models import Feature

        initiative = 0
        alert = Feature.objects.get(name__iexact='Alert')
        if alert in self.features.all():
            initiative += 4 + self.get_ability_bonus('DEX')

        else:
            initiative += self.get_ability_bonus('DEX')

        return initiative

    def get_armor_class(self):
        """
        Returns the total armor class for a character.
        :return: int()
        """

        armors = self.armor_inv.all()

        armor_class = 0

        if len(armors) > 0:
            for armor in armors:
                armor_class += armor.base_armor_class
                if armor.dexterity_modifier is True and armor.dexterity_modifier_max == -1:
                        armor_class += self.get_ability_bonus('DEX')
                elif armor.dexterity_modifier == True:
                    if self.get_ability_bonus('DEX') >= 2:
                        armor_class += 2
                    else:
                        armor_class += self.get_ability_bonus('DEX')
        else:
            armor_class += 10 + self.get_ability_bonus('DEX')

        return armor_class

    def __str__(self):
        return self.char_name
Exemple #26
0
class Group(models.Model):

    class Meta:
        app_label = 'multiple_m2m_mig'

    people = GM2MField()
Exemple #27
0
class Action(models.Model):
    """
    An action initiated by an actor and described by a verb.
    An action may have:
    - target objects (affected by the action)
    - related objects (related to the action)
    """

    actor_ct = models.ForeignKey(ContentType,
                                 on_delete=models.CASCADE,
                                 null=True)
    actor_pk = models.CharField(max_length=255, null=True)
    #: The actor, can be anything
    actor = GenericForeignKey('actor_ct', 'actor_pk')

    # using hidden relations so that the related objects' model classes are
    # not cluttered. The reverse relations are available through the
    # RelatedModel's ``actions`` attribute (as a manager) and its methods

    #: The target objects, can contain several objects of different types
    targets = GM2MField(pk_maxlength=PK_MAXLENGTH,
                        related_name='actions_as_target+')
    #: The related objects, can also contain several objects of different types
    related = GM2MField(pk_maxlength=PK_MAXLENGTH,
                        related_name='actions_as_related+')

    #: The action's verb or identifier
    verb = models.CharField(max_length=255)
    #: The action's level
    level = models.PositiveSmallIntegerField(default=DEFAULT_LEVEL)
    #: Data associated to the action (stored in a JSON field)
    data = JSONField(default={})

    #: The timestamp of the action, from which actions are ordered
    timestamp = models.DateTimeField(default=now)

    # default manager
    objects = DefaultActionManager()

    class Meta:
        ordering = ('-timestamp', )

    def __init__(self, *args, **kwargs):
        super(Action, self).__init__(*args, **kwargs)
        self._unread_in_cache = {}
        self.handler = ActionHandlerMetaclass.create_handler(self)

    def _render(self, context=None):
        """
        Renders the action from a template
        """
        return self.handler.render(context)

    def is_unread_for(self, user):
        """
        Returns True if the action is unread for that user
        """
        if self in user.unread_actions.all():
            return True
        return False

    def mark_read_for(self, user, force=False):
        """
        Attempts to mark the action as read using the tracker's mark_read
        method. Returns True if the action was unread before
        To mark several actions as read, prefer the classmethod
        bulk_mark_read_for
        """
        return user.unread_actions.mark_read(self, force=force)

    def render(self, user=None, context=None):
        """
        Renders the action, attempting to mark it as read if user is not None
        Returns a rendered string
        """
        if not context:
            context = {}
        if user:
            context['user'] = user
        else:
            user = context.get('user', None)
        if user and 'unread' not in context:
            context['unread'] = self.mark_read_for(user)
        return self._render(context)

    @classmethod
    def bulk_is_unread_for(cls, user, actions):
        """
        Does not bring any performance gains over Action.is_read method, exists
        for the sake of consistency with bulk_mark_read_for and bulk_render
        """
        unread = []
        for a in actions:
            if a.level >= READABLE_LEVEL:
                unread.append(a.is_unread_for(user))
        return unread

    @classmethod
    def bulk_mark_read_for(cls, user, actions, force=False):
        """
        Marks an iterable of actions as read for the given user
        It is more efficient than calling the mark_read method on each action,
        especially if many actions belong to only a few followers

        Returns a list ``l`` of booleans. If ``actions[i]`` was unread before
        the call to bulk_mark_read_for, ``l[i]`` is True
        """

        unread_actions = user.unread_actions.all()

        unread = []
        to_mark_read = []
        for a in actions:
            is_unread = a in unread_actions
            unread.append(is_unread)
            if is_unread:
                to_mark_read.append(a)

        user.unread_actions.bulk_mark_read(to_mark_read, force)

        return unread

    @classmethod
    def bulk_render(cls, actions=(), user=None, context=None):
        """
        Renders an iterable actions, returning a list of rendered
        strings in the same order as ``actions``

        If ``user`` is provided, the class method will attempt to mark the
        actions as read for the user using Action.mark_read above
        """
        if not context:
            context = {}
        if user:
            context['user'] = user
        else:
            user = context.get('user', None)

        unread = context.pop('unread', None)
        if unread is None and user:
            unread = cls.bulk_mark_read_for(user, actions)
        else:
            # no need to attempt using count(), if actions is a queryset it
            # needs to be evaluated next anyway
            unread = [unread] * len(actions)

        rendered = []
        for a, urd in zip(actions, unread):
            rendered.append(a._render(dict(context, unread=urd)))
        return rendered