class Article(WeChatModel): material = m.ForeignKey(Material, related_name="articles", on_delete=m.CASCADE) title = m.CharField(_("title"), max_length=64) thumb_media_id = m.CharField(_("thumb_media_id"), max_length=64) show_cover_pic = m.BooleanField(_("show cover"), default=True) author = m.CharField(_("author"), max_length=24, blank=True, null=True, default="") digest = m.CharField(_("digest"), max_length=256, blank=True, null=True, default="") content = m.TextField(_("content")) url = m.CharField(_("url"), max_length=256) content_source_url = m.CharField(_("content source url"), max_length=256) need_open_comment = m.NullBooleanField(_("need open comment"), default=None) only_fans_can_comment = m.NullBooleanField(_("only fans can comment"), default=None) index = m.PositiveSmallIntegerField(_("index")) _thumb_url = m.CharField(db_column="thumb_url", max_length=256, null=True, default=None) synced_at = m.DateTimeField(_("synchronized at"), auto_now_add=True) class Meta(object): verbose_name = _("article") verbose_name_plural = _("articles") unique_together = (("material", "index"), ) ordering = ("material", "index") @property def app(self): return self.material and self.material.app @property def app_id(self): return self.material and self.material.app_id @property def thumb_url(self): if self._thumb_url is None and self.thumb_media_id: # 不存在url时通过thumb_media_id同步 image = Material.objects.filter( app=self.app, media_id=self.thumb_media_id).first() self._thumb_url = image and image.url self._thumb_url is not None and self.save() return self._thumb_url @thumb_url.setter def thumb_url(self, value): self._thumb_url = value @classmethod @appmethod("sync_articles") def sync(cls, app, id=None): if id: return Material.sync(app, id, Material.Type.NEWS) else: with transaction.atomic(): return Material.sync_type(app, Material.Type.NEWS) def to_json(self): return dict( title=self.title, thumb_media_id=self.thumb_media_id, show_cover_pic=1 if self.show_cover_pic else 0, need_open_comment=1 if self.need_open_comment else 0, only_fans_can_comment=1 if self.only_fans_can_comment else 0, author=self.author, digest=self.digest, content=self.content, url=self.url, content_source_url=self.content_source_url) def __str__(self): return "{0}".format(self.title)
class Support(Model): enabled = models.NullBooleanField( verbose_name=_("Enable automatic support alerts to iXsystems"), default=False, null=True, ) name = models.CharField( verbose_name=_('Name of Primary Contact'), max_length=200, blank=True, ) title = models.CharField( verbose_name=_('Title'), max_length=200, blank=True, ) email = models.EmailField( verbose_name=_('E-mail'), max_length=200, blank=True, ) phone = models.CharField( verbose_name=_('Phone'), max_length=200, blank=True, ) secondary_name = models.CharField( verbose_name=_('Name of Secondary Contact'), max_length=200, blank=True, ) secondary_title = models.CharField( verbose_name=_('Secondary Title'), max_length=200, blank=True, ) secondary_email = models.EmailField( verbose_name=_('Secondary E-mail'), max_length=200, blank=True, ) secondary_phone = models.CharField( verbose_name=_('Secondary Phone'), max_length=200, blank=True, ) class Meta: verbose_name = _("Proactive Support") class FreeAdmin: deletable = False @classmethod def is_available(cls, support=None): """ Checks whether the Proactive Support tab should be shown. It should only be for TrueNAS and Siver/Gold Customers. Returns: tuple(bool, Support instance) """ if notifier().is_freenas(): return False, support if support is None: try: support = cls.objects.order_by('-id')[0] except IndexError: support = cls.objects.create() license, error = get_license() if license is None: return False, support if license.contract_type in ( ContractType.silver.value, ContractType.gold.value, ): return True, support return False, support def is_enabled(self): """ Returns if the proactive support is enabled. This means if certain failures should be reported to iXsystems. Returns: bool """ return self.is_available(support=self)[0] and self.enabled
class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='AuthorProfile', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('slug', models.SlugField(blank=True)), ('linked_in_url', models.URLField(null=True, blank=True)), ('twitter_url', models.URLField(null=True, blank=True)), ('watercolor_image', models.ImageField(null=True, upload_to=b'biographies/', blank=True)), ('small_image', models.ImageField(null=True, upload_to=b'biographies/', blank=True)), ('biography', models.TextField( help_text= b'The description will be added to the Biography page', null=True, verbose_name=b'Biography Content', blank=True)), ('user', models.OneToOneField(related_name='author_profile', to=settings.AUTH_USER_MODEL)), ], options={}, bases=(models.Model, ), ), migrations.CreateModel( name='CampaignsSignup', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('email', models.EmailField(unique=True, max_length=75)), ('telephone', models.CharField(max_length=100, null=True, blank=True)), ('alt_telephone', models.CharField(max_length=100, null=True, blank=True)), ('name', models.CharField(max_length=100, null=True, blank=True)), ('newsletter', models.NullBooleanField(default=True)), ('created_date', models.DateTimeField(auto_now_add=True)), ('last_updated', models.DateTimeField(auto_now=True)), ('is_synched', models.NullBooleanField(default=True)), ('best_call_time', models.CharField(max_length=10, null=True, blank=True)), ('is_client', models.NullBooleanField(default=False)), ('is_fake', models.BooleanField(default=False)), ('source', models.CharField(max_length=100, null=True, blank=True)), ], options={ 'ordering': ['created_date'], }, bases=(models.Model, ), ), migrations.CreateModel( name='CarouselTab', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('title', models.CharField(max_length=500)), ('description', models.CharField(max_length=500)), ('order', models.IntegerField()), ('media', models.ImageField(null=True, upload_to=b'carousel/', blank=True)), ('cta_link_title', models.CharField(max_length=100, null=True, blank=True)), ('cta_link', models.URLField(null=True, blank=True)), ('created_date', models.DateTimeField(auto_now_add=True)), ('last_updated', models.DateTimeField(auto_now=True)), ], options={}, bases=(models.Model, ), ), migrations.CreateModel( name='HealthcheckSignup', fields=[ ('uuid', django_extensions.db.fields.UUIDField(primary_key=True, serialize=False, editable=False, blank=True, name=b'uuid')), ('first_name', models.CharField(max_length=20)), ('last_name', models.CharField(max_length=50)), ('email', models.EmailField(max_length=75)), ('telephone', models.CharField( unique=True, max_length=20, error_messages={ b'unique': b'A healthcheck request with this telephone number already exists.' })), ('date_requested', models.DateTimeField(auto_now_add=True)), ], options={}, bases=(models.Model, ), ), migrations.CreateModel( name='NewsletterSignup', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('email', models.EmailField(max_length=75)), ('created_date', models.DateTimeField(auto_now_add=True)), ('last_updated', models.DateTimeField(auto_now=True)), ('is_synched', models.NullBooleanField(default=False)), ('activation_key', models.CharField(max_length=40, null=True)), ('is_activated', models.BooleanField(default=True)), ('source', models.CharField(max_length=100, null=True, blank=True)), ], options={}, bases=(models.Model, ), ), migrations.CreateModel( name='Profile', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('dob', models.DateField(null=True, blank=True)), ('telephone', models.CharField(max_length=250, null=True, blank=True)), ('salutation', models.CharField(max_length=10)), ('postcode', models.CharField(max_length=10, null=True, blank=True)), ('newsletter', models.NullBooleanField(default=False)), ('ratealerts', models.NullBooleanField(default=False)), ('created_date', models.DateTimeField(auto_now_add=True, null=True)), ('last_updated', models.DateTimeField(auto_now=True, null=True)), ('is_synched', models.NullBooleanField( default=False, help_text= b'Signifies if the user details have been synced with the SalesForce system' )), ('ip_address', models.CharField(max_length=100, null=True, blank=True)), ('source', models.CharField(max_length=100, null=True, blank=True)), ('skeleton_user', models.NullBooleanField( default=False, help_text= b'Whether they have been created from the sync or not')), ('filled_in_name', models.BooleanField(default=True)), ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)), ], options={ 'permissions': (('change_sccode', 'Can update SC codes for multiple accounts'), ('add_product', 'Can add a product to a customers portfolio'), ('change_user_portfolio', 'Can change a users portfolio'), ('change_user_activation', 'Can change a users activation status'), ('change_user_email', 'Can change a users email address'), ('add_concierge_client', 'Can add a new concierge client'), ('change_user_password', 'Can change a users password'), ('change_user_subscriptions', 'Can change a users subscriptions'), ('change_user_sync', 'Can change a users sync status')), }, bases=(models.Model, ), ), migrations.CreateModel( name='RateAlertsSignup', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('email', models.EmailField(max_length=75)), ('created_date', models.DateTimeField(auto_now_add=True)), ('last_updated', models.DateTimeField(auto_now=True)), ('is_synched', models.NullBooleanField(default=False)), ('activation_key', models.CharField(max_length=40, null=True)), ('is_activated', models.BooleanField(default=True)), ('source', models.CharField(max_length=100, null=True, blank=True)), ], options={}, bases=(models.Model, ), ), migrations.CreateModel( name='Rates', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('boe_rate', models.DecimalField(max_digits=4, decimal_places=2)), ('inflation_rate', models.DecimalField(max_digits=4, decimal_places=2)), ('created_date', models.DateTimeField(auto_now_add=True)), ('last_updated', models.DateTimeField(auto_now=True)), ], options={ 'verbose_name_plural': 'Rates', }, bases=(models.Model, ), ), migrations.CreateModel( name='Referrer', fields=[ ('uuid', django_extensions.db.fields.UUIDField(primary_key=True, serialize=False, editable=False, blank=True, name=b'uuid')), ('name', models.TextField()), ], options={}, bases=(models.Model, ), ), migrations.CreateModel( name='ReminderSignup', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('email', models.EmailField(max_length=75)), ('created_date', models.DateTimeField(auto_now_add=True)), ('last_updated', models.DateTimeField(auto_now=True)), ('is_synched', models.NullBooleanField(default=False)), ('healthcheck', models.NullBooleanField(default=False)), ('bestbuys', models.NullBooleanField(default=False)), ], options={}, bases=(models.Model, ), ), migrations.CreateModel( name='Tweet', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('title', models.CharField(max_length=255)), ('summary', models.CharField(max_length=255)), ('created_date', models.DateTimeField(auto_now_add=True)), ('last_updated', models.DateTimeField(auto_now=True)), ], options={ 'get_latest_by': 'last_updated', }, bases=(models.Model, ), ), migrations.CreateModel( name='UserNext', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('uuid', models.CharField(max_length=255, null=True, blank=True)), ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)), ], options={}, bases=(models.Model, ), ), migrations.CreateModel( name='UserReferral', fields=[ ('uuid', django_extensions.db.fields.UUIDField(primary_key=True, serialize=False, editable=False, blank=True, name=b'uuid')), ('referral_action', models.CharField( default=b'unknown', max_length=30, choices=[ (b'unknown', b'User Performed An Unknown Paid For Action'), (b'signup', b'User Signed Up'), (b'rate_tracker', b'User Subscribed To RateTracker'), (b'rate_tracker_used', b'User has used RateTracker'), (b'rate_alerts', b'User Subscribed To Rate Alerts'), (b'newsletter', b'User Subscribed To Newsletter'), (b'savers_priority_list', b'User Subscribed To The Savers Priority List'), (b'seven_pitfalls', b'User Signed Up Via Seven Pitfalls To Larger Savers' ), (b'petition', b'User Subscribed To The Petition'), (b'concierge_enquiry', b'User Enquired About Concierge'), (b'concierge_client', b'User Signed Up To Concierge'), (b'recurring_weekly_best_buys', b'User Signed Up For Recurring Best Buys - Weekly'), (b'recurring_monthly_best_buys', b'User Signed Up For Recurring Best Buys - Monthly'), (b'fifty_pound_challenge', b'User Signed Up For The \xc2\xa350 Challenge'), (b'the_biggest_mistake', b'User Signed Up For The Biggest Mistake'), (b'the_value_of_advice', b'User Signed Up For The Value Of Advice'), (b'tpo_referral', b'User was referred to TPO'), (b'bj_referral', b'User was referred to Beckford James') ])), ('referral_date', models.DateTimeField(auto_now_add=True)), ('referral_paid', models.BooleanField(default=False)), ('referral_paid_date', models.DateTimeField(null=True)), ('referrer', models.ForeignKey(to='common.Referrer', null=True)), ('referrer_from', models.ForeignKey(related_name='referrerfrom', to='common.Referrer', null=True)), ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), ], options={ 'ordering': ('referral_date', ), }, bases=(models.Model, ), ), migrations.CreateModel( name='UUIDNext', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('uuid', models.CharField(unique=True, max_length=255)), ('params', models.CharField(max_length=500, null=True, blank=True)), ('next', models.CharField(max_length=50)), ], options={}, bases=(models.Model, ), ), migrations.AlterUniqueTogether( name='userreferral', unique_together=set([('user', 'referral_action')]), ), ]
class CertificateGenerationCourseSetting(TimeStampedModel): """ Enable or disable certificate generation for a particular course. In general, we should only enable self-generated certificates for a course once we successfully generate example certificates for the course. This is enforced in the UI layer, but not in the data layer. .. no_pii: """ course_key = CourseKeyField(max_length=255, db_index=True) self_generation_enabled = models.BooleanField( default=False, help_text=( u"Allow students to generate their own certificates for the course. " u"Enabling this does NOT affect usage of the management command used " u"for batch certificate generation." ) ) language_specific_templates_enabled = models.BooleanField( default=False, help_text=( u"Render translated certificates rather than using the platform's " u"default language. Available translations are controlled by the " u"certificate template." ) ) include_hours_of_effort = models.NullBooleanField( default=None, help_text=( u"Display estimated time to complete the course, which is equal to the maximum hours of effort per week " u"times the length of the course in weeks. This attribute will only be displayed in a certificate when the " u"attributes 'Weeks to complete' and 'Max effort' have been provided for the course run and its certificate " # lint-amnesty, pylint: disable=line-too-long u"template includes Hours of Effort." ) ) class Meta(object): get_latest_by = 'created' app_label = "certificates" @classmethod def get(cls, course_key): """ Retrieve certificate generation settings for a course. Arguments: course_key (CourseKey): The identifier for the course. Returns: CertificateGenerationCourseSetting """ try: latest = cls.objects.filter(course_key=course_key).latest() except cls.DoesNotExist: return None else: return latest @classmethod def is_self_generation_enabled_for_course(cls, course_key): """Check whether self-generated certificates are enabled for a course. Arguments: course_key (CourseKey): The identifier for the course. Returns: boolean """ try: latest = cls.objects.filter(course_key=course_key).latest() except cls.DoesNotExist: return False else: return latest.self_generation_enabled @classmethod def set_self_generation_enabled_for_course(cls, course_key, is_enabled): """Enable or disable self-generated certificates for a course. Arguments: course_key (CourseKey): The identifier for the course. is_enabled (boolean): Whether to enable or disable self-generated certificates. """ default = { 'self_generation_enabled': is_enabled } CertificateGenerationCourseSetting.objects.update_or_create( course_key=course_key, defaults=default )
class NullBooleanData(models.Model): data = models.NullBooleanField(null=True)
class Migration(migrations.Migration): dependencies = [] operations = [ migrations.CreateModel( name='Category', fields=[ ('id', models.BigIntegerField(help_text='\u54c1\u7c7bID', serialize=False, primary_key=True)), ('pid', models.BigIntegerField( help_text='\u54c1\u7c7b\u7236\u8282\u70b9', null=True, blank=True)), ('name', models.CharField(help_text='\u54c1\u7c7b\u540d', max_length=256)), ('grade', models.IntegerField(help_text='\u7c7b\u76ee', null=True, blank=True)), ('is_leaf', models.NullBooleanField( help_text='\u662f\u5426\u53f6\u8282\u70b9')), ('leaf_ids', models.CharField( help_text= '\u6240\u6709\u53f6\u5b50\u8282\u70b9, \u4e0d\u5305\u542b\u81ea\u5df1', max_length=512, null=True)), ('sub_category_ids', models.CharField( help_text= '\u53f6\u5b50\u8282\u70b9\u7684\u5b50\u54c1\u7c7bID', max_length=4000, null=True, blank=True)), ('create_time', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', null=True, blank=True)), ('update_time', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', null=True, blank=True)), ], options={ 'db_table': 'category', }, ), migrations.CreateModel( name='Industry', fields=[ ('id', models.BigIntegerField(help_text='\u884c\u4e1aID', serialize=False, primary_key=True)), ('name', models.CharField(help_text='\u884c\u4e1a\u540d', max_length=256)), ('db_name', models.CharField( help_text= '\u6570\u636e\u5e93\u4e2d\u4f7f\u7528\u7684\u8868\u524d\u7f00', max_length=256)), ('create_time', models.DateTimeField(help_text='\u521b\u5efa\u65f6\u95f4', null=True, blank=True)), ('update_time', models.DateTimeField(help_text='\u66f4\u65b0\u65f6\u95f4', null=True, blank=True)), ('query_type', models.CharField( help_text='y=\u6309\u5e74, m=\u6309\u6708, d=\u6309\u5929', max_length=256)), ('start_date', models.DateField(help_text='hive\u8868min(daterange)')), ('end_date', models.DateField(help_text='hive\u8868max(daterange)')), ], options={ 'db_table': 'industry', }, ), migrations.AddField( model_name='category', name='industry', field=models.ForeignKey( on_delete=django.db.models.deletion.DO_NOTHING, to='dmreport.Industry', help_text='\u884c\u4e1aID'), ), ]
class ResearchProject(models.Model): """ Research projects are entities for grouping collections (and by that resources) for future processing. Access to various operations on projects are described by :class:`ResearchProjectRole` objects. Research project is a kind of a middle-step between resources and classifications. """ name = models.CharField(max_length=255, unique=True) acronym = models.CharField(max_length=10, unique=True) description = SafeTextField(max_length=2000, null=True, blank=True) abstract = SafeTextField(max_length=2000, null=True, blank=True) methods = SafeTextField(max_length=2000, null=True, blank=True) owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='research_projects') collections = models.ManyToManyField('storage.Collection', through='ResearchProjectCollection', blank=True, related_name='research_projects') date_created = models.DateTimeField(auto_now_add=True) status = models.NullBooleanField(choices=ResearchProjectStatus.CHOICES) status_date = models.DateTimeField(blank=True, null=True, editable=False) keywords = TaggableManager() objects = ResearchProjectManager() class Meta: ordering = ['-status_date'] def __unicode__(self): return unicode(self.acronym) def get_roles(self): """Return mapping between users and their roles: .. code-block:: python { <user>: [<role_name>, <role_name>, ...], <user>: [<role_name>, <role_name>, ...], ... } """ role_map = {} roles = self.project_roles.all() for role in roles: role_map.setdefault(role.user, []).append(role) return role_map def get_user_roles(self, user=None): """Returns a tuple of project roles for given user. :param: user :class:`auth.User` instance for which the roles are determined :return: list of role names of given user withing the project """ user = user or get_current_user() roles = self.project_roles.filter(user=user) return [role.get_name_display() for role in roles] def get_user_roles_with_profiles(self): return self.project_roles.all().select_related('user', 'user__userprofile') def can_update(self, user=None): """Determines whether given user can update the project. :param: user :class:`auth.User` instance for which test is made :return: True if user can update project, False otherwise """ user = user or get_current_user() return self.status is True and user.is_authenticated() and ( self.owner == user or self.project_roles.filter( user=user, name__in=ResearchProjectRoleType.EDIT).exists()) def can_delete(self, user=None): """Determines whether given user can delete the project. :param: user :class:`auth.User` instance for which test is made :return: True if user can delete the project, False otherwise """ user = user or get_current_user() return self.status is True and user.is_authenticated() and ( self.owner == user or self.project_roles.filter( user=user, name__in=ResearchProjectRoleType.DELETE).exists()) def can_view(self, user=None): """Determines whether given user can see the details of a project. :param: user :class:`auth.User` instance for which test is made :return: True if user can see the details of the project, False otherwise """ user = user or get_current_user() return self.status is True and user.is_authenticated() and ( self.owner == user or self.project_roles.filter(user=user).exists()) def can_create_classification_project(self, user=None): """Determine if user can use this project to create classification project""" return self.can_view(user=user) def get_absolute_url(self): """Return url of research project details""" return reverse('research:project_detail', kwargs={'pk': self.pk}) def save(self, **kwargs): """ If project has been accepted, then accept date is set, also when project is created, two notifications are sent: * to user, that project has been created * to admins, that project has been created and waiting for approve or decline """ if (self.status is not None and self.status_date is None): self.status_date = datetime_aware() super(ResearchProject, self).save(**kwargs) def get_admin_url(self): """ Get full url to the research project change view in admin based on project.pk """ request = get_current_request() return request.build_absolute_uri( reverse('admin:research_researchproject_change', args=(self.pk, ))) def send_create_message(self): """Notify all django admins about new project using :class:`apps.messaging.models.Message` (application messaging) """ User = get_user_model() recipients = User.objects.filter(is_active=True, is_superuser=True) body_template = ( 'New research project has been created. You can approve or reject it ' 'by changing its status at:\n' '{url}').format(url=reverse( 'admin:research_researchproject_change', args=(self.pk, ))) for recipient in recipients: Message.objects.create( subject=(u"New research project: <strong>{name}</strong> " u"created").format(name=self.name), text=body_template, user_from=self.owner, user_to=recipient, date_sent=datetime_aware(), message_type=MessageType.RESEARCH_PROJECT_CREATED)
class Value(models.Model): ''' Putting the **V** in *EAV*. This model stores the value for one particular :class:`Attribute` for some entity. As with most EAV implementations, most of the columns of this model will be blank, as onle one *value_* field will be used. Example: >>> import eav >>> from django.contrib.auth.models import User >>> eav.register(User) >>> u = User.objects.create(username='******') >>> a = Attribute.objects.create(name='Favorite Drink', datatype='text', ... slug='fav_drink') >>> Value.objects.create(entity=u, attribute=a, value_text='red bull') <Value: crazy_dev_user - Favorite Drink: "red bull"> ''' entity_ct = models.ForeignKey(ContentType, related_name='value_entities') entity_id = models.IntegerField() entity = generic.GenericForeignKey(ct_field='entity_ct', fk_field='entity_id') value_text = models.TextField(blank=True, null=True) value_float = models.FloatField(blank=True, null=True) value_int = models.IntegerField(blank=True, null=True) value_date = models.DateTimeField(blank=True, null=True) value_bool = models.NullBooleanField(blank=True, null=True) value_enum = models.ManyToManyField(EnumValue, blank=True, null=True, related_name='eav_values') generic_value_id = models.IntegerField(blank=True, null=True) generic_value_ct = models.ForeignKey(ContentType, blank=True, null=True, related_name='value_values') value_object = generic.GenericForeignKey(ct_field='generic_value_ct', fk_field='generic_value_id') created = models.DateTimeField(_(u"created"), default=datetime.now) modified = models.DateTimeField(_(u"modified"), auto_now=True) attribute = models.ForeignKey(Attribute, db_index=True, verbose_name=_(u"attribute")) def save(self, *args, **kwargs): ''' Validate and save this value ''' self.full_clean() super(Value, self).save(*args, **kwargs) def clean(self): ''' Raises ``ValidationError`` if this value's attribute is *TYPE_ENUM* and value_enum is not a valid choice for this value's attribute. ''' try: if self.attribute.datatype == Attribute.TYPE_ENUM and \ self.value_enum: for value in self.value_enum.all(): if value not in self.attribute.enum_group.enums.all(): raise ValidationError(_(u"%(choice)s is not a valid " \ u"choice for %s(attribute)") % \ {'choice': value, 'attribute': self.attribute}) except ValueError: pass def _get_value(self): ''' Return the python object this value is holding ''' return getattr(self, 'value_%s' % self.attribute.datatype) def _set_value(self, new_value): ''' Set the object this value is holding ''' if self.attribute.datatype == 'enum': try: for value in new_value: pass if self.value_enum: self.value_enum.clear() for value in new_value: self.value_enum.add(value) except Exception: pass else: setattr(self, 'value_%s' % self.attribute.datatype, new_value) value = property(_get_value, _set_value) def __unicode__(self): return u"%s - %s" % (self.entity, self.attribute.name)
class Migration(migrations.Migration): replaces = [('pretixbase', '0108_auto_20190201_1527'), ('pretixbase', '0109_auto_20190208_1432'), ('pretixbase', '0110_auto_20190219_1245'), ('pretixbase', '0111_auto_20190219_0949'), ('pretixbase', '0112_auto_20190304_1726'), ('pretixbase', '0113_auto_20190312_0942'), ('pretixbase', '0114_auto_20190316_1014'), ('pretixbase', '0115_auto_20190323_2238'), ('pretixbase', '0116_auto_20190402_0722'), ('pretixbase', '0117_auto_20190418_1149'), ('pretixbase', '0118_auto_20190423_0839'), ('pretixbase', '0119_auto_20190509_0654'), ('pretixbase', '0120_auto_20190509_0736'), ('pretixbase', '0121_order_email_known_to_work'), ('pretixbase', '0122_orderposition_web_secret'), ('pretixbase', '0123_auto_20190530_1035'), ('pretixbase', '0124_seat_seat_guid'), ('pretixbase', '0125_voucher_show_hidden_items'), ('pretixbase', '0126_item_show_quota_left'), ('pretixbase', '0127_auto_20190711_0705'), ('pretixbase', '0128_auto_20190715_1510'), ('pretixbase', '0129_auto_20190724_1548'), ('pretixbase', '0130_auto_20190729_1311'), ('pretixbase', '0131_auto_20190729_1422'), ('pretixbase', '0132_auto_20190808_1253'), ('pretixbase', '0133_auto_20190830_1513'), ('pretixbase', '0134_auto_20190909_1042'), ('pretixbase', '0135_auto_20191007_0803'), ('pretixbase', '0136_auto_20190918_1742'), ('pretixbase', '0137_auto_20191015_1141'), ('pretixbase', '0138_auto_20191017_1151'), ('pretixbase', '0139_auto_20191019_1317'), ('pretixbase', '0140_voucher_seat'), ('pretixbase', '0141_seat_sorting_rank')] dependencies = [ ('pretixbase', '0107_auto_20190129_1337'), ] operations = [ migrations.AddField( model_name='item', name='generate_tickets', field=models.NullBooleanField( verbose_name='Allow ticket download'), ), migrations.AddField( model_name='invoiceline', name='event_date_from', field=models.DateTimeField(null=True), ), migrations.AddField( model_name='invoiceline', name='subevent', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='pretixbase.SubEvent'), ), migrations.AlterField( model_name='event', name='plugins', field=models.TextField(blank=True, default='', verbose_name='Plugins'), preserve_default=False, ), migrations.AddField( model_name='order', name='testmode', field=models.BooleanField(default=False), ), migrations.AddField( model_name='event', name='testmode', field=models.BooleanField(default=False), ), migrations.RunPython( code=make_checkins_unique, reverse_code=django.db.migrations.operations.special.RunPython. noop, ), migrations.AlterUniqueTogether( name='checkin', unique_together={('list', 'position')}, ), migrations.AddField( model_name='question', name='dependency_question', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='dependent_questions', to='pretixbase.Question'), ), migrations.AddField( model_name='question', name='dependency_value', field=models.TextField(blank=True, null=True), ), migrations.AddField( model_name='cartposition', name='is_bundled', field=models.BooleanField(default=False), ), migrations.AlterField( model_name='cartposition', name='addon_to', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='addons', to='pretixbase.CartPosition'), ), migrations.AlterField( model_name='orderposition', name='addon_to', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='addons', to='pretixbase.OrderPosition'), ), migrations.AddField( model_name='item', name='require_bundling', field=models.BooleanField( default=False, help_text= 'If this option is set, the product will only be sold as part of bundle products.', verbose_name='Only sell this product as part of a bundle'), ), migrations.CreateModel( name='ItemBundle', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('count', models.PositiveIntegerField(default=1, verbose_name='Number')), ('designated_price', models.DecimalField( blank=True, decimal_places=2, default=Decimal('0.00'), help_text= "If set, it will be shown that this bundled item is responsible for the given value of the total gross price. This might be important in cases of mixed taxation, but can be kept blank otherwise. This value will NOT be added to the base item's price.", max_digits=10, verbose_name='Designated price part')), ('base_item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='bundles', to='pretixbase.Item')), ('bundled_item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='bundled_with', to='pretixbase.Item', verbose_name='Bundled item')), ('bundled_variation', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='bundled_with', to='pretixbase.ItemVariation', verbose_name='Bundled variation')), ], ), migrations.AddField( model_name='device', name='revoked', field=models.BooleanField(default=False), ), migrations.AddField( model_name='itemvariation', name='original_price', field=models.DecimalField( blank=True, decimal_places=2, help_text= 'If set, this will be displayed next to the current price to show that the current price is a discounted one. This is just a cosmetic setting and will not actually impact pricing.', max_digits=7, null=True, verbose_name='Original price'), ), migrations.AddField( model_name='subevent', name='is_public', field=models.BooleanField( default=True, help_text= 'If selected, this event will show up publicly on the list of dates for your event.', verbose_name='Show in lists'), ), migrations.AddField( model_name='question', name='hidden', field=models.BooleanField( default=False, help_text='This question will only show up in the backend.', verbose_name='Hidden question'), ), migrations.AlterField( model_name='cartposition', name='attendee_name_parts', field=jsonfallback.fields.FallbackJSONField(default=dict), ), migrations.AlterField( model_name='cartposition', name='subevent', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.PROTECT, to='pretixbase.SubEvent'), ), migrations.AlterField( model_name='cartposition', name='voucher', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.PROTECT, to='pretixbase.Voucher'), ), migrations.AlterField( model_name='event', name='is_public', field=models.BooleanField(default=True), ), migrations.AlterField( model_name='invoiceaddress', name='name_parts', field=jsonfallback.fields.FallbackJSONField(default=dict), ), migrations.AlterField( model_name='item', name='sales_channels', field=pretix.base.models.fields.MultiStringField(default=['web']), ), migrations.AlterField( model_name='order', name='sales_channel', field=models.CharField(default='web', max_length=190), ), migrations.AlterField( model_name='orderposition', name='attendee_name_parts', field=jsonfallback.fields.FallbackJSONField(default=dict), ), migrations.AlterField( model_name='orderposition', name='subevent', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.PROTECT, to='pretixbase.SubEvent'), ), migrations.AlterField( model_name='orderposition', name='voucher', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.PROTECT, to='pretixbase.Voucher'), ), migrations.AlterField( model_name='staffsessionauditlog', name='method', field=models.CharField(max_length=255), ), migrations.AlterField( model_name='user', name='email', field=models.EmailField(db_index=True, max_length=190, null=True, unique=True), ), migrations.AddField( model_name='order', name='email_known_to_work', field=models.BooleanField(default=False), ), migrations.AddField( model_name='orderposition', name='web_secret', field=models.CharField( db_index=True, default=pretix.base.models.orders.generate_secret, max_length=32), ), migrations.CreateModel( name='SeatingPlan', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)), ('name', models.CharField(max_length=190)), ('layout', models.TextField()), ('organizer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='seating_plans', to='pretixbase.Organizer')), ], options={ 'abstract': False, }, bases=(models.Model, pretix.base.models.base.LoggingMixin), ), migrations.CreateModel( name='SeatCategoryMapping', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)), ('layout_category', models.CharField(max_length=190)), ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='seat_category_mappings', to='pretixbase.Event')), ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='seat_category_mappings', to='pretixbase.Item')), ('subevent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='seat_category_mappings', to='pretixbase.SubEvent')), ], ), migrations.CreateModel( name='Seat', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)), ('name', models.CharField(max_length=190)), ('blocked', models.BooleanField(default=False)), ('event', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='seats', to='pretixbase.Event')), ('product', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='seats', to='pretixbase.Item')), ('subevent', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='seats', to='pretixbase.SubEvent')), ('seat_guid', models.CharField(db_index=True, default=None, max_length=190)), ], ), migrations.AddField( model_name='cartposition', name='seat', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.PROTECT, to='pretixbase.Seat'), ), migrations.AddField( model_name='event', name='seating_plan', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.PROTECT, related_name='events', to='pretixbase.SeatingPlan'), ), migrations.AddField( model_name='orderposition', name='seat', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.PROTECT, to='pretixbase.Seat'), ), migrations.AddField( model_name='subevent', name='seating_plan', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.PROTECT, related_name='subevents', to='pretixbase.SeatingPlan'), ), migrations.AddField( model_name='voucher', name='show_hidden_items', field=models.BooleanField(default=True), ), migrations.RunPython( code=set_show_hidden_items, reverse_code=django.db.migrations.operations.special.RunPython. noop, ), migrations.AddField( model_name='item', name='show_quota_left', field=models.NullBooleanField(), ), migrations.RenameField( model_name='question', old_name='dependency_value', new_name='dependency_values', ), migrations.AlterField( model_name='question', name='dependency_values', field=pretix.base.models.fields.MultiStringField(default=['']), ), migrations.AddField( model_name='quota', name='close_when_sold_out', field=models.BooleanField(default=False), ), migrations.AddField( model_name='quota', name='closed', field=models.BooleanField(default=False), ), migrations.AddField( model_name='item', name='hidden_if_available', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.SET_NULL, to='pretixbase.Quota'), ), migrations.AddField( model_name='seat', name='row_name', field=models.CharField(default='', max_length=190), ), migrations.AddField( model_name='seat', name='seat_number', field=models.CharField(default='', max_length=190), ), migrations.AddField( model_name='seat', name='zone_name', field=models.CharField(default='', max_length=190), ), migrations.AddField( model_name='item', name='allow_waitinglist', field=models.BooleanField(default=True), ), migrations.AddField( model_name='invoice', name='invoice_to_state', field=models.CharField(max_length=190, null=True), ), migrations.AddField( model_name='invoiceaddress', name='state', field=models.CharField(default='', max_length=255), preserve_default=False, ), migrations.AddField( model_name='question', name='print_on_invoice', field=models.BooleanField(default=False), ), migrations.CreateModel( name='WebAuthnDevice', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)), ('name', models.CharField(max_length=64)), ('confirmed', models.BooleanField(default=True)), ('credential_id', models.CharField(max_length=255, null=True)), ('rp_id', models.CharField(max_length=255, null=True)), ('icon_url', models.CharField(max_length=255, null=True)), ('ukey', models.TextField(null=True)), ('pub_key', models.TextField(null=True)), ('sign_count', models.IntegerField(default=0)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], options={ 'abstract': False, }, ), migrations.RunPython( code=mail_migrator, reverse_code=django.db.migrations.operations.special.RunPython. noop, ), migrations.AddField( model_name='checkin', name='auto_checked_in', field=models.BooleanField(default=False), ), migrations.AddField( model_name='checkinlist', name='auto_checkin_sales_channels', field=pretix.base.models.fields.MultiStringField(default=[]), ), migrations.AddField( model_name='user', name='auth_backend', field=models.CharField(default='native', max_length=255), ), migrations.CreateModel( name='GiftCard', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)), ('issuance', models.DateTimeField(auto_now_add=True)), ('secret', models.CharField( db_index=True, default=pretix.base.models.giftcards.gen_giftcard_secret, max_length=190)), ('currency', models.CharField(max_length=10)), ('issued_in', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='issued_gift_cards', to='pretixbase.OrderPosition')), ('issuer', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='issued_gift_cards', to='pretixbase.Organizer')), ('testmode', models.BooleanField(default=False)), ], options={ 'unique_together': {('secret', 'issuer')}, }, bases=(models.Model, pretix.base.models.base.LoggingMixin), ), migrations.AddField( model_name='item', name='issue_giftcard', field=models.BooleanField(default=False), ), migrations.AddField( model_name='team', name='can_manage_gift_cards', field=models.BooleanField(default=False), ), migrations.AlterField( model_name='question', name='dependency_values', field=pretix.base.models.fields.MultiStringField(default=[]), ), migrations.AlterField( model_name='voucher', name='item', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vouchers', to='pretixbase.Item'), ), migrations.AlterField( model_name='voucher', name='quota', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vouchers', to='pretixbase.Quota'), ), migrations.AlterField( model_name='voucher', name='variation', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vouchers', to='pretixbase.ItemVariation'), ), migrations.CreateModel( name='GiftCardTransaction', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)), ('datetime', models.DateTimeField(auto_now_add=True)), ('value', models.DecimalField(decimal_places=2, max_digits=10)), ('card', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='transactions', to='pretixbase.GiftCard')), ('order', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='gift_card_transactions', to='pretixbase.Order')), ('payment', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='gift_card_transactions', to='pretixbase.OrderPayment')), ('refund', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='gift_card_transactions', to='pretixbase.OrderRefund')), ], options={ 'ordering': ('datetime', ), }, ), migrations.CreateModel( name='GiftCardAcceptance', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)), ('collector', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='gift_card_issuer_acceptance', to='pretixbase.Organizer')), ('issuer', models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name='gift_card_collector_acceptance', to='pretixbase.Organizer')), ], ), migrations.RunPython( code=fwd, reverse_code=django.db.migrations.operations.special.RunPython. noop, ), migrations.AddField( model_name='event', name='geo_lat', field=models.FloatField(null=True), ), migrations.AddField( model_name='event', name='geo_lon', field=models.FloatField(null=True), ), migrations.AddField( model_name='subevent', name='geo_lat', field=models.FloatField(null=True), ), migrations.AddField( model_name='subevent', name='geo_lon', field=models.FloatField(null=True), ), migrations.AddField( model_name='voucher', name='seat', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vouchers', to='pretixbase.Seat'), ), migrations.AddField( model_name='seat', name='sorting_rank', field=models.BigIntegerField(default=0), ), ]
class Server(models.Model): # 服务器信息 in_ip = models.CharField(max_length=100, null=True, blank=True, unique=True, verbose_name=u'内网地址') # 内网ip idc = models.ForeignKey(Idc, blank=True, null=True, related_name='servers', on_delete=models.SET_NULL, verbose_name=u'IDC 机房') app_project = models.ForeignKey(AppProject, blank=True, null=True, related_name='app', on_delete=models.SET_NULL, verbose_name=u'部署应用') system_user = models.ForeignKey(SystemUser, on_delete=models.SET_NULL, null=True, verbose_name='登陆用户', blank=True) groups = models.ManyToManyField(ServerGroup, blank=True, related_name='servers', verbose_name=u'资产组') ex_ip = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'外网地址') # 弹性ip project_name = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'项目名称') host_name = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'主机名称') service_name = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'服务名称') position = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'位置') cpu_model = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'CPU型号') cpu_cores = models.IntegerField(null=True, blank=True, verbose_name=u'CPU核数') cpu_count = models.IntegerField(null=True, blank=True, verbose_name=u'CPU个数') os_version = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'系统版本') os_kernel = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'系统内核') status = models.NullBooleanField(default=False, null=True, blank=True, verbose_name=u'运行状态') max_open_files = models.IntegerField(null=True, blank=True, verbose_name=u'最大打开文件数') uptime = models.IntegerField(null=True, blank=True, verbose_name=u'在线时间(天)') mem = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'内存') mem_free = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'剩余内存') mem_rate = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'内存使用率') disk = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'磁盘') disk_free = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'剩余磁盘') disk_rate = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'磁盘使用率') swap_total = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'总交换内存') swap_free = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'剩余交换内存') swap_rate = models.CharField(max_length=100, null=True, blank=True, verbose_name=u'交换内存使用率') ctime = models.DateTimeField(auto_now_add=True, verbose_name=u'创建时间') author = models.ForeignKey(User, null=True, on_delete=models.SET_NULL, verbose_name=u'创建者') def __unicode__(self): return '%s - %s' % (self.in_ip, self.host_name) class Meta: permissions = ( ("view_server", ("查看主机列表")), ("add_server", ("添加主机")), ("change_server", ("编辑主机")), ("update_server", ("更新主机")), ("delete_server", ("删除主机")), ("view_monitor", ("查看监控列表")), ) default_permissions = ()
class Deploy(Model): __core__ = False organization_id = BoundedPositiveIntegerField(db_index=True) release = FlexibleForeignKey('sentry.Release') environment_id = BoundedPositiveIntegerField(db_index=True) date_finished = models.DateTimeField(default=timezone.now) date_started = models.DateTimeField(null=True, blank=True) name = models.CharField(max_length=64, null=True, blank=True) url = models.URLField(null=True, blank=True) notified = models.NullBooleanField(null=True, db_index=True, default=False) class Meta: app_label = 'sentry' db_table = 'sentry_deploy' @staticmethod def get_lock_key(deploy_id): return 'deploy-notify:%s' % deploy_id @classmethod def notify_if_ready(cls, deploy_id, fetch_complete=False): """ create activity and send deploy notifications if they haven't been sent """ from sentry.models import Activity, Environment, ReleaseCommit, ReleaseHeadCommit lock_key = cls.get_lock_key(deploy_id) lock = locks.get(lock_key, duration=30) with TimedRetryPolicy(10)(lock.acquire): deploy = cls.objects.filter( id=deploy_id, ).select_related('release').get() if deploy.notified: return release = deploy.release environment = Environment.objects.get( organization_id=deploy.organization_id, id=deploy.environment_id, ) if not fetch_complete: release_has_commits = ReleaseCommit.objects.filter( organization_id=release.organization_id, release=release, ).exists() if not release_has_commits: # check if we have head commits, which # would indicate that we're waiting for # fetch_commits to complete if ReleaseHeadCommit.objects.filter( organization_id=release.organization_id, release=release, ).exists(): return activity = None for project in deploy.release.projects.all(): activity = Activity.objects.create( type=Activity.DEPLOY, project=project, ident=Activity.get_version_ident(release.version), data={ 'version': release.version, 'deploy_id': deploy.id, 'environment': environment.name, }, datetime=deploy.date_finished, ) # Somewhat hacky, only send notification for one # Deploy Activity record because it will cover all projects if activity is not None: activity.send_notification() deploy.update(notified=True)
class Migration(migrations.Migration): initial = True dependencies = [] operations = [ migrations.CreateModel( name='DuplicateFeed', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('duplicate_address', models.CharField(db_index=True, max_length=764)), ('duplicate_link', models.CharField(db_index=True, max_length=764, null=True)), ('duplicate_feed_id', models.CharField(db_index=True, max_length=255, null=True)), ], ), migrations.CreateModel( name='Feed', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('feed_address', models.URLField(db_index=True, max_length=764)), ('feed_address_locked', models.NullBooleanField(default=False)), ('feed_link', models.URLField(blank=True, default='', max_length=1000, null=True)), ('feed_link_locked', models.BooleanField(default=False)), ('hash_address_and_link', models.CharField(max_length=64, unique=True)), ('feed_title', models.CharField(blank=True, default='[Untitled]', max_length=255, null=True)), ('is_push', models.NullBooleanField(default=False)), ('active', models.BooleanField(db_index=True, default=True)), ('num_subscribers', models.IntegerField(default=-1)), ('active_subscribers', models.IntegerField(db_index=True, default=-1)), ('premium_subscribers', models.IntegerField(default=-1)), ('active_premium_subscribers', models.IntegerField(default=-1)), ('last_update', models.DateTimeField(db_index=True)), ('next_scheduled_update', models.DateTimeField()), ('last_story_date', models.DateTimeField(blank=True, null=True)), ('fetched_once', models.BooleanField(default=False)), ('known_good', models.BooleanField(default=False)), ('has_feed_exception', models.BooleanField(db_index=True, default=False)), ('has_page_exception', models.BooleanField(db_index=True, default=False)), ('has_page', models.BooleanField(default=True)), ('exception_code', models.IntegerField(default=0)), ('errors_since_good', models.IntegerField(default=0)), ('min_to_decay', models.IntegerField(default=0)), ('days_to_trim', models.IntegerField(default=90)), ('creation', models.DateField(auto_now_add=True)), ('etag', models.CharField(blank=True, max_length=255, null=True)), ('last_modified', models.DateTimeField(blank=True, null=True)), ('stories_last_month', models.IntegerField(default=0)), ('average_stories_per_month', models.IntegerField(default=0)), ('last_load_time', models.IntegerField(default=0)), ('favicon_color', models.CharField(blank=True, max_length=6, null=True)), ('favicon_not_found', models.BooleanField(default=False)), ('s3_page', models.NullBooleanField(default=False)), ('s3_icon', models.NullBooleanField(default=False)), ('search_indexed', models.NullBooleanField(default=None)), ('branch_from_feed', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='rss_feeds.Feed')), ], options={ 'db_table': 'feeds', 'ordering': ['feed_title'], }, ), migrations.CreateModel( name='FeedData', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('feed_tagline', models.CharField(blank=True, max_length=1024, null=True)), ('story_count_history', models.TextField(blank=True, null=True)), ('feed_classifier_counts', models.TextField(blank=True, null=True)), ('popular_tags', models.CharField(blank=True, max_length=1024, null=True)), ('popular_authors', models.CharField(blank=True, max_length=2048, null=True)), ('feed', utils.fields.AutoOneToOneField( on_delete=django.db.models.deletion.CASCADE, related_name='data', to='rss_feeds.Feed')), ], ), migrations.AddField( model_name='duplicatefeed', name='feed', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name='duplicate_addresses', to='rss_feeds.Feed'), ), ]
class Migration(migrations.Migration): dependencies = [ ('materia', '0001_initial'), ] operations = [ migrations.CreateModel( name='AssuntoNorma', fields=[ ('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)), ('assunto', models.CharField(max_length=50, verbose_name='Assunto')), ('descricao', models.CharField(blank=True, max_length=250, null=True, verbose_name='Descrição')), ], options={ 'verbose_name_plural': 'Assuntos de Norma', 'verbose_name': 'Assunto de Norma', }, ), migrations.CreateModel( name='LegislacaoCitada', fields=[ ('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)), ('disposicoes', models.CharField(blank=True, max_length=15, null=True, verbose_name='Disposição')), ('parte', models.CharField(blank=True, max_length=8, null=True, verbose_name='Parte')), ('livro', models.CharField(blank=True, max_length=7, null=True, verbose_name='Livro')), ('titulo', models.CharField(blank=True, max_length=7, null=True, verbose_name='Título')), ('capitulo', models.CharField(blank=True, max_length=7, null=True, verbose_name='Capítulo')), ('secao', models.CharField(blank=True, max_length=7, null=True, verbose_name='Seção')), ('subsecao', models.CharField(blank=True, max_length=7, null=True, verbose_name='Subseção')), ('artigo', models.CharField(blank=True, max_length=4, null=True, verbose_name='Artigo')), ('paragrafo', models.CharField(blank=True, max_length=3, null=True, verbose_name='Parágrafo')), ('inciso', models.CharField(blank=True, max_length=10, null=True, verbose_name='Inciso')), ('alinea', models.CharField(blank=True, max_length=3, null=True, verbose_name='Alínea')), ('item', models.CharField(blank=True, max_length=3, null=True, verbose_name='Item')), ('materia', models.ForeignKey(to='materia.MateriaLegislativa')), ], options={ 'verbose_name_plural': 'Matérias Legislativas', 'verbose_name': 'Matéria Legislativa', }, ), migrations.CreateModel( name='NormaJuridica', fields=[ ('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)), ('numero', models.IntegerField(verbose_name='Número')), ('ano', models.SmallIntegerField(verbose_name='Ano')), ('esfera_federacao', models.CharField(choices=[('E', 'Estadual'), ('F', 'Federal'), ('M', 'Municipal')], max_length=1, verbose_name='Esfera Federação')), ('data', models.DateField(blank=True, null=True, verbose_name='Data')), ('data_publicacao', models.DateField(blank=True, null=True, verbose_name='Data Publicação')), ('veiculo_publicacao', models.CharField(blank=True, max_length=30, null=True, verbose_name='Veículo Publicação')), ('pagina_inicio_publicacao', models.IntegerField(blank=True, null=True, verbose_name='Pg. Início')), ('pagina_fim_publicacao', models.IntegerField(blank=True, null=True, verbose_name='Pg. Fim')), ('ementa', models.TextField(verbose_name='Ementa')), ('indexacao', models.TextField(blank=True, null=True, verbose_name='Indexação')), ('observacao', models.TextField(blank=True, null=True, verbose_name='Observação')), ('complemento', models.NullBooleanField(verbose_name='Complementar ?')), ('data_vigencia', models.DateField(blank=True, null=True)), ('timestamp', models.DateTimeField()), ('assunto', models.ForeignKey(to='norma.AssuntoNorma')), ('materia', models.ForeignKey(blank=True, null=True, to='materia.MateriaLegislativa')), ], options={ 'verbose_name_plural': 'Normas Jurídicas', 'verbose_name': 'Norma Jurídica', }, ), migrations.CreateModel( name='TipoNormaJuridica', fields=[ ('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)), ('equivalente_lexml', models.CharField( blank=True, max_length=50, null=True, verbose_name='Equivalente LexML', choices=[('constituicao', 'constituicao'), ('ementa.constitucional', 'ementa.constitucional'), ('lei.complementar', 'lei.complementar'), ('lei.delegada', 'lei.delegada'), ('lei', 'lei'), ('decreto.lei', 'decreto.lei'), ('medida.provisoria', 'medida.provisoria'), ('decreto', 'decreto'), ('lei.organica', 'lei.organica'), ('emenda.lei.organica', 'emenda.lei.organica'), ('decreto.legislativo', 'decreto.legislativo'), ('resolucao', 'resolucao'), ('regimento.interno', 'regimento.interno')])), ('sigla', models.CharField(max_length=3, verbose_name='Sigla')), ('descricao', models.CharField(max_length=50, verbose_name='Descrição')), ], options={ 'verbose_name_plural': 'Tipos de Norma Jurídica', 'verbose_name': 'Tipo de Norma Jurídica', }, ), migrations.CreateModel( name='VinculoNormaJuridica', fields=[ ('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)), ('tipo_vinculo', models.CharField(blank=True, max_length=1, null=True, choices=[ ('A', 'Altera a norma'), ('R', 'Revoga a norma'), ('P', 'Revoga parcialmente a norma'), ('T', 'Revoga por consolidação a norma'), ('C', 'Norma correlata'), ('I', 'Suspende a execução da norma'), ('G', 'Regulamenta a norma') ])), ('norma_referente', models.ForeignKey(to='norma.NormaJuridica', related_name='+')), ('norma_referida', models.ForeignKey(to='norma.NormaJuridica', related_name='+')), ], options={ 'verbose_name_plural': 'Vínculos entre Normas Jurídicas', 'verbose_name': 'Vínculo entre Normas Jurídicas', }, ), migrations.AddField( model_name='normajuridica', name='tipo', field=models.ForeignKey(to='norma.TipoNormaJuridica', verbose_name='Tipo'), ), migrations.AddField( model_name='legislacaocitada', name='norma', field=models.ForeignKey(to='norma.NormaJuridica'), ), ]
class AbstractProductAttributeValue(models.Model): """ The "through" model for the m2m relationship between catalogue.Product and catalogue.ProductAttribute. This specifies the value of the attribute for a particular product For example: number_of_pages = 295 """ attribute = models.ForeignKey('catalogue.ProductAttribute', on_delete=models.CASCADE, verbose_name=_("Attribute")) product = models.ForeignKey('catalogue.Product', on_delete=models.CASCADE, related_name='attribute_values', verbose_name=_("Product")) value_text = models.TextField(_('Text'), blank=True, null=True) value_integer = models.IntegerField(_('Integer'), blank=True, null=True) value_boolean = models.NullBooleanField(_('Boolean'), blank=True) value_float = models.FloatField(_('Float'), blank=True, null=True) value_richtext = models.TextField(_('Richtext'), blank=True, null=True) value_date = models.DateField(_('Date'), blank=True, null=True) value_datetime = models.DateTimeField(_('DateTime'), blank=True, null=True) value_multi_option = models.ManyToManyField( 'catalogue.AttributeOption', blank=True, related_name='multi_valued_attribute_values', verbose_name=_("Value multi option")) value_option = models.ForeignKey('catalogue.AttributeOption', blank=True, null=True, on_delete=models.CASCADE, verbose_name=_("Value option")) value_file = models.FileField(upload_to=settings.OSCAR_IMAGE_FOLDER, max_length=255, blank=True, null=True) value_image = models.ImageField(upload_to=settings.OSCAR_IMAGE_FOLDER, max_length=255, blank=True, null=True) value_entity = GenericForeignKey('entity_content_type', 'entity_object_id') entity_content_type = models.ForeignKey(ContentType, blank=True, editable=False, on_delete=models.CASCADE, null=True) entity_object_id = models.PositiveIntegerField(null=True, blank=True, editable=False) def _get_value(self): value = getattr(self, 'value_%s' % self.attribute.type) if hasattr(value, 'all'): value = value.all() return value def _set_value(self, new_value): attr_name = 'value_%s' % self.attribute.type if self.attribute.is_option and isinstance(new_value, str): # Need to look up instance of AttributeOption new_value = self.attribute.option_group.options.get( option=new_value) elif self.attribute.is_multi_option: getattr(self, attr_name).set(new_value) return setattr(self, attr_name, new_value) return value = property(_get_value, _set_value) class Meta: abstract = True app_label = 'catalogue' unique_together = ('attribute', 'product') verbose_name = _('Product attribute value') verbose_name_plural = _('Product attribute values') def __str__(self): return self.summary() def summary(self): """ Gets a string representation of both the attribute and it's value, used e.g in product summaries. """ return "%s: %s" % (self.attribute.name, self.value_as_text) @property def value_as_text(self): """ Returns a string representation of the attribute's value. To customise e.g. image attribute values, declare a _image_as_text property and return something appropriate. """ property_name = '_%s_as_text' % self.attribute.type return getattr(self, property_name, self.value) @property def _multi_option_as_text(self): return ', '.join( str(option) for option in self.value_multi_option.all()) @property def _richtext_as_text(self): return strip_tags(self.value) @property def _entity_as_text(self): """ Returns the unicode representation of the related model. You likely want to customise this (and maybe _entity_as_html) if you use entities. """ return str(self.value) @property def value_as_html(self): """ Returns a HTML representation of the attribute's value. To customise e.g. image attribute values, declare a _image_as_html property and return e.g. an <img> tag. Defaults to the _as_text representation. """ property_name = '_%s_as_html' % self.attribute.type return getattr(self, property_name, self.value_as_text) @property def _richtext_as_html(self): return mark_safe(self.value)
class Migration(migrations.Migration): initial = True dependencies = [] operations = [ migrations.CreateModel( name="Collect", fields=[ ( "id", models.AutoField( auto_created=True, primary_key=True, serialize=False, verbose_name="ID", ), ), ( "status", models.CharField( choices=[ ("started", "Collecte terrain en cours"), ("ended", "Collecte terminée, analyse des données"), ("finalized", "Collecte finalisée avec documents"), ], default="started", max_length=50, ), ), ("started_on", models.DateTimeField(auto_now_add=True)), ("ended_on", models.DateTimeField(blank=True, null=True)), ("finalized_on", models.DateTimeField(blank=True, null=True)), ("uploaded_on", models.DateTimeField(blank=True, null=True)), ( "cercle_id", models.CharField(default="33", max_length=100, verbose_name="Cercle"), ), ( "commune_id", models.CharField(max_length=100, verbose_name="Commune"), ), ("suffix", models.CharField(max_length=50, verbose_name="Suffixe")), ( "mayor_title", models.CharField( choices=[("sir", "M."), ("madam", "Mme"), ("doctor", "Dr")], max_length=50, verbose_name="Titre", ), ), ( "mayor_name", models.CharField(max_length=100, verbose_name="Nom du maire"), ), ("ona_form_pk", models.IntegerField(blank=True, null=True)), ("ona_scan_form_pk", models.IntegerField(blank=True, null=True)), ("nb_submissions", models.IntegerField(blank=True, null=True)), ("nb_indigents", models.IntegerField(blank=True, null=True)), ("nb_non_indigents", models.IntegerField(blank=True, null=True)), ("nb_medias_form", models.IntegerField(blank=True, null=True)), ("nb_medias_scan_form", models.IntegerField(blank=True, null=True)), ("medias_size_form", models.IntegerField(blank=True, null=True)), ("medias_size_scan_form", models.IntegerField(blank=True, null=True)), ], options={ "ordering": ["-started_on"], }, ), migrations.CreateModel( name="Settings", fields=[ ("key", models.SlugField(primary_key=True, serialize=False)), ("value", models.CharField(max_length=500)), ], options={ "verbose_name": "Setting", "verbose_name_plural": "Settings", "ordering": ["key"], }, ), migrations.CreateModel( name="Target", fields=[ ( "identifier", models.CharField(max_length=10, primary_key=True, serialize=False), ), ("first_name", models.CharField(max_length=250)), ("last_name", models.CharField(max_length=250)), ("age", models.IntegerField()), ( "gender", models.CharField( choices=[("male", "Masculin"), ("female", "Feminin")], max_length=20, ), ), ("region", models.CharField(max_length=100)), ("cercle", models.CharField(max_length=100)), ("commune", models.CharField(max_length=100)), ("village", models.CharField(max_length=100)), ("is_indigent", models.NullBooleanField()), ("form_dataset", jsonfield.fields.JSONField(blank=True, default=dict)), ( "scan_form_dataset", jsonfield.fields.JSONField(blank=True, default=dict), ), ( "collect", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name="targets", to="hamed.Collect", ), ), ], options={ "ordering": ["-collect__started_on", "last_name", "first_name"], }, ), migrations.AlterUniqueTogether( name="collect", unique_together=set([("commune_id", "suffix")]), ), ]
class ArtworkStub(ArtBaseModel): """ The artwork MySQL stub. This model should be considered read only. """ from django.contrib.auth.models import User user = models.ForeignKey(User, related_name="artworks") title = models.CharField(max_length=1024, blank=True, null=True) byline = models.CharField(max_length=200, blank=True, null=True) technologies = models.ManyToManyField(Technology, null=True, blank=True) work_type = models.ForeignKey(WorkType, null=True, blank=True) summary = models.TextField(blank=True, null=True, max_length=400) statement = models.TextField(blank=True, null=True) readme = models.TextField(blank=True, null=True) description = models.TextField(blank=True, null=True) image_featured = ThumbnailerImageField( upload_to=featured_upload_to, blank=True, default="artbase/images/rhizome_art_default.png", resize_source=dict(size=(950, 375), crop='smart', quality=99), help_text="Wide Featured Image: 950w x 375h px") image_large = ThumbnailerImageField( upload_to=large_upload_to, blank=True, resize_source=dict(size=(1024, 768), crop='smart', quality=99), default="artbase/images/rhizome_art_default.png", help_text="Full Screen Image: 1024w x 768h px") image_medium = ThumbnailerImageField( upload_to=medium_upload_to, blank=True, default="artbase/images/rhizome_art_default.png", resize_source=dict(size=(470, 355), crop='smart', quality=99), help_text="Main Image: 470w x 355h px") image_small = ThumbnailerImageField( upload_to=small_upload_to, blank=True, default="artbase/images/rhizome_art_default.png", resize_source=dict(size=(135, 170), crop='smart', quality=99), help_text="Thumbnail: 135w x 170h px") license = models.ForeignKey(License, null=True, blank=True, default=get_arr) url = models.URLField(blank=True, null=True, max_length=300) location = models.URLField(blank=True, max_length=300, null=True) location_type = models.CharField(max_length=16, choices=LOCATION_TYPE_CHOICES, blank=True, null=True) agree_to_agreement = models.NullBooleanField(default=False) allow_comments = models.BooleanField(_('allow comments'), default=True, blank=True) needs_repair = models.BooleanField(_('needs repair'), default=False, blank=True) approved_date = models.DateTimeField(null=True, blank=True) submitted_date = models.DateTimeField(null=True, blank=True) status = models.CharField(max_length=300, choices=STATUS_CHOICES, blank=True, default="unsubmitted", db_index=True) external_collections = models.ManyToManyField( ExternalCollection, null=True, blank=True, through='ExternalCollectionWork') tags = TagField(max_length=1024, null=True, blank=True) worked_with = models.CharField(max_length=1024, null=True, blank=True) created_date = models.DateTimeField( null=True, blank=True) #date the work was actually created by the artist notices = models.CharField(max_length=1024, null=True, blank=True) format = models.CharField(max_length=1024, null=True, blank=True) state_ed = models.CharField(max_length=1024, null=True, blank=True) collective = models.CharField(max_length=1024, null=True, blank=True) other_artists = models.CharField(max_length=1024, null=True, blank=True) tech_details = models.TextField(null=True, blank=True) completion_percentage = models.FloatField(null=True, blank=True) class Meta: ordering = ['title'] verbose_name = _('Artwork') verbose_name_plural = _('Artworks') def __unicode__(self): return self.title def tally_completion_percentage(self): ##### # Eventually this should be turned into something comprehensive, but this will do for now. ##### completed_fields = 0 total_fields = 0 for attr, value in self.__dict__.iteritems(): if attr == "notices" or attr == "collective" or attr == "readme" \ or attr == "worked_with" or attr == "allow_comments" or attr == "other_artists" \ or attr == "tech_details": pass else: total_fields += 1 if value: completed_fields += 1 if "image" in attr: if "rhizome_art_default.png" in "%s" % value: completed_fields -= 1 if not value or value == "": completed_fields -= 1 percent_complete = round((completed_fields / total_fields), 2) * 100 return percent_complete def is_halfway_complete(self): if float(self.completion_percentage) >= 50.0: return True else: return False def save(self, **kwargs): if not self.byline: self.byline = self.user.get_profile() self.completion_percentage = self.tally_completion_percentage() if not self.created_date: self.created_date = self.created if not self.license: self.license = get_arr() license = dict(title="%s" % self.license.title, slug="%s" % self.license.slug, url="%s" % self.license.url, image="%s" % self.license.image) new = not self.id doc = self.get_document() super(ArtworkStub, self).save(**kwargs) if new or not doc: self.create_document() def remove(self, **kwargs): self.status = "deleted" self.save() def artist(self): # TODO: update to return byline try: return self.user except: return None def get_status(self): return "%s" % self.status def get_document(self): #return Artwork.load(db, str(self.id)) return Artwork.objects.get( pk=str(self.id) ) #use django like syntax established in utils/model_document.py def create_document(self): ''' creates a couchdb document for the relevant artwork stub ''' new_doc_d = { "titles": [{ "display_string": self.title }], "url": self.url, "summary": self.summary, "created": self.created_date, "description": self.description, "creators": [{ "name": { "display_string": self.user.__unicode__(), "name_authority": "Rhizome" }, "user_id": self.user.id, "roles": "primary creator" }], "license": [{ "title": "%s" % self.license.title, "slug": "%s" % self.license.slug, "url": "%s" % self.license.url, "image": "%s" % self.license.image, }] } new_doc = Artwork(**new_doc_d) new_doc.id = str(self.id) new_doc.save() return new_doc def sync_document(self): ''' syncs a stub and it's couchdb document ''' document = self.get_document() if document: if not document.agree_to_agreement or document.agree_to_agreement == "null" \ or document.agree_to_agreement != self.agree_to_agreement and self.agree_to_agreement: document.agree_to_agreement = self.agree_to_agreement if not document.dates.start or document.dates.start == "null" \ or document.dates.start != self.created_date and self.created_date: document.dates.start = self.created_date if not document.publish_date or document.publish_date == "null" \ or document.publish_date != self.submitted_date and self.submitted_date: document.publish_date = self.submitted_date if not document.approved_date or document.approved_date == "null" \ or document.approved_date != self.approved_date and self.approved_date: document.approved_date = self.approved_date if not document.byline or document.byline == "null" \ or document.byline != self.byline and self.byline: document.byline = self.byline if not document.created or document.created == "null" \ or document.created != self.created and self.created: document.created = self.created if not document.description or document.description == "null" \ or document.description != self.description and self.description: document.description = self.description if not document.format or document.format == "null" \ or document.format != self.format and self.format: document.format = self.format if not document.summary or document.summary == "null" \ or document.summary != self.summary and self.summary: document.summary = self.summary if not document.statement or document.statement == "null" \ or document.statement != self.statement and self.statement: document.statement = self.statement if not document.image_featured or document.image_featured == "null" \ or document.image_featured != self.image_featured and self.image_featured: document.image_featured = self.image_featured if not document.image_large or document.image_large == "null" \ or document.image_large != self.image_large and self.image_large: document.image_large = self.image_large if not document.image_medium or document.image_medium == "null" \ or document.image_medium != self.image_medium and self.image_medium: document.image_medium = self.image_medium if not document.image_small or document.image_small == "null" \ or document.image_small != self.image_small and self.image_small: document.image_small = self.image_small if not document.location or document.location == "null" \ or document.location != self.location and self.location: document.location = self.location if not document.location_type or document.location_type == "null" \ or document.location_type != self.location_type and self.location_type: document.location_type = self.location_type if not document.user_id or document.user_id == "null" \ or document.user_id != self.user_id and self.user_id: document.user_id = self.user_id if not document.mat_techs or document.mat_techs == "null" \ or document.mat_techs != self.get_technologies() and self.get_technologies(): techs = self.get_technologies() tech_list = [] for tech in techs: d = { "display_string": "%s" % tech.display_string, "concept_authority": "Rhizome", "concept_authority_id": "1", "type": "%s" % tech.type, } tech_list.append(d) document.mat_techs = tech_list if not document.license or document.user_id == "null" \ or document.user_id != self.license and self.license: document.license = self.license.title if not document.readme or document.readme == "null" \ or document.readme != self.readme and self.readme: document.readme = self.readme if not document.status or document.status == "null" \ or document.status != self.status and self.status: document.status = self.status if not document.url or document.url == "null" \ or document.url != self.url and self.url: document.url = self.url if self.work_type: if not document.work_types or document.work_types == "null": document.work_types = [] work_dict = { "concept_authority": "Rhizome", "concept_authority_id": 1, "display_string": "%s" % self.work_type.work_type, "eff_date": datetime.datetime.now(), "type": "%s" % self.work_type.work_type, "preferred": True } document.work_types.append(work_dict) for item in document.work_types: if item and item["concept_authority"] == "Rhizome": if item["type"] != self.work_type.work_type: item["type"] = "%s" % self.work_type.work_type item[ "display_string"] = "%s" % self.work_type.work_type item["eff_date"] = datetime.datetime.now() #document.save() def view_url(self): if self.status == "approved": return "/artbase/artwork/%s/" % self.id else: return "/portfolios/artwork/%s/" % self.id def get_absolute_url(self): return "/artbase/artwork/%s" % self.id def edit_url(self): return "/artbase/artwork/%s/edit/" % self.id def get_location_admin(self): return '<a href="%s" target="_blank">%s</a>' % (self.location, self.location) get_location_admin.short_description = 'Location' get_location_admin.allow_tags = True #TAGS def get_tags(self): """ To get at the actual list of tags and not just the comma or or space separated string """ return Tag.objects.get_for_object(self) def get_approved_tags(self): """ returns list of approved tag objects for artwork """ ctype = ContentType.objects.get_for_model(self) approved = [] for tag in TaggedItem.objects.filter(content_type__pk=ctype.id, object_id=self.id, approved=True): try: approved.append(tag.tag) except: pass return approved def get_approved_tags_relationships(self): """ returns list of approved tag relationships (taggeditems) for artwork """ ctype = ContentType.objects.get_for_model(self) approved_rels = [] for tag in TaggedItem.objects.filter(content_type__pk=ctype.id, object_id=self.id, approved=True): try: approved_rels.append(tag.tag) except: pass return approved_rels def get_artist_tags(self): """ returns list of user (not approved) tag objects for artwork """ ctype = ContentType.objects.get_for_model(self) artist_tags = [] for tag in TaggedItem.objects.filter(content_type__pk=ctype.id, object_id=self.id, approved=False): try: artist_tags.append(tag.tag) except: pass return artist_tags def get_artist_tags_relationships(self): """ returns list of user (not approved) tag relationships (taggeditems) for artwork """ ctype = ContentType.objects.get_for_model(self) artist_tags_rels = [] for tag in TaggedItem.objects.filter(content_type__pk=ctype.id, object_id=self.id, approved=False): try: artist_tags_rels.append(tag.tag) except: pass return artist_tags_rels def get_related_works(self, limit=None): related_works_list = [] related_works_list_append = related_works_list.append if limit: related_works = TaggedItem.objects.get_related( self, self.__class__, limit + 5) for work in related_works: if work.image_medium != "artbase/images/rhizome_art_default.png" \ and work.status != "accepted" and work.status != "deleted": related_works_list_append(work) if len(related_works_list) == limit: return related_works_list else: related_works = TaggedItem.objects.get_related( self, self.__class__, 100) for work in related_works: if work.image_medium != "artbase/images/rhizome_art_default.png" \ and work.status != "unsubmitted" and work.status != "deleted": related_works_list_append(work) if len(related_works_list) == 5: return related_works_list def content_type(self): ct = ContentType.objects.get_for_model(self) return ct def content_type_id(self): ct = ContentType.objects.get_for_model(self) return ct.id def get_artist(self): if self.byline: return self.byline return self.user.get_profile() def get_audio(self): """ To get at the audio media associated with the artwork """ return Audio.objects.filter(work=self) def get_video(self): """ To get the video media associated with the artwork """ return Video.objects.filter(work=self) def get_technologies(self): return self.technologies.all() def get_saved_by(self): from accounts.models import RhizomeUser return RhizomeUser.objects \ .filter(saved_artworks__id = self.id) \ .filter(is_active = True) \ .filter(visible=True) def get_collection_fragment_url(self): return "/artbase/collections/artwork/%s/fragment.html" % self.id
class squirrels(models.Model): Longitude= models.DecimalField(max_digits=10,decimal_places=10) Latitude=models.DecimalField(max_digits=10,decimal_places=10) Unique_Squirrel_ID=models.CharField(max_length=30,unique=True) AM,PM='AM','PM' Shift=models.CharField(max_length=30, choices=((AM,'AM'),(PM,'PM'),),) Date=models.DateField(blank=True,null=True,max_length=30,default=timezone.now) adult,juvenile='Adult','Juvenile' age_choices=((adult,"Adult"),(juvenile, "Juvenile"),) Age=models.CharField(max_length=30,choices=age_choices,default=adult) gray,cinnamon,black='Gray','Cinnamon','Black' fur_choices=((gray,"Gray"),(cinnamon, "Cinnamon"),(black,"Black"),) Primary_fur_color=models.CharField(max_length=30,choices=fur_choices,default=gray) ground_plane,above_ground="Ground Plane","Above Ground" location_choices=((ground_plane,"Ground Plane"),(above_ground,"Above Ground"),) Location=models.CharField(max_length=30,choices=location_choices,default=ground_plane) Specific_location=models.CharField(max_length=30,blank=True) Running=models.NullBooleanField(help_text='run') Chasing=models.NullBooleanField(help_text='Chase') Climbing=models.NullBooleanField(help_text='Climb') Eating=models.NullBooleanField(help_text='Eat') Foraging=models.NullBooleanField(help_text='Forage') Other_Activities=models.CharField(help_text='Others',max_length=30,) Kuks=models.NullBooleanField(help_text='Kuks') Quaas=models.NullBooleanField(help_text='Quaas') Moans=models.NullBooleanField(help_text='Moans') Tail_flags=models.NullBooleanField(help_text='Tailflags') Tail_twitches=models.NullBooleanField(help_text='Tail twitches') Approaches=models.NullBooleanField(help_text='Approaches') Indifferent=models.NullBooleanField(help_text='Indifferent') Runs_from=models.NullBooleanField(help_text='Runs from') def __str__(self): return self.Unique_Squirrel_ID
class Migration(migrations.Migration): initial = True dependencies = [ ('sites', '0002_alter_domain_unique'), ('contenttypes', '0002_remove_content_type_name'), ] operations = [ migrations.CreateModel( name='Attribute', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(help_text='User-friendly attribute name', max_length=100, verbose_name='name')), ('slug', eav.fields.EavSlugField( help_text='Short unique attribute label', verbose_name='slug')), ('description', models.CharField(blank=True, help_text='Short description', max_length=256, null=True, verbose_name='description')), ('type', models.CharField(blank=True, max_length=20, null=True, verbose_name='type')), ('datatype', eav.fields.EavDatatypeField(choices=[ ('text', 'Text'), ('float', 'Float'), ('int', 'Integer'), ('date', 'Date'), ('bool', 'True / False'), ('object', 'Django Object'), ('enum', 'Multiple Choice') ], max_length=6, verbose_name='data type')), ('created', models.DateTimeField(default=datetime.datetime.now, editable=False, verbose_name='created')), ('modified', models.DateTimeField(auto_now=True, verbose_name='modified')), ('required', models.BooleanField(default=False, verbose_name='required')), ], options={ 'ordering': ['name'], }, managers=[ ('objects', django.db.models.manager.Manager()), ('on_site', django.contrib.sites.managers.CurrentSiteManager()), ], ), migrations.CreateModel( name='EnumGroup', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=100, unique=True, verbose_name='name')), ], ), migrations.CreateModel( name='EnumValue', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('value', models.CharField(db_index=True, max_length=50, unique=True, verbose_name='value')), ], ), migrations.CreateModel( name='Value', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('entity_id', models.IntegerField()), ('value_text', models.TextField(blank=True, null=True)), ('value_float', models.FloatField(blank=True, null=True)), ('value_int', models.IntegerField(blank=True, null=True)), ('value_date', models.DateTimeField(blank=True, null=True)), ('value_bool', models.NullBooleanField()), ('generic_value_id', models.IntegerField(blank=True, null=True)), ('created', models.DateTimeField(default=datetime.datetime.now, verbose_name='created')), ('modified', models.DateTimeField(auto_now=True, verbose_name='modified')), ('attribute', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='eav.Attribute', verbose_name='attribute')), ('entity_ct', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='value_entities', to='contenttypes.ContentType')), ('generic_value_ct', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='value_values', to='contenttypes.ContentType')), ('value_enum', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='eav_values', to='eav.EnumValue')), ], ), migrations.AddField( model_name='enumgroup', name='enums', field=models.ManyToManyField(to='eav.EnumValue', verbose_name='enum group'), ), migrations.AddField( model_name='attribute', name='enum_group', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='eav.EnumGroup', verbose_name='choice group'), ), migrations.AddField( model_name='attribute', name='site', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to='sites.Site', verbose_name='site'), ), migrations.AlterUniqueTogether( name='attribute', unique_together=set([('site', 'slug')]), ), ]
class FilterSet(models.Model): """Filter sets are used to compare different aspects of DMARC aggregate reports in the associated analysis view. Each filter set can have various filters. Most filter can have one or more values, hence the one-to- many relationship. E.g. the filter for raw DKIM results can be one or more of 'none', 'pass', 'fail', 'policy', 'neutral', 'temperror', 'permerror'. NOTE: When using filters to query DMARC aggregate report data the following rules apply: - All filter fields of the same class are ORed E.g. Two raw DKIM result filters 'temperror' and 'permerror' returns all reports that have a raw DKIM result of 'temperror' **OR** 'permerror'. - All filter fields of classes are ANDed E.g. A DKIM result filter of 'pass' and a SPF result filter of 'pass' returns only reports that have a DKIM **AND** SPF result of 'pass'. """ view = models.ForeignKey("View") label = models.CharField(max_length=100) color = models.CharField(max_length=7) # A boolean filter does not need to be one-to-many multiple_dkim = models.NullBooleanField() def getQuery(self): """Return combined view and filter set filters for this filter set as complex SQL query using django's `Q` object. See https://docs.djangoproject.com/en/1.11/ref/models/querysets/#q-objects for more information. """ # Get a list of object managers, each of which containing the # corresponding view and filter set filter field objects of all # available filter set classes. filter_field_managers = [ manager for manager in self.getFilterSetFilterFieldManagers() ] + [manager for manager in self.view.getViewFilterFieldManagers()] # Create an OR query for all filter fields of the same class or_queries = [] for manager in filter_field_managers: filter_fields = manager.all() if filter_fields: or_queries.append( reduce(lambda x, y: x | y, [ filter_field.getRecordFilter() for filter_field in filter_fields ])) # If there are different filter field OR queries, combine those # queries as one AND query if or_queries: return reduce(lambda x, y: x & y, [or_query for or_query in or_queries]) # If the filter set does not have any filter fields, we return an empty # query, which is equivalent to querying all objects, e.g.: # `View.objects.all() == View.objects.filter(Q())` else: return Q() def getMessageCountPerDay(self): """Return list of date and message count tuples, ordered by date, for this filter set. """ # NOTE: We first filter distinct record ids for this filter set # and then use those record ids as additional filter parameter when we # perform the actual query for message count by date. This workaround # is (?) required to not get duplicate record rows that we can't # `distinct` away when using `annotate`, due to some crazy db joins. # TODO: Revise the workaround # Query distinct record ids for this filter set distinct_records = Record.objects.filter( self.getQuery()).distinct().values("id") # Query the sum of message counts per day for above filtered # records, ordered by date in ascending order return Record.objects.filter(id__in=distinct_records).values( "report__date_range_begin").annotate( date=TruncDay("report__date_range_begin"), cnt=Sum("count")).values("date", "cnt").order_by("date") def getMessageCountPerCountry(self): """Return list of country and message count tuples for this filter set. """ # NOTE: See note in `getMessageCountPerDay` for more info about two # query workaround # Query distinct record ids for this filter set distinct_records = Record.objects.filter( self.getQuery()).distinct().values("id") # Query the sum of message counts per country for above filtered # records, ordered by date in ascending order return Record.objects.filter( id__in=distinct_records).values("country_iso_code").annotate( cnt=Sum("count")).values("country_iso_code", "cnt") def getFilterSetFilterFieldManagers(self): """Wrapper for internal `_get_related_managers` helper function to return object managers for `FilterSetFilterField` subclasses related to this filter set. """ return _get_related_managers(self, FilterSetFilterField)
class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='Authority', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ], options={ 'verbose_name_plural': 'Authorities', }, bases=(models.Model,), ), migrations.CreateModel( name='ChangeRecord', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('lemma', models.CharField(max_length=1024)), ('datetime', models.DateTimeField()), ('session', models.CharField(max_length=100, null=True)), ('ctype', models.CharField(max_length=1, choices=[ ('C', 'Create'), ('U', 'Update'), ('R', 'Revert')])), ('csubtype', models.CharField(max_length=1, choices=[ ('A', 'Automatic'), ('M', 'Manual'), ('R', 'Recovery')])), ('published', models.BooleanField(default=False)), ], options={ }, bases=(models.Model,), ), migrations.CreateModel( name='Chunk', fields=[ ('c_hash', models.CharField(help_text='This is the primary key for chunks. It is a hash of the <code>data</code> field.', max_length=40, serialize=False, primary_key=True)), ('is_normal', models.BooleanField(default=True, help_text="A 'normal' chunk is one that is well-formed XML")), ('schema_version', models.CharField( help_text='This is the version of the btw-storage schema that ought to be used to validate this chunk.', max_length=10)), ('_valid', models.NullBooleanField(help_text='Whether this chunk is valid when validated against the schema version specified in the <code>schema_version</code> field. You do not normally access this field through <code>valid</code>.', db_column='valid')), ('data', models.TextField()), ], options={ }, bases=(models.Model,), ), migrations.CreateModel( name='DeletionChange', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('ctype', models.CharField(max_length=1, choices=[ ('D', 'Delete'), ('U', 'Undelete')])), ('datetime', models.DateTimeField()), ], options={ }, bases=(models.Model,), ), migrations.CreateModel( name='Entry', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('lemma', models.CharField(max_length=1024)), ('deleted', models.BooleanField(default=False)), ('latest', models.ForeignKey(related_name='+', to='lexicography.ChangeRecord', null=True, on_delete=models.CASCADE)), ('latest_published', models.ForeignKey( related_name='+', to='lexicography.ChangeRecord', null=True, on_delete=models.CASCADE)), ], options={ 'verbose_name_plural': 'Entries', 'permissions': (('garbage_collect', 'Perform a garbage collection.'),), }, bases=(models.Model,), ), migrations.CreateModel( name='EntryLock', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('datetime', models.DateTimeField()), ('entry', models.ForeignKey( to='lexicography.Entry', on_delete=models.CASCADE)), ('owner', models.ForeignKey( to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE)), ], options={ 'verbose_name': 'Entry lock', 'verbose_name_plural': 'Entry locks', }, bases=(models.Model,), ), migrations.CreateModel( name='Handle', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('session', models.CharField(max_length=100)), ('handle', models.IntegerField()), ('entry', models.ForeignKey(to='lexicography.Entry', null=True, on_delete=models.CASCADE)), ], options={ }, bases=(models.Model,), ), migrations.CreateModel( name='OtherAuthority', fields=[ ('authority_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='lexicography.Authority', on_delete=models.CASCADE)), ('name', models.CharField(max_length=1024)), ], options={ 'verbose_name_plural': 'OtherAuthorities', }, bases=('lexicography.authority',), ), migrations.CreateModel( name='PublicationChange', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('ctype', models.CharField(max_length=1, choices=[ ('P', 'Publish'), ('U', 'Unpublish')])), ('datetime', models.DateTimeField()), ('changerecord', models.ForeignKey( to='lexicography.ChangeRecord', on_delete=models.CASCADE)), ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=django.db.models.deletion.PROTECT)), ], options={ }, bases=(models.Model,), ), migrations.CreateModel( name='UserAuthority', fields=[ ('authority_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='lexicography.Authority', on_delete=models.CASCADE)), ('user', models.ForeignKey( to=settings.AUTH_USER_MODEL, on_delete=models.PROTECT)), ], options={ 'verbose_name_plural': 'UserAuthorities', }, bases=('lexicography.authority',), ), migrations.AlterUniqueTogether( name='handle', unique_together=set([('session', 'entry'), ('session', 'handle')]), ), migrations.AlterUniqueTogether( name='entrylock', unique_together=set([('entry',)]), ), migrations.AlterUniqueTogether( name='entry', unique_together=set([('lemma',)]), ), migrations.AddField( model_name='deletionchange', name='entry', field=models.ForeignKey( to='lexicography.Entry', on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( model_name='deletionchange', name='user', field=models.ForeignKey( to=settings.AUTH_USER_MODEL, on_delete=django.db.models.deletion.PROTECT), preserve_default=True, ), migrations.AddField( model_name='changerecord', name='c_hash', field=models.ForeignKey( to='lexicography.Chunk', on_delete=django.db.models.deletion.PROTECT), preserve_default=True, ), migrations.AddField( model_name='changerecord', name='entry', field=models.ForeignKey( to='lexicography.Entry', on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( model_name='changerecord', name='user', field=models.ForeignKey( to=settings.AUTH_USER_MODEL, on_delete=django.db.models.deletion.PROTECT), preserve_default=True, ), migrations.AlterUniqueTogether( name='changerecord', unique_together=set([('entry', 'datetime', 'ctype')]), ), ]
class Status(models.Model): objects = StatusManager() coordinates = JSONField(null=True) created_at = models.DateTimeField() deleted = models.BooleanField(blank=True, default=False) entities = JSONField(null=True) favorite_count = models.BigIntegerField(null=True, default=0) filter_level = models.CharField(max_length=50, null=True, default=None) hashtags = JSONField(null=True) id = models.BigIntegerField(primary_key=True) id_str = models.CharField(max_length=64) in_reply_to_screen_name = models.CharField(max_length=50, null=True, blank=True, default=None) in_reply_to_status_id = models.BigIntegerField(null=True, blank=True, default=None) in_reply_to_user_id = models.BigIntegerField(null=True, blank=True, default=None) in_reply_to_user_id_str = models.BigIntegerField(null=True, blank=True, default=None) lang = models.CharField(max_length=20, null=True, blank=True, default=None) media = JSONField(null=True) place = JSONField(null=True, blank=True, default=None) possibly_sensitive = models.NullBooleanField(null=True, blank=True, default=None) quoted_status_id = models.BigIntegerField(blank=True, null=True, default=None) # = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, default=None) scopes = JSONField(null=True, blank=True, default=None) retweet_count = models.BigIntegerField(null=True, default=0) source = models.TextField(null=True, blank=True, default=None) text = models.TextField() truncated = models.NullBooleanField(null=True, blank=True, default=False) user = models.ForeignKey(User, on_delete=models.CASCADE) user_json = JSONField(null=True) user_mentions = JSONField(null=True) urls = JSONField(null=True) withheld_copyright = models.NullBooleanField(null=True, blank=True, default=False) withheld_in_countries = JSONField(null=True, blank=True, default=None) withheld_scope = models.CharField(max_length=50, null=True, blank=True, default=None) def save(self, *args, **kwargs): if self.user_id: self.proc_user() if not self.id_str: setattr(self, 'id_str', str(self.id)) super(Status, self).save(*args, **kwargs) self.parse_entities() def parse_dict(self, obj, *args, **kwargs): from dateutil.parser import parse for k, v in list(obj.items()): if k == 'created_at': self.created_at = parse(v) elif k == 'user': setattr(self, 'user_json', v) setattr(self, 'user_id', v.get('id')) elif hasattr(self, k): setattr(self, k, v) self.save() return self def import_dict(self, obj, *args, **kwargs): from dateutil.parser import parse for k, v in list(obj.items()): if k == 'id_tweet': setattr(self, 'id', v) elif k == 'id_user': setattr(self, 'user_id', v) elif k == 'created_at': self.created_at = parse(v) elif hasattr(self, k): setattr(self, k, v.strip() if type(v) is unicode else v) self.save() return self def proc_user(self): if User.objects.filter(id=self.user_id).exists(): self.user = User.objects.filter(id=self.user_id).get() else: if self.user_json is not None: self.user = User().parse_dict(self.user_json) else: self.user = User.objects.get_or_retrieve(uid=self.user_id) def parse_entities(self): if self.entities is not None: pass if self.hashtags is not None: self.insert_hashtags() if self.user_mentions is not None: self.insert_user_mentions() if self.media is not None: self.insert_media() if self.urls is not None: self.insert_urls() def insert_hashtags(self): for ht in self.hashtags: Hashtag.objects.get_or_create(status=self, text=ht.get('text'), indices=ht.get('indices', None)) def insert_user_mentions(self): for um in self.user_mentions: UserMention.objects.get_or_create(status=self, user_id=um['id'], indices=um.get('indices', None), name=um['name'], screen_name=um['screen_name']) def insert_urls(self): for ur in self.urls: URL.objects.get_or_create(status=self, display_url=ur.get('display_url', None), expanded_url=ur.get( 'expanded_url', None), indices=ur.get('indices', None), url=ur.get('url', None)) def insert_media(self): for me in self.media: MediaEntity.objects.get_or_create( status=self, display_url=me.get('display_url', None), expanded_url=me.get('expanded_url', None), id=me.get('id'), id_str=me.get('id_str'), indices=me.get('indices', None), ext_alt_text=me.get('ext_alt_text', None), media_url=me.get('media_url', None), media_url_https=me.get('media_url_https', None), sizes=me.get('sizes', None), source_status_id=me.get('source_status_id', None), source_status_id_str=me.get('source_status_id_str', None), type=me.get('type', None), url=me.get('url', None)) class Meta: app_label = 'twistreapy'
class NullBooleanModel(models.Model): nbfield = models.BooleanField(null=True, blank=True) nbfield_old = models.NullBooleanField()
class UserProfile(models.Model): user = models.OneToOneField(User, primary_key=True, related_name='profile') profile_picture = ResizedImageField(size=[512, 512], quality=100, upload_to='profile_pictures', null=True, blank=True) phone_number = models.CharField(max_length=12, null=True, blank=True) zipcode = models.CharField(max_length=5, null=True, blank=True) biography = models.TextField(blank=True) playa_name = models.CharField(max_length=64, blank=True, null=True) food_restrictions = models.ManyToManyField(FoodRestriction, blank=True) skills = models.ManyToManyField(Skill, blank=True) years_on_playa = models.IntegerField(blank=True, null=True) invited_by = models.CharField(max_length=64, null=True, blank=True) is_verified_by_admin = models.NullBooleanField('Verified') @property def username(self) -> str: return self.user.username @property def first_name(self) -> str: return self.user.first_name @property def last_name(self) -> str: return self.user.last_name @property def email(self) -> str: return self.user.email def try_fetch_current_attendance(self, include_soft_deleted=False ) -> Optional[AttendanceProfile]: current_year = get_next_event_year() try: if include_soft_deleted: return AttendanceProfile.objects.get(user=self.user, year=current_year) else: return AttendanceProfile.objects.get(user=self.user, year=current_year, deleted_at=None) except AttendanceProfile.DoesNotExist: return None @property def is_attending(self) -> bool: return self.try_fetch_current_attendance() is not None @property def paid_dues(self) -> bool: attendance = self.try_fetch_current_attendance() if attendance is None: return False return attendance.paid_dues def profile_pic_url(self) -> str: if self.profile_picture: assert settings.AWS_STORAGE_BUCKET_NAME return self.profile_picture.url return static('default-profile-pic.png') def get_rich_zipcode(self) -> Optional[Zipcode]: if not self.zipcode: return None search = ZipcodeSearchEngine() return search.by_zipcode(self.zipcode) def city_and_state(self) -> Optional[str]: zipcode = self.get_rich_zipcode() if zipcode is None: return None return '{}, {}'.format(zipcode['City'], zipcode['State']) def get_timezone_offset(self) -> Optional[str]: zipcode = self.get_rich_zipcode() if zipcode is None: return None tf = TimezoneFinder() longitude = zipcode['Longitude'] latitude = zipcode['Latitude'] timezone_name = tf.timezone_at(lng=longitude, lat=latitude) if timezone_name is None: return None return datetime.datetime.now( pytz.timezone(timezone_name)).strftime('%z') def missing_social_media_link_types(self) -> List[str]: from main.models import SocialMediaLink existing_links = {(link.account_type, link.get_account_type_display()) for link in self.social_media_links.all()} return list(set(SocialMediaLink.ACCOUNT_TYPES) - existing_links) def formatted_phone_number(self) -> Optional[str]: if self.phone_number: try: parsed_number = phonenumbers.parse(self.phone_number, 'US') return phonenumbers.format_number(parsed_number, phonenumbers.PhoneNumber()) except Exception as e: import traceback traceback.print_exc() print('Error parsing phone number: {}'.format( self.phone_number)) return None return None def get_absolute_url(self) -> str: return reverse('user-profile', kwargs={'user_id': self.user.id}) def get_formatted_name(self) -> str: full_name = self.user.get_full_name() base_name = full_name if full_name else self.user.get_username() if self.playa_name: return '{} ({})'.format(base_name, self.playa_name) return full_name def __str__(self) -> str: return str(self.user) @classmethod def parse_phone_number(cls, raw_number: str) -> str: try: parsed_number = phonenumbers.parse(raw_number, 'US') formatted_phone = phonenumbers.format_number( parsed_number, phonenumbers.PhoneNumber()) if len(formatted_phone) != 12: raise ValidationError( 'Invalid phone number. Expected xxx-xxx-xxxx') chunks = formatted_phone.split('-') if len(chunks) != 3 or len(chunks[0]) != 3 or len( chunks[1]) != 3 or len(chunks[2]) != 4: raise ValidationError( 'Invalid phone number. Expected xxx-xxx-xxxx') except Exception: raise ValidationError( 'Invalid phone number. Expected xxx-xxx-xxxx') return formatted_phone @classmethod def csv_columns(cls) -> List[str]: return [ "First Name", "Last Name", "Email", "Attending", "Paid Dues", "Location", "Food Restrictions", "Skills", "Years on Playa", "Invited By" ] def to_csv(self) -> List[str]: food_restrictions = ','.join( [fr.name for fr in self.food_restrictions.all()]) skills = ','.join([skill.name for skill in self.skills.all()]) return [ self.first_name, self.last_name, self.email, self.is_attending, self.paid_dues, self.city_and_state(), food_restrictions, skills, self.years_on_playa, self.invited_by ]
class CleanStory(models.Model): fearful = models.NullBooleanField() webStory = models.OneToOneField(WebStory, primary_key=True) text = models.TextField(blank=False)
class YouthVisit(models.Model): '''YouthVisit model''' MET_GOALS_YES = 'Yes' MET_GOALS_NO = 'No' MET_GOALS_NA = 'N/A' youth_id = models.ForeignKey( Youth, on_delete=models.CASCADE, verbose_name='Youth', help_text= "If the Youth isn't in the system already, you can add them with the green plus icon" ) # Required fields visit_start_date = models.DateField( 'initial start date for the visit', default=timezone_date, help_text="When the youth entered the shelter") current_placement_type = models.ForeignKey( PlacementType, on_delete=models.PROTECT, help_text= "Please use 'change bed type' button to change bed types within a visit" ) current_placement_start_date = models.DateField( 'placement start date', default=timezone_date, help_text="When the most recent/current bed type was assigned") # Non-required fields current_placement_extension_days = models.IntegerField( default=0, blank=True, help_text="Please use the 'add extension' button, do not edit directly" ) city_of_origin = models.CharField(max_length=256, null=True, blank=True) state_of_origin = models.CharField(max_length=64, default='Washington', null=True, blank=True) guardian_name = models.CharField(max_length=256, null=True, blank=True) guardian_relationship = models.CharField(max_length=256, null=True, blank=True) guardian_phone_number = models.CharField(max_length=64, null=True, blank=True) referred_by = models.CharField(max_length=256, null=True, blank=True) social_worker = models.CharField(max_length=256, null=True, blank=True) visit_exit_date = models.DateField(null=True, blank=True) permanent_housing = models.NullBooleanField(null=True, blank=True) exited_to = models.CharField(max_length=256, null=True, blank=True) csec_referral = models.BooleanField(default=False) family_engagement_referral = models.BooleanField(default=False) met_greater_than_50_percent_goals = models.CharField( max_length=32, default=MET_GOALS_NA, choices=((MET_GOALS_YES, MET_GOALS_YES), (MET_GOALS_NO, MET_GOALS_NO), (MET_GOALS_NA, MET_GOALS_NA)), blank=True) case_manager = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='+') personal_counselor = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, related_name='+') # School tracker fields - Not required fields school = models.ForeignKey(School, on_delete=models.SET_NULL, null=True, blank=True) school_am_transport = models.CharField( max_length=256, null=True, blank=True, help_text="Transporting agency or vehicle description") school_am_pickup_time = models.CharField(max_length=256, null=True, blank=True) school_am_phone = models.CharField(max_length=64, null=True, blank=True) school_pm_transport = models.CharField( max_length=256, null=True, blank=True, help_text="Transporting agency or vehicle description") school_pm_dropoff_time = models.CharField(max_length=256, null=True, blank=True) school_pm_phone = models.CharField(max_length=64, null=True, blank=True) school_date_requested = models.DateField( 'date information was requested from school', null=True, blank=True) school_mkv_complete = models.BooleanField(default=False) notes = models.TextField(null=True, blank=True) def __str__(self): return 'Youth: ' + self.youth_id.youth_name + ' - Placement date: ' + str( self.current_placement_start_date) def is_active(self): '''Return True if the Youth for this visit is still active''' today = timezone_date() return self.visit_exit_date is None is_active.boolean = True is_active.short_description = 'Is Active?' def is_before_estimated_exited_date(self): '''Return True if the today is before the youth's estimated exit date''' today = timezone_date() return today <= self.estimated_exit_date() def estimated_exit_date(self): '''Compute the current estimated exit date for this youth's visit Estimated exit date = placement date + CURRENT placement type default stay duration Returns a datetime.date object ''' return self.current_placement_start_date + ( timedelta(days=self.current_placement_type.default_stay_length) + timedelta(days=self.current_placement_extension_days)) def total_days_stayed(self): '''Sums and returns the days in this visit, which can include multiple placements and extensions''' end_date = self.visit_exit_date if self.visit_exit_date != None else timezone_date( ) return (end_date - self.visit_start_date).days def form_type_progress(self): '''Computes the ratio of forms marked as completed for this youth's visit Forms are grouped into their type and a dictionary is returned with type/ratio pairs ''' result = {} # Builds a QuerySet of each FormType and the total count of forms with that type form_type_counts = FormType.objects.annotate(form_count=Count('form')) # Returns a QuerySet of forms completed for this visit youth_visit_done_forms = FormYouthVisit.objects.filter( youth_visit_id=self, status='done') for form_type in form_type_counts: # Counts the forms marked as done with each form type done_count = youth_visit_done_forms.filter( form_id__form_type_id=form_type).count() # Calculate the ratio, store with the key as the form type name if form_type.form_count == 0: result[form_type.form_type_name] = 0.0 else: result[form_type. form_type_name] = done_count / form_type.form_count return result def overall_form_progress(self): '''Return the percentage of forms completed out of possible forms as a ratio ''' # Count the total number of forms in the database youth_visit_total_forms = FormYouthVisit.objects.filter( youth_visit_id=self).count() # Count the number of forms maked as completed for this youth's visit youth_visit_done_form_count = FormYouthVisit.objects.filter( youth_visit_id=self, status='done').count() if youth_visit_total_forms == 0: return 0.0 return youth_visit_done_form_count / youth_visit_total_forms def get_absolute_url(self): return '/'
class Ligand(models.Model): properities = models.ForeignKey( 'LigandProperities', on_delete=models.CASCADE) name = models.TextField() pdbe = models.CharField(max_length=3, null=True) canonical = models.NullBooleanField() # required to flag 'safe' alias, eg one parent ambigious_alias = models.NullBooleanField() endogenous = models.BooleanField(default=False) def __str__(self): return self.name class Meta(): db_table = 'ligand' unique_together = ('name', 'canonical') def load_by_gtop_id(self, ligand_name, gtop_id, ligand_type): logger = logging.getLogger('build') # get the data from cache or web services cache_dir = ['guidetopharmacology', 'ligands'] url = 'http://www.guidetopharmacology.org/services/ligands/$index' gtop = fetch_from_web_api(url, gtop_id, cache_dir) if gtop: # get name from response ligand_name = gtop['name'] if ligand_name == '11-<i>cis</i>-retinal': ligand_name = 'retinal' # does a ligand by this name already exists? try: existing_ligand = Ligand.objects.get( name=ligand_name, canonical=True) return existing_ligand except Ligand.DoesNotExist: web_resource = False if gtop_id: # gtoplig webresource web_resource = WebResource.objects.get(slug='gtoplig') return self.update_ligand(ligand_name, {}, ligand_type, web_resource, gtop_id) def load_from_pubchem(self, lookup_type, pubchem_id, ligand_type, ligand_title=False, pdbe=None): logger = logging.getLogger('build') # if ligand title is specified, use that as the name if ligand_title: ligand_name = ligand_title # otherwise, fetch ligand name from pubchem else: # check cache cache_dir = ['pubchem', 'cid', 'synonyms'] url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/{}/$index/synonyms/json'.format( lookup_type) pubchem = fetch_from_web_api(url, pubchem_id, cache_dir) ##print (pubchem) # get name from response try: ligand_name = pubchem['InformationList']['Information'][0]['Synonym'][0] except: # Some compounds do not have a name but are still a valid pubchem entry. (Peptides) logger.warning( 'Ligand {} does not have a name in PubChem'.format(pubchem_id)) ligand_name = lookup_type + ' ' + pubchem_id # return None # fetch ligand properties from pubchem properties = {} # check cache cache_dir = ['pubchem', 'cid', 'property'] url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/{}/$index/property/CanonicalSMILES,InChIKey,MolecularWeight,HBondDonorCount,HBondAcceptorCount,XLogP,RotatableBondCount/json'.format( lookup_type) pubchem = fetch_from_web_api(url, pubchem_id, cache_dir) # get properties from response if pubchem == False: logger.warning('Ligand {} not found in PubChem'.format(pubchem_id)) return None if pubchem['PropertyTable']['Properties'][0]: if 'HBondAcceptorCount' in pubchem['PropertyTable']['Properties'][0]: properties['hacc'] = pubchem['PropertyTable']['Properties'][0]['HBondAcceptorCount'] if 'HBondDonorCount' in pubchem['PropertyTable']['Properties'][0]: properties['hdon'] = pubchem['PropertyTable']['Properties'][0]['HBondDonorCount'] if 'XLogP' in pubchem['PropertyTable']['Properties'][0]: properties['logp'] = pubchem['PropertyTable']['Properties'][0]['XLogP'] if 'RotatableBondCount' in pubchem['PropertyTable']['Properties'][0]: properties['rotatable_bonds'] = pubchem['PropertyTable']['Properties'][0]['RotatableBondCount'] if 'MolecularWeight' in pubchem['PropertyTable']['Properties'][0]: properties['mw'] = pubchem['PropertyTable']['Properties'][0]['MolecularWeight'] try: properties['smiles'] = pubchem['PropertyTable']['Properties'][0]['CanonicalSMILES'] properties['inchikey'] = pubchem['PropertyTable']['Properties'][0]['InChIKey'] except: logger.warning('Ligand {} not found in PubChem'.format(pubchem_id)) return None # pubchem webresource web_resource = WebResource.objects.get(slug='pubchem') #print (web_resource) # does a ligand with this canonical name already exist try: return Ligand.objects.get(name=ligand_name, canonical=True) # FIXME check inchikey except Ligand.DoesNotExist: pass # continue # does a (canonical) ligand with this inchikey already exist? try: existing_lp = LigandProperities.objects.get( inchikey=properties['inchikey']) self.properities = existing_lp self.name = ligand_name self.canonical = False self.ambigious_alias = False self.pdbe = pdbe try: self.save() return self except IntegrityError: return Ligand.objects.get(name=ligand_name, canonical=False) except LigandProperities.DoesNotExist: return self.update_ligand(ligand_name, properties, ligand_type, web_resource, pubchem_id, pdbe) def update_ligand(self, ligand_name, properties, ligand_type, web_resource=False, web_resource_index=False, pdbe=None): lp = LigandProperities.objects.create(ligand_type=ligand_type) # assign properties for prop in properties: setattr(lp, prop, properties[prop]) # assign web link if web_resource and web_resource_index: try: wl, created = WebLink.objects.get_or_create( index=web_resource_index, web_resource=web_resource) except IntegrityError: wl = WebLink.objects.get( index=web_resource_index, web_resource=web_resource) lp.web_links.add(wl) # try saving the properties, catch IntegrityErrors due to concurrent processing try: lp.save() except IntegrityError: lp = LigandProperities.objects.get(inchikey=properties['inchikey']) self.name = ligand_name self.canonical = True self.ambigious_alias = False self.properities = lp self.pdbe = pdbe try: self.save() return self except IntegrityError: return Ligand.objects.get(name=ligand_name, canonical=True) def load_by_name(self, name): logger = logging.getLogger('build') # fetch ligand info from pubchem - start by getting name and 'canonical' name pubchem_url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/' + \ name + '/synonyms/TXT' # if inchikey has been added use this -- especially to avoid updating a wrong inchikey to a synonym. if self.properities.inchikey: pubchem_url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/InchiKey/' + \ self.properities.inchikey + '/synonyms/TXT' try: req = urlopen(pubchem_url) pubchem = req.read().decode('UTF-8').splitlines() pubchem_name = pubchem[0] except: # name not matched in pubchem if self.properities.inchikey: # if inchikey has been added for check this pubchem_url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/InchiKey/' + \ self.properities.inchikey + '/synonyms/TXT' try: req = urlopen(pubchem_url) pubchem = req.read().decode('UTF-8').splitlines() pubchem_name = pubchem[0] except: # name not matched in pubchem - exit cos something is wrong logger.info( 'Ligand not found by InchiKey in pubchem: ' + str(self.properities.inchikey)) return else: # if name not found and no inchikey, then no point in looking further logger.info( 'Ligand not found in pubchem by name (Consider renaming): ' + str(name)) return pubchem_url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/name/' + \ quote(pubchem_name) + '/property/CanonicalSMILES,InChIKey/json' if self.properities.inchikey: pubchem_url = 'https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/inChiKey/' + \ self.properities.inchikey + '/property/CanonicalSMILES,InChIKey/json' try: req = urlopen(pubchem_url) pubchem = json.loads(req.read().decode('UTF-8')) except: # JSON failed return # weblink pubchem_id = pubchem['PropertyTable']['Properties'][0]['CID'] try: web_resource = WebResource.objects.get(slug='pubchem') except: # abort if pdb resource is not found raise Exception('PubChem resource not found, aborting!') pubchem_inchikey = '' pubchem_smiles = '' # SMILES pubchem_smiles = pubchem['PropertyTable']['Properties'][0]['CanonicalSMILES'] # InChIKey pubchem_inchikey = pubchem['PropertyTable']['Properties'][0]['InChIKey'] try: # now that we have inchikey, try and see if it exists in DB existing_lp = LigandProperities.objects.get( inchikey=pubchem_inchikey) self.properities = existing_lp except: wl, created = WebLink.objects.get_or_create( index=pubchem_id, web_resource=web_resource) self.properities.web_links.add(wl) # ligand type self.properities.ligand_type, created = LigandType.objects.get_or_create( slug='sm', defaults={'name': 'Small molecule'}) self.properities.inchikey = pubchem_inchikey self.properities.smiles = pubchem_smiles self.properities.save() if pubchem_name.lower() != name.lower(): # if not canonical name logger.info("Updating canonical flag to Pubchem. PubChem canonical: " + pubchem_name + ". DB canonical: " + name) self.canonical = False try: self.save() except IntegrityError: logger.error("FAILED SAVING LIGAND, duplicate?") # NEED TO CHECK BY INCHI KEY - SOME CANONICAL NAMES HAVE MANY ICHIKEYS (DOXEPIN) canonical_entry = Ligand.objects.filter( name=pubchem_name, properities__inchikey=pubchem_inchikey) if canonical_entry.exists(): return else: # insert the 'canonical' entry try: canonical_entry = Ligand() canonical_entry.name = pubchem_name canonical_entry.canonical = True canonical_entry.properities = self.properities canonical_entry.save() except IntegrityError: logger.error( "FAILED SAVING CANONICAL LIGAND, duplicate? " + pubchem_name + " " + name) print("FAILED SAVING CANONICAL LIGAND, duplicate? " + pubchem_name + " " + name)
def test_null_boolean_field_raises_error_message(self): f = models.NullBooleanField() self._test_validation_messages( f, 'fõo', ["'fõo' value must be either None, True or False."])
class AbstractBaseJob(models.Model): STATUS = Choices( (0, 'created', _('Enqueued')), (1, 'started', _('In Progress')), (2, 'failed', _('Failed')), (3, 'succeeded', _('Succeeded')), (4, 'rescheduled', _('Rescheduled')), # Used to be "defunct" which turnout to be defunct # Removed to avoid confusion but number has been left the same for backwards compatibility (6, 'forced', _('Forced')), (7, 'skipped', _('Skipped')), (8, 'retried', _('Retrying')), (9, 'cancelled', _('Cancelled')), ) READY_STATUSES = ( STATUS.created, STATUS.started, STATUS.rescheduled, STATUS.cancelled, ) class SkipReasons(enum.Enum): duplicated = 'Previously Succeeded' encompassed = 'Encompassing task succeeded' comprised = 'Comprised of succeeded tasks' pointless = 'Any effects will be overwritten by another queued job' obsolete = 'Uses an old version of a dependency' task_id = models.UUIDField(null=True) status = models.IntegerField(db_index=True, choices=STATUS, default=STATUS.created) claimed = models.NullBooleanField() error_type = models.TextField(blank=True, null=True, db_index=True) error_message = models.TextField(blank=True, null=True, db_column='message') error_context = models.TextField(blank=True, default='', db_column='context') completions = models.IntegerField(default=0) date_started = models.DateTimeField(null=True, blank=True) date_created = models.DateTimeField(auto_now_add=True, editable=False) date_modified = models.DateTimeField(auto_now=True, editable=False, db_index=True) share_version = models.TextField(default=get_share_version, editable=False) objects = AbstractJobManager() class JSONAPIMeta(BaseJSONAPIMeta): pass class Meta: abstract = True ordering = ('-date_modified', ) def start(self, claim=False): # TODO double check existing values to make sure everything lines up. stamp = timezone.now() logger.debug('Setting %r to started at %r', self, stamp) self.status = self.STATUS.started self.claimed = claim self.date_started = stamp self.save(update_fields=('status', 'claimed', 'date_started', 'date_modified')) return True def fail(self, exception): logger.debug('Setting %r to failed due to %r', self, exception) self.error_message = exception if isinstance(exception, Exception): self.error_type = type(exception).__name__ tb = traceback.TracebackException.from_exception(exception) self.error_context = '\n'.join(tb.format(chain=True)) else: self.error_type = None self.error_context = '' self.status = self.STATUS.failed self.claimed = False self.save(update_fields=('status', 'error_type', 'error_message', 'error_context', 'claimed', 'date_modified')) return True def succeed(self): self.error_type = None self.error_message = None self.error_context = '' self.claimed = False self.completions += 1 self.status = self.STATUS.succeeded logger.debug('Setting %r to succeeded with %d completions', self, self.completions) self.save(update_fields=('status', 'error_type', 'error_message', 'error_context', 'completions', 'claimed', 'date_modified')) return True def reschedule(self, claim=False): self.status = self.STATUS.rescheduled self.claimed = claim self.save(update_fields=('status', 'claimed', 'date_modified')) return True def forced(self, exception): logger.debug('Setting %r to forced with error_context %r', self, exception) self.error_message = exception if isinstance(exception, Exception): self.error_type = type(exception).__name__ tb = traceback.TracebackException.from_exception(exception) self.error_context = '\n'.join(tb.format(chain=True)) else: self.error_type = None self.error_context = '' self.status = self.STATUS.forced self.claimed = False self.save(update_fields=('status', 'error_type', 'error_message', 'error_context', 'claimed', 'date_modified')) return True def skip(self, reason): logger.debug('Setting %r to skipped with context %r', self, reason) self.completions += 1 self.error_context = reason.value self.status = self.STATUS.skipped self.claimed = False self.save(update_fields=('status', 'error_context', 'completions', 'claimed', 'date_modified')) return True def cancel(self): logger.debug('Setting %r to cancelled', self) self.status = self.STATUS.cancelled self.claimed = False self.save(update_fields=('status', 'claimed', 'date_modified')) return True @contextmanager def handle(self): # Flush any pending changes. Any updates # beyond here will be field specific self.save() is_main_thread = threading.current_thread() == threading.main_thread() if is_main_thread: # Protect ourselves from SIGTERM def on_sigterm(sig, frame): self.cancel() prev_handler = signal.signal(signal.SIGTERM, on_sigterm) self.start() try: yield except Exception as e: self.fail(e) raise else: # If the handler didn't handle setting a status, assume success if self.status == self.STATUS.started: self.succeed() finally: if is_main_thread: # Detach from SIGTERM, resetting the previous handle signal.signal(signal.SIGTERM, prev_handler) def __repr__(self): return '<{} {} ({})>'.format(self.__class__.__name__, self.id, self.STATUS[self.status])
class GameReplay(models.Model): """ Represents a replay as captured from the point of view of a single packet stream sent to a Hearthstone client. Replays can be uploaded by either of the players or by any number of spectators who watched the match. It is possible that the same game could be uploaded from multiple points of view. When this happens each GameReplay will point to the same GlobalGame record via the global_game foreign key. It is possible that different uploads of the same game will have different information in them. For example: - If Player A and Player B are Real ID Friends and Player C is Battle.net friends with just Player B, then when Player C spectates a match between Players A and B, his uploaded replay will show the BattleTag as the name of Player A. However if Player B uploads a replay of the same match, his replay will show the real name for Player A. - Likewise, if Player C either starts spectating the game after it has already begun or stops spectating before it ends, then his uploaded replay will have fewer turns of gameplay then Player B's replay. """ class Meta: # ordering = ("global_game", ) # Ordering on global_game causes nasty inner joins. # We order by descending ID instead for now, until we have an upload_date. ordering = ("-id", ) # Replays are unique to a perspective on the game (global_game): # - client_handle: the *same* client cant be used for multiple replays # - reconnecting: We do not currently unify games where the player reconnects # - friendly_player_id: Unique across a client_handle and a spectator_mode unique_together = ( "global_game", "client_handle", "friendly_player_id", "spectator_mode", "reconnecting" ) id = models.BigAutoField(primary_key=True) shortid = ShortUUIDField("Short ID") upload_token = models.ForeignKey( AuthToken, on_delete=models.SET_NULL, null=True, blank=True, related_name="replays" ) user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True, related_name="replays" ) global_game = models.ForeignKey( GlobalGame, on_delete=models.CASCADE, related_name="replays", help_text="References the single global game that this replay shows." ) # The "friendly player" is the player whose cards are at the bottom of the # screen when watching a game. For spectators this is determined by which # player they started spectating first (if they spectate both). friendly_player_id = PlayerIDField( "Friendly PlayerID", null=True, help_text="PlayerID of the friendly player (1 or 2)", ) # When serving replay data in the security context of the user who uploaded this replay # this deck list should be used for the opponent, so as to avoid revealing unplayed cards # in the opponent's deck, which we might know in the case where multiple uploads were # unified. If the other uploader has set their replay visibility to private, then we cannot # leak the cards in their deck, via the globalgameplayer. opponent_revealed_deck = models.ForeignKey( Deck, on_delete=models.PROTECT, null=True, help_text="As much as is known of the opponent's starting deck list." ) # This is useful to know because replays that are spectating both players # will have more data then those from a single player. # For example, they will have access to the cards that are in each players hand. # This is detectable from the raw logs, although we currently intend to have # the client uploading the replay provide it. spectator_mode = models.BooleanField(default=False) spectator_password = models.CharField("Spectator Password", max_length=16, blank=True) client_handle = models.IntegerField(null=True, blank=True) aurora_password = models.CharField(max_length=16, blank=True) build = models.PositiveIntegerField("Hearthstone Build", null=True, blank=True) replay_xml = models.FileField(upload_to=generate_upload_path) hsreplay_version = models.CharField( "HSReplay library version", max_length=16, help_text="The HSReplay library version used to generate the replay", ) hslog_version = models.CharField( "hslog library version", max_length=24, help_text="The python-hearthstone library version at processing", null=True, # TODO: Remove this once the table is clean of NULLs ) upload_ip = models.GenericIPAddressField(null=True, help_text="Uploader IP address") user_agent = models.CharField(max_length=100, null=True, help_text="Uploader User-Agent") # The fields below capture the preferences of the user who uploaded it. is_deleted = models.BooleanField( "Soft deleted", default=False, help_text="Indicates user request to delete the upload" ) won = models.NullBooleanField() disconnected = models.BooleanField(default=False) reconnecting = models.BooleanField( "Is reconnecting", default=False, help_text="Whether the player is reconnecting to an existing game", ) resumable = models.NullBooleanField() visibility = IntEnumField(enum=Visibility, default=Visibility.Public) hide_player_names = models.BooleanField(default=False) views = models.PositiveIntegerField(default=0) objects = GameReplayManager() def __str__(self): return str(self.global_game) @property def pretty_name(self): return self.build_pretty_name() @property def pretty_name_spoilerfree(self): return self.build_pretty_name(spoilers=False) @property def upload_event_admin_url(self): from hsreplaynet.uploads.models import UploadEvent # These get garbage collected periodically # So this will not exist for old games upload_event = UploadEvent.objects.filter(shortid=self.shortid) if upload_event.count() > 0: return upload_event.first().get_admin_url() else: return None def build_pretty_name(self, spoilers=True): players = self.global_game.players.values_list("player_id", "final_state", "name") if len(players) != 2: return "Broken game (%i players)" % (len(players)) if players[0][0] == self.friendly_player_id: friendly, opponent = players else: opponent, friendly = players if spoilers: if self.disconnected: state = "Disconnected" elif self.won: state = "Won" elif friendly[1] == opponent[1]: state = "Tied" else: state = "Lost" return "%s (%s) vs. %s" % (friendly[2], state, opponent[2]) return "%s vs. %s" % (friendly[2], opponent[2]) def get_absolute_url(self): return reverse("games_replay_view", kwargs={"id": self.shortid}) def generate_description(self): tpl = "Watch a game of Hearthstone between %s (%s) and %s (%s) in your browser." players = self.global_game.players.all() if len(players) != 2: return "" player1, player2 = players[0], players[1] return tpl % ( player1, player1.hero.card_class.name.capitalize(), player2, player2.hero.card_class.name.capitalize() ) def player(self, number): for player in self.global_game.players.all(): if player.player_id == number: return player @property def friendly_player(self): return self.global_game.players.get(player_id=self.friendly_player_id) @property def friendly_deck(self): return self.friendly_player.deck_list @property def opposing_player(self): return self.global_game.players.exclude(player_id=self.friendly_player_id).get() @property def opposing_deck(self): return self.opponent_revealed_deck def related_replays(self, num=3): """ Returns RelatedReplayRecommendation objects similar to this one. The criteria used to generate the recommendations may vary across game types. """ from hsreplaynet.games.recommendations import recommend_related_replays return recommend_related_replays(self, num) def serialize(self): from hsreplaynet.api.serializers import GameReplaySerializer from .processing import get_replay_url s = GameReplaySerializer(self) serialized = s.data serialized["url"] = get_replay_url(self.shortid) return serialized
class OsfStorageFolder(OsfStorageFileNode, Folder): is_root = models.NullBooleanField() objects = OsfStorageFolderManager() @property def is_checked_out(self): sql = """ WITH RECURSIVE is_checked_out_cte(id, parent_id, checkout_id) AS ( SELECT T.id, T.parent_id, T.checkout_id FROM %s AS T WHERE T.id = %s UNION ALL SELECT T.id, T.parent_id, T.checkout_id FROM is_checked_out_cte AS R JOIN %s AS T ON T.parent_id = R.id ) SELECT N.checkout_id FROM is_checked_out_cte as N WHERE N.checkout_id IS NOT NULL LIMIT 1; """ with connection.cursor() as cursor: cursor.execute(sql, [ AsIs(self._meta.db_table), self.pk, AsIs(self._meta.db_table) ]) row = cursor.fetchone() if row and row[0]: return True return False @property def is_preprint_primary(self): if hasattr(self.target, 'primary_file') and self.target.primary_file: for child in self.children.all(): if getattr(child.target, 'primary_file', None): if child.is_preprint_primary: return True return False def serialize(self, include_full=False, version=None): # Versions just for compatibility ret = super(OsfStorageFolder, self).serialize() if include_full: ret['fullPath'] = self.materialized_path return ret def update_region_from_latest_version(self, destination_parent): for child in self.children.all().prefetch_related('versions'): child.update_region_from_latest_version(destination_parent)