Пример #1
0
class Invitation(models.Model):
    person = models.ForeignKey(Person, related_name='invitations')
    invited_by = models.ForeignKey(Person, related_name='sent_invitations')
    email = models.EmailField()
    message = models.TextField(null=True, blank=True)
    datetime = models.DateTimeField(auto_now_add=True)
    uuid = uuidfield.UUIDField(auto=True)

    def is_expired(self):
        return hasattr(self.person, 'user')

    def send(self):
        subject = _("Invitation to V LO graduates community.")
        context = {
            'person': self.person,
            'invited_by': self.invited_by,
            'message': self.message
        }

        send_templated_email(
            subject,
            'community/invite.html',
            context,
            [self.email],
        )
class Migration(migrations.Migration):

    dependencies = []

    operations = [
        migrations.CreateModel(
            name='DbOwnersManagerTable',
            fields=[
                ('customer_id',
                 uuidfield.UUIDField(primary_key=True,
                                     serialize=False,
                                     editable=False,
                                     max_length=32,
                                     blank=True,
                                     unique=True)),
                ('customer_name', models.CharField(unique=True,
                                                   max_length=100)),
                ('customer_description', models.CharField(max_length=500)),
                ('db_manager_settings', models.CharField(max_length=2000)),
                ('creation_time',
                 models.DateTimeField(auto_now_add=True, null=True)),
                ('last_update_time',
                 models.DateTimeField(auto_now=True, null=True)),
                ('wx_appid', models.CharField(max_length=200)),
                ('wx_appsecret', models.CharField(max_length=200)),
            ],
            options={},
            bases=(models.Model, ),
        ),
        migrations.CreateModel(
            name='WeixinUser',
            fields=[
                ('weixinuser_id',
                 models.CharField(max_length=50,
                                  serialize=False,
                                  primary_key=True)),
                ('nick_name', models.CharField(max_length=150)),
                ('creation_time',
                 models.DateTimeField(auto_now_add=True, null=True)),
                ('last_message_time',
                 models.DateTimeField(auto_now=True, null=True)),
                ('menu_flag', models.SmallIntegerField(default=0)),
                ('person_loate', models.CharField(max_length=100)),
                ('person_deliver_info', models.BinaryField(max_length=1000)),
                ('user_is_subscribe', models.IntegerField(default=0)),
                ('user_wx_nickname', models.BinaryField(max_length=200)),
                ('user_wx_sex', models.IntegerField(default=0)),
                ('user_wx_img', models.CharField(max_length=500)),
                ('user_wx_subscribe_time', models.IntegerField(default=0)),
                ('user_wx_remark', models.CharField(max_length=500)),
                ('user_wx_group_id', models.IntegerField(default=0)),
                ('user_last_wx_info_update_time',
                 models.DateTimeField(null=True)),
            ],
            options={},
            bases=(models.Model, ),
        ),
    ]
Пример #3
0
class Invitation(models.Model):
    person = models.ForeignKey(Person, related_name='invitations')
    invited_by = models.ForeignKey(Person, related_name='sent_invitations')
    email = models.EmailField()
    message = models.TextField(null=True, blank=True)
    datetime = models.DateTimeField(auto_now_add=True)
    uuid = uuidfield.UUIDField(auto=True)

    def is_expired(self):
        return hasattr(self.person, 'user')
Пример #4
0
class Job(models.Model):

    STATES = Choices("NEW", "READY", "PROCESSING", "FAILED", "COMPLETE")

    id = uuidfield.UUIDField(primary_key=True, auto=True, db_index=True)
    created = models.DateTimeField(auto_now_add=True, db_index=True)
    modified = models.DateTimeField(auto_now=True)
    name = models.CharField(max_length=100)
    state = models.CharField(max_length=20,
                             choices=STATES,
                             default=STATES.NEW,
                             db_index=True)
    next_task = models.CharField(max_length=100, blank=True)
    workspace = JSONField(null=True)
    queue_name = models.CharField(max_length=20,
                                  default='default',
                                  db_index=True)

    class Meta:
        ordering = ['-created']

    objects = JobManager()

    def save(self, *args, **kwargs):
        if not self.pk:
            self.next_task = get_next_task_name(self.name)
            self.workspace = self.workspace or {}

            try:
                self.run_creation_hook()
            except Exception as exception:  # noqa
                logger.exception(
                    "Failed to create new job, creation hook raised an exception"
                )
                return  # cancel the save

        return super(Job, self).save(*args, **kwargs)

    def update_next_task(self):
        self.next_task = get_next_task_name(self.name, self.next_task) or ''

    def get_failure_hook_name(self):
        return get_failure_hook_name(self.name)

    def get_creation_hook_name(self):
        return get_creation_hook_name(self.name)

    def run_creation_hook(self):
        creation_hook_name = self.get_creation_hook_name()
        if creation_hook_name:
            logger.info("Running creation hook %s for new job",
                        creation_hook_name)
            creation_hook_function = import_by_path(creation_hook_name)
            creation_hook_function(self)
Пример #5
0
class LoadBalancer(models.Model):
    """
    Load balancers adhere to a `protocol` (http and tcp for now).

    For rackspace, the endpoint is set until the load balancer is deleted.
    For docker, the endpoint will change on each system startup.

    port_name is the name of the instance port that should be used to propagate
    to the lb backend.
    """
    id = uuidfield.UUIDField(primary_key=True)
    port_name = models.TextField(validators=[alphanumeric])
    protocol = models.CharField(max_length=10,
                                choices=(('http', 'http'), ('tcp', 'tcp')))
    options = jsonfield.JSONField(default={})

    @classmethod
    def create(cls, group, port_name, protocol, options={}):
        """
        :Parameters:
          - `options`: {
                'securePort': 443,
                'sslTermination': True,
                'secureTrafficOnly': False,
                'certificate': '<cert>',
                'privatekey': '<key>'
            }
        """
        lb_id = uuid.uuid4().hex
        lb = cls(id=lb_id,
                 port_name=port_name,
                 protocol=protocol,
                 options=options)
        lb.group = group
        host, port = lb.backend.create_lb(lb)

        # Add key to config
        lb.group.environment.system.config_manager.set(
            lb.config_key, json.dumps({
                'host': host,
                'port': port
            }))

        # Add group to endpoint supervisor
        endpoints = supervisors.endpoint_supervisor_client()
        endpoints.add_group(lb.group.pk, lb.group.config_key)
        lb.save()

        return lb

    def add_endpoint(self, endpoint):
        """
        Chooses and adds an endpoint to the load balancer.

        :Parameters:
          - `endpoint`: {
            'host': '11.22.33.44',
            'ports': {'http': 80, 'https': 443}
          }
        """
        self._apply_endpoint(self.backend.lb_add_endpoint, endpoint)

    def remove_endpoint(self, endpoint):
        """
        Chooses and removes an endpoint from the load balancer.

        :Parameters:
          - `endpoint`: {
            'host': '11.22.33.44',
            'ports': {'http': 80, 'https': 443}
          }
        """
        self._apply_endpoint(self.backend.lb_remove_endpoint, endpoint)

    def _apply_endpoint(self, func, endpoint):
        host = endpoint['host']
        port = endpoint['ports'].get(self.port_name)
        if port != None:
            func(self, host, port)
        else:
            log.info('Unable to find port with name "%s"' % self.port_name)

    @property
    def backend(self):
        backend = self.group.environment.backend
        if not backend:
            raise Exception('no backend defined for environment')
        return backend

    @property
    def config_key(self):
        """
        Returns the load balancer's key in the configuration manager.
        """
        return self.group.environment.system.config_manager.get_lb_key(self)

    @classmethod
    def pre_delete(cls, sender, instance, **kwargs):
        lb = instance
        # Remove group from endpoint supervisor
        endpoints = supervisors.endpoint_supervisor_client()
        endpoints.remove_group(lb.group.pk)
        # Remove key from config
        lb.group.environment.system.config_manager.delete(lb.config_key)
        lb.backend.delete_lb(lb)
Пример #6
0
class Instance(AuditedModel):
    """
    A running instance of a node.
    """
    id = uuidfield.UUIDField(auto=True, primary_key=True)
    environment = models.ForeignKey('Environment', related_name='instances')
    host = models.ForeignKey('Host', related_name='instances')
    node = models.ForeignKey('Node', related_name='instances')

    @classmethod
    def create(cls, env, host, node):
        """
        Creates an instance through the host's agent.

        :Parameters:
          - `env`: the instance's environment.
          - `host`: the instance's host.
          - `node`: the instance's node.
        """
        instance = cls(environment=env, host=host, node=node)
        instance.save()
        # REM: block
        instance.sync_node(node)
        # REM: block
        host.agent.add_instance(instance)

        return instance

    def sync_node(self, node):
        """
        Sync the instance's node to the agent. The node will be pulled if it
        isn't there already.

        :Parameters:
          - `node`: the node to sync
        """
        # REM: block
        if node not in self.host.nodes:
            self.host.agent.add_node(node)
            if self.environment.current_release:
                # Use the environment's release
                self.host.agent.pull(node,
                                     release=self.environment.current_release)
            elif self.environment.using_source:
                self.host.agent.pull(node)
            else:
                # Environment has not yet been deployed to
                pass

    def reload(self):
        """
        Since reload is only used in development, there is no need to update
        the load balancer.
        """
        return self.host.agent.reload_instance(self)

    @property
    def load_balancer(self):
        """
        Returns the instance's parent load balancer.
        """
        if self.host.group:
            return self.host.group.load_balancer
        return None

    @property
    def config_key(self):
        """
        Returns the instance's key in the configuration manager.
        """
        return self.environment.system.config_manager.get_instance_key(self)

    def restart(self):
        """
        When the agent restarts an instance, it restarts with the newest
        revision of the node. Restarting should take place after the host pulls
        its nodes.
        """
        # Restart instance
        self.safe_run(self.host.agent.restart_instance)

    def safe_run(self, func):
        """
        If the instance belongs to a load balancer, `func` is run while
        mirroring instance state to the load balancer.

        Restarting or removing any instance belonging to a load balancer
        uses a block/unblock pattern. This ensures that the endpoint manager
        does not remove the endpoint on its own. Since we must know the exact
        time the endpoint is removed from the load balancer, `_safe_run`
        removes it manually.

        :Parameters:
          - `func`: the function to safely run.
        """
        if self.load_balancer:
            # Have endpoint manager block (ignore) this instance
            endpoints = supervisors.endpoint_supervisor_client()
            endpoints.block_instance(self.pk)
            # Manually remove the instance's endpoint from the load balancer
            config_manager = self.environment.system.config_manager
            endpoint = json.loads(config_manager.get(self.config_key))
            self.load_balancer.remove_endpoint(endpoint)

        # Run `func` now that instance state is mirrored to its load balancer
        func(self)

        if self.load_balancer:
            # Have endpoint manager unblock this instance
            endpoints.unblock_instance(self.pk)

    @classmethod
    def pre_delete(cls, sender, instance, **kwargs):
        """
        Deletes the instance through the host's agent.
        """
        # Remove instance
        instance.safe_run(instance.host.agent.remove_instance)
Пример #7
0
class RegistrationProfile(models.Model):
    """
    A simple profile which stores an activation key for use during
    user account registration.

    Generally, you will not want to interact directly with instances
    of this model; the provided manager includes methods
    for creating and activating new accounts, as well as for cleaning
    out accounts which have never been activated.

    While it is possible to use this model as the value of the
    ``AUTH_PROFILE_MODULE`` setting, it's not recommended that you do
    so. This model's sole purpose is to store data temporarily during
    account registration and activation.

    """
    user = models.ForeignKey(User, unique=True, verbose_name=_('user'))
    activation_key = uuidfield.UUIDField(auto=True)
    is_activated = models.BooleanField(default=False)

    objects = RegistrationManager()

    class Meta:
        verbose_name = _('registration profile')
        verbose_name_plural = _('registration profiles')

    def __unicode__(self):
        return u"Registration information for %s" % self.user

    def activation_key_expired(self):
        """
        Determine whether this ``RegistrationProfile``'s activation
        key has expired, returning a boolean -- ``True`` if the key
        has expired.

        Key expiration is determined by a two-step process:

        1. If the user has already activated, the key will have been
           reset to the string constant ``ACTIVATED``. Re-activating
           is not permitted, and so this method returns ``True`` in
           this case.

        2. Otherwise, the date the user signed up is incremented by
           the number of days specified in the setting
           ``ACCOUNT_ACTIVATION_DAYS`` (which should be the number of
           days after signup during which a user is allowed to
           activate their account); if the result is less than or
           equal to the current date, the key has expired and this
           method returns ``True``.

        """
        expiration_date = datetime.timedelta(
            days=settings.ACCOUNT_ACTIVATION_DAYS)
        return self.is_activated or (self.user.date_joined + expiration_date <=
                                     datetime_now())

    activation_key_expired.boolean = True

    def send_activation_email(self):
        """
        Send an activation email to the user associated with this
        ``RegistrationProfile``.

        The activation email will make use of two templates:

        ``registration/activation_email_subject.txt``
            This template will be used for the subject line of the
            email. Because it is used as the subject line of an email,
            this template's output **must** be only a single line of
            text; output longer than one line will be forcibly joined
            into only a single line.

        ``registration/activation_email.txt``
            This template will be used for the body of the email.

        These templates will each receive the following context
        variables:

        ``activation_key``
            The activation key for the new account.

        ``expiration_days``
            The number of days remaining during which the account may
            be activated.
        """
        ctx_dict = {
            'activation_key': self.activation_key,
            'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
        }
        subject = render_to_string('registration/activation_email_subject.txt',
                                   ctx_dict)
        # Email subject *must not* contain newlines
        subject = ''.join(subject.splitlines())

        message = {
            'template': 'registration/activation_email.html',
            'context': ctx_dict
        }

        self.user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
class Migration(migrations.Migration):

    dependencies = []

    operations = [
        migrations.CreateModel(
            name='Device',
            fields=[
                ('id',
                 models.AutoField(verbose_name='ID',
                                  serialize=False,
                                  auto_created=True,
                                  primary_key=True)),
                ('device_name', models.CharField(max_length=100)),
                ('device_description',
                 models.CharField(default=None, max_length=100)),
                ('register_time',
                 models.DateTimeField(auto_now_add=True, null=True)),
            ],
            options={},
            bases=(models.Model, ),
        ),
        migrations.CreateModel(
            name='Group',
            fields=[
                ('id',
                 models.AutoField(verbose_name='ID',
                                  serialize=False,
                                  auto_created=True,
                                  primary_key=True)),
                ('group_name', models.CharField(max_length=20)),
                ('group_description', models.CharField(max_length=150)),
            ],
            options={},
            bases=(models.Model, ),
        ),
        migrations.CreateModel(
            name='JobSeqs',
            fields=[
                ('jobID',
                 uuidfield.UUIDField(primary_key=True,
                                     serialize=False,
                                     editable=False,
                                     max_length=32,
                                     blank=True,
                                     unique=True)),
                ('job_creationTime', models.DateTimeField(auto_now_add=True)),
                ('job_content', models.CharField(max_length=200)),
                ('job_status', models.SmallIntegerField()),
                ('job_description',
                 models.CharField(default=None, max_length=200)),
            ],
            options={},
            bases=(models.Model, ),
        ),
        migrations.CreateModel(
            name='WeixinUser',
            fields=[
                ('id',
                 models.AutoField(verbose_name='ID',
                                  serialize=False,
                                  auto_created=True,
                                  primary_key=True)),
                ('weixinUserID', models.CharField(max_length=30)),
                ('creation_time',
                 models.DateTimeField(auto_now_add=True, null=True)),
                ('lastmessagetime',
                 models.DateTimeField(auto_now_add=True, null=True)),
                ('lastconnectiontime',
                 models.DateTimeField(auto_now=True, null=True)),
                ('menu_flag', models.SmallIntegerField(default=0)),
                ('belong_group', models.ForeignKey(to='wxapi.Group',
                                                   null=True)),
            ],
            options={},
            bases=(models.Model, ),
        ),
        migrations.AddField(
            model_name='jobseqs',
            name='operator_user',
            field=models.ForeignKey(to='wxapi.WeixinUser', null=True),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='jobseqs',
            name='target_device',
            field=models.OneToOneField(null=True, to='wxapi.Device'),
            preserve_default=True,
        ),
        migrations.AddField(
            model_name='device',
            name='belong_group',
            field=models.ForeignKey(to='wxapi.Group', null=True),
            preserve_default=True,
        ),
    ]
Пример #9
0
class Survey(models.Model):
    uuid = uuidfield.UUIDField(auto=True, version=4, hyphenate=True)
    created_at = models.DateTimeField(default=timezone.now)
    updated_at = models.DateTimeField(auto_now=True)

    # This field stores the running total of all of the collected salaries
    # while salaries are being collected, and the average salary if collection
    # has completed.
    total = models.BigIntegerField(default=get_default_total)
    # The tracker field stores a VERY large number that is used to enforce one
    # response per participant.  Each link sent to a participant has a large
    # prime number embedded in it.  Each time a response is entered, the
    # `tracker` number is multiplied by that number.  This way, we can know if
    # someone has already responded by checking to see if the tracker number is
    # divisible by the prime that was assigned to them.
    _tracker = models.CharField(default='1', max_length=10000, null=True)

    num_collected = models.PositiveIntegerField(default=0, null=True)
    num_expected = models.PositiveIntegerField(null=True)

    @property
    def tracker(self):
        if self._tracker is None:
            return None
        return long(self._tracker)

    @tracker.setter
    def tracker(self, value):
        if value is None:
            self._tracker = None
        else:
            self._tracker = str(value)

    def has_key_been_recorded(self, key):
        if self.tracker is None:
            return None
        return self.tracker % key == 0

    def record_salary(self, salary, key):
        if self.has_key_been_recorded(key):
            raise ValueError("This key has already recorded a salary")
        self.tracker *= key
        self.total += salary
        self.num_collected += 1
        self.save()

    @property
    def is_open(self):
        return self.tracker is not None

    @property
    def is_finalized(self):
        return not self.is_open

    @property
    def is_finalizable(self):
        return self.num_collected >= 4

    def finalize(self, seed):
        if not self.is_finalizable:
            raise ValueError(
                "Survey must have at least 4 responses to be finalized")
        total = self.total - seed
        self.total = total / self.num_collected
        self.num_collected = None
        self.num_expected = None
        self.tracker = None
        self.save()