mirror of https://github.com/zulip/zulip.git
models: Implicitly type model fields with django-stubs.
Previously, we type the model fields with explicit type annotations manually with the approximate types. This was because the lack of types for Django. django-stubs provides more specific types for all these fields that incompatible with our previous approximate annotations. So now we can remove the inline type annotations and rely on the types defined in the stubs. This allows mypy to infer the types of the model fields for us. Signed-off-by: Zixuan James Li <p359101898@gmail.com>
This commit is contained in:
parent
b28949b9e7
commit
4c3c976174
|
@ -1,5 +1,4 @@
|
||||||
import datetime
|
import datetime
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Q, UniqueConstraint
|
from django.db.models import Q, UniqueConstraint
|
||||||
|
@ -9,13 +8,13 @@ from zerver.models import Realm, Stream, UserProfile
|
||||||
|
|
||||||
|
|
||||||
class FillState(models.Model):
|
class FillState(models.Model):
|
||||||
property: str = models.CharField(max_length=40, unique=True)
|
property = models.CharField(max_length=40, unique=True)
|
||||||
end_time: datetime.datetime = models.DateTimeField()
|
end_time = models.DateTimeField()
|
||||||
|
|
||||||
# Valid states are {DONE, STARTED}
|
# Valid states are {DONE, STARTED}
|
||||||
DONE = 1
|
DONE = 1
|
||||||
STARTED = 2
|
STARTED = 2
|
||||||
state: int = models.PositiveSmallIntegerField()
|
state = models.PositiveSmallIntegerField()
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"<FillState: {self.property} {self.end_time} {self.state}>"
|
return f"<FillState: {self.property} {self.end_time} {self.state}>"
|
||||||
|
@ -34,10 +33,10 @@ class BaseCount(models.Model):
|
||||||
# Note: When inheriting from BaseCount, you may want to rearrange
|
# Note: When inheriting from BaseCount, you may want to rearrange
|
||||||
# the order of the columns in the migration to make sure they
|
# the order of the columns in the migration to make sure they
|
||||||
# match how you'd like the table to be arranged.
|
# match how you'd like the table to be arranged.
|
||||||
property: str = models.CharField(max_length=32)
|
property = models.CharField(max_length=32)
|
||||||
subgroup: Optional[str] = models.CharField(max_length=16, null=True)
|
subgroup = models.CharField(max_length=16, null=True)
|
||||||
end_time: datetime.datetime = models.DateTimeField()
|
end_time = models.DateTimeField()
|
||||||
value: int = models.BigIntegerField()
|
value = models.BigIntegerField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
|
@ -161,12 +161,12 @@ def confirmation_url(
|
||||||
|
|
||||||
class Confirmation(models.Model):
|
class Confirmation(models.Model):
|
||||||
content_type = models.ForeignKey(ContentType, on_delete=CASCADE)
|
content_type = models.ForeignKey(ContentType, on_delete=CASCADE)
|
||||||
object_id: int = models.PositiveIntegerField(db_index=True)
|
object_id = models.PositiveIntegerField(db_index=True)
|
||||||
content_object = GenericForeignKey("content_type", "object_id")
|
content_object = GenericForeignKey("content_type", "object_id")
|
||||||
date_sent: datetime.datetime = models.DateTimeField(db_index=True)
|
date_sent = models.DateTimeField(db_index=True)
|
||||||
confirmation_key: str = models.CharField(max_length=40, db_index=True)
|
confirmation_key = models.CharField(max_length=40, db_index=True)
|
||||||
expiry_date: Optional[datetime.datetime] = models.DateTimeField(db_index=True, null=True)
|
expiry_date = models.DateTimeField(db_index=True, null=True)
|
||||||
realm: Optional[Realm] = models.ForeignKey(Realm, null=True, on_delete=CASCADE)
|
realm = models.ForeignKey(Realm, null=True, on_delete=CASCADE)
|
||||||
|
|
||||||
# The following list is the set of valid types
|
# The following list is the set of valid types
|
||||||
USER_REGISTRATION = 1
|
USER_REGISTRATION = 1
|
||||||
|
@ -177,7 +177,7 @@ class Confirmation(models.Model):
|
||||||
MULTIUSE_INVITE = 6
|
MULTIUSE_INVITE = 6
|
||||||
REALM_CREATION = 7
|
REALM_CREATION = 7
|
||||||
REALM_REACTIVATION = 8
|
REALM_REACTIVATION = 8
|
||||||
type: int = models.PositiveSmallIntegerField()
|
type = models.PositiveSmallIntegerField()
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"<Confirmation: {self.content_object}>"
|
return f"<Confirmation: {self.content_object}>"
|
||||||
|
@ -264,7 +264,7 @@ class RealmCreationKey(models.Model):
|
||||||
|
|
||||||
# True just if we should presume the email address the user enters
|
# True just if we should presume the email address the user enters
|
||||||
# is theirs, and skip sending mail to it to confirm that.
|
# is theirs, and skip sending mail to it to confirm that.
|
||||||
presume_email_valid: bool = models.BooleanField(default=False)
|
presume_email_valid = models.BooleanField(default=False)
|
||||||
|
|
||||||
class Invalid(Exception):
|
class Invalid(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import datetime
|
|
||||||
from decimal import Decimal
|
|
||||||
from typing import Any, Dict, Optional, Union
|
from typing import Any, Dict, Optional, Union
|
||||||
|
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
|
@ -18,21 +16,17 @@ class Customer(models.Model):
|
||||||
and the active plan, if any.
|
and the active plan, if any.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
realm: Optional[Realm] = models.OneToOneField(Realm, on_delete=CASCADE, null=True)
|
realm = models.OneToOneField(Realm, on_delete=CASCADE, null=True)
|
||||||
remote_server: Optional[RemoteZulipServer] = models.OneToOneField(
|
remote_server = models.OneToOneField(RemoteZulipServer, on_delete=CASCADE, null=True)
|
||||||
RemoteZulipServer, on_delete=CASCADE, null=True
|
stripe_customer_id = models.CharField(max_length=255, null=True, unique=True)
|
||||||
)
|
sponsorship_pending = models.BooleanField(default=False)
|
||||||
stripe_customer_id: Optional[str] = models.CharField(max_length=255, null=True, unique=True)
|
|
||||||
sponsorship_pending: bool = models.BooleanField(default=False)
|
|
||||||
# A percentage, like 85.
|
# A percentage, like 85.
|
||||||
default_discount: Optional[Decimal] = models.DecimalField(
|
default_discount = models.DecimalField(decimal_places=4, max_digits=7, null=True)
|
||||||
decimal_places=4, max_digits=7, null=True
|
|
||||||
)
|
|
||||||
# Some non-profit organizations on manual license management pay
|
# Some non-profit organizations on manual license management pay
|
||||||
# only for their paid employees. We don't prevent these
|
# only for their paid employees. We don't prevent these
|
||||||
# organizations from adding more users than the number of licenses
|
# organizations from adding more users than the number of licenses
|
||||||
# they purchased.
|
# they purchased.
|
||||||
exempt_from_from_license_number_check: bool = models.BooleanField(default=False)
|
exempt_from_from_license_number_check = models.BooleanField(default=False)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_self_hosted(self) -> bool:
|
def is_self_hosted(self) -> bool:
|
||||||
|
@ -96,8 +90,8 @@ def get_last_associated_event_by_type(
|
||||||
|
|
||||||
|
|
||||||
class Session(models.Model):
|
class Session(models.Model):
|
||||||
customer: Customer = models.ForeignKey(Customer, on_delete=CASCADE)
|
customer = models.ForeignKey(Customer, on_delete=CASCADE)
|
||||||
stripe_session_id: str = models.CharField(max_length=255, unique=True)
|
stripe_session_id = models.CharField(max_length=255, unique=True)
|
||||||
payment_intent = models.ForeignKey("PaymentIntent", null=True, on_delete=CASCADE)
|
payment_intent = models.ForeignKey("PaymentIntent", null=True, on_delete=CASCADE)
|
||||||
|
|
||||||
UPGRADE_FROM_BILLING_PAGE = 1
|
UPGRADE_FROM_BILLING_PAGE = 1
|
||||||
|
@ -105,11 +99,11 @@ class Session(models.Model):
|
||||||
FREE_TRIAL_UPGRADE_FROM_BILLING_PAGE = 20
|
FREE_TRIAL_UPGRADE_FROM_BILLING_PAGE = 20
|
||||||
FREE_TRIAL_UPGRADE_FROM_ONBOARDING_PAGE = 30
|
FREE_TRIAL_UPGRADE_FROM_ONBOARDING_PAGE = 30
|
||||||
CARD_UPDATE_FROM_BILLING_PAGE = 40
|
CARD_UPDATE_FROM_BILLING_PAGE = 40
|
||||||
type: int = models.SmallIntegerField()
|
type = models.SmallIntegerField()
|
||||||
|
|
||||||
CREATED = 1
|
CREATED = 1
|
||||||
COMPLETED = 10
|
COMPLETED = 10
|
||||||
status: int = models.SmallIntegerField(default=CREATED)
|
status = models.SmallIntegerField(default=CREATED)
|
||||||
|
|
||||||
def get_status_as_string(self) -> str:
|
def get_status_as_string(self) -> str:
|
||||||
return {Session.CREATED: "created", Session.COMPLETED: "completed"}[self.status]
|
return {Session.CREATED: "created", Session.COMPLETED: "completed"}[self.status]
|
||||||
|
@ -142,8 +136,8 @@ class Session(models.Model):
|
||||||
|
|
||||||
|
|
||||||
class PaymentIntent(models.Model):
|
class PaymentIntent(models.Model):
|
||||||
customer: Customer = models.ForeignKey(Customer, on_delete=CASCADE)
|
customer = models.ForeignKey(Customer, on_delete=CASCADE)
|
||||||
stripe_payment_intent_id: str = models.CharField(max_length=255, unique=True)
|
stripe_payment_intent_id = models.CharField(max_length=255, unique=True)
|
||||||
|
|
||||||
REQUIRES_PAYMENT_METHOD = 1
|
REQUIRES_PAYMENT_METHOD = 1
|
||||||
REQUIRES_CONFIRMATION = 20
|
REQUIRES_CONFIRMATION = 20
|
||||||
|
@ -153,7 +147,7 @@ class PaymentIntent(models.Model):
|
||||||
CANCELLED = 60
|
CANCELLED = 60
|
||||||
SUCCEEDED = 70
|
SUCCEEDED = 70
|
||||||
|
|
||||||
status: int = models.SmallIntegerField()
|
status = models.SmallIntegerField()
|
||||||
last_payment_error = models.JSONField(default=None, null=True)
|
last_payment_error = models.JSONField(default=None, null=True)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -200,47 +194,47 @@ class CustomerPlan(models.Model):
|
||||||
# A customer can only have one ACTIVE plan, but old, inactive plans
|
# A customer can only have one ACTIVE plan, but old, inactive plans
|
||||||
# are preserved to allow auditing - so there can be multiple
|
# are preserved to allow auditing - so there can be multiple
|
||||||
# CustomerPlan objects pointing to one Customer.
|
# CustomerPlan objects pointing to one Customer.
|
||||||
customer: Customer = models.ForeignKey(Customer, on_delete=CASCADE)
|
customer = models.ForeignKey(Customer, on_delete=CASCADE)
|
||||||
|
|
||||||
automanage_licenses: bool = models.BooleanField(default=False)
|
automanage_licenses = models.BooleanField(default=False)
|
||||||
charge_automatically: bool = models.BooleanField(default=False)
|
charge_automatically = models.BooleanField(default=False)
|
||||||
|
|
||||||
# Both of these are in cents. Exactly one of price_per_license or
|
# Both of these are in cents. Exactly one of price_per_license or
|
||||||
# fixed_price should be set. fixed_price is only for manual deals, and
|
# fixed_price should be set. fixed_price is only for manual deals, and
|
||||||
# can't be set via the self-serve billing system.
|
# can't be set via the self-serve billing system.
|
||||||
price_per_license: Optional[int] = models.IntegerField(null=True)
|
price_per_license = models.IntegerField(null=True)
|
||||||
fixed_price: Optional[int] = models.IntegerField(null=True)
|
fixed_price = models.IntegerField(null=True)
|
||||||
|
|
||||||
# Discount that was applied. For display purposes only.
|
# Discount that was applied. For display purposes only.
|
||||||
discount: Optional[Decimal] = models.DecimalField(decimal_places=4, max_digits=6, null=True)
|
discount = models.DecimalField(decimal_places=4, max_digits=6, null=True)
|
||||||
|
|
||||||
# Initialized with the time of plan creation. Used for calculating
|
# Initialized with the time of plan creation. Used for calculating
|
||||||
# start of next billing cycle, next invoice date etc. This value
|
# start of next billing cycle, next invoice date etc. This value
|
||||||
# should never be modified. The only exception is when we change
|
# should never be modified. The only exception is when we change
|
||||||
# the status of the plan from free trial to active and reset the
|
# the status of the plan from free trial to active and reset the
|
||||||
# billing_cycle_anchor.
|
# billing_cycle_anchor.
|
||||||
billing_cycle_anchor: datetime.datetime = models.DateTimeField()
|
billing_cycle_anchor = models.DateTimeField()
|
||||||
|
|
||||||
ANNUAL = 1
|
ANNUAL = 1
|
||||||
MONTHLY = 2
|
MONTHLY = 2
|
||||||
billing_schedule: int = models.SmallIntegerField()
|
billing_schedule = models.SmallIntegerField()
|
||||||
|
|
||||||
# The next date the billing system should go through ledger
|
# The next date the billing system should go through ledger
|
||||||
# entries and create invoices for additional users or plan
|
# entries and create invoices for additional users or plan
|
||||||
# renewal. Since we use a daily cron job for invoicing, the
|
# renewal. Since we use a daily cron job for invoicing, the
|
||||||
# invoice will be generated the first time the cron job runs after
|
# invoice will be generated the first time the cron job runs after
|
||||||
# next_invoice_date.
|
# next_invoice_date.
|
||||||
next_invoice_date: Optional[datetime.datetime] = models.DateTimeField(db_index=True, null=True)
|
next_invoice_date = models.DateTimeField(db_index=True, null=True)
|
||||||
|
|
||||||
# On next_invoice_date, we go through ledger entries that were
|
# On next_invoice_date, we go through ledger entries that were
|
||||||
# created after invoiced_through and process them by generating
|
# created after invoiced_through and process them by generating
|
||||||
# invoices for any additional users and/or plan renewal. Once the
|
# invoices for any additional users and/or plan renewal. Once the
|
||||||
# invoice is generated, we update the value of invoiced_through
|
# invoice is generated, we update the value of invoiced_through
|
||||||
# and set it to the last ledger entry we processed.
|
# and set it to the last ledger entry we processed.
|
||||||
invoiced_through: Optional["LicenseLedger"] = models.ForeignKey(
|
invoiced_through = models.ForeignKey(
|
||||||
"LicenseLedger", null=True, on_delete=CASCADE, related_name="+"
|
"LicenseLedger", null=True, on_delete=CASCADE, related_name="+"
|
||||||
)
|
)
|
||||||
end_date: Optional[datetime.datetime] = models.DateTimeField(null=True)
|
end_date = models.DateTimeField(null=True)
|
||||||
|
|
||||||
DONE = 1
|
DONE = 1
|
||||||
STARTED = 2
|
STARTED = 2
|
||||||
|
@ -248,12 +242,12 @@ class CustomerPlan(models.Model):
|
||||||
# This status field helps ensure any errors encountered during the
|
# This status field helps ensure any errors encountered during the
|
||||||
# invoicing process do not leave our invoicing system in a broken
|
# invoicing process do not leave our invoicing system in a broken
|
||||||
# state.
|
# state.
|
||||||
invoicing_status: int = models.SmallIntegerField(default=DONE)
|
invoicing_status = models.SmallIntegerField(default=DONE)
|
||||||
|
|
||||||
STANDARD = 1
|
STANDARD = 1
|
||||||
PLUS = 2 # not available through self-serve signup
|
PLUS = 2 # not available through self-serve signup
|
||||||
ENTERPRISE = 10
|
ENTERPRISE = 10
|
||||||
tier: int = models.SmallIntegerField()
|
tier = models.SmallIntegerField()
|
||||||
|
|
||||||
ACTIVE = 1
|
ACTIVE = 1
|
||||||
DOWNGRADE_AT_END_OF_CYCLE = 2
|
DOWNGRADE_AT_END_OF_CYCLE = 2
|
||||||
|
@ -265,7 +259,7 @@ class CustomerPlan(models.Model):
|
||||||
LIVE_STATUS_THRESHOLD = 10
|
LIVE_STATUS_THRESHOLD = 10
|
||||||
ENDED = 11
|
ENDED = 11
|
||||||
NEVER_STARTED = 12
|
NEVER_STARTED = 12
|
||||||
status: int = models.SmallIntegerField(default=ACTIVE)
|
status = models.SmallIntegerField(default=ACTIVE)
|
||||||
|
|
||||||
# TODO maybe override setattr to ensure billing_cycle_anchor, etc
|
# TODO maybe override setattr to ensure billing_cycle_anchor, etc
|
||||||
# are immutable.
|
# are immutable.
|
||||||
|
@ -329,38 +323,38 @@ class LicenseLedger(models.Model):
|
||||||
in case of issues.
|
in case of issues.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
plan: CustomerPlan = models.ForeignKey(CustomerPlan, on_delete=CASCADE)
|
plan = models.ForeignKey(CustomerPlan, on_delete=CASCADE)
|
||||||
|
|
||||||
# Also True for the initial upgrade.
|
# Also True for the initial upgrade.
|
||||||
is_renewal: bool = models.BooleanField(default=False)
|
is_renewal = models.BooleanField(default=False)
|
||||||
|
|
||||||
event_time: datetime.datetime = models.DateTimeField()
|
event_time = models.DateTimeField()
|
||||||
|
|
||||||
# The number of licenses ("seats") purchased by the the organization at the time of ledger
|
# The number of licenses ("seats") purchased by the the organization at the time of ledger
|
||||||
# entry creation. Normally, to add a user the organization needs at least one spare license.
|
# entry creation. Normally, to add a user the organization needs at least one spare license.
|
||||||
# Once a license is purchased, it is valid till the end of the billing period, irrespective
|
# Once a license is purchased, it is valid till the end of the billing period, irrespective
|
||||||
# of whether the license is used or not. So the value of licenses will never decrease for
|
# of whether the license is used or not. So the value of licenses will never decrease for
|
||||||
# subsequent LicenseLedger entries in the same billing period.
|
# subsequent LicenseLedger entries in the same billing period.
|
||||||
licenses: int = models.IntegerField()
|
licenses = models.IntegerField()
|
||||||
|
|
||||||
# The number of licenses the organization needs in the next billing cycle. The value of
|
# The number of licenses the organization needs in the next billing cycle. The value of
|
||||||
# licenses_at_next_renewal can increase or decrease for subsequent LicenseLedger entries in
|
# licenses_at_next_renewal can increase or decrease for subsequent LicenseLedger entries in
|
||||||
# the same billing period. For plans on automatic license management this value is usually
|
# the same billing period. For plans on automatic license management this value is usually
|
||||||
# equal to the number of activated users in the organization.
|
# equal to the number of activated users in the organization.
|
||||||
licenses_at_next_renewal: Optional[int] = models.IntegerField(null=True)
|
licenses_at_next_renewal = models.IntegerField(null=True)
|
||||||
|
|
||||||
|
|
||||||
class ZulipSponsorshipRequest(models.Model):
|
class ZulipSponsorshipRequest(models.Model):
|
||||||
id: int = models.AutoField(auto_created=True, primary_key=True, verbose_name="ID")
|
id = models.AutoField(auto_created=True, primary_key=True, verbose_name="ID")
|
||||||
realm: Realm = models.ForeignKey(Realm, on_delete=CASCADE)
|
realm = models.ForeignKey(Realm, on_delete=CASCADE)
|
||||||
requested_by: UserProfile = models.ForeignKey(UserProfile, on_delete=CASCADE)
|
requested_by = models.ForeignKey(UserProfile, on_delete=CASCADE)
|
||||||
|
|
||||||
org_type: int = models.PositiveSmallIntegerField(
|
org_type = models.PositiveSmallIntegerField(
|
||||||
default=Realm.ORG_TYPES["unspecified"]["id"],
|
default=Realm.ORG_TYPES["unspecified"]["id"],
|
||||||
choices=[(t["id"], t["name"]) for t in Realm.ORG_TYPES.values()],
|
choices=[(t["id"], t["name"]) for t in Realm.ORG_TYPES.values()],
|
||||||
)
|
)
|
||||||
|
|
||||||
MAX_ORG_URL_LENGTH: int = 200
|
MAX_ORG_URL_LENGTH: int = 200
|
||||||
org_website: str = models.URLField(max_length=MAX_ORG_URL_LENGTH, blank=True, null=True)
|
org_website = models.URLField(max_length=MAX_ORG_URL_LENGTH, blank=True, null=True)
|
||||||
|
|
||||||
org_description: str = models.TextField(default="")
|
org_description = models.TextField(default="")
|
||||||
|
|
868
zerver/models.py
868
zerver/models.py
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,4 @@
|
||||||
import datetime
|
|
||||||
from typing import List, Tuple
|
from typing import List, Tuple
|
||||||
from uuid import UUID
|
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
@ -31,25 +29,25 @@ class RemoteZulipServer(models.Model):
|
||||||
|
|
||||||
# The unique UUID (`zulip_org_id`) and API key (`zulip_org_key`)
|
# The unique UUID (`zulip_org_id`) and API key (`zulip_org_key`)
|
||||||
# for this remote server registration.
|
# for this remote server registration.
|
||||||
uuid: UUID = models.UUIDField(unique=True)
|
uuid = models.UUIDField(unique=True)
|
||||||
api_key: str = models.CharField(max_length=API_KEY_LENGTH)
|
api_key = models.CharField(max_length=API_KEY_LENGTH)
|
||||||
|
|
||||||
# The hostname and contact details are not verified/trusted. Thus,
|
# The hostname and contact details are not verified/trusted. Thus,
|
||||||
# they primarily exist so that we can communicate with the
|
# they primarily exist so that we can communicate with the
|
||||||
# maintainer of a server about abuse problems.
|
# maintainer of a server about abuse problems.
|
||||||
hostname: str = models.CharField(max_length=HOSTNAME_MAX_LENGTH)
|
hostname = models.CharField(max_length=HOSTNAME_MAX_LENGTH)
|
||||||
contact_email: str = models.EmailField(blank=True, null=False)
|
contact_email = models.EmailField(blank=True, null=False)
|
||||||
last_updated: datetime.datetime = models.DateTimeField("last updated", auto_now=True)
|
last_updated = models.DateTimeField("last updated", auto_now=True)
|
||||||
|
|
||||||
# Whether the server registration has been deactivated.
|
# Whether the server registration has been deactivated.
|
||||||
deactivated: bool = models.BooleanField(default=False)
|
deactivated = models.BooleanField(default=False)
|
||||||
|
|
||||||
# Plan types for self-hosted customers
|
# Plan types for self-hosted customers
|
||||||
PLAN_TYPE_SELF_HOSTED = 1
|
PLAN_TYPE_SELF_HOSTED = 1
|
||||||
PLAN_TYPE_STANDARD = 102
|
PLAN_TYPE_STANDARD = 102
|
||||||
|
|
||||||
# The current billing plan for the remote server, similar to Realm.plan_type.
|
# The current billing plan for the remote server, similar to Realm.plan_type.
|
||||||
plan_type: int = models.PositiveSmallIntegerField(default=PLAN_TYPE_SELF_HOSTED)
|
plan_type = models.PositiveSmallIntegerField(default=PLAN_TYPE_SELF_HOSTED)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"<RemoteZulipServer {self.hostname} {str(self.uuid)[0:12]}>"
|
return f"<RemoteZulipServer {self.hostname} {str(self.uuid)[0:12]}>"
|
||||||
|
@ -61,10 +59,10 @@ class RemoteZulipServer(models.Model):
|
||||||
class RemotePushDeviceToken(AbstractPushDeviceToken):
|
class RemotePushDeviceToken(AbstractPushDeviceToken):
|
||||||
"""Like PushDeviceToken, but for a device connected to a remote server."""
|
"""Like PushDeviceToken, but for a device connected to a remote server."""
|
||||||
|
|
||||||
server: RemoteZulipServer = models.ForeignKey(RemoteZulipServer, on_delete=models.CASCADE)
|
server = models.ForeignKey(RemoteZulipServer, on_delete=models.CASCADE)
|
||||||
# The user id on the remote server for this device
|
# The user id on the remote server for this device
|
||||||
user_id: int = models.BigIntegerField(null=True)
|
user_id = models.BigIntegerField(null=True)
|
||||||
user_uuid: UUID = models.UUIDField(null=True)
|
user_uuid = models.UUIDField(null=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = [
|
unique_together = [
|
||||||
|
@ -90,7 +88,7 @@ class RemoteZulipServerAuditLog(AbstractRealmAuditLog):
|
||||||
authoritative storage location for the server's history.
|
authoritative storage location for the server's history.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
server: RemoteZulipServer = models.ForeignKey(RemoteZulipServer, on_delete=models.CASCADE)
|
server = models.ForeignKey(RemoteZulipServer, on_delete=models.CASCADE)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"<RemoteZulipServerAuditLog: {self.server} {self.event_type} {self.event_time} {self.id}>"
|
return f"<RemoteZulipServerAuditLog: {self.server} {self.event_type} {self.event_time} {self.id}>"
|
||||||
|
@ -101,19 +99,19 @@ class RemoteRealmAuditLog(AbstractRealmAuditLog):
|
||||||
billing. See RealmAuditLog and AbstractRealmAuditLog for details.
|
billing. See RealmAuditLog and AbstractRealmAuditLog for details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
server: RemoteZulipServer = models.ForeignKey(RemoteZulipServer, on_delete=models.CASCADE)
|
server = models.ForeignKey(RemoteZulipServer, on_delete=models.CASCADE)
|
||||||
realm_id: int = models.IntegerField(db_index=True)
|
realm_id = models.IntegerField(db_index=True)
|
||||||
# The remote_id field lets us deduplicate data from the remote server
|
# The remote_id field lets us deduplicate data from the remote server
|
||||||
remote_id: int = models.IntegerField(db_index=True)
|
remote_id = models.IntegerField(db_index=True)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"<RemoteRealmAuditLog: {self.server} {self.event_type} {self.event_time} {self.id}>"
|
return f"<RemoteRealmAuditLog: {self.server} {self.event_type} {self.event_time} {self.id}>"
|
||||||
|
|
||||||
|
|
||||||
class RemoteInstallationCount(BaseCount):
|
class RemoteInstallationCount(BaseCount):
|
||||||
server: RemoteZulipServer = models.ForeignKey(RemoteZulipServer, on_delete=models.CASCADE)
|
server = models.ForeignKey(RemoteZulipServer, on_delete=models.CASCADE)
|
||||||
# The remote_id field lets us deduplicate data from the remote server
|
# The remote_id field lets us deduplicate data from the remote server
|
||||||
remote_id: int = models.IntegerField(db_index=True)
|
remote_id = models.IntegerField(db_index=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("server", "property", "subgroup", "end_time")
|
unique_together = ("server", "property", "subgroup", "end_time")
|
||||||
|
@ -127,10 +125,10 @@ class RemoteInstallationCount(BaseCount):
|
||||||
|
|
||||||
# We can't subclass RealmCount because we only have a realm_id here, not a foreign key.
|
# We can't subclass RealmCount because we only have a realm_id here, not a foreign key.
|
||||||
class RemoteRealmCount(BaseCount):
|
class RemoteRealmCount(BaseCount):
|
||||||
server: RemoteZulipServer = models.ForeignKey(RemoteZulipServer, on_delete=models.CASCADE)
|
server = models.ForeignKey(RemoteZulipServer, on_delete=models.CASCADE)
|
||||||
realm_id: int = models.IntegerField(db_index=True)
|
realm_id = models.IntegerField(db_index=True)
|
||||||
# The remote_id field lets us deduplicate data from the remote server
|
# The remote_id field lets us deduplicate data from the remote server
|
||||||
remote_id: int = models.IntegerField(db_index=True)
|
remote_id = models.IntegerField(db_index=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ("server", "realm_id", "property", "subgroup", "end_time")
|
unique_together = ("server", "realm_id", "property", "subgroup", "end_time")
|
||||||
|
|
Loading…
Reference in New Issue