示例#1
0
class Migration(migrations.Migration):
    initial = True

    dependencies = [
        ('thesis', '0011_auto_20200429_2213'),
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='Review',
            fields=[
                ('id',
                 models.UUIDField(default=uuid.uuid4,
                                  editable=False,
                                  primary_key=True,
                                  serialize=False)),
                ('created',
                 django_extensions.db.fields.CreationDateTimeField(
                     auto_now_add=True, verbose_name='created')),
                ('modified',
                 django_extensions.db.fields.ModificationDateTimeField(
                     auto_now=True, verbose_name='modified')),
                ('comment', models.TextField(verbose_name='Review comment')),
                ('questions',
                 models.TextField(verbose_name='Review questions')),
                ('difficulty',
                 models.PositiveSmallIntegerField(
                     help_text=
                     'As value between 1 and 3 inclusive, higher is harder.',
                     validators=[
                         django.core.validators.MinValueValidator(1),
                         django.core.validators.MaxValueValidator(3)
                     ],
                     verbose_name='Difficulty')),
                ('grades',
                 django.contrib.postgres.fields.
                 ArrayField(base_field=models.PositiveSmallIntegerField(
                     help_text=
                     'As value between 1 and 4 inclusive, higher is better.',
                     validators=[
                         django.core.validators.MinValueValidator(1),
                         django.core.validators.MaxValueValidator(4)
                     ]),
                            size=None,
                            validators=[
                                django.contrib.postgres.validators.
                                ArrayMinLengthValidator(5),
                                django.contrib.postgres.validators.
                                ArrayMaxLengthValidator(6)
                            ],
                            verbose_name='Grades')),
                ('thesis',
                 models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
                                   related_name='review_thesis',
                                   to='thesis.ThesisAuthor')),
                ('user',
                 models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
                                   related_name='review_user',
                                   to=settings.AUTH_USER_MODEL)),
            ],
            options={
                'verbose_name': 'Review',
                'verbose_name_plural': 'Reviews',
            },
        ),
    ]
示例#2
0
class Migration(migrations.Migration):

    initial = True

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='Correspondence',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('name', models.CharField(max_length=254)),
                ('email', models.EmailField(max_length=254)),
                ('subject', models.CharField(max_length=254)),
                ('content', models.TextField()),
                ('created_on', models.DateTimeField(auto_now_add=True)),
            ],
        ),
        migrations.CreateModel(
            name='University',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('name', models.CharField(max_length=254)),
                ('description', models.CharField(blank=True, max_length=254)),
            ],
            options={
                'verbose_name_plural': 'universities',
            },
        ),
        migrations.CreateModel(
            name='Program',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('name', models.CharField(max_length=254)),
                ('description', models.CharField(blank=True, max_length=254)),
                ('members',
                 models.ManyToManyField(blank=True,
                                        related_name='programs',
                                        to=settings.AUTH_USER_MODEL)),
                ('university',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   related_name='programs',
                                   to='community.university')),
            ],
        ),
        migrations.CreateModel(
            name='Profile',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('description', models.CharField(blank=True, max_length=254)),
                ('year',
                 models.PositiveSmallIntegerField(blank=True,
                                                  choices=[(1, 1), (2, 2),
                                                           (3, 3), (4, 4),
                                                           (5, 5)],
                                                  null=True)),
                ('phone_number',
                 phonenumber_field.modelfields.PhoneNumberField(blank=True,
                                                                max_length=128,
                                                                null=True,
                                                                region=None)),
                ('discord_username',
                 models.CharField(blank=True, max_length=254, null=True)),
                ('facebook_link',
                 models.CharField(blank=True, max_length=254, null=True)),
                ('skype_link',
                 models.CharField(blank=True, max_length=254, null=True)),
                ('user',
                 annoying.fields.AutoOneToOneField(
                     on_delete=django.db.models.deletion.CASCADE,
                     to=settings.AUTH_USER_MODEL)),
            ],
        ),
    ]
class PositiveSmallIntegerData(models.Model):
    data = models.PositiveSmallIntegerField(null=True)
示例#4
0
文件: models.py 项目: alunix/edid.tv
class EDID(models.Model):
    objects = EDIDPublicManager()
    all_objects = models.Manager()

    manufacturer = models.ForeignKey(Manufacturer)

    # Initialized and basic data auto-added
    STATUS_INITIALIZED = 0
    # Standard and detailed timings auto-added
    STATUS_TIMINGS_ADDED = 1
    # Manually edited by users
    STATUS_EDITED = 2
    # Private, hidden from public
    STATUS_PRIVATE = 3
    STATUS_CHOICES = ((STATUS_INITIALIZED, 'Initialized'),
                      (STATUS_TIMINGS_ADDED, 'Timings Added'),
                      (STATUS_EDITED, 'Edited'),
                      (STATUS_PRIVATE, 'Private'))
    status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES,
                                              default=STATUS_INITIALIZED)

    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True)

    # Binary file encoded in base64
    file_base64 = models.TextField(editable=False)

    ### Header
    # ID Product Code
    manufacturer_product_code = models.CharField(max_length=4, blank=True)
    # ID Serial Number, 32-bit
    manufacturer_serial_number = models.PositiveIntegerField(blank=True,
                                                             null=True)
    # Week of manufacture, 1-54, 0==Unknown, 255==the year model
    week_of_manufacture = models.PositiveSmallIntegerField()
    # Year of manufacture, 1990-2245
    year_of_manufacture = models.PositiveSmallIntegerField()

    # EDID version and revision
    VERSION_1_0 = 0
    VERSION_1_1 = 1
    VERSION_1_2 = 2
    VERSION_1_3 = 3
    VERSION_1_4 = 4
    VERSION_2_0 = 5
    VERSION_CHOICES = (
        (VERSION_1_0, '1.0'),
        (VERSION_1_1, '1.1'),
        (VERSION_1_2, '1.2'),
        (VERSION_1_3, '1.3'),
        (VERSION_1_4, '1.4'),
        (VERSION_2_0, '2.0'),
    )
    version = models.PositiveSmallIntegerField(choices=VERSION_CHOICES)

    ### ASCII Text Descriptors
    # Monitor Name, from Monitor Descriptor Description (type 0xFC)
    monitor_name = models.CharField(max_length=13, blank=True)
    # Monitor Serial Number, from Monitor Descriptor Description (type 0xFF)
    monitor_serial_number = models.CharField(max_length=13, blank=True)
    # Monitor Data String, from Monitor Descriptor Description (type 0xFE)
    monitor_data_string = models.CharField(max_length=13, blank=True)

    ### bdp=Basic display parameters
    bdp_video_input_analog = 0
    bdp_video_input_digital = 1
    BDP_VIDEO_INPUT_CHOICES = ((bdp_video_input_analog, 'Analog'),
                               (bdp_video_input_digital, 'Digital'))
    bdp_video_input = models.PositiveSmallIntegerField(
        'video input',
        choices=BDP_VIDEO_INPUT_CHOICES,
        default=bdp_video_input_analog
    )

    # Analog Input
    bdp_signal_level_std_0700_0300 = 0
    bdp_signal_level_std_0714_0286 = 1
    bdp_signal_level_std_1000_0400 = 2
    bdp_signal_level_std_0700_0000 = 3
    BDP_SIGNAL_LVL_STD_CHOICE = (
        (bdp_signal_level_std_0700_0300, '(0.700, 0.300)'),
        (bdp_signal_level_std_0714_0286, '(0.714, 0.286)'),
        (bdp_signal_level_std_1000_0400, '(1.000, 0.400)'),
        (bdp_signal_level_std_0700_0000, '(0.700, 0.000)'),
    )
    bdp_signal_level_standard = models.PositiveSmallIntegerField(
        'signal level standard', choices=BDP_SIGNAL_LVL_STD_CHOICE,
        blank=True, null=True)

    bdp_blank_to_black_setup = models.NullBooleanField(
        'blank-to-black setup level')
    bdp_separate_syncs = models.NullBooleanField('separate sync')
    bdp_composite_sync = models.NullBooleanField(
        'composite sync signal on horizontal')
    bdp_sync_on_green_video = models.NullBooleanField(
        'composite sync signal on green video')
    bdp_vsync_serration = models.NullBooleanField(
        'serration on the vertical sync')

    # Digital Input
    bdp_video_input_dfp_1 = models.NullBooleanField('digital flat panel 1.x')

    bdp_max_horizontal_image_size = models.PositiveSmallIntegerField(
        'maximum horizontal image size')
    bdp_max_vertical_image_size = models.PositiveSmallIntegerField(
        'maximum vertical image size')
    bdp_display_gamma = models.DecimalField('display gamma', max_digits=3,
                                            decimal_places=2, blank=True,
                                            null=True)

    BDP_FEATURE_DISPLY_CHOICE = (
        (DisplayType.Monochrome, 'Monochrome or grayscale display'),
        (DisplayType.RGB, 'RGB color display'),
        (DisplayType.Non_RGB, 'Non-RGB multicolor display'),
        (DisplayType.Undefined, 'Undefined'),
    )

    bdp_feature_standby = models.BooleanField('standby mode')
    bdp_feature_suspend = models.BooleanField('suspend mode')
    bdp_feature_active_off = models.BooleanField(
        'active off/very low power mode')
    bdp_feature_display_type = models.PositiveSmallIntegerField(
        'display color type', choices=BDP_FEATURE_DISPLY_CHOICE)
    bdp_feature_standard_srgb = models.BooleanField('standard sRGB')
    bdp_feature_pref_timing_mode = models.BooleanField(
        'preferred timing mode')
    bdp_feature_default_gtf = models.BooleanField('default GTF')

    ### chr=Chromaticity
    chr_red_x = models.DecimalField(
        'red x', max_digits=4, decimal_places=3)
    chr_red_y = models.DecimalField(
        'red y', max_digits=4, decimal_places=3)
    chr_green_x = models.DecimalField(
        'green x', max_digits=4, decimal_places=3)
    chr_green_y = models.DecimalField(
        'green y', max_digits=4, decimal_places=3)
    chr_blue_x = models.DecimalField(
        'blue x', max_digits=4, decimal_places=3)
    chr_blue_y = models.DecimalField(
        'blue y', max_digits=4, decimal_places=3)
    chr_white_x = models.DecimalField(
        'white x', max_digits=4, decimal_places=3)
    chr_white_y = models.DecimalField(
        'white y', max_digits=4, decimal_places=3)

    ### est_timings=Established Timings
    est_timings_720_400_70 = models.BooleanField('720x400@70Hz')
    est_timings_720_400_88 = models.BooleanField('720x400@88Hz')
    est_timings_640_480_60 = models.BooleanField('640x480@60Hz')
    est_timings_640_480_67 = models.BooleanField('640x480@67Hz')
    est_timings_640_480_72 = models.BooleanField('640x480@72Hz')
    est_timings_640_480_75 = models.BooleanField('640x480@75Hz')
    est_timings_800_600_56 = models.BooleanField('800x600@56Hz')
    est_timings_800_600_60 = models.BooleanField('800x600@60Hz')
    est_timings_800_600_72 = models.BooleanField('800x600@72Hz')
    est_timings_800_600_75 = models.BooleanField('800x600@75Hz')
    est_timings_832_624_75 = models.BooleanField('832x624@75Hz')
    est_timings_1024_768_87 = models.BooleanField('1024x768@87Hz')
    est_timings_1024_768_60 = models.BooleanField('1024x768@60Hz')
    est_timings_1024_768_70 = models.BooleanField('1024x768@70Hz')
    est_timings_1024_768_75 = models.BooleanField('1024x768@75Hz')
    est_timings_1280_1024_75 = models.BooleanField('1280x1024@75Hz')

    ### mrl=Monitor range limits, optional starting from v1.1
    monitor_range_limits = models.BooleanField('monitor range limits')

    # in kHz
    mrl_min_horizontal_rate = models.PositiveSmallIntegerField(
        'minimum horizontal rate', blank=True, null=True)
    mrl_max_horizontal_rate = models.PositiveSmallIntegerField(
        'maximum horizontal rate', blank=True, null=True)

    # in Hz
    mrl_min_vertical_rate = models.PositiveSmallIntegerField(
        'minimum vertical rate', blank=True, null=True)
    mrl_max_vertical_rate = models.PositiveSmallIntegerField(
        'maximum vertical rate', blank=True, null=True)

    # in MHz
    mrl_max_pixel_clock = models.PositiveSmallIntegerField(
        'maximum supported pixel clock', blank=True, null=True)

    mrl_secondary_gtf_curve_support = models.NullBooleanField(
        'secondary GTF curve')

    # in kHz
    mrl_secondary_gtf_start_freq = models.PositiveSmallIntegerField(
        'start frequency', blank=True, null=True)
    mrl_secondary_gtf_c = models.PositiveSmallIntegerField(
        'C', blank=True, null=True)
    mrl_secondary_gtf_m = models.PositiveSmallIntegerField(
        'M', blank=True, null=True)
    mrl_secondary_gtf_k = models.PositiveSmallIntegerField(
        'K', blank=True, null=True)
    mrl_secondary_gtf_j = models.PositiveSmallIntegerField(
        'J', blank=True, null=True)

    @classmethod
    def create(cls, file_base64, edid_data):
        edid = cls(file_base64=file_base64)

        # Add basic data
        edid._populate_from_edid_parser(edid_data)

        return edid

    def _populate_from_edid_parser(self, edid):
        ### Header
        try:
            self.manufacturer = Manufacturer.objects.get(
                name_id=edid['ID_Manufacturer_Name'])
        except ObjectDoesNotExist:
            # UNK is reserved for unknown manufacturer
            self.manufacturer = Manufacturer.objects.get(name_id='UNK')

        self.manufacturer_product_code = edid['ID_Product_Code']
        self.manufacturer_serial_number = edid['ID_Serial_Number']

        self.week_of_manufacture = edid['Week_of_manufacture']
        self.year_of_manufacture = edid['Year_of_manufacture']

        if edid['EDID_version'] == 1:
            if edid['EDID_revision'] == 0:
                self.version = self.VERSION_1_0
            elif edid['EDID_revision'] == 1:
                self.version = self.VERSION_1_1
            elif edid['EDID_revision'] == 2:
                self.version = self.VERSION_1_2
            elif edid['EDID_revision'] == 3:
                self.version = self.VERSION_1_3
            elif edid['EDID_revision'] == 4:
                self.version = self.VERSION_1_4
        elif edid['EDID_version'] == 2:
            if edid['EDID_revision'] == 0:
                self.version = self.VERSION_2_0

        if self.version is None:
            raise ValidationError('Invalid EDID version and revision.')

        ### ASCII Text Descriptors
        if 'Monitor_Name' in edid:
            self.monitor_name = edid['Monitor_Name']

        if 'Monitor_Serial_Number' in edid:
            self.monitor_serial_number = edid['Monitor_Serial_Number']

        if 'Monitor_Data_String' in edid:
            self.monitor_data_string = edid['Monitor_Data_String']

        ### Basic display parameters
        bdp = edid['Basic_display_parameters']
        self.bdp_video_input = bdp['Video_Input']

        if not self.bdp_video_input:
            # Analog Input
            if bdp['Signal_Level_Standard'] == (0.700, 0.300):
                self.bdp_signal_level_standard = \
                    self.bdp_signal_level_std_0700_0300
            elif bdp['Signal_Level_Standard'] == (0.714, 0.286):
                self.bdp_signal_level_standard = \
                    self.bdp_signal_level_std_0714_0286
            elif bdp['Signal_Level_Standard'] == (1.000, 0.400):
                self.bdp_signal_level_standard = \
                    self.bdp_signal_level_std_1000_0400
            elif bdp['Signal_Level_Standard'] == (0.700, 0.000):
                self.bdp_signal_level_standard = \
                    self.bdp_signal_level_std_0700_0000
            else:
                raise ValidationError(
                    'Invalid signal level standard can not be parsed.'
                )

            self.bdp_blank_to_black_setup = bdp['Blank-to-black_setup']
            self.bdp_separate_syncs = bdp['Separate_syncs']
            self.bdp_composite_sync = bdp['Composite_sync']
            self.bdp_sync_on_green_video = bdp['Sync_on_green_video']
            self.bdp_vsync_serration = bdp['Vsync_serration']
        else:
            # Digital Input
            self.bdp_video_input_dfp_1 = bdp['Video_Input_DFP_1']

        self.bdp_max_horizontal_image_size = bdp['Max_Horizontal_Image_Size']
        self.bdp_max_vertical_image_size = bdp['Max_Vertical_Image_Size']
        self.bdp_display_gamma = bdp['Display_Gamma']

        self.bdp_feature_standby = bdp['Feature_Support']['Standby']
        self.bdp_feature_suspend = bdp['Feature_Support']['Suspend']
        self.bdp_feature_active_off = bdp['Feature_Support']['Active-off']
        self.bdp_feature_display_type = bdp['Feature_Support']['Display_Type']
        self.bdp_feature_standard_srgb = \
            bdp['Feature_Support']['Standard-sRGB']
        self.bdp_feature_pref_timing_mode = \
            bdp['Feature_Support']['Preferred_Timing_Mode']
        self.bdp_feature_default_gtf = bdp['Feature_Support']['Default_GTF']

        ### Chromaticity
        self.chr_red_x = edid['Chromaticity']['Red_x']
        self.chr_red_y = edid['Chromaticity']['Red_y']
        self.chr_green_x = edid['Chromaticity']['Green_x']
        self.chr_green_y = edid['Chromaticity']['Green_y']
        self.chr_blue_x = edid['Chromaticity']['Blue_x']
        self.chr_blue_y = edid['Chromaticity']['Blue_y']
        self.chr_white_x = edid['Chromaticity']['White_x']
        self.chr_white_y = edid['Chromaticity']['White_y']

        ### Established Timings
        self.est_timings_720_400_70 = \
            edid['Established_Timings']['720x400@70Hz']
        self.est_timings_720_400_88 = \
            edid['Established_Timings']['720x400@88Hz']
        self.est_timings_640_480_60 = \
            edid['Established_Timings']['640x480@60Hz']
        self.est_timings_640_480_67 = \
            edid['Established_Timings']['640x480@67Hz']
        self.est_timings_640_480_72 = \
            edid['Established_Timings']['640x480@72Hz']
        self.est_timings_640_480_75 = \
            edid['Established_Timings']['640x480@75Hz']
        self.est_timings_800_600_56 = \
            edid['Established_Timings']['800x600@56Hz']
        self.est_timings_800_600_60 = \
            edid['Established_Timings']['800x600@60Hz']
        self.est_timings_800_600_72 = \
            edid['Established_Timings']['800x600@72Hz']
        self.est_timings_800_600_75 = \
            edid['Established_Timings']['800x600@75Hz']
        self.est_timings_832_624_75 = \
            edid['Established_Timings']['832x624@75Hz']
        self.est_timings_1024_768_87 = \
            edid['Established_Timings']['1024x768@87Hz']
        self.est_timings_1024_768_60 = \
            edid['Established_Timings']['1024x768@60Hz']
        self.est_timings_1024_768_70 = \
            edid['Established_Timings']['1024x768@70Hz']
        self.est_timings_1024_768_75 = \
            edid['Established_Timings']['1024x768@75Hz']
        self.est_timings_1280_1024_75 = \
            edid['Established_Timings']['1280x1024@75Hz']

    def populate_timings_from_parser(self, edid):
        for item in edid['Standard_Timings']:
            data = edid['Standard_Timings'][item]
            identification = re.search(r"^Identification_(\d+)$", item,
                                       re.IGNORECASE)

            if data['Image_aspect_ratio'] == (1, 1):
                aspect_ratio = StandardTiming.ASPECT_RATIO_1_1
            elif data['Image_aspect_ratio'] == (16, 10):
                aspect_ratio = StandardTiming.ASPECT_RATIO_16_10
            elif data['Image_aspect_ratio'] == (4, 3):
                aspect_ratio = StandardTiming.ASPECT_RATIO_4_3
            elif data['Image_aspect_ratio'] == (5, 4):
                aspect_ratio = StandardTiming.ASPECT_RATIO_5_4
            elif data['Image_aspect_ratio'] == (16, 9):
                aspect_ratio = StandardTiming.ASPECT_RATIO_16_9
            else:
                raise ValidationError(
                    'Invalid aspect ratio can not be parsed.'
                )

            timing = StandardTiming(
                identification=identification.group(1),
                user=self.user,
                horizontal_active=data['Horizontal_active'],
                vertical_active=data['Vertical_active'],
                refresh_rate=data['Refresh_Rate'],
                aspect_ratio=aspect_ratio
            )

            self.standardtiming_set.add(timing)

        for item in edid['Descriptors']:
            data = edid['Descriptors'][item]
            identification = re.search(r"^Timing_Descriptor_(\d+)$", item,
                                       re.IGNORECASE)
            if not identification:
                # Not timing descriptor
                break

            timing = DetailedTiming(
                identification=identification.group(1),
                user=self.user,
                pixel_clock=data['Pixel_clock'],
                horizontal_active=data['Horizontal_Active'],
                horizontal_blanking=data['Horizontal_Blanking'],
                horizontal_sync_offset=data['Horizontal_Sync_Offset'],
                horizontal_sync_pulse_width=data[
                    'Horizontal_Sync_Pulse_Width'
                ],
                horizontal_image_size=data['Horizontal_Image_Size'],
                horizontal_border=data['Horizontal_Border'],
                vertical_active=data['Vertical_Active'],
                vertical_blanking=data['Vertical_Blanking'],
                vertical_sync_offset=data['Vertical_Sync_Offset'],
                vertical_sync_pulse_width=data['Vertical_Sync_Pulse_Width'],
                vertical_image_size=data['Vertical_Image_Size'],
                vertical_border=data['Vertical_Border'],
                flags_interlaced=data['Flags']['Interlaced'],
                flags_stereo_mode=data['Flags']['Stereo_Mode'],
                flags_sync_scheme=data['Flags']['Sync_Scheme']
            )

            if (timing.flags_sync_scheme ==
                    DetailedTiming.Sync_Scheme.Digital_Separate):
                timing.flags_horizontal_polarity = \
                    data['Flags']['Horizontal_Polarity']
                timing.flags_vertical_polarity = \
                    data['Flags']['Vertical_Polarity']
            else:
                timing.flags_serrate = data['Flags']['Serrate']

                if (timing.flags_sync_scheme ==
                        DetailedTiming.Sync_Scheme.Digital_Composite):
                    timing.flags_composite_polarity = \
                        data['Flags']['Composite_Polarity']
                else:
                    timing.flags_sync_on_rgb = data['Flags']['Sync_On_RGB']

            self.detailedtiming_set.add(timing)

        if 'Monitor_Range_Limits_Descriptor' in edid['Descriptors']:
            self.monitor_range_limits = True
            data = edid['Descriptors']['Monitor_Range_Limits_Descriptor']

            self.mrl_min_horizontal_rate = data['Min_Horizontal_rate']
            self.mrl_max_horizontal_rate = data['Max_Horizontal_rate']
            self.mrl_min_vertical_rate = data['Min_Vertical_rate']
            self.mrl_max_vertical_rate = data['Max_Vertical_rate']
            self.mrl_max_pixel_clock = data['Max_Supported_Pixel_Clock']
            self.mrl_secondary_gtf_curve_support = \
                data['Secondary_GTF_curve_supported']

            if self.mrl_secondary_gtf_curve_support:
                self.mrl_secondary_gtf_start_freq = \
                    data['Secondary_GTF']['start_frequency']
                self.mrl_secondary_gtf_c = data['Secondary_GTF']['C']
                self.mrl_secondary_gtf_m = data['Secondary_GTF']['M']
                self.mrl_secondary_gtf_k = data['Secondary_GTF']['K']
                self.mrl_secondary_gtf_j = data['Secondary_GTF']['J']
        else:
            self.monitor_range_limits = False

        self.status = self.STATUS_TIMINGS_ADDED

    def get_absolute_url(self):
        return reverse('edid-detail', kwargs={'pk': self.pk})

    def get_comments(self):
        comments = list(Comment.objects.filter(EDID=self)
                                       .select_related('user').all())

        ordered_comments = self._get_nested_comments(comments, 0)

        return ordered_comments

    def _get_nested_comments(self, comments, level, parent=None):
        nested_comments = []

        for comment in comments:
            if comment.level == level and comment.parent == parent:
                deep_nested_comments = {'comment': comment}

                deeper_nested_comments = self._get_nested_comments(
                    comments, comment.level + 1, comment
                )
                if deeper_nested_comments:
                    deep_nested_comments['subcomments'] = \
                        deeper_nested_comments

                nested_comments.append(deep_nested_comments)

        if not nested_comments:
            return None

        return nested_comments

    def get_est_timings(self):
        """
        Returns established timings in a dictionary.
        """

        return [
            {'horizontal_active': 720, 'vertical_active': 400,
             'refresh_rate': 70, 'supported': self.est_timings_720_400_70},
            {'horizontal_active': 720, 'vertical_active': 400,
             'refresh_rate': 88, 'supported': self.est_timings_720_400_88},

            {'horizontal_active': 640, 'vertical_active': 480,
             'refresh_rate': 60, 'supported': self.est_timings_640_480_60},
            {'horizontal_active': 640, 'vertical_active': 480,
             'refresh_rate': 67, 'supported': self.est_timings_640_480_67},
            {'horizontal_active': 640, 'vertical_active': 480,
             'refresh_rate': 72, 'supported': self.est_timings_640_480_72},
            {'horizontal_active': 640, 'vertical_active': 480,
             'refresh_rate': 75, 'supported': self.est_timings_640_480_75},

            {'horizontal_active': 800, 'vertical_active': 600,
             'refresh_rate': 56, 'supported': self.est_timings_800_600_56},
            {'horizontal_active': 800, 'vertical_active': 600,
             'refresh_rate': 60, 'supported': self.est_timings_800_600_60},
            {'horizontal_active': 800, 'vertical_active': 600,
             'refresh_rate': 72, 'supported': self.est_timings_800_600_72},
            {'horizontal_active': 800, 'vertical_active': 600,
             'refresh_rate': 75, 'supported': self.est_timings_800_600_75},

            {'horizontal_active': 832, 'vertical_active': 624,
             'refresh_rate': 75, 'supported': self.est_timings_832_624_75},

            {'horizontal_active': 1024, 'vertical_active': 768,
             'refresh_rate': 87, 'supported': self.est_timings_1024_768_87},
            {'horizontal_active': 1024, 'vertical_active': 768,
             'refresh_rate': 60, 'supported': self.est_timings_1024_768_60},
            {'horizontal_active': 1024, 'vertical_active': 768,
             'refresh_rate': 70, 'supported': self.est_timings_1024_768_70},
            {'horizontal_active': 1024, 'vertical_active': 768,
             'refresh_rate': 75, 'supported': self.est_timings_1024_768_75},

            {'horizontal_active': 1280, 'vertical_active': 1024,
             'refresh_rate': 75, 'supported': self.est_timings_1280_1024_75},
        ]

    def get_maximum_resolution(self):
        """
        Returns parameters of the maximum resolution supported by timings.
        """

        maximum_resolution = {
            'horizontal_active': 0, 'vertical_active': 0, 'refresh_rate': 0
        }

        for timing in self.get_est_timings():
            if timing['supported']:
                maximum_resolution = self._update_maximum_resolution(
                    maximum_resolution,
                    timing['horizontal_active'],
                    timing['vertical_active'],
                    timing['refresh_rate']
                )

        for timing in self.standardtiming_set.all():
            maximum_resolution = self._update_maximum_resolution(
                maximum_resolution,
                timing.horizontal_active,
                timing.vertical_active,
                timing.refresh_rate
            )

        for timing in self.detailedtiming_set.all():
            maximum_resolution = self._update_maximum_resolution(
                maximum_resolution,
                timing.horizontal_active,
                timing.vertical_active,
                timing.pixel_clock / 1000
            )

        return maximum_resolution

    def _update_maximum_resolution(self, maximum_resolution, horizontal_active,
                                   vertical_active, refresh_rate):
        """
        Updates maximum_resolution if the new timing have higher resolution.

        Higher resolution is determined by the total number of pixels.
        """

        maximum_resolution_pixels = maximum_resolution['horizontal_active'] \
            * maximum_resolution['vertical_active']

        if (horizontal_active * vertical_active) > maximum_resolution_pixels:
            maximum_resolution = {
                'horizontal_active': horizontal_active,
                'vertical_active': vertical_active,
                'refresh_rate': refresh_rate
            }

        return maximum_resolution

    def __unicode__(self):
        return "%s %s" % (self.manufacturer.name, self.monitor_name)
示例#5
0
class CredentialApplication(models.Model):
    """
    An application to become PhysioNet credentialed
    """
    RESEARCHER_CATEGORIES = (
        (0, 'Student'),
        (7, 'Graduate Student'),
        (1, 'Postdoc'),
        (2, 'Academic Researcher'),
        (3, 'Hospital Researcher'),
        (4, 'Industry Researcher'),
        (5, 'Government Researcher'),
        (6, 'Independent Researcher'),
    )

    REFERENCE_CATEGORIES = (
        (0, 'Supervisor (required for students and Postdocs)'),
        (1, 'Colleague'),
        (2, 'Coauthor'),
        (3, 'Other'),
    )

    COURSE_CATEGORIES = (
        (0, 'Not for a course'),
        (1, 'I am taking a course using the data'),
    )

    REFERENCE_RESPONSES = (
        ('', '-----------'),
        (1, 'No'),
        (2, 'Yes')
    )

    REJECT_ACCEPT_WITHDRAW = (
        ('', '-----------'),
        (1, 'Reject'),
        (2, 'Accept'),
        (3, 'Withdrawn'),
        (4, 'Revoked')
    )

    SUBMISSION_STATUS_LABELS = {
        0: 'Not submitted.',
        10: 'Initial review.',
        20: 'Training check.',
        30: 'Personal ID check.',
        40: 'Reference check.',
        50: 'Awaiting reference response.',
        60: 'Final review.',
        70: 'Rejected.',
        80: 'Accepted.'
    }

    # Maximum size for training_completion_report
    MAX_REPORT_SIZE = 2 * 1024 * 1024

    # Location for storing files associated with the application
    FILE_ROOT = os.path.join(settings.MEDIA_ROOT, 'credential-applications')

    slug = models.SlugField(max_length=20, unique=True, db_index=True)
    application_datetime = models.DateTimeField(auto_now_add=True)
    user = models.ForeignKey('user.User', related_name='credential_applications',
        on_delete=models.CASCADE)
    # Personal fields
    first_names = models.CharField(max_length=100, validators=[validators.validate_name])
    last_name = models.CharField(max_length=50, validators=[validators.validate_name])
    researcher_category = models.PositiveSmallIntegerField(choices=RESEARCHER_CATEGORIES)
    # Organization fields
    organization_name = models.CharField(max_length=200,
        validators=[validators.validate_organization])
    job_title = models.CharField(max_length=60,
        validators=[validators.validate_job_title])
    city = models.CharField(max_length=100,
        validators=[validators.validate_city])
    state_province = models.CharField(max_length=100,
        validators=[validators.validate_state], default='', blank=True)
    country = models.CharField(max_length=2, choices=COUNTRIES)
    webpage = models.URLField(default='', blank=True)
    zip_code = models.CharField(max_length=60,
        validators=[validators.validate_zipcode])
    suffix = models.CharField(max_length=60,
        validators=[validators.validate_suffix], default='', blank=True)
    # Human resources training
    training_course_name = models.CharField(max_length=100, default='',
        blank=True, validators=[validators.validate_training_course])
    training_completion_date = models.DateField(null=True, blank=True)
    training_completion_report = models.FileField(
        upload_to=training_report_path, validators=[FileExtensionValidator(
            ['pdf'], 'File must be a pdf.')])
    training_completion_report_url = models.URLField(blank=True, null=True)
    # Course info
    course_category = models.PositiveSmallIntegerField(choices=COURSE_CATEGORIES,
        null=True, blank=True)
    course_info = models.CharField(max_length=100, default='', blank=True,
        validators=[validators.validate_course])
    # Reference
    reference_category = models.PositiveSmallIntegerField(null=True,
        blank=True, choices=REFERENCE_CATEGORIES)
    reference_name = models.CharField(max_length=202, default='', blank=True,
                                      validators=[validators.validate_reference_name])
    reference_email = models.EmailField(default='', blank=True)
    reference_title = models.CharField(max_length=60, default='', blank=True,
        validators=[validators.validate_reference_title])
    # 0 1 2 3 = pending, rejected, accepted, withdrawn
    status = models.PositiveSmallIntegerField(default=0, choices=REJECT_ACCEPT_WITHDRAW)
    # 0 10 20 30 40 50 60 70 80 = not submitted, initial, training,
    # personal ID, reference, reference response, final, rejected, accepted
    submission_status = models.PositiveSmallIntegerField(default=10)
    reference_contact_datetime = models.DateTimeField(null=True)
    reference_response_datetime = models.DateTimeField(null=True)
    # Whether reference verifies the applicant. 0 1 2 = null, no, yes
    reference_response = models.PositiveSmallIntegerField(default=0,
        choices=REFERENCE_RESPONSES)
    reference_response_text = models.CharField(max_length=2000,
        validators=[validators.validate_reference_response])
    research_summary = models.CharField(max_length=1000,
        validators=[validators.validate_research_summary])
    project_of_interest = models.ForeignKey('project.PublishedProject', null=True,
        on_delete=models.SET_NULL, limit_choices_to={'access_policy': 2},)
    decision_datetime = models.DateTimeField(null=True)
    responder = models.ForeignKey('user.User', null=True,
        related_name='responded_applications', on_delete=models.SET_NULL)
    responder_comments = models.CharField(max_length=500, default='',
        blank=True)
    revoked_datetime = models.DateTimeField(null=True)

    def file_root(self):
        """Location for storing files associated with the application"""
        return os.path.join(CredentialApplication.FILE_ROOT, self.slug)

    def get_full_name(self):
        return ' '.join([self.first_names, self.last_name])

    def get_latest_by_user(self):
        return CredentialApplication.objects.filter(user=self.user).last()

    def is_latest_by_user(self):
        if self == CredentialApplication.objects.filter(user=self.user).last():
            return True
        else:
            return False

    def is_legacy(self):
        return False

    def submission_status_label(self):
        return ActiveProject.SUBMISSION_STATUS_LABELS[self.submission_status]

    def time_elapsed(self):
        return (timezone.now() - self.first_date).days

    def _apply_decision(self, decision, responder):
        """
        Reject, accept, or withdraw a credentialing application.

        Args:
            decision (int): 1 = reject, 2 = accept, 3 = withdraw.
            responder (str): User object
        """
        self.responder = responder
        self.status = decision
        self.decision_datetime = timezone.now()
        self.save()

    def reject(self, responder):
        """
        Reject a credentialing application.
        """
        self._apply_decision(1, responder)

    def accept(self, responder):
        """
        Reject a credentialing application.
        """
        try:
            with transaction.atomic():
                self._apply_decision(2, responder)
                # update the user credentials
                user = self.user
                user.is_credentialed = True
                user.credential_datetime = timezone.now()
                user.save()
        except DatabaseError:
            messages.error(request, 'Database error. Please try again.')

    def withdraw(self, responder):
        """
        Reject a credentialing application.
        """
        self._apply_decision(3, responder)

    def ref_known_flag(self):
        """
        Returns True if the reference is known, else False. By "Known" we mean
        that the reference has been previously contacted.
        """
        if CredentialApplication.objects.filter(
            reference_email__iexact=self.reference_email,
            reference_contact_datetime__isnull=False).exclude(
            reference_email=''):
            return True
        elif LegacyCredential.objects.filter(
            reference_email__iexact=self.reference_email).exclude(
            reference_email=''):
            return True
        else:
            return False

    def revoke(self):
        """
        Revokes an approved application.
        """
        # Set the application as unsucessful with the current datetime
        self.status = 4
        self.revoked_datetime = timezone.now()

        # Removes credentialing from the user
        self.user.is_credentialed = False
        self.user.credential_datetime = None

        with transaction.atomic():
            self.user.save()
            self.save()

        logger.info('Credentialing for user {0} has been removed.'.format(
            self.user.email))

    def remove_contact_reference(self):
        """
        Remove the date that indicates when the reference was contacted.
        Note that this may also affect the "known" status of the reference.
        """
        self.reference_contact_datetime = None
        self.save()
class Migration(migrations.Migration):

    dependencies = [
        ('cases', '0029_auto_20200710_2011'),
    ]

    operations = [
        migrations.AddField(
            model_name='case',
            name='woonevaluatie_gepersonaliseerd_doel_1',
            field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 1'),
        ),
        migrations.AddField(
            model_name='case',
            name='woonevaluatie_gepersonaliseerd_doel_1_behaald',
            field=models.PositiveSmallIntegerField(blank=True, choices=[(1, 'Ja'), (2, 'Nee')], null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 1 behaald'),
        ),
        migrations.AddField(
            model_name='case',
            name='woonevaluatie_gepersonaliseerd_doel_1_stand_van_zaken',
            field=models.TextField(blank=True, null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 1,  stand van zaken'),
        ),
        migrations.AddField(
            model_name='case',
            name='woonevaluatie_gepersonaliseerd_doel_2',
            field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 2'),
        ),
        migrations.AddField(
            model_name='case',
            name='woonevaluatie_gepersonaliseerd_doel_2_behaald',
            field=models.PositiveSmallIntegerField(blank=True, choices=[(1, 'Ja'), (2, 'Nee')], null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 2 behaald'),
        ),
        migrations.AddField(
            model_name='case',
            name='woonevaluatie_gepersonaliseerd_doel_2_stand_van_zaken',
            field=models.TextField(blank=True, null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 2,  stand van zaken'),
        ),
        migrations.AddField(
            model_name='case',
            name='woonevaluatie_gepersonaliseerd_doel_3',
            field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 3'),
        ),
        migrations.AddField(
            model_name='case',
            name='woonevaluatie_gepersonaliseerd_doel_3_behaald',
            field=models.PositiveSmallIntegerField(blank=True, choices=[(1, 'Ja'), (2, 'Nee')], null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 3 behaald'),
        ),
        migrations.AddField(
            model_name='case',
            name='woonevaluatie_gepersonaliseerd_doel_3_stand_van_zaken',
            field=models.TextField(blank=True, null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 3,  stand van zaken'),
        ),
        migrations.AddField(
            model_name='caseversion',
            name='woonevaluatie_gepersonaliseerd_doel_1',
            field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 1'),
        ),
        migrations.AddField(
            model_name='caseversion',
            name='woonevaluatie_gepersonaliseerd_doel_1_behaald',
            field=models.PositiveSmallIntegerField(blank=True, choices=[(1, 'Ja'), (2, 'Nee')], null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 1 behaald'),
        ),
        migrations.AddField(
            model_name='caseversion',
            name='woonevaluatie_gepersonaliseerd_doel_1_stand_van_zaken',
            field=models.TextField(blank=True, null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 1,  stand van zaken'),
        ),
        migrations.AddField(
            model_name='caseversion',
            name='woonevaluatie_gepersonaliseerd_doel_2',
            field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 2'),
        ),
        migrations.AddField(
            model_name='caseversion',
            name='woonevaluatie_gepersonaliseerd_doel_2_behaald',
            field=models.PositiveSmallIntegerField(blank=True, choices=[(1, 'Ja'), (2, 'Nee')], null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 2 behaald'),
        ),
        migrations.AddField(
            model_name='caseversion',
            name='woonevaluatie_gepersonaliseerd_doel_2_stand_van_zaken',
            field=models.TextField(blank=True, null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 2,  stand van zaken'),
        ),
        migrations.AddField(
            model_name='caseversion',
            name='woonevaluatie_gepersonaliseerd_doel_3',
            field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 3'),
        ),
        migrations.AddField(
            model_name='caseversion',
            name='woonevaluatie_gepersonaliseerd_doel_3_behaald',
            field=models.PositiveSmallIntegerField(blank=True, choices=[(1, 'Ja'), (2, 'Nee')], null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 3 behaald'),
        ),
        migrations.AddField(
            model_name='caseversion',
            name='woonevaluatie_gepersonaliseerd_doel_3_stand_van_zaken',
            field=models.TextField(blank=True, null=True, verbose_name='Woonevaluatie gepersonaliseerd doel 3,  stand van zaken'),
        ),
        migrations.AlterField(
            model_name='case',
            name='woonevaluatie_akkoord_zorgaanbieder_naam',
            field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Woonevaluatie akkoord zorgaanbieder naam en functie'),
        ),
        migrations.AlterField(
            model_name='caseversion',
            name='woonevaluatie_akkoord_zorgaanbieder_naam',
            field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Woonevaluatie akkoord zorgaanbieder naam en functie'),
        ),
    ]
class Migration(migrations.Migration):

    initial = True

    dependencies = []

    operations = [
        migrations.CreateModel(
            name='AuthGroup',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('name', models.CharField(max_length=150, unique=True)),
            ],
            options={
                'db_table': 'auth_group',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='AuthGroupPermissions',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
            ],
            options={
                'db_table': 'auth_group_permissions',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='AuthPermission',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('name', models.CharField(max_length=255)),
                ('codename', models.CharField(max_length=100)),
            ],
            options={
                'db_table': 'auth_permission',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='AuthUser',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('password', models.CharField(max_length=128)),
                ('last_login', models.DateTimeField(blank=True, null=True)),
                ('is_superuser', models.IntegerField()),
                ('username', models.CharField(max_length=150, unique=True)),
                ('first_name', models.CharField(max_length=150)),
                ('last_name', models.CharField(max_length=150)),
                ('email', models.CharField(max_length=254)),
                ('is_staff', models.IntegerField()),
                ('is_active', models.IntegerField()),
                ('date_joined', models.DateTimeField()),
            ],
            options={
                'db_table': 'auth_user',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='AuthUserGroups',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
            ],
            options={
                'db_table': 'auth_user_groups',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='AuthUserUserPermissions',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
            ],
            options={
                'db_table': 'auth_user_user_permissions',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DjangoAdminLog',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('action_time', models.DateTimeField()),
                ('object_id', models.TextField(blank=True, null=True)),
                ('object_repr', models.CharField(max_length=200)),
                ('action_flag', models.PositiveSmallIntegerField()),
                ('change_message', models.TextField()),
            ],
            options={
                'db_table': 'django_admin_log',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DjangoContentType',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('app_label', models.CharField(max_length=100)),
                ('model', models.CharField(max_length=100)),
            ],
            options={
                'db_table': 'django_content_type',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DjangoMigrations',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('app', models.CharField(max_length=255)),
                ('name', models.CharField(max_length=255)),
                ('applied', models.DateTimeField()),
            ],
            options={
                'db_table': 'django_migrations',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DjangoSession',
            fields=[
                ('session_key',
                 models.CharField(max_length=40,
                                  primary_key=True,
                                  serialize=False)),
                ('session_data', models.TextField()),
                ('expire_date', models.DateTimeField()),
            ],
            options={
                'db_table': 'django_session',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Issue',
            fields=[
                ('id',
                 models.AutoField(db_column='Id',
                                  primary_key=True,
                                  serialize=False)),
                ('title', models.TextField(blank=True, null=True)),
                ('link', models.CharField(blank=True,
                                          max_length=160,
                                          null=True)),
                ('type', models.CharField(blank=True, max_length=7,
                                          null=True)),
                ('dep_id', models.IntegerField(blank=True, null=True)),
                ('people_id',
                 models.CharField(blank=True, max_length=20, null=True)),
                ('year', models.IntegerField(blank=True, null=True)),
            ],
            options={
                'db_table': 'issue',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='NewsEvents',
            fields=[
                ('id',
                 models.AutoField(db_column='Id',
                                  primary_key=True,
                                  serialize=False)),
                ('date', models.DateField(blank=True, null=True)),
                ('title', models.TextField(blank=True, null=True)),
                ('shorttext', models.TextField(blank=True, null=True)),
                ('text', models.TextField(blank=True, null=True)),
                ('type', models.CharField(blank=True, max_length=1,
                                          null=True)),
            ],
            options={
                'db_table': 'news_events',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='People',
            fields=[
                ('id',
                 models.AutoField(db_column='Id',
                                  primary_key=True,
                                  serialize=False)),
                ('name', models.CharField(blank=True, max_length=80,
                                          null=True)),
                ('phone', models.CharField(blank=True,
                                           max_length=60,
                                           null=True)),
                ('email', models.CharField(blank=True,
                                           max_length=50,
                                           null=True)),
                ('post', models.TextField(blank=True, null=True)),
                ('name_link', models.TextField(blank=True, null=True)),
                ('type', models.CharField(blank=True, max_length=3,
                                          null=True)),
                ('info', models.TextField(blank=True, null=True)),
                ('hist', models.IntegerField(blank=True, null=True)),
                ('iss', models.CharField(blank=True, max_length=60,
                                         null=True)),
            ],
            options={
                'db_table': 'people',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Plav',
            fields=[
                ('id',
                 models.AutoField(db_column='Id',
                                  primary_key=True,
                                  serialize=False)),
                ('time_create', models.IntegerField(blank=True, null=True)),
                ('time_progn', models.IntegerField(blank=True, null=True)),
                ('vlazh', models.TextField(blank=True, null=True)),
                ('osadki', models.TextField(blank=True, null=True)),
                ('veter', models.TextField(blank=True, null=True)),
                ('temp', models.TextField(blank=True, null=True)),
                ('temp_priz', models.TextField(blank=True, null=True)),
                ('type', models.CharField(blank=True, max_length=12,
                                          null=True)),
                ('link', models.TextField(blank=True, null=True)),
                ('text', models.TextField(blank=True, null=True)),
            ],
            options={
                'db_table': 'PLAV',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Requests',
            fields=[
                ('id', models.SmallAutoField(primary_key=True,
                                             serialize=False)),
                ('dept', models.TextField(blank=True, null=True)),
                ('chamber', models.SmallIntegerField(blank=True, null=True)),
                ('name', models.TextField(blank=True, null=True)),
                ('date', models.DateField()),
                ('text', models.TextField()),
                ('label', models.IntegerField(blank=True, null=True)),
                ('phone', models.BigIntegerField(blank=True, null=True)),
                ('comment', models.TextField(blank=True, null=True)),
                ('idrand', models.IntegerField()),
                ('dateok', models.DateField(blank=True, null=True)),
            ],
            options={
                'db_table': 'requests',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='SiteFace',
            fields=[
                ('id',
                 models.AutoField(db_column='Id',
                                  primary_key=True,
                                  serialize=False)),
                ('paramname', models.TextField(blank=True, null=True)),
                ('paramvalue', models.TextField(blank=True, null=True)),
            ],
            options={
                'db_table': 'site_face',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='SiteFaceEn',
            fields=[
                ('id',
                 models.AutoField(db_column='Id',
                                  primary_key=True,
                                  serialize=False)),
                ('paramname', models.TextField(blank=True, null=True)),
                ('paramvalue', models.TextField(blank=True, null=True)),
            ],
            options={
                'db_table': 'site_face_en',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Structure',
            fields=[
                ('id',
                 models.AutoField(db_column='Id',
                                  primary_key=True,
                                  serialize=False)),
                ('title', models.CharField(blank=True,
                                           max_length=80,
                                           null=True)),
                ('name_id', models.IntegerField(blank=True, null=True)),
                ('type', models.CharField(blank=True, max_length=5,
                                          null=True)),
                ('dep_id', models.IntegerField(blank=True, null=True)),
                ('info', models.TextField(blank=True, null=True)),
            ],
            options={
                'db_table': 'structure',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Towns',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('lat', models.FloatField(blank=True, null=True)),
                ('lon', models.FloatField(blank=True, null=True)),
                ('name',
                 models.CharField(blank=True,
                                  db_column='Name',
                                  max_length=1,
                                  null=True)),
                ('regname',
                 models.CharField(blank=True,
                                  db_column='RegName',
                                  max_length=1,
                                  null=True)),
                ('size', models.PositiveIntegerField(blank=True, null=True)),
                ('regnum', models.IntegerField()),
            ],
            options={
                'db_table': 'towns',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Vacanc',
            fields=[
                ('id',
                 models.AutoField(db_column='Id',
                                  primary_key=True,
                                  serialize=False)),
                ('vacancy', models.TextField(blank=True, null=True)),
                ('speciality', models.TextField(blank=True, null=True)),
                ('pay', models.CharField(blank=True, max_length=25,
                                         null=True)),
            ],
            options={
                'db_table': 'vacanc',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Wrf',
            fields=[
                ('id',
                 models.AutoField(db_column='Id',
                                  primary_key=True,
                                  serialize=False)),
                ('time_create', models.IntegerField(blank=True, null=True)),
                ('time_progn', models.IntegerField(blank=True, null=True)),
                ('vlazh', models.TextField(blank=True, null=True)),
                ('osadki', models.TextField(blank=True, null=True)),
                ('veter', models.TextField(blank=True, null=True)),
                ('temp', models.TextField(blank=True, null=True)),
                ('temp_priz', models.TextField(blank=True, null=True)),
                ('type', models.CharField(blank=True, max_length=12,
                                          null=True)),
                ('link', models.TextField(blank=True, null=True)),
                ('text', models.TextField(blank=True, null=True)),
            ],
            options={
                'db_table': 'WRF',
                'managed': False,
            },
        ),
    ]
示例#8
0
class Migration(migrations.Migration):

    initial = True

    dependencies = [
        ('taggit', '0002_auto_20150616_2121'),
        ('structure', '0001_squashed_0054'),
    ]

    operations = [
        migrations.CreateModel(
            name='AzureService',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('uuid', waldur_core.core.fields.UUIDField()),
                ('available_for_all',
                 models.BooleanField(
                     default=False,
                     help_text=
                     'Service will be automatically added to all customers projects if it is available for all'
                 )),
                ('customer',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   to='structure.Customer',
                                   verbose_name='organization')),
            ],
            options={
                'abstract': False,
            },
            bases=(waldur_core.core.models.DescendantMixin,
                   waldur_core.logging.loggers.LoggableMixin, models.Model),
        ),
        migrations.CreateModel(
            name='AzureServiceProjectLink',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('cloud_service_name',
                 models.CharField(blank=True, max_length=255)),
                ('project',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   to='structure.Project')),
                ('service',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   to='waldur_azure.AzureService')),
            ],
            options={
                'abstract': False,
            },
            bases=(waldur_core.core.models.DescendantMixin,
                   waldur_core.logging.loggers.LoggableMixin, models.Model),
        ),
        migrations.CreateModel(
            name='Image',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('name',
                 models.CharField(
                     max_length=150,
                     validators=[waldur_core.core.validators.validate_name],
                     verbose_name='name')),
                ('uuid', waldur_core.core.fields.UUIDField()),
                ('backend_id', models.CharField(max_length=255, unique=True)),
            ],
            options={
                'abstract': False,
            },
            bases=(waldur_core.core.models.BackendModelMixin, models.Model),
        ),
        migrations.CreateModel(
            name='InstanceEndpoint',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('local_port',
                 models.IntegerField(validators=[
                     django.core.validators.MaxValueValidator(65535)
                 ])),
                ('public_port',
                 models.IntegerField(validators=[
                     django.core.validators.MaxValueValidator(65535)
                 ])),
                ('protocol',
                 models.CharField(blank=True,
                                  choices=[('tcp', 'tcp'), ('udp', 'udp')],
                                  max_length=3)),
                ('name',
                 models.CharField(blank=True,
                                  choices=[('SSH', 'SSH'),
                                           ('Remote Desktop', 'Remote Desktop')
                                           ],
                                  max_length=255)),
            ],
            bases=(waldur_core.core.models.BackendModelMixin, models.Model),
        ),
        migrations.CreateModel(
            name='VirtualMachine',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('created',
                 model_utils.fields.AutoCreatedField(
                     default=django.utils.timezone.now,
                     editable=False,
                     verbose_name='created')),
                ('modified',
                 model_utils.fields.AutoLastModifiedField(
                     default=django.utils.timezone.now,
                     editable=False,
                     verbose_name='modified')),
                ('description',
                 models.CharField(blank=True,
                                  max_length=500,
                                  verbose_name='description')),
                ('name',
                 models.CharField(
                     max_length=150,
                     validators=[waldur_core.core.validators.validate_name],
                     verbose_name='name')),
                ('uuid', waldur_core.core.fields.UUIDField()),
                ('error_message', models.TextField(blank=True)),
                ('latitude', models.FloatField(blank=True, null=True)),
                ('longitude', models.FloatField(blank=True, null=True)),
                ('runtime_state',
                 models.CharField(blank=True,
                                  max_length=150,
                                  verbose_name='runtime state')),
                ('state',
                 django_fsm.FSMIntegerField(choices=[(5, 'Creation Scheduled'),
                                                     (6, 'Creating'),
                                                     (1, 'Update Scheduled'),
                                                     (2, 'Updating'),
                                                     (7, 'Deletion Scheduled'),
                                                     (8, 'Deleting'),
                                                     (3, 'OK'), (4, 'Erred')],
                                            default=5)),
                ('backend_id', models.CharField(blank=True, max_length=255)),
                ('cores',
                 models.PositiveSmallIntegerField(
                     default=0, help_text='Number of cores in a VM')),
                ('ram',
                 models.PositiveIntegerField(default=0,
                                             help_text='Memory size in MiB')),
                ('disk',
                 models.PositiveIntegerField(default=0,
                                             help_text='Disk size in MiB')),
                ('min_ram',
                 models.PositiveIntegerField(
                     default=0, help_text='Minimum memory size in MiB')),
                ('min_disk',
                 models.PositiveIntegerField(
                     default=0, help_text='Minimum disk size in MiB')),
                ('image_name', models.CharField(blank=True, max_length=150)),
                ('key_name', models.CharField(blank=True, max_length=50)),
                ('key_fingerprint', models.CharField(blank=True,
                                                     max_length=47)),
                ('user_data',
                 models.TextField(
                     blank=True,
                     help_text=
                     'Additional data that will be added to instance on provisioning'
                 )),
                ('start_time', models.DateTimeField(blank=True, null=True)),
                ('public_ips',
                 waldur_core.core.fields.JSONField(
                     blank=True,
                     default=[],
                     help_text='List of public IP addresses')),
                ('private_ips',
                 waldur_core.core.fields.JSONField(
                     blank=True,
                     default=[],
                     help_text='List of private IP addresses')),
                ('user_username', models.CharField(max_length=50)),
                ('user_password', models.CharField(max_length=50)),
                ('service_project_link',
                 models.ForeignKey(on_delete=django.db.models.deletion.PROTECT,
                                   related_name='virtualmachines',
                                   to='waldur_azure.AzureServiceProjectLink')),
                ('tags',
                 waldur_core.core.shims.TaggableManager(
                     related_name='+',
                     blank=True,
                     help_text='A comma-separated list of tags.',
                     through='taggit.TaggedItem',
                     to='taggit.Tag',
                     verbose_name='Tags')),
            ],
            options={
                'abstract': False,
            },
            bases=(waldur_core.core.models.DescendantMixin,
                   waldur_core.core.models.BackendModelMixin,
                   waldur_core.logging.loggers.LoggableMixin, models.Model),
        ),
        migrations.AddField(
            model_name='instanceendpoint',
            name='instance',
            field=models.ForeignKey(
                on_delete=django.db.models.deletion.PROTECT,
                related_name='endpoints',
                to='waldur_azure.VirtualMachine'),
        ),
        migrations.AddField(
            model_name='azureservice',
            name='projects',
            field=models.ManyToManyField(
                related_name='azure_services',
                through='waldur_azure.AzureServiceProjectLink',
                to='structure.Project'),
        ),
        migrations.AddField(
            model_name='azureservice',
            name='settings',
            field=models.ForeignKey(
                on_delete=django.db.models.deletion.CASCADE,
                to='structure.ServiceSettings'),
        ),
        migrations.AlterUniqueTogether(
            name='azureserviceprojectlink',
            unique_together=set([('service', 'project')]),
        ),
        migrations.AlterUniqueTogether(
            name='azureservice',
            unique_together=set([('customer', 'settings')]),
        ),
    ]
示例#9
0
class Migration(migrations.Migration):

    initial = True

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('products', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='Collecting',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
        ),
        migrations.CreateModel(
            name='Share',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('image',
                 models.ImageField(upload_to='s_images/', verbose_name='이미지')),
                ('content', models.TextField(verbose_name='내용')),
                ('collection_name',
                 models.CharField(max_length=100, verbose_name='컬렉션명')),
                ('collection_products',
                 models.TextField(verbose_name='컬렉션 상품')),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('user',
                 models.ForeignKey(
                     null=True,
                     on_delete=django.db.models.deletion.SET_NULL,
                     to=settings.AUTH_USER_MODEL,
                     verbose_name='작성자')),
            ],
            options={
                'verbose_name': '공유',
                'verbose_name_plural': '공유',
            },
        ),
        migrations.CreateModel(
            name='CollectionProduct',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('qunatity',
                 models.PositiveSmallIntegerField(verbose_name='수량')),
                ('sub_total', models.PositiveIntegerField(verbose_name='가격')),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('product',
                 models.OneToOneField(
                     on_delete=django.db.models.deletion.CASCADE,
                     to='products.Product',
                     verbose_name='상품')),
            ],
            options={
                'verbose_name': '컬렉션상품',
                'verbose_name_plural': '컬렉션상품',
            },
        ),
        migrations.CreateModel(
            name='Collection',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('collection_total',
                 models.PositiveIntegerField(default=0, verbose_name='가격')),
                ('period',
                 models.CharField(blank=True,
                                  choices=[('1W', '1주'), ('2W', '2주'),
                                           ('3W', '3주'), ('1M', '1달'),
                                           ('2M', '2달'), ('3M', '3달')],
                                  max_length=2,
                                  verbose_name='배송주기')),
                ('name', models.CharField(max_length=100,
                                          verbose_name='컬렉션명')),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('collection_products',
                 models.ManyToManyField(blank=True,
                                        related_name='collection_products',
                                        through='picks.Collecting',
                                        to='picks.CollectionProduct',
                                        verbose_name='컬렉션 상품')),
                ('user',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   to=settings.AUTH_USER_MODEL,
                                   verbose_name='사용자')),
            ],
            options={
                'verbose_name': '컬렉션',
                'verbose_name_plural': '컬렉션',
            },
        ),
        migrations.AddField(
            model_name='collecting',
            name='collection',
            field=models.ForeignKey(
                on_delete=django.db.models.deletion.CASCADE,
                to='picks.Collection',
                verbose_name='컬렉션'),
        ),
        migrations.AddField(
            model_name='collecting',
            name='collection_product',
            field=models.ForeignKey(
                on_delete=django.db.models.deletion.CASCADE,
                to='picks.CollectionProduct',
                verbose_name='컬렉션 상품'),
        ),
        migrations.AlterUniqueTogether(
            name='collecting',
            unique_together={('collection', 'collection_product')},
        ),
    ]
示例#10
0
class Migration(migrations.Migration):

    initial = True

    dependencies = []

    operations = [
        migrations.CreateModel(
            name='Archdiocese',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('name', models.CharField(max_length=200)),
                ('city', models.CharField(max_length=200)),
                ('state', models.CharField(max_length=200)),
                ('mother_church_name', models.CharField(max_length=200)),
                ('mother_church_address', models.CharField(max_length=200)),
                ('mother_church_zipcode', models.CharField(max_length=200)),
                ('establish_date',
                 models.DateTimeField(verbose_name='date established')),
                ('change_date',
                 models.DateTimeField(verbose_name='date established')),
                ('end_date',
                 models.DateTimeField(verbose_name='date established')),
            ],
        ),
        migrations.CreateModel(
            name='Diocese',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('name', models.CharField(max_length=200)),
                ('city', models.CharField(max_length=200)),
                ('state', models.CharField(max_length=200)),
                ('establish_date',
                 models.DateTimeField(verbose_name='date established')),
                ('change_date',
                 models.DateTimeField(verbose_name='date established')),
                ('end_date',
                 models.DateTimeField(verbose_name='date established')),
                ('archdiocese',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   to='diocese.Archdiocese')),
            ],
        ),
        migrations.CreateModel(
            name='Statistics',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('year', models.PositiveSmallIntegerField()),
                ('total_priests', models.PositiveSmallIntegerField()),
                ('num_parishes', models.PositiveSmallIntegerField()),
                ('diocese',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   to='diocese.Diocese')),
            ],
        ),
    ]
示例#11
0
class Migration(migrations.Migration):

    initial = True

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ("artist", "0001_initial"),
    ]

    operations = [
        migrations.CreateModel(
            name="Campaign",
            fields=[
                (
                    "id",
                    models.AutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                (
                    "amount",
                    models.PositiveIntegerField(
                        help_text=
                        "The amount of money the artist wishes to raise"),
                ),
                (
                    "reason",
                    models.CharField(
                        help_text=
                        "The reason why the artist is raising money, in a few words",
                        max_length=40,
                    ),
                ),
                (
                    "value_per_share",
                    models.PositiveIntegerField(
                        default=1,
                        help_text=
                        "The value (in dollars) per share the artist wishes to sell",
                    ),
                ),
                (
                    "start_datetime",
                    models.DateTimeField(
                        db_index=True,
                        default=django.utils.timezone.now,
                        help_text=
                        "When the campaign will start accepting investors",
                    ),
                ),
                (
                    "end_datetime",
                    models.DateTimeField(
                        blank=True,
                        db_index=True,
                        help_text=
                        "When the campaign ends and will no longer accept investors (no end date if blank)",
                        null=True,
                    ),
                ),
                (
                    "use_of_funds",
                    models.TextField(
                        blank=True,
                        help_text="A description of how the funds will be used",
                        null=True,
                    ),
                ),
                (
                    "fans_percentage",
                    models.PositiveSmallIntegerField(
                        help_text=
                        "The percentage of revenue that goes back to the fans (a value from 0-100)"
                    ),
                ),
                (
                    "artist",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        to="artist.Artist"),
                ),
            ],
        ),
        migrations.CreateModel(
            name="Expense",
            fields=[
                (
                    "id",
                    models.AutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                (
                    "expense",
                    models.CharField(
                        help_text=
                        "A description of one of the expenses for the artist (eg. Studio cost)",
                        max_length=30,
                    ),
                ),
                (
                    "campaign",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        to="campaign.Campaign",
                    ),
                ),
            ],
        ),
        migrations.CreateModel(
            name="Investment",
            fields=[
                (
                    "id",
                    models.AutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                (
                    "transaction_datetime",
                    models.DateTimeField(auto_now_add=True, db_index=True),
                ),
                (
                    "num_shares",
                    models.PositiveSmallIntegerField(
                        default=1,
                        help_text=
                        "The number of shares a user made in a transaction",
                    ),
                ),
                (
                    "campaign",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        to="campaign.Campaign",
                    ),
                ),
                (
                    "user",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        to=settings.AUTH_USER_MODEL,
                    ),
                ),
            ],
        ),
        migrations.CreateModel(
            name="RevenueReport",
            fields=[
                (
                    "id",
                    models.AutoField(
                        auto_created=True,
                        primary_key=True,
                        serialize=False,
                        verbose_name="ID",
                    ),
                ),
                (
                    "amount",
                    models.PositiveIntegerField(
                        help_text=
                        "The amount of revenue generated (in dollars) being reported (since last report)"
                    ),
                ),
                ("reported_datetime", models.DateTimeField(auto_now_add=True)),
                (
                    "campaign",
                    models.ForeignKey(
                        on_delete=django.db.models.deletion.CASCADE,
                        to="campaign.Campaign",
                    ),
                ),
            ],
        ),
        migrations.AlterUniqueTogether(name="expense",
                                       unique_together={("campaign", "expense")
                                                        }),
    ]
示例#12
0
class Migration(migrations.Migration):

    initial = True

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('common', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='Activity',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('title', models.CharField(max_length=120, verbose_name='标题')),
                ('cover',
                 models.ImageField(max_length=200,
                                   upload_to='',
                                   verbose_name='封面图')),
                ('activity_type',
                 models.PositiveSmallIntegerField(choices=[(0, '线上'),
                                                           (1, '线下')],
                                                  default=0,
                                                  verbose_name='活动类型')),
                ('start_at',
                 models.DateTimeField(blank=True,
                                      null=True,
                                      verbose_name='开始时间')),
                ('end_at',
                 models.DateTimeField(blank=True,
                                      null=True,
                                      verbose_name='结束时间')),
                ('ticket_price',
                 models.FloatField(default=0, verbose_name='费用(元)')),
                ('address',
                 models.CharField(max_length=120, verbose_name='具体位置信息')),
                ('live_plateform',
                 models.CharField(blank=True,
                                  max_length=120,
                                  verbose_name='直播平台')),
                ('live_address',
                 models.CharField(blank=True,
                                  max_length=20,
                                  verbose_name='直播地址|微信群名')),
                ('total_user',
                 models.PositiveIntegerField(default=0, verbose_name='活动人数')),
                ('contact_name',
                 models.CharField(max_length=100, verbose_name='联系人')),
                ('contact_info',
                 models.CharField(max_length=100, verbose_name='联系人电话|微信')),
                ('total_view',
                 models.PositiveIntegerField(default=0, verbose_name='查看人数')),
                ('total_registration',
                 models.PositiveIntegerField(default=0, verbose_name='报名个数')),
                ('create_at',
                 models.DateTimeField(auto_now_add=True, verbose_name='创建时间')),
                ('area',
                 models.ForeignKey(
                     on_delete=django.db.models.deletion.DO_NOTHING,
                     to='common.Area',
                     verbose_name='区域')),
                ('user',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   to=settings.AUTH_USER_MODEL,
                                   verbose_name='发起人')),
            ],
            options={
                'db_table': 'activity',
                'ordering': ['-id'],
            },
        ),
        migrations.CreateModel(
            name='Registration',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('status',
                 models.PositiveSmallIntegerField(choices=[(0, '成功')],
                                                  default=0)),
                ('create_at',
                 models.DateTimeField(auto_now_add=True, verbose_name='申请时间')),
                ('activity',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   to='activity.Activity',
                                   verbose_name='活动')),
                ('user',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   to=settings.AUTH_USER_MODEL,
                                   verbose_name='申请人')),
            ],
            options={
                'db_table': 'registration',
                'unique_together': {('user', 'activity')},
                'index_together': {('user', 'activity')},
            },
        ),
    ]
示例#13
0
class Podcast(UUIDModel, TitleModel, DescriptionModel, LinkModel,
        LanguageModel, LastUpdateModel, UpdateInfoModel, LicenseModel,
        FlattrModel, ContentTypesModel, MergedIdsModel, OutdatedModel,
        AuthorModel, UrlsMixin, SlugsMixin, TagsMixin, MergedUUIDsMixin,
        TwitterModel, ):
    """ A Podcast """

    logo_url = models.URLField(null=True, max_length=1000)
    group = models.ForeignKey(PodcastGroup, null=True,
                              on_delete=models.PROTECT)
    group_member_name = models.CharField(max_length=30, null=True, blank=False)

    # if p1 is related to p2, p2 is also related to p1
    related_podcasts = models.ManyToManyField('self', symmetrical=True)

    subscribers = models.PositiveIntegerField(default=0)
    restrictions = models.CharField(max_length=20, null=False, blank=True,
                                    default='')
    common_episode_title = models.CharField(max_length=100, null=False, blank=True)
    new_location = models.URLField(max_length=1000, null=True, blank=False)
    latest_episode_timestamp = models.DateTimeField(null=True)
    episode_count = models.PositiveIntegerField(default=0)
    hub = models.URLField(null=True)

    # Interval between episodes, within a specified range
    update_interval = models.PositiveSmallIntegerField(null=False,
        default=DEFAULT_UPDATE_INTERVAL)

    # factor to increase update_interval if an update does not find any
    # new episodes
    update_interval_factor = models.FloatField(default=1)

    # "order" value of the most recent episode (will be the highest of all)
    max_episode_order = models.PositiveIntegerField(null=True, default=None)

    # indicates whether the search index is up-to-date (or needs updating)
    search_index_uptodate = models.BooleanField(default=False, db_index=True)

    # search vector for full-text search
    search_vector = SearchVectorField(null=True)

    objects = PodcastManager()

    class Meta:
        index_together = [
            ('last_update',),
        ]

    def subscriber_count(self):
        # TODO: implement
        return self.subscribers

    def group_with(self, other, grouptitle, myname, othername):
        """ Group the podcast with another one """
        # TODO: move to PodcastGroup?

        if bool(self.group) and (self.group == other.group):
            # they are already grouped
            return

        group1 = self.group
        group2 = other.group

        if group1 and group2:
            raise ValueError('both podcasts already are in different groups')

        elif not (group1 or group2):
            # Form a new group
            import uuid
            group = PodcastGroup.objects.create(id=uuid.uuid1(), title=grouptitle)
            self.group_member_name = myname
            self.group = group
            self.save()

            other.group_member_name = othername
            other.group = group
            other.save()

            return group

        elif group1:
            # add other to self's group
            other.group_member_name = othername
            other.group = group1
            other.save()
            return group1

        else:
            # add self to other's group
            self.group_member_name = myname
            self.group = group2
            self.save()
            return group2

    def get_common_episode_title(self, num_episodes=100):

        if self.common_episode_title:
            return self.common_episode_title

        episodes = self.episode_set.all()[:num_episodes]

        # We take all non-empty titles
        titles = [_f for _f in (e.title for e in episodes) if _f]

        # there can not be a "common" title of a single title
        if len(titles) < 2:
            return None

        # get the longest common substring
        common_title = utils.longest_substr(titles)

        # but consider only the part up to the first number. Otherwise we risk
        # removing part of the number (eg if a feed contains episodes 100-199)
        common_title = re.search(r'^\D*', common_title).group(0)

        if len(common_title.strip()) < 2:
            return None

        return common_title


    def get_episode_before(self, episode):
        if not episode.released:
            return None
        return self.episode_set.filter(released__lt=episode.released).latest()

    def get_episode_after(self, episode):
        if not episode.released:
            return None
        return self.episode_set.filter(released__gt=episode.released).first()

    @property
    def scope(self):
        """ A podcast is always in the global scope """
        return ''

    @property
    def as_scope(self):
        """ If models use this object as scope, they'll use this value """
        return self.id.hex

    @property
    def display_title(self):
        """ a title for display purposes """
        if self.title:
            return self.title

        if not self.url:
            logger.warn('Podcast with ID {podcast_id} does not have a URL'
                .format(podcast_id=self.id))
            return _('Unknown Podcast')

        return _('Unknown Podcast from {domain}'.format(
            domain=utils.get_domain(self.url)))

    @property
    def next_update(self):
        interval = (timedelta(hours=self.update_interval) *
                    self.update_interval_factor)
        return self.last_update + interval
class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.FILER_IMAGE_MODEL),
        ('cms', '0016_auto_20160608_1535'),
        ('simple_plugins', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='SimplePageTeaserPluginModel',
            fields=[
                ('cmsplugin_ptr',
                 models.OneToOneField(
                     auto_created=True,
                     on_delete=django.db.models.deletion.CASCADE,
                     parent_link=True,
                     primary_key=True,
                     related_name='simple_plugins_simplepageteaserpluginmodel',
                     serialize=False,
                     to='cms.CMSPlugin')),
                ('flavor',
                 models.PositiveSmallIntegerField(
                     choices=[(1, 'Bold headings and action button'
                               ), (2,
                                   'Photo and read-more button'), (
                                       3, 'Simple'), (4,
                                                      'More stories link')])),
                ('override_title', models.CharField(blank=True,
                                                    max_length=80)),
                ('subtitle', models.CharField(blank=True, max_length=80)),
                ('content',
                 djangocms_text_ckeditor.fields.HTMLField(blank=True)),
                ('image',
                 filer.fields.image.FilerImageField(
                     blank=True,
                     null=True,
                     on_delete=django.db.models.deletion.CASCADE,
                     to=settings.FILER_IMAGE_MODEL)),
                ('page',
                 models.ForeignKey(
                     null=True,
                     on_delete=django.db.models.deletion.SET_NULL,
                     to='cms.Page')),
            ],
            options={
                'abstract': False,
            },
            bases=('cms.cmsplugin', ),
        ),
        migrations.AlterField(
            model_name='simpletextpluginmodel',
            name='flavor',
            field=models.PositiveSmallIntegerField(
                choices=[(1, 'Not yet implemented')]),
        ),
        migrations.AlterField(
            model_name='textandimagepluginmodel',
            name='flavor',
            field=models.PositiveSmallIntegerField(
                choices=[(1, 'Not yet implemented')]),
        ),
    ]
class Migration(migrations.Migration):

    initial = True

    dependencies = [
        ('dashboard', '0008_auto_20200429_2301'),
    ]

    operations = [
        migrations.CreateModel(
            name='ArtEvents',
            fields=[
                ('eid', models.CharField(db_column='Eid', max_length=60, primary_key=True, serialize=False)),
                ('title', models.CharField(blank=True, max_length=60, null=True)),
                ('e_image', models.CharField(blank=True, max_length=200, null=True)),
                ('seatmap', models.CharField(blank=True, max_length=200, null=True)),
            ],
            options={
                'db_table': 'Art_Events',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Artist',
            fields=[
                ('aid', models.CharField(db_column='Aid', max_length=20, primary_key=True, serialize=False)),
                ('artist_name', models.CharField(blank=True, max_length=40, null=True)),
                ('info', models.CharField(blank=True, max_length=255, null=True)),
            ],
            options={
                'db_table': 'Artist',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='AuthGroup',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=150, unique=True)),
            ],
            options={
                'db_table': 'auth_group',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='AuthGroupPermissions',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
            ],
            options={
                'db_table': 'auth_group_permissions',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='AuthPermission',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=255)),
                ('codename', models.CharField(max_length=100)),
            ],
            options={
                'db_table': 'auth_permission',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='AuthUser',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('password', models.CharField(max_length=128)),
                ('last_login', models.DateTimeField(blank=True, null=True)),
                ('is_superuser', models.IntegerField()),
                ('username', models.CharField(max_length=150, unique=True)),
                ('first_name', models.CharField(max_length=30)),
                ('last_name', models.CharField(max_length=150)),
                ('email', models.CharField(max_length=254)),
                ('is_staff', models.IntegerField()),
                ('is_active', models.IntegerField()),
                ('date_joined', models.DateTimeField()),
            ],
            options={
                'db_table': 'auth_user',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='AuthUserGroups',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
            ],
            options={
                'db_table': 'auth_user_groups',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='AuthUserUserPermissions',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
            ],
            options={
                'db_table': 'auth_user_user_permissions',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DashboardArtist',
            fields=[
                ('aid', models.CharField(db_column='Aid', max_length=20, primary_key=True, serialize=False)),
                ('artist_name', models.CharField(max_length=20)),
                ('info', models.CharField(max_length=50)),
            ],
            options={
                'db_table': 'dashboard_artist',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DashboardExhibition',
            fields=[
                ('eid', models.CharField(db_column='Eid', max_length=20, primary_key=True, serialize=False)),
                ('background', models.CharField(max_length=20)),
            ],
            options={
                'db_table': 'dashboard_exhibition',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DashboardHeld',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('eid', models.CharField(db_column='Eid', max_length=20)),
                ('lid', models.CharField(db_column='Lid', max_length=20)),
            ],
            options={
                'db_table': 'dashboard_held',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DashboardLocation',
            fields=[
                ('lid', models.CharField(db_column='Lid', max_length=20, primary_key=True, serialize=False)),
                ('longitude', models.CharField(max_length=20)),
                ('latitude', models.CharField(max_length=20)),
                ('address', models.CharField(max_length=20)),
                ('zipcode', models.CharField(max_length=20)),
            ],
            options={
                'db_table': 'dashboard_location',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DashboardPerform',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('eid', models.CharField(db_column='Eid', max_length=20)),
                ('aid', models.CharField(db_column='Aid', max_length=20)),
            ],
            options={
                'db_table': 'dashboard_perform',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DashboardTheater',
            fields=[
                ('eid', models.CharField(db_column='Eid', max_length=20, primary_key=True, serialize=False)),
                ('genre', models.CharField(max_length=20)),
            ],
            options={
                'db_table': 'dashboard_theater',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DashboardTime',
            fields=[
                ('time_serial', models.CharField(max_length=20, primary_key=True, serialize=False)),
                ('date', models.CharField(max_length=20)),
            ],
            options={
                'db_table': 'dashboard_time',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DjangoAdminLog',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('action_time', models.DateTimeField()),
                ('object_id', models.TextField(blank=True, null=True)),
                ('object_repr', models.CharField(max_length=200)),
                ('action_flag', models.PositiveSmallIntegerField()),
                ('change_message', models.TextField()),
            ],
            options={
                'db_table': 'django_admin_log',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DjangoContentType',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('app_label', models.CharField(max_length=100)),
                ('model', models.CharField(max_length=100)),
            ],
            options={
                'db_table': 'django_content_type',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DjangoMigrations',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('app', models.CharField(max_length=255)),
                ('name', models.CharField(max_length=255)),
                ('applied', models.DateTimeField()),
            ],
            options={
                'db_table': 'django_migrations',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='DjangoSession',
            fields=[
                ('session_key', models.CharField(max_length=40, primary_key=True, serialize=False)),
                ('session_data', models.TextField()),
                ('expire_date', models.DateTimeField()),
            ],
            options={
                'db_table': 'django_session',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Location',
            fields=[
                ('lid', models.CharField(db_column='Lid', max_length=20, primary_key=True, serialize=False)),
                ('longitude', models.CharField(blank=True, max_length=30, null=True)),
                ('latitude', models.CharField(blank=True, max_length=30, null=True)),
                ('address', models.CharField(blank=True, max_length=80, null=True)),
                ('zipcode', models.CharField(blank=True, max_length=20, null=True)),
            ],
            options={
                'db_table': 'Location',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Payment',
            fields=[
                ('pid', models.CharField(db_column='Pid', max_length=20, primary_key=True, serialize=False)),
                ('address', models.CharField(blank=True, max_length=200, null=True)),
                ('fname', models.CharField(blank=True, max_length=50, null=True)),
                ('lname', models.CharField(blank=True, max_length=50, null=True)),
                ('ticket_num', models.CharField(blank=True, max_length=20, null=True)),
                ('total_price', models.CharField(blank=True, max_length=20, null=True)),
            ],
            options={
                'db_table': 'Payment',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Subscription',
            fields=[
                ('sid', models.CharField(db_column='Sid', max_length=100, primary_key=True, serialize=False)),
                ('email', models.CharField(blank=True, max_length=100, null=True)),
                ('s_name', models.CharField(blank=True, max_length=100, null=True)),
            ],
            options={
                'db_table': 'Subscription',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='TicketHas',
            fields=[
                ('tid', models.CharField(db_column='Tid', max_length=20, primary_key=True, serialize=False)),
                ('price', models.IntegerField(blank=True, null=True)),
                ('amount', models.IntegerField(blank=True, null=True)),
                ('refund_policy', models.CharField(blank=True, max_length=20, null=True)),
            ],
            options={
                'db_table': 'Ticket_has',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Time',
            fields=[
                ('time_serial', models.CharField(max_length=20, primary_key=True, serialize=False)),
                ('date_ymd', models.CharField(blank=True, db_column='date_YMD', max_length=20, null=True)),
            ],
            options={
                'db_table': 'Time',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Buy',
            fields=[
                ('pid', models.OneToOneField(db_column='Pid', on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='dashboard.Payment')),
            ],
            options={
                'db_table': 'buy',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Concert',
            fields=[
                ('eid', models.OneToOneField(db_column='Eid', on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='dashboard.ArtEvents')),
                ('concert_type', models.CharField(blank=True, max_length=20, null=True)),
            ],
            options={
                'db_table': 'Concert',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Exhibition',
            fields=[
                ('eid', models.OneToOneField(db_column='Eid', on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='dashboard.ArtEvents')),
                ('background', models.CharField(blank=True, max_length=20, null=True)),
            ],
            options={
                'db_table': 'Exhibition',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Held',
            fields=[
                ('eid', models.OneToOneField(db_column='Eid', on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='dashboard.ArtEvents')),
            ],
            options={
                'db_table': 'held',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Perform',
            fields=[
                ('eid', models.OneToOneField(db_column='Eid', on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='dashboard.ArtEvents')),
            ],
            options={
                'db_table': 'Perform',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='Theater',
            fields=[
                ('eid', models.OneToOneField(db_column='Eid', on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='dashboard.ArtEvents')),
                ('genre', models.CharField(blank=True, max_length=20, null=True)),
            ],
            options={
                'db_table': 'Theater',
                'managed': False,
            },
        ),
        migrations.CreateModel(
            name='TOn',
            fields=[
                ('eid', models.OneToOneField(db_column='Eid', on_delete=django.db.models.deletion.DO_NOTHING, primary_key=True, serialize=False, to='dashboard.ArtEvents')),
            ],
            options={
                'db_table': 'T_on',
                'managed': False,
            },
        ),
    ]
示例#16
0
文件: models.py 项目: kotenev/taska
class Process(models.Model):
    '''A process is an running instance of a Workflow.

    A workflow can be executed multiple times (and by different people), we call each run of this workflow, a process.

    Attributes:
        :id (int): Private sequential identificator
        :workflow (Workflow): :class:`workflow.models.Workflow` instance this process is based on
        :executioner (User): :class:`django.contrib.auth.models.User` this process is executed by
        :hash (str): Public hash that identifies the process instance publicly
        :start_date (datetime): Creation date
        :end_date (datetime): End date
        :status (smallint): Indicator of the status of execution of the process
        :removed (boolean): Logical indicator of removal status of this workflow

    '''
    # Status literals, representing the translation to the statuses the process can be in
    RUNNING = 1
    FINISHED = 2
    CANCELED = 3
    OVERDUE = 4
    WAITING = 5

    STATUS = ((RUNNING, 'Process is running'),
              (FINISHED, 'Process has ended successfully'),
              (CANCELED, 'Process was canceled'),
              (OVERDUE, 'Process has gone over end_date'),
              (WAITING, 'Process is waiting for users availability'))
    workflow = models.ForeignKey(Workflow)
    title = models.CharField(max_length=200, null=True)
    description = models.CharField(max_length=2000, null=True, default="")
    executioner = models.ForeignKey(User)
    hash = models.CharField(max_length=50, unique=True)
    start_date = models.DateTimeField(auto_now_add=True)
    end_date = models.DateTimeField(null=True)
    status = models.PositiveSmallIntegerField(choices=STATUS, default=RUNNING)
    removed = models.BooleanField(default=False)

    days_after_delay = models.IntegerField(default=0)
    send_notification_until = models.DateTimeField(null=True)
    days_before_delay = models.IntegerField(default=0)

    @staticmethod
    def statusCode(interpret_code):
        for code, translation in Process.STATUS:
            if code == interpret_code:
                return translation

        return "Unknown"

    def __unicode__(self):
        #return u'%s (started %s)' % (self.title or self.workflow, self.start_date.strftime("%Y-%m-%d %H:%M"))
        return u'%s' % (self.title or self.workflow)

    def tasks(self):
        return ProcessTask.all(process=self)

    def getAllUsersEnvolved(self, notification=True):
        tmp = []
        tasks = self.tasks()
        for task in tasks:
            tmp += task.getAllUsersEnvolved(notification)

        # Remove duplicates
        seq = set(tmp)
        return list(seq)

    @transaction.atomic
    def cancel(self):
        ''' Cancels a process, also canceling all pending tasks in it and requests related with it too
        '''
        ptasks = self.tasks()

        for ptask in ptasks:
            if ptask.status == ProcessTask.WAITING_AVAILABILITY  or\
                    ptask.status == ProcessTask.REJECTED or\
                    ptask.status == ProcessTask.WAITING or\
                    ptask.status == ProcessTask.RUNNING:
                ptask.status = ProcessTask.CANCELED
                ptask.save()

        requests = Request.all(process=self.hash)

        for request in requests:
            request.remove()

        self.status = Process.CANCELED
        self.save()

    @transaction.atomic
    def move(self):
        '''
            Reaccess tasks status (so we can move the state machine forward)
        '''
        ptasks = self.tasks()
        if self.status == Process.WAITING:
            watasks = ProcessTask.all(process=self).filter(
                status=ProcessTask.WAITING_AVAILABILITY).count()

            if watasks == 0:
                self.status = Process.RUNNING
                self.save()
                History.new(event=History.RUN,
                            actor=self.executioner,
                            object=self)
                self.move()
        else:
            wlist = ptasks.filter(status=ProcessTask.WAITING)

            for ptask in wlist:
                move = True
                deps = ptask.task.dependencies()

                for dep in deps:
                    pdep = ptasks.get(task=dep.dependency)

                    if not (pdep.status == ProcessTask.FINISHED
                            or pdep.status == ProcessTask.CANCELED):
                        move = False

                    if ptask.allow_sbe:
                        ptus = ProcessTaskUser.all(processtask=pdep)
                        for ptu in ptus:
                            if ptu.status == ProcessTaskUser.FINISHED or ptu.status == ProcessTaskUser.CANCELED or ptu.finished:
                                ptask.status = ProcessTask.RUNNING
                                ptus2 = ProcessTaskUser.all(processtask=ptask)
                                for ptu2 in ptus2:
                                    if (ptu.user == ptu2.user):
                                        ptu2.status = ProcessTaskUser.RUNNING
                                        ptu2.save()
                                        History.new(event=History.RUN,
                                                    actor=ptu.user,
                                                    object=ptu,
                                                    authorized=[ptu.user],
                                                    related=[ptask.process])
                        ptask.save()

                if move:
                    ptask.status = ProcessTask.RUNNING
                    ptus = ProcessTaskUser.all(processtask=ptask)
                    for ptu in ptus:
                        if ptu.status == ProcessTaskUser.ACCEPTED or ptu.status == ProcessTaskUser.WAITING:
                            ptu.status = ProcessTaskUser.RUNNING
                            ptu.save()
                    ptask.save()

                    pusers = ptask.users()
                    for puser in pusers:
                        History.new(event=History.RUN,
                                    actor=puser.user,
                                    object=puser,
                                    authorized=[puser.user],
                                    related=[ptask.process])

            if ptasks.filter(
                    Q(status=ProcessTask.WAITING)
                    | Q(status=ProcessTask.RUNNING)
                    | Q(status=ProcessTask.IMPROVING)).count(
                    ) == 0:  # and self.status != Process.FINISHED:
                self.status = Process.FINISHED
                self.end_date = timezone.now()

                History.new(event=History.DONE,
                            actor=self.executioner,
                            object=self)

                self.save()

    def progress(self):
        all = ProcessTask.all(process=self).count()
        done = ProcessTask.all(process=self).filter(
            Q(status=ProcessTask.FINISHED)
            | Q(status=ProcessTask.CANCELED)).count()

        try:
            return done * 100 / all
        except ZeroDivisionError:
            return 0

    def changeReminders(self, reminders):
        self.days_after_delay = reminders.get('after')
        self.send_notification_until = reminders.get('repeatUpTo')
        self.days_before_delay = reminders.get('before')
        self.save()

    def start(self):
        ptasks = self.tasks()

        for ptask in ptasks:
            if ptask.status == ProcessTask.WAITING_AVAILABILITY:  # or ptask.status == ProcessTask.REJECTED:
                ptask.status = ProcessTask.WAITING
                ptask.save()
                ptu = ProcessTaskUser.all(processtask=ptask)
                for ptuser in ptu:
                    if ptuser.status == ProcessTaskUser.ACCEPTED:
                        ptuser.status = ProcessTaskUser.WAITING
                        ptuser.save()

        self.status = Process.RUNNING
        self.save()
        self.move()

    def validateAcceptions(self):
        ptasks = self.tasks()
        for ptask in ptasks:
            for ptasksUser in ProcessTaskUser.all(processtask=ptask):
                if(ptasksUser.status == ProcessTaskUser.WAITING or \
                               ptasksUser.status == ProcessTaskUser.REJECTED ):
                    return False
        return True

    def resignRejectedUser(self, oldUser, newUser):
        #Resign all tasks that the old user belongs
        ptasks = self.tasks()
        for ptask in ptasks:
            ptask.resignRejectedUser(oldUser, newUser)
        self.save()

    class Meta:
        ordering = ["-id"]
        verbose_name_plural = "Processes"

    @staticmethod
    def allWithDelay():
        tmp = Process.objects.filter(Q(removed=False) &
                                     Q(Q(status=Process.RUNNING) | Q(status=Process.WAITING)))\
            .exclude(days_after_delay = 0)\
            .filter(send_notification_until__gte=timezone.now())
        return tmp

    @staticmethod
    def allWithNotificationBeforeDelay():
        tmp = Process.objects.filter(Q(removed=False) &
                                     Q(Q(status=Process.RUNNING) | Q(status=Process.WAITING))) \
            .exclude(days_before_delay=0)
        return tmp

    @staticmethod
    def all(workflow=None, executioner=None):
        ''' Returns all valid process instances (excluding logically removed processes)
        '''
        tmp = Process.objects.filter(removed=False)

        if workflow != None:
            tmp = tmp.filter(workflow=workflow)

        if executioner != None:
            tmp = tmp.filter(executioner=executioner)
        # else
        return tmp
示例#17
0
class Maps(CMSPlugin):
    """
    Integration of a map with support for different providers
    """
    translatable_content_excluded_fields = [
        'address', 'zipcode', 'width', 'height'
    ]

    map_provider = models.CharField(_("map provider"),
                                    max_length=16,
                                    blank=False,
                                    null=False,
                                    choices=PROVIDERS,
                                    default=PROVIDERS[0][0])

    title = models.CharField(_("map title"),
                             max_length=100,
                             blank=True,
                             null=True)

    address = models.CharField(_("address"), max_length=150)
    zipcode = models.CharField(_("zip code"), max_length=30)
    city = models.CharField(_("city"), max_length=100)

    content = models.CharField(
        _("additional content"),
        max_length=255,
        blank=True,
        help_text=_('Displayed under address in the bubble.'))

    style = models.TextField(
        _("custom map style"),
        blank=True,
        help_text=_(
            'Provide a valid JSON configuration (escaped). See '
            'developers.google.com/maps/documentation/javascript/styling'))

    ZOOM_LEVELS = [(c, str(c)) for c in range(22)]
    zoom = models.PositiveSmallIntegerField(_("zoom level"),
                                            choices=ZOOM_LEVELS,
                                            default=13)

    lat = models.DecimalField(
        _('latitude'),
        max_digits=10,
        decimal_places=6,
        null=True,
        blank=True,
        help_text=_('Use latitude & longitude to fine tune the map position.'))

    lng = models.DecimalField(_('longitude'),
                              max_digits=10,
                              decimal_places=6,
                              null=True,
                              blank=True)

    route_planer_title = models.CharField(
        _("route planner title"),
        max_length=150,
        blank=True,
        null=True,
        default=_('Calculate your fastest way to here'))

    route_planer = models.BooleanField(_("route planner"), default=False)

    width = models.CharField(_('width'),
                             max_length=6,
                             default='100%',
                             help_text=_('Plugin width (in px, em, %).'))

    height = models.CharField(_('height'),
                              max_length=6,
                              default='400px',
                              help_text=_('Plugin height (in px, em).'))

    info_window = models.BooleanField(_('info window'),
                                      default=True,
                                      help_text=_('Show textbox over marker'))

    scrollwheel = models.BooleanField(
        _('scrollwheel'),
        default=True,
        help_text=_('Enable scrollwheel zooming on the map'))

    double_click_zoom = models.BooleanField(_('double click zoom'),
                                            default=True)

    draggable = models.BooleanField(_('draggable'), default=True)

    keyboard_shortcuts = models.BooleanField(_('keyboard shortcuts'),
                                             default=True)

    pan_control = models.BooleanField(_('Pan control'), default=True)

    zoom_control = models.BooleanField(_('Zoom control'), default=True)

    street_view_control = models.BooleanField(_('Street View control'),
                                              default=True)

    layers_control = models.BooleanField(_('Layers control'), default=True)

    scale_bar = models.BooleanField(_('Scale bar'), default=False)

    def __str__(self):
        return "%s (%s, %s %s)" % (
            self.get_title(),
            self.address,
            self.zipcode,
            self.city,
        )

    def get_title(self):
        """Title displayed as a map header"""
        return _("Map") if self.title is None else self.title

    def get_lat_lng(self):
        """Lat/Lon tuple or None (if unset)"""
        if self.lat and self.lng:
            return self.lat, self.lng
        return None
示例#18
0
文件: models.py 项目: kotenev/taska
class ProcessTask(models.Model):
    '''A task assignment, in the context of a Process.

    This model connects several workflow related tasks with a process instance. Defining a process implies setting up process tasks.

    Attributes:
        :process (Process): :class:`Process` related with this instance
        :task (Task): :class:`workflow.models.Task` related with this instance
        :status (smallint): Indicator of the status of execution of the process
        :deadline (datetime): Date this Process related Task should end
    '''
    # Status literals, representing the translation to the statuses the process can be in
    WAITING = 1
    RUNNING = 2
    FINISHED = 3
    CANCELED = 4
    OVERDUE = 5
    IMPROVING = 6
    WAITING_AVAILABILITY = 7
    REJECTED = 8

    STATUS = ((WAITING, 'Task is waiting execution'),
              (RUNNING, 'Task is running'), (FINISHED,
                                             'Task has ended successfully'),
              (CANCELED, 'Task was canceled'), (OVERDUE,
                                                'Task has gone over end_date'),
              (IMPROVING, 'Task is running again to be improved'),
              (WAITING_AVAILABILITY, 'Task is waiting for users availability'),
              (REJECTED, 'Task has some users that rejected this task'))
    process = models.ForeignKey(Process)
    task = models.ForeignKey(Task)
    status = models.PositiveSmallIntegerField(choices=STATUS, default=WAITING)
    deadline = models.DateTimeField()
    hash = models.CharField(max_length=50)
    removed = models.BooleanField(default=False)
    allow_sbe = models.BooleanField(default=False)

    @staticmethod
    def statusCode(code):
        try:
            return dict(ProcessTask.STATUS)[code]
        except KeyError:
            return "Unknown"

    def __unicode__(self):
        return u'%s - %s' % (self.task, self.process)

    def rpr(self):
        ts = Task.all().get_subclass(id=self.task.id)
        return "%s/%s" % (ts.type(), self.hash)

    def users(self):
        return ProcessTaskUser.all(processtask=self)

    def user(self, user):
        return ProcessTaskUser.all(processtask=self).get(user=user)

    def refreshState(self):
        #translate
        #Verificar se todos aceitaram
        #   Se sim, mudar estado para waiting
        #   Se nao, manter estado de waitingavailability
        #   Se alguem recusou, mudar estado para rejected

        allUser = ProcessTaskUser \
            .all(processtask=self, reassigned=False)
        allAccepted = True

        for usr in allUser:
            #if usr.status ==  ProcessTaskUser.REJECTED:
            #self.status = ProcessTask.REJECTED
            if usr.status == ProcessTaskUser.WAITING:
                allAccepted = False

        if allAccepted:  #Refresh the status of all taskuser and the task too
            self.status = ProcessTask.WAITING
            for usr in allUser:
                if usr.status == ProcessTaskUser.ACCEPTED:  #Only change the accepted because the reject we want to keep rejected
                    usr.status = ProcessTaskUser.WAITING
                    usr.save()

        self.save()

    def resignRejectedUser(self, oldUser, newUser):
        tasks = ProcessTaskUser.all(processtask=self).filter(user=oldUser)
        exists = ProcessTaskUser.all(processtask=self).filter(
            user=newUser).count()
        if exists == 0 or int(oldUser) == int(newUser):
            for task in tasks:
                task.changeUser(newUser)

                History.new(event=History.ADD,
                            actor=task.processtask.process.executioner,
                            object=task.processtask.process,
                            authorized=[newUser],
                            related=[task.processtask.process])
        else:
            for task in tasks:
                task.delete()
        self.save()

    def move(self, force=False, finishTask=True):
        missing = ProcessTaskUser\
            .all(processtask=self, reassigned=False) \
            .filter(~Q(status=ProcessTaskUser.REJECTED), finished=False).count()

        if missing == 0:
            if (finishTask):
                self.status = ProcessTask.FINISHED
            self.save()

            # IF WE ARE BEFORE A FORM TASK, UPLOAD THE EXPORT RESULTS PASSING THEM BELOW, bit of a hack
            task = Task.objects.get_subclass(id=self.task.id)

            self.__exportForm(task)

            #self.process.move()

        else:
            if force:
                self.__exportForm(Task.objects.get_subclass(id=self.task.id))

        self.process.move()

    def getAllUsersEnvolved(self, notification=True):
        tmp = []
        for taskUser in ProcessTaskUser.all(processtask=self):
            if taskUser.getUser() not in tmp:
                if ((notification and taskUser.getUser().profile.notification
                     == True) or notification == False
                    ) and taskUser.status != ProcessTaskUser.REJECTED:
                    tmp += [taskUser.getUser()]
        return tmp

    def __exportForm(self, task):
        if task.type() == 'form.FormTask' and task.output_resources:

            exporter = task.get_exporter('xlsx', self)

            export = exporter.export(export_file=True)

            users = self.users()

            if len(users) > 0:
                result = users[0].getResult()

                if result:
                    ex_files = list(result.outputs.all().select_subclasses())

                    for fil in ex_files:
                        if fil.filename == export.filename:
                            result.outputs.remove(fil)

                    result.outputs.add(export)

    def calculateStart(self):
        deps = self.task.dependencies().values_list('id', flat=True)

        pdeps = ProcessTask.all().filter(task__in=deps).order_by('-deadline')

        if pdeps.count() > 0:
            return pdeps[0].deadline

        return self.process.start_date

    @staticmethod
    def all(process=None):
        ''' Returns all valid process task instances (excluding logically removed process tasks)

        '''
        tmp = ProcessTask.objects.filter(removed=False)

        if process != None:
            tmp = tmp.filter(process=process)

        return tmp
示例#19
0
class Migration(migrations.Migration):

    initial = True

    dependencies = [
        ('profiles', '0001_initial'),
        ('contenttypes', '0002_remove_content_type_name'),
    ]

    operations = [
        migrations.CreateModel(
            name='Answer',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('created_on', models.DateTimeField(auto_now_add=True)),
                ('updated_on', models.DateTimeField(auto_now=True)),
                ('uuid',
                 shortuuidfield.fields.ShortUUIDField(blank=True,
                                                      editable=False,
                                                      max_length=22)),
                ('position',
                 models.PositiveSmallIntegerField(blank=True,
                                                  null=True,
                                                  verbose_name='Position')),
                ('object_id', models.PositiveIntegerField()),
                ('is_correct', models.BooleanField(default=False)),
                ('content_type',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   to='contenttypes.ContentType')),
            ],
            options={
                'ordering': ['position'],
                'db_table': 'curricula_answers',
            },
        ),
        migrations.CreateModel(
            name='Curriculum',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('created_on', models.DateTimeField(auto_now_add=True)),
                ('updated_on', models.DateTimeField(auto_now=True)),
                ('uuid',
                 shortuuidfield.fields.ShortUUIDField(blank=True,
                                                      editable=False,
                                                      max_length=22)),
                ('name', models.CharField(db_index=True, max_length=200)),
                ('published_on',
                 models.DateTimeField(blank=True,
                                      null=True,
                                      verbose_name='date published')),
                ('image', models.ImageField(blank=True, upload_to='')),
            ],
            options={
                'verbose_name_plural': 'curricula',
                'db_table': 'curricula_curricula',
            },
        ),
        migrations.CreateModel(
            name='Lesson',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('created_on', models.DateTimeField(auto_now_add=True)),
                ('updated_on', models.DateTimeField(auto_now=True)),
                ('uuid',
                 shortuuidfield.fields.ShortUUIDField(blank=True,
                                                      editable=False,
                                                      max_length=22)),
                ('name', models.CharField(max_length=200)),
                ('published_on',
                 models.DateTimeField(blank=True,
                                      null=True,
                                      verbose_name='date published')),
                ('image', models.ImageField(upload_to='')),
                ('position',
                 models.PositiveSmallIntegerField(blank=True,
                                                  null=True,
                                                  verbose_name='Position')),
            ],
            options={
                'ordering': ['position'],
                'db_table': 'curricula_lessons',
            },
        ),
        migrations.CreateModel(
            name='LessonProgress',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('created_on', models.DateTimeField(auto_now_add=True)),
                ('updated_on', models.DateTimeField(auto_now=True)),
                ('score', models.SmallIntegerField(default=0)),
                ('lesson',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   related_name='progress',
                                   to='curricula.Lesson')),
                ('profile',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   related_name='lesson_progress',
                                   to='profiles.Profile')),
            ],
            options={
                'db_table': 'curricula_lesson_progress',
            },
        ),
        migrations.CreateModel(
            name='Module',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('created_on', models.DateTimeField(auto_now_add=True)),
                ('updated_on', models.DateTimeField(auto_now=True)),
                ('uuid',
                 shortuuidfield.fields.ShortUUIDField(blank=True,
                                                      editable=False,
                                                      max_length=22)),
                ('name', models.CharField(max_length=200)),
                ('published_on',
                 models.DateTimeField(blank=True,
                                      null=True,
                                      verbose_name='date published')),
                ('image', models.ImageField(upload_to='')),
                ('position',
                 models.PositiveSmallIntegerField(blank=True,
                                                  null=True,
                                                  verbose_name='Position')),
            ],
            options={
                'ordering': ['position'],
                'db_table': 'curricula_modules',
            },
        ),
        migrations.CreateModel(
            name='Question',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('created_on', models.DateTimeField(auto_now_add=True)),
                ('updated_on', models.DateTimeField(auto_now=True)),
                ('uuid',
                 shortuuidfield.fields.ShortUUIDField(blank=True,
                                                      editable=False,
                                                      max_length=22)),
                ('text', models.CharField(max_length=200)),
                ('published_on',
                 models.DateTimeField(blank=True,
                                      null=True,
                                      verbose_name='date published')),
                ('image', models.ImageField(blank=True, upload_to='')),
                ('question_type',
                 django_light_enums.db.EnumField(choices=[
                     (10, 'SINGLE_ANSWER'), (20, 'MULTIPLE_CHOICE')
                 ],
                                                 default=10,
                                                 enum_values=(10, 20))),
                ('position',
                 models.PositiveSmallIntegerField(blank=True,
                                                  null=True,
                                                  verbose_name='Position')),
                ('lesson',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   related_name='questions',
                                   to='curricula.Lesson')),
            ],
            options={
                'ordering': ['position'],
                'db_table': 'curricula_questions',
            },
        ),
        migrations.CreateModel(
            name='Text',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('created_on', models.DateTimeField(auto_now_add=True)),
                ('updated_on', models.DateTimeField(auto_now=True)),
                ('text', models.CharField(max_length=200)),
            ],
            options={
                'db_table': 'curricula_texts',
            },
        ),
        migrations.CreateModel(
            name='Unit',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('created_on', models.DateTimeField(auto_now_add=True)),
                ('updated_on', models.DateTimeField(auto_now=True)),
                ('uuid',
                 shortuuidfield.fields.ShortUUIDField(blank=True,
                                                      editable=False,
                                                      max_length=22)),
                ('name', models.CharField(max_length=200)),
                ('published_on',
                 models.DateTimeField(blank=True,
                                      null=True,
                                      verbose_name='date published')),
                ('image', models.ImageField(blank=True, upload_to='')),
                ('position',
                 models.PositiveSmallIntegerField(blank=True,
                                                  null=True,
                                                  verbose_name='Position')),
                ('curriculum',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   related_name='units',
                                   to='curricula.Curriculum')),
            ],
            options={
                'ordering': ['position'],
                'db_table': 'curricula_units',
            },
        ),
        migrations.CreateModel(
            name='UserResponse',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('created_on', models.DateTimeField(auto_now_add=True)),
                ('updated_on', models.DateTimeField(auto_now=True)),
                ('object_id', models.PositiveIntegerField()),
                ('is_correct', models.BooleanField(default=False)),
                ('content_type',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   to='contenttypes.ContentType')),
                ('profile',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   related_name='responses',
                                   to='profiles.Profile')),
                ('question',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   related_name='responses',
                                   to='curricula.Question')),
            ],
            options={
                'db_table': 'curricula_user_responses',
            },
        ),
        migrations.CreateModel(
            name='Vector',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('created_on', models.DateTimeField(auto_now_add=True)),
                ('updated_on', models.DateTimeField(auto_now=True)),
                ('magnitude',
                 models.FloatField(blank=True,
                                   null=True,
                                   verbose_name='Magnitude')),
                ('angle',
                 models.FloatField(blank=True, null=True,
                                   verbose_name='Angle')),
                ('x_component',
                 models.FloatField(blank=True,
                                   null=True,
                                   verbose_name='x-Component')),
                ('y_component',
                 models.FloatField(blank=True,
                                   null=True,
                                   verbose_name='y-Component')),
            ],
            options={
                'db_table': 'curricula_vectors',
            },
        ),
        migrations.AddField(
            model_name='module',
            name='unit',
            field=models.ForeignKey(
                on_delete=django.db.models.deletion.CASCADE,
                related_name='modules',
                to='curricula.Unit'),
        ),
        migrations.AddField(
            model_name='lesson',
            name='module',
            field=models.ForeignKey(
                on_delete=django.db.models.deletion.CASCADE,
                related_name='lessons',
                to='curricula.Module'),
        ),
        migrations.AddField(
            model_name='answer',
            name='question',
            field=models.ForeignKey(
                on_delete=django.db.models.deletion.CASCADE,
                related_name='answers',
                to='curricula.Question'),
        ),
    ]
示例#20
0
文件: models.py 项目: kotenev/taska
class ProcessTaskUser(models.Model):
    '''Model that connects a ProcessTask and a User

    Each task can have multiple users associated (or can be reassigned).

    Attributes:
        :user (User): :class:`django.contrib.auth.models.User` related with this instance
        :processtask (ProcessTask): class:`ProcessTask` related with this instance
        :reassigned (boolean): Indicates if this user was reassignment in the middle of a task
        :reassign_date (datetime): Timestamp of this user reassignment (if any)
        ...
        :status (smallint): Indicator of the status of the user decision
    '''
    # Status literals, representing the translation to the statuses the process task can be in
    WAITING = 1
    ACCEPTED = 2
    REJECTED = 3
    RUNNING = 4
    FINISHED = 5
    CANCELED = 6
    OVERDUE = 7
    IMPROVING = 8

    STATUS = ((WAITING, 'Task is waiting confirmation from user'),
              (ACCEPTED, 'Task was accepted'), (REJECTED, 'Task was rejected'),
              (RUNNING, 'Task is running'), (FINISHED,
                                             'Task has ended successfully'),
              (CANCELED, 'Task was canceled'), (OVERDUE,
                                                'Task has gone over end_date'),
              (IMPROVING, 'Task is running again to be improved'))

    user = models.ForeignKey(User)
    processtask = models.ForeignKey(ProcessTask)
    reassigned = models.BooleanField(default=False)
    reassign_date = models.DateTimeField(null=True, blank=True)
    finished = models.BooleanField(default=False)
    hash = models.CharField(max_length=50)
    status = models.PositiveSmallIntegerField(choices=STATUS, default=WAITING)

    class Meta:
        ordering = ['-processtask__deadline']

    def __unicode__(self):
        return u'%s - %s' % (self.processtask, self.user)

    def requests(self):
        return Request.objects.filter(
            Q(processtaskuser=self)
            | Q(processtaskuser__processtask=self.processtask, public=True))

    def getUser(self):
        return self.user

    def getEnvolvedUser(self):
        if self.status != ProcessTaskUser.REJECTED:
            return self.user
        return None

    def getResult(self):
        from result.models import Result
        try:
            return Result.all(processtaskuser=self)

        except Result.DoesNotExist, IndexError:
            pass

        return None
class Migration(migrations.Migration):

    dependencies = [
        ('intake', '0006_auto_20160614_2216'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='applicationlogentry',
            name='action_type',
        ),
        migrations.RemoveField(
            model_name='applicationlogentry',
            name='updated_field',
        ),
        migrations.RemoveField(
            model_name='formsubmission',
            name='confirmation_sent',
        ),
        migrations.RemoveField(
            model_name='formsubmission',
            name='due_for_followup',
        ),
        migrations.RemoveField(
            model_name='formsubmission',
            name='followup_answered',
        ),
        migrations.RemoveField(
            model_name='formsubmission',
            name='followup_sent',
        ),
        migrations.RemoveField(
            model_name='formsubmission',
            name='opened_by_agency',
        ),
        migrations.RemoveField(
            model_name='formsubmission',
            name='processed_by_agency',
        ),
        migrations.RemoveField(
            model_name='formsubmission',
            name='reviewed_by_staff',
        ),
        migrations.RemoveField(
            model_name='formsubmission',
            name='submitted_to_agency',
        ),
        migrations.RemoveField(
            model_name='formsubmission',
            name='told_eligible',
        ),
        migrations.RemoveField(
            model_name='formsubmission',
            name='told_ineligible',
        ),
        migrations.AddField(
            model_name='applicationlogentry',
            name='event_type',
            field=models.PositiveSmallIntegerField(choices=[(1, 'opened'), (2, 'referred'), (3, 'processed'), (4, 'deleted')], default=1),
            preserve_default=False,
        ),
        migrations.AlterField(
            model_name='formsubmission',
            name='old_uuid',
            field=models.CharField(default=intake.models.gen_uuid, max_length=34, unique=True),
        ),
    ]
示例#22
0
文件: models.py 项目: kotenev/taska
class Request(models.Model):
    '''Represents a request made over a ProcessTask assignment.

    Each user assigned to a ProcessTask, is allowed to make requests about the task (such as asking for reassignments or for task clarification).

    Attributes:
        :processtaskuser (ProcessTaskUser): :class:`ProcessTaskUser` related with this request
        :type (smallint): Type of the request
        :title (str): Title of the request message (if any message annexed)
        :message (str): Content of the request message (if any message annexed)
        :date (datetime): Date the request we made on
    '''
    # TYPE literals, representing the translation to the type of requests available
    REASSIGN = 1
    CLARIFICATION = 2

    TYPES = (
        (REASSIGN, 'Ask for reassignment of task'),
        (CLARIFICATION, 'Ask for task clarification'),
    )
    hash = models.CharField(max_length=50, default="ERROR")
    processtaskuser = models.ForeignKey(ProcessTaskUser)
    type = models.PositiveSmallIntegerField(choices=TYPES,
                                            default=CLARIFICATION)
    title = models.CharField(max_length=100, null=True)
    message = models.TextField(null=True)
    date = models.DateTimeField(auto_now_add=True)
    resolved = models.BooleanField(default=False)
    public = models.BooleanField(default=False)
    removed = models.BooleanField(default=False)

    class Meta:
        ordering = ['-id']

    def process(self):
        return self.processtaskuser.processtask.process.hash

    def task(self):
        return self.processtaskuser.processtask.task.hash

    def resolve(self):
        try:
            if self.response:
                self.resolved = True
            else:
                self.resolved = False
        except RequestResponse.DoesNotExist:
            self.resolved = True

        self.save()

    def remove(self):
        self.removed = True

        self.save()

    @staticmethod
    def all(executioner=None, requester=None, process=None):
        tmp = Request.objects.filter(removed=False)

        if executioner != None:
            tmp = tmp.filter(
                processtaskuser__processtask__process__executioner=executioner)

        if requester != None:
            tmp = tmp.filter(processtaskuser__user=requester)

        if process != None:
            tmp = tmp.filter(
                processtaskuser__processtask__process__hash=process)

        return tmp

    def __unicode__(self):
        ptask = self.processtaskuser.processtask
        return u"Request for Task %s in Process %s" % (ptask.task,
                                                       ptask.process)
示例#23
0
文件: models.py 项目: alunix/edid.tv
class DetailedTiming(Timing):
    # Pixel clock in kHz
    pixel_clock = models.PositiveIntegerField()

    horizontal_active = models.PositiveSmallIntegerField()
    horizontal_blanking = models.PositiveSmallIntegerField()
    horizontal_sync_offset = models.PositiveSmallIntegerField()
    horizontal_sync_pulse_width = models.PositiveSmallIntegerField()
    horizontal_image_size = models.PositiveSmallIntegerField()
    horizontal_border = models.PositiveSmallIntegerField()

    vertical_active = models.PositiveSmallIntegerField()
    vertical_blanking = models.PositiveSmallIntegerField()
    vertical_sync_offset = models.PositiveSmallIntegerField()
    vertical_sync_pulse_width = models.PositiveSmallIntegerField()
    vertical_image_size = models.PositiveSmallIntegerField()
    vertical_border = models.PositiveSmallIntegerField()

    flags_interlaced = models.BooleanField('interlaced')

    Stereo_Mode = DisplayStereoMode
    STEREO_MODE_CHOICES = (
        (Stereo_Mode.Normal_display, 'Normal display, no stereo.'),
        (Stereo_Mode.Field_sequential_right,
            'Field sequential stereo, right image when stereo sync.'),
        (Stereo_Mode.Field_sequential_left,
            'Field sequential stereo, left image when stereo sync.'),
        (Stereo_Mode.Interleaved_2_way_right,
            '2-way interleaved stereo, right image on even lines.'),
        (Stereo_Mode.Interleaved_2_way_left,
            '2-way interleaved stereo, left image on even lines.'),
        (Stereo_Mode.Interleaved_4_way, '4-way interleaved stereo.'),
        (Stereo_Mode.Interleaved_side_by_side,
            'Side-by-Side interleaved stereo.'),
    )
    flags_stereo_mode = models.PositiveSmallIntegerField(
        'stereo mode',
        choices=STEREO_MODE_CHOICES
    )

    Sync_Scheme = TimingSyncScheme
    SYNC_SCHEME_CHOICES = (
        (Sync_Scheme.Analog_Composite, 'Analog Composite'),
        (Sync_Scheme.Bipolar_Analog_Composite, 'Bipolar Analog Composite'),
        (Sync_Scheme.Digital_Composite, 'Digital Composite'),
        (Sync_Scheme.Digital_Separate, 'Digital Separate'),
    )
    flags_sync_scheme = models.PositiveSmallIntegerField(
        'sync scheme',
        choices=SYNC_SCHEME_CHOICES
    )

    # If flags_sync_scheme == Digital_Separate
    flags_horizontal_polarity = models.NullBooleanField('horizontal polarity')
    flags_vertical_polarity = models.NullBooleanField('vertical polarity')

    # If not flags_sync_scheme == Digital_Separate
    flags_serrate = models.NullBooleanField('serrate')

    # If flags_sync_scheme == Digital_Composite
    flags_composite_polarity = models.NullBooleanField('composite polarity')

    # If not flags_sync_scheme == Digital_Composite and
    # not flags_sync_scheme == Digital_Separate
    flags_sync_on_rgb = models.NullBooleanField('sync on RGB')

    def __unicode__(self):
        return "%dx%d@%dHz" % (self.horizontal_active, self.vertical_active,
                               self.pixel_clock / 1000)
示例#24
0
class OrganizationMember(Model):
    """
    Identifies relationships between organizations and users.

    Users listed as team members are considered to have access to all projects
    and could be thought of as team owners (though their access level may not)
    be set to ownership.
    """

    __core__ = True

    organization = FlexibleForeignKey("sentry.Organization",
                                      related_name="member_set")

    user = FlexibleForeignKey(settings.AUTH_USER_MODEL,
                              null=True,
                              blank=True,
                              related_name="sentry_orgmember_set")
    email = models.EmailField(null=True, blank=True, max_length=75)
    role = models.CharField(max_length=32,
                            default=six.text_type(roles.get_default().id))
    flags = BitField(flags=((u"sso:linked", u"sso:linked"), (u"sso:invalid",
                                                             u"sso:invalid")),
                     default=0)
    token = models.CharField(max_length=64, null=True, blank=True, unique=True)
    date_added = models.DateTimeField(default=timezone.now)
    token_expires_at = models.DateTimeField(default=None, null=True)
    has_global_access = models.BooleanField(default=True)
    teams = models.ManyToManyField("sentry.Team",
                                   blank=True,
                                   through="sentry.OrganizationMemberTeam")
    inviter = FlexibleForeignKey(
        settings.AUTH_USER_MODEL,
        null=True,
        blank=True,
        related_name="sentry_inviter_set",
        on_delete=models.SET_NULL,
    )
    invite_status = models.PositiveSmallIntegerField(
        choices=(
            (InviteStatus.APPROVED.value, _("Approved")),
            (
                InviteStatus.REQUESTED_TO_BE_INVITED.value,
                _("Organization member requested to invite user"),
            ),
            (InviteStatus.REQUESTED_TO_JOIN.value,
             _("User requested to join organization")),
        ),
        default=InviteStatus.APPROVED.value,
        null=True,
    )

    # Deprecated -- no longer used
    type = BoundedPositiveIntegerField(default=50, blank=True)

    class Meta:
        app_label = "sentry"
        db_table = "sentry_organizationmember"
        unique_together = (("organization", "user"), ("organization", "email"))

    __repr__ = sane_repr("organization_id", "user_id", "role")

    @transaction.atomic
    def save(self, *args, **kwargs):
        assert self.user_id or self.email, "Must set user or email"
        if self.token and not self.token_expires_at:
            self.refresh_expires_at()
        super(OrganizationMember, self).save(*args, **kwargs)

    def set_user(self, user):
        self.user = user
        self.email = None
        self.token = None
        self.token_expires_at = None

    def remove_user(self):
        self.email = self.get_email()
        self.user = None
        self.token = self.generate_token()

    def regenerate_token(self):
        self.token = self.generate_token()
        self.refresh_expires_at()

    def refresh_expires_at(self):
        now = timezone.now()
        self.token_expires_at = now + timedelta(days=INVITE_DAYS_VALID)

    def approve_invite(self):
        self.invite_status = InviteStatus.APPROVED.value
        self.regenerate_token()

    def get_invite_status_name(self):
        if self.invite_status is None:
            return
        return invite_status_names[self.invite_status]

    @property
    def invite_approved(self):
        return self.invite_status == InviteStatus.APPROVED.value

    @property
    def requested_to_join(self):
        return self.invite_status == InviteStatus.REQUESTED_TO_JOIN.value

    @property
    def requested_to_be_invited(self):
        return self.invite_status == InviteStatus.REQUESTED_TO_BE_INVITED.value

    @property
    def is_pending(self):
        return self.user_id is None

    @property
    def token_expired(self):
        # Old tokens don't expire to preserve compatibility and not require
        # a backfill migration.
        if self.token_expires_at is None:
            return False
        if self.token_expires_at > timezone.now():
            return False
        return True

    @property
    def legacy_token(self):
        checksum = md5()
        checksum.update(six.text_type(self.organization_id).encode("utf-8"))
        checksum.update(self.get_email().encode("utf-8"))
        checksum.update(force_bytes(settings.SECRET_KEY))
        return checksum.hexdigest()

    def generate_token(self):
        return uuid4().hex + uuid4().hex

    def get_invite_link(self):
        if not self.is_pending or not self.invite_approved:
            return None
        return absolute_uri(
            reverse(
                "sentry-accept-invite",
                kwargs={
                    "member_id": self.id,
                    "token": self.token or self.legacy_token
                },
            ))

    def send_invite_email(self):
        from sentry.utils.email import MessageBuilder

        context = {
            "email": self.email,
            "organization": self.organization,
            "url": self.get_invite_link(),
        }

        msg = MessageBuilder(
            subject="Join %s in using Sentry" % self.organization.name,
            template="sentry/emails/member-invite.txt",
            html_template="sentry/emails/member-invite.html",
            type="organization.invite",
            context=context,
        )

        try:
            msg.send_async([self.get_email()])
        except Exception as e:
            logger = get_logger(name="sentry.mail")
            logger.exception(e)

    def send_sso_link_email(self, actor, provider):
        from sentry.utils.email import MessageBuilder

        link_args = {"organization_slug": self.organization.slug}

        context = {
            "organization":
            self.organization,
            "actor":
            actor,
            "provider":
            provider,
            "url":
            absolute_uri(reverse("sentry-auth-organization",
                                 kwargs=link_args)),
        }

        msg = MessageBuilder(
            subject="Action Required for %s" % (self.organization.name, ),
            template="sentry/emails/auth-link-identity.txt",
            html_template="sentry/emails/auth-link-identity.html",
            type="organization.auth_link",
            context=context,
        )
        msg.send_async([self.get_email()])

    def send_sso_unlink_email(self, actor, provider):
        from sentry.utils.email import MessageBuilder
        from sentry.models import LostPasswordHash

        email = self.get_email()

        recover_uri = u"{path}?{query}".format(
            path=reverse("sentry-account-recover"),
            query=urlencode({"email": email}))

        # Nothing to send if this member isn't associated to a user
        if not self.user_id:
            return

        context = {
            "email": email,
            "recover_url": absolute_uri(recover_uri),
            "has_password": self.user.password,
            "organization": self.organization,
            "actor": actor,
            "provider": provider,
        }

        if not self.user.password:
            password_hash = LostPasswordHash.for_user(self.user)
            context["set_password_url"] = password_hash.get_absolute_url(
                mode="set_password")

        msg = MessageBuilder(
            subject="Action Required for %s" % (self.organization.name, ),
            template="sentry/emails/auth-sso-disabled.txt",
            html_template="sentry/emails/auth-sso-disabled.html",
            type="organization.auth_sso_disabled",
            context=context,
        )
        msg.send_async([email])

    def get_display_name(self):
        if self.user_id:
            return self.user.get_display_name()
        return self.email

    def get_label(self):
        if self.user_id:
            return self.user.get_label()
        return self.email or self.id

    def get_email(self):
        if self.user_id and self.user.email:
            return self.user.email
        return self.email

    def get_avatar_type(self):
        if self.user_id:
            return self.user.get_avatar_type()
        return "letter_avatar"

    def get_audit_log_data(self):
        from sentry.models import Team

        teams = list(
            Team.objects.filter(id__in=OrganizationMemberTeam.objects.filter(
                organizationmember=self, is_active=True).values_list(
                    "team", flat=True)).values("id", "slug"))

        return {
            "email": self.get_email(),
            "user": self.user_id,
            "teams": [t["id"] for t in teams],
            "teams_slugs": [t["slug"] for t in teams],
            "has_global_access": self.has_global_access,
            "role": self.role,
            "invite_status": invite_status_names[self.invite_status],
        }

    def get_teams(self):
        from sentry.models import Team

        return Team.objects.filter(
            status=TeamStatus.VISIBLE,
            id__in=OrganizationMemberTeam.objects.filter(
                organizationmember=self, is_active=True).values("team"),
        )

    def get_scopes(self):
        scopes = roles.get(self.role).scopes

        disabled_scopes = set()

        if self.role == "member":
            if not self.organization.get_option("sentry:events_member_admin",
                                                EVENTS_MEMBER_ADMIN_DEFAULT):
                disabled_scopes.add("event:admin")
            if not self.organization.get_option("sentry:alerts_member_write",
                                                ALERTS_MEMBER_WRITE_DEFAULT):
                disabled_scopes.add("alerts:write")

        scopes = frozenset(s for s in scopes if s not in disabled_scopes)
        return scopes

    @classmethod
    def delete_expired(cls, threshold):
        """
        Delete un-accepted member invitations that expired
        ``threshold`` days ago.
        """
        cls.objects.filter(
            token_expires_at__lt=threshold,
            user_id__exact=None).exclude(email__exact=None).delete()
示例#25
0
class Migration(migrations.Migration):

    dependencies = [
        ("problems", "0004_razstavirazliko"),
    ]

    operations = [
        migrations.AlterModelOptions(
            name="iskanjenicelpolinoma",
            options={"verbose_name": "iskanje ničel polinoma"},
        ),
        migrations.AlterModelOptions(
            name="krajsanjeulomkov",
            options={"verbose_name": "krajšanje ulomkov"},
        ),
        migrations.AlterModelOptions(
            name="prostobesedilo",
            options={"verbose_name": "prosto besedilo"},
        ),
        migrations.AlterModelOptions(
            name="razstavirazliko",
            options={"verbose_name": "razstavi razliko"},
        ),
        migrations.AlterModelOptions(
            name="razstavivieta",
            options={"verbose_name": "razstavi Vieta"},
        ),
        migrations.AlterField(
            model_name="iskanjenicelpolinoma",
            name="stevilo_nicel",
            field=models.PositiveSmallIntegerField(
                help_text="Največje število ničel polinoma (vedno bo vsaj 1).",
                verbose_name="število ničel",
            ),
        ),
        migrations.AlterField(
            model_name="iskanjenicelpolinoma",
            name="velikost_nicle",
            field=models.PositiveSmallIntegerField(
                help_text=
                "Največja velikost ničle glede na absolutno vrednost.",
                verbose_name="velikost ničle",
            ),
        ),
        migrations.AlterField(
            model_name="krajsanjeulomkov",
            name="najvecji_faktor",
            field=models.PositiveSmallIntegerField(
                help_text=
                "Največji faktor med neokrajšanim in okrajšanim ulomkom.",
                verbose_name="največji faktor",
            ),
        ),
        migrations.AlterField(
            model_name="krajsanjeulomkov",
            name="najvecji_imenovalec",
            field=models.PositiveSmallIntegerField(
                help_text=
                "Največji imenovalec, ki se bo pojavljal v okrajšanem ulomku.",
                verbose_name="največji imenovalec",
            ),
        ),
        migrations.AlterField(
            model_name="krajsanjeulomkov",
            name="najvecji_stevec",
            field=models.PositiveSmallIntegerField(
                help_text=
                "Največji števec, ki se bo pojavljal v okrajšanem ulomku.",
                verbose_name="največji števec",
            ),
        ),
        migrations.AlterField(
            model_name="prostobesedilo",
            name="odgovor",
            field=models.TextField(help_text="Poljubno besedilo odgovora.",
                                   verbose_name="odgovor"),
        ),
        migrations.AlterField(
            model_name="prostobesedilo",
            name="vprasanje",
            field=models.TextField(help_text="Poljubno besedilo vprašanja.",
                                   verbose_name="vprašanje"),
        ),
        migrations.AlterField(
            model_name="razstavirazliko",
            name="linearna_kombinacija",
            field=models.BooleanField(
                help_text=
                "Ali naj naloga vsebuje linearno kombinacijo dveh neznank ali enostaven dvočlenik?",
                verbose_name="linearna kombinacija",
            ),
        ),
        migrations.AlterField(
            model_name="razstavirazliko",
            name="najmanjsa_potenca",
            field=models.PositiveSmallIntegerField(
                help_text="Najmanjša možna potenca za razstavljanje.",
                verbose_name="najmanjša potenca",
            ),
        ),
        migrations.AlterField(
            model_name="razstavirazliko",
            name="najvecja_potenca",
            field=models.PositiveSmallIntegerField(
                help_text="Največja možna potenca za razstavljanje.",
                verbose_name="največja potenca",
            ),
        ),
        migrations.AlterField(
            model_name="razstavivieta",
            name="maksimalna_vrednost",
            field=models.PositiveSmallIntegerField(
                help_text=
                "Največja možna vrednost razstavljenega člena glede na absolutno vrednost",
                verbose_name="maksimalna vrednost",
            ),
        ),
        migrations.AlterField(
            model_name="razstavivieta",
            name="vodilni_koeficient",
            field=models.BooleanField(
                help_text="Ali naj bo vodilni koeficient različen od 1?",
                verbose_name="vodilni koeficient",
            ),
        ),
    ]
class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='Game',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('date',
                 models.DateTimeField(default=django.utils.timezone.now)),
                ('game_map',
                 models.CharField(choices=[('Tharsis', 'Tharsis'),
                                           ('Elysium', 'Elysium'),
                                           ('Hellas', 'Hellas')],
                                  default='Tharsis',
                                  max_length=16)),
                ('draft_variant', models.BooleanField(default=True)),
                ('prelude', models.BooleanField(default=False)),
                ('venus_next', models.BooleanField(default=False)),
                ('colonies', models.BooleanField(default=False)),
            ],
        ),
        migrations.CreateModel(
            name='Player',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('nickname', models.CharField(max_length=32, unique=True)),
                ('motto',
                 models.CharField(blank=True, max_length=128, null=True)),
                ('user',
                 models.OneToOneField(
                     blank=True,
                     null=True,
                     on_delete=django.db.models.deletion.CASCADE,
                     to=settings.AUTH_USER_MODEL)),
            ],
        ),
        migrations.CreateModel(
            name='PlayerScore',
            fields=[
                ('id',
                 models.AutoField(auto_created=True,
                                  primary_key=True,
                                  serialize=False,
                                  verbose_name='ID')),
                ('corporation',
                 models.CharField(choices=[
                     ('Aphrodite', 'Aphrodite'), ('Aridor', 'Aridor'),
                     ('Arklight', 'Arklight'), ('Celestic', 'Celestic'),
                     ('Cheung Shing Mars', 'Cheung Shing Mars'),
                     ('Credicor', 'Credicor'), ('Ecoline', 'Ecoline'),
                     ('Helion', 'Helion'),
                     ('Interplanetary Cinematics',
                      'Interplanetary Cinematics'), ('Inventrix', 'Inventrix'),
                     ('Manutech', 'Manutech'),
                     ('Mining Guild', 'Mining Guild'),
                     ('Morning Star Inc.', 'Morning Star Inc.'),
                     ('Phobolog', 'Phobolog'), ('Point Luna', 'Point Luna'),
                     ('Polyphemos', 'Polyphemos'), ('Poseidon', 'Poseidon'),
                     ('Robinson Industries', 'Robinson Industries'),
                     ('Saturn Systems', 'Saturn Systems'),
                     ('Storm Craft Incorporated', 'Storm Craft Incorporated'),
                     ('Terractor', 'Terractor'),
                     ('Tharsis Republic', 'Tharsis Republic'),
                     ('Thorgate', 'Thorgate'),
                     ('United Nations Mars Initiative',
                      'United Nations Mars Initiative'),
                     ('Valley Trust', 'Valley Trust'), ('Viron', 'Viron'),
                     ('Vitor', 'Vitor')
                 ],
                                  max_length=64)),
                ('terraform_rating',
                 models.PositiveSmallIntegerField(default=20)),
                ('milestones', models.PositiveSmallIntegerField(default=0)),
                ('awards', models.PositiveSmallIntegerField(default=0)),
                ('greeneries', models.PositiveSmallIntegerField(default=0)),
                ('cities', models.PositiveSmallIntegerField(default=0)),
                ('event_cards', models.SmallIntegerField(default=0)),
                ('automated_cards', models.SmallIntegerField(default=0)),
                ('active_cards', models.SmallIntegerField(default=0)),
                ('resources', models.SmallIntegerField(default=0)),
                ('game',
                 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
                                   related_name='scores',
                                   to='mars_api.game')),
                ('player',
                 models.ForeignKey(
                     null=True,
                     on_delete=django.db.models.deletion.SET_NULL,
                     related_name='scores',
                     to='mars_api.player')),
            ],
            options={
                'default_related_name': 'scores',
            },
        ),
        migrations.AddConstraint(
            model_name='game',
            constraint=models.CheckConstraint(
                check=models.Q(game_map__in={'Hellas', 'Tharsis', 'Elysium'}),
                name="Only {'Hellas', 'Elysium', 'Tharsis'} maps are allowed."
            ),
        ),
        migrations.AddConstraint(
            model_name='playerscore',
            constraint=models.UniqueConstraint(
                fields=('player', 'game'),
                name='one_score_per_player_per_game'),
        ),
        migrations.AddConstraint(
            model_name='playerscore',
            constraint=models.UniqueConstraint(
                fields=('corporation', 'game'),
                name='only_unique_corporations_per_game'),
        ),
        migrations.AddConstraint(
            model_name='playerscore',
            constraint=models.CheckConstraint(
                check=models.Q(
                    corporation__in={
                        'Celestic', 'Thorgate', 'Cheung Shing Mars',
                        'Poseidon', 'Storm Craft Incorporated', 'Helion',
                        'Inventrix', 'Aridor', 'Valley Trust', 'Viron',
                        'Robinson Industries',
                        'United Nations Mars Initiative', 'Vitor',
                        'Point Luna', 'Arklight', 'Aphrodite', 'Polyphemos',
                        'Phobolog', 'Manutech', 'Terractor', 'Ecoline',
                        'Tharsis Republic', 'Morning Star Inc.',
                        'Mining Guild', 'Saturn Systems',
                        'Interplanetary Cinematics', 'Credicor'
                    }),
                name='Only defined corporations are allowed.'),
        ),
        migrations.RemoveConstraint(
            model_name='game',
            name="Only {'Hellas', 'Elysium', 'Tharsis'} maps are allowed.",
        ),
        migrations.AddConstraint(
            model_name='game',
            constraint=models.CheckConstraint(
                check=models.Q(game_map__in={'Hellas', 'Tharsis', 'Elysium'}),
                name="Only {'Elysium', 'Hellas', 'Tharsis'} maps are allowed."
            ),
        ),
        migrations.RemoveConstraint(
            model_name='game',
            name="Only {'Elysium', 'Hellas', 'Tharsis'} maps are allowed.",
        ),
        migrations.AddConstraint(
            model_name='game',
            constraint=models.CheckConstraint(
                check=models.Q(game_map__in={'Hellas', 'Tharsis', 'Elysium'}),
                name="Only {'Hellas', 'Elysium', 'Tharsis'} maps are allowed."
            ),
        ),
        migrations.RemoveConstraint(
            model_name='game',
            name="Only {'Hellas', 'Elysium', 'Tharsis'} maps are allowed.",
        ),
        migrations.AddConstraint(
            model_name='game',
            constraint=models.CheckConstraint(
                check=models.Q(game_map__in={'Hellas', 'Tharsis', 'Elysium'}),
                name="Only {'Elysium', 'Hellas', 'Tharsis'} maps are allowed."
            ),
        ),
        migrations.RemoveConstraint(
            model_name='game',
            name="Only {'Elysium', 'Hellas', 'Tharsis'} maps are allowed.",
        ),
        migrations.AddConstraint(
            model_name='game',
            constraint=models.CheckConstraint(
                check=models.Q(game_map__in={'Hellas', 'Tharsis', 'Elysium'}),
                name="Only {'Hellas', 'Elysium', 'Tharsis'} maps are allowed."
            ),
        ),
        migrations.RemoveConstraint(
            model_name='game',
            name="Only {'Hellas', 'Elysium', 'Tharsis'} maps are allowed.",
        ),
        migrations.AddConstraint(
            model_name='game',
            constraint=models.CheckConstraint(
                check=models.Q(game_map__in={'Hellas', 'Tharsis', 'Elysium'}),
                name="Only {'Elysium', 'Hellas', 'Tharsis'} maps are allowed."
            ),
        ),
        migrations.RemoveConstraint(
            model_name='game',
            name="Only {'Elysium', 'Hellas', 'Tharsis'} maps are allowed.",
        ),
        migrations.AddConstraint(
            model_name='game',
            constraint=models.CheckConstraint(
                check=models.Q(game_map__in={'Hellas', 'Tharsis', 'Elysium'}),
                name="Only {'Elysium', 'Tharsis', 'Hellas'} maps are allowed."
            ),
        ),
        migrations.RemoveConstraint(
            model_name='game',
            name="Only {'Elysium', 'Tharsis', 'Hellas'} maps are allowed.",
        ),
        migrations.AddConstraint(
            model_name='game',
            constraint=models.CheckConstraint(
                check=models.Q(game_map__in={'Hellas', 'Tharsis', 'Elysium'}),
                name='Only defined maps are allowed.'),
        ),
        migrations.RemoveConstraint(
            model_name='playerscore',
            name='Only defined corporations are allowed.',
        ),
        migrations.AddField(
            model_name='game',
            name='number_of_generations',
            field=models.PositiveSmallIntegerField(default=10),
        ),
        migrations.AlterField(
            model_name='playerscore',
            name='corporation',
            field=models.CharField(choices=[
                ('Aphrodite', 'Aphrodite'),
                ('Aridor', 'Aridor'), ('Arklight', 'Arklight'),
                ('Celestic', 'Celestic'),
                ('Cheung Shing Mars', 'Cheung Shing Mars'),
                ('Credicor', 'Credicor'), ('Ecoline', 'Ecoline'),
                ('Helion', 'Helion'),
                ('Interplanetary Cinematics', 'Interplanetary Cinematics'),
                ('Inventrix', 'Inventrix'), ('N/A', 'N/A'),
                ('Manutech', 'Manutech'), ('Mining Guild', 'Mining Guild'),
                ('Morning Star Inc.', 'Morning Star Inc.'),
                ('Phobolog', 'Phobolog'), ('Point Luna', 'Point Luna'),
                ('Polyphemos', 'Polyphemos'), ('Poseidon', 'Poseidon'),
                ('Robinson Industries', 'Robinson Industries'),
                ('Saturn Systems', 'Saturn Systems'),
                ('Storm Craft Incorporated', 'Storm Craft Incorporated'),
                ('Teractor', 'Teractor'),
                ('Tharsis Republic', 'Tharsis Republic'),
                ('Thorgate', 'Thorgate'),
                ('United Nations Mars Initiative',
                 'United Nations Mars Initiative'),
                ('Valley Trust', 'Valley Trust'), ('Viron', 'Viron'),
                ('Vitor', 'Vitor')
            ],
                                   max_length=64),
        ),
        migrations.AddConstraint(
            model_name='playerscore',
            constraint=models.CheckConstraint(
                check=models.Q(
                    corporation__in={
                        'Celestic', 'Thorgate', 'Poseidon',
                        'Cheung Shing Mars', 'Storm Craft Incorporated',
                        'Helion', 'Inventrix', 'Aridor', 'Valley Trust',
                        'Viron', 'Robinson Industries', 'Teractor',
                        'United Nations Mars Initiative', 'Vitor',
                        'Point Luna', 'Arklight', 'Aphrodite', 'Phobolog',
                        'Polyphemos', 'Manutech', 'N/A', 'Ecoline',
                        'Tharsis Republic', 'Morning Star Inc.',
                        'Mining Guild', 'Saturn Systems',
                        'Interplanetary Cinematics', 'Credicor'
                    }),
                name='Only defined corporations are allowed.'),
        ),
        migrations.RemoveConstraint(
            model_name='playerscore',
            name='only_unique_corporations_per_game',
        ),
        migrations.AddConstraint(
            model_name='playerscore',
            constraint=models.UniqueConstraint(
                condition=models.Q(_negated=True,
                                   corporation__startswith='N/A'),
                fields=('corporation', 'game'),
                name='only_unique_corporations_per_game'),
        ),
        migrations.RemoveConstraint(
            model_name='playerscore',
            name='only_unique_corporations_per_game',
        ),
        migrations.AddConstraint(
            model_name='playerscore',
            constraint=models.UniqueConstraint(
                fields=('corporation', 'game'),
                name='only_unique_corporations_per_game'),
        ),
        migrations.RemoveConstraint(
            model_name='playerscore',
            name='only_unique_corporations_per_game',
        ),
        migrations.AddConstraint(
            model_name='playerscore',
            constraint=models.UniqueConstraint(
                condition=models.Q(_negated=True,
                                   corporation__startswith='N/A'),
                fields=('corporation', 'game'),
                name='only_unique_corporations_per_game'),
        ),
    ]
class PositiveSmallIntegerPKData(models.Model):
    data = models.PositiveSmallIntegerField(primary_key=True)
示例#28
0
class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='CarBodyType',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=20)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
            options={
                'abstract': False,
            },
        ),
        migrations.CreateModel(
            name='CarColor',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=20)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
            options={
                'abstract': False,
            },
        ),
        migrations.CreateModel(
            name='CarFuelType',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=20)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
            options={
                'abstract': False,
            },
        ),
        migrations.CreateModel(
            name='CarMake',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('slug', models.SlugField(editable=False)),
                ('name', models.CharField(max_length=50)),
                ('active', models.BooleanField(default=False)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
        ),
        migrations.CreateModel(
            name='CarModel',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('slug', models.SlugField(editable=False)),
                ('name', models.CharField(max_length=50)),
                ('active', models.BooleanField(default=False)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('make', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.carmake')),
            ],
        ),
        migrations.CreateModel(
            name='CarTransmission',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=20)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
            options={
                'abstract': False,
            },
        ),
        migrations.CreateModel(
            name='CarSubmodel',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('slug', models.SlugField(editable=False)),
                ('name', models.CharField(blank=True, max_length=50, null=True)),
                ('active', models.BooleanField(default=False)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
                ('model', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.carmodel')),
            ],
        ),
        migrations.CreateModel(
            name='Car',
            fields=[
                ('id', models.UUIDField(db_index=True, default=uuid.uuid4, primary_key=True, serialize=False)),
                ('active', models.BooleanField(default=False)),
                ('year', models.PositiveSmallIntegerField(validators=[django.core.validators.MinValueValidator(1900), django.core.validators.MaxValueValidator(2050)])),
                ('mileage', models.PositiveIntegerField(blank=True, null=True)),
                ('price', models.PositiveIntegerField(blank=True, null=True)),
                ('created_at', models.DateTimeField()),
                ('updated_at', models.DateTimeField()),
                ('body_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='store.carbodytype')),
                ('exterior_color', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='store.carcolor')),
                ('fuel_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='store.carfueltype')),
                ('make', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='store.carmake')),
                ('model', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='store.carmodel')),
                ('submodel', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='store.carsubmodel')),
                ('transmission', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='store.cartransmission')),
            ],
        ),
    ]
示例#29
0
class Partner(models.Model):
    """
    A partner organization which provides access grants to paywalled resources.
    This model tracks contact information for the partner as well as extra
    information they require on access grant applications.
    """
    class Meta:
        app_label = 'resources'
        verbose_name = 'partner'
        verbose_name_plural = 'partners'
        ordering = ['company_name']

    # --------------------------------------------------------------------------
    # Managers
    # --------------------------------------------------------------------------

    # Define managers. Note that the basic manager must be first to make
    # Django internals work as expected, but we define objects as our custom
    # manager so that we don't inadvertently expose unavailable Partners to
    # end users.
    even_not_available = models.Manager()
    objects = AvailablePartnerManager()

    # --------------------------------------------------------------------------
    # Attributes
    # --------------------------------------------------------------------------

    company_name = models.CharField(max_length=40,
        # Translators: In the administrator interface, this text is help text for a field where staff can enter the name of the partner. Don't translate McFarland.
        help_text=_("Partner's name (e.g. McFarland). Note: "
        "this will be user-visible and *not translated*."))
    date_created = models.DateField(auto_now_add=True)
    coordinator = models.ForeignKey(User, blank=True, null=True,
        on_delete=models.SET_NULL,
        # Translators: In the administrator interface, this text is help text for a field where staff can specify the username of the account coordinator for this partner.
        help_text=_('The coordinator for this Partner, if any.'))
    featured = models.BooleanField(default=False,
        # Translators: In the administrator interface, this text is help text for a check box where staff can select whether a publisher will be featured on the website's front page.
        help_text=_("Mark as true to feature this partner on the front page."))
    company_location = CountryField(null=True,
        # Translators: In the administrator interface, this text is help text for a field where staff can enter the partner organisation's country.
        help_text=_("Partner's primary location."))

    # Status metadata
    # --------------------------------------------------------------------------
    # AVAILABLE partners are displayed to users.
    # NOT AVAILABLE partners are only accessible through the admin interface.
    # These may be, e.g., partners TWL used to work with but no longer does
    # (kept in the database for recordkeeping), or they may be partners TWL
    # is setting up a relationship with but isn't ready to expose to public
    # view.
    # We default to NOT_AVAILABLE to avoid inadvertently exposing Partners to
    # the application process when they're not ready yet, and to give staff
    # a chance to build their record incrementally and fix errors.
    AVAILABLE = 0
    NOT_AVAILABLE = 1
    WAITLIST = 2

    STATUS_CHOICES = (
        # Translators: This is a status for a Partner, denoting that editors can apply for access.
        (AVAILABLE, _('Available')),
        # Translators: This is a status for a Partner, denoting that editors cannot apply for access and the Partner will not be displayed to them.
        (NOT_AVAILABLE, _('Not available')),
        # Translators: This is a status for a Partner, denoting that it has no access grants available at this time (but should later).
        (WAITLIST, _('Waitlisted')),
    )

    EMAIL = 0
    CODES = 1
    PROXY = 2
    BUNDLE = 3

    AUTHORIZATION_METHODS = (
        # Translators: This is the name of the authorization method whereby user accounts are set up by email.
        (EMAIL, _('Email')),
        # Translators: This is the name of the authorization method whereby user accounts are set up via an access code.
        (CODES, _('Access codes')),
        # Translators: This is the name of the authorization method whereby users access resources via an IP proxy.
        (PROXY, _('Proxy')),
        # Translators: This is the name of the authorization method whereby users access resources automatically via the library bundle.
        (BUNDLE, _('Library Bundle')),
    )

    status = models.IntegerField(choices=STATUS_CHOICES,
        default=NOT_AVAILABLE,
        # Translators: In the administrator interface, this text is help text for a field where staff can specify whether this partner should be displayed to users.
        help_text=_('Should this Partner be displayed to users? Is it '
                    'open for applications right now?'))

    renewals_available = models.BooleanField(default=False,
        # Translators: In the administrator interface, this text is help text for a field where staff specify whether users can request their account be renewed/extended for this partner.
        help_text=_('Can access grants to this partner be renewed? If so, '
            'users will be able to request renewals at any time.'))
            
    accounts_available = models.PositiveSmallIntegerField(blank=True, null=True, 
        # Translators: In the administrator interface, this text is help text for a field where staff specify the total number of available accounts.
        help_text=_('Add number of new accounts to the existing value, not by reseting it to zero.'))
    
    # Optional resource metadata
    # --------------------------------------------------------------------------

    terms_of_use = models.URLField(blank=True, null=True,
        # Translators: In the administrator interface, this text is help text for a field where staff can link to a partner's Terms of Use.
        help_text=_("Link to terms of use. Required if users must agree to "
            "terms of use to get access; optional otherwise."))

    short_description = models.TextField(max_length=1000, blank=True, null=True,
        # Translators: In the administrator interface, this text is help text for a field where staff can provide a description of a partner's available resources.
        help_text=_("Optional short description of this partner's resources."))

    description = models.TextField("long description", blank=True,
        # Translators: In the administrator interface, this text is help text for a field where staff can provide a long description of a partner's available resources.
        help_text=_("Optional detailed description in addition to the short "
        "description such as collections, instructions, notes, special "
        "requirements, alternate access options, unique features, citations notes."))
        
    send_instructions = models.TextField(blank=True, null=True,
        # Translators: In the administrator interface, this text is help text for a field where staff can provide instructions to coordinators on sending user data to partners.
        help_text=_("Optional instructions for sending application data to "
            "this partner."))
    
    excerpt_limit = models.PositiveSmallIntegerField(blank=True, null=True,
          # Translators: In the administrator interface, this text is help text for a field where staff can optionally provide a excerpt word limit per article.
          help_text=_("Optional excerpt limit in terms of number of words per article. Leave empty if no limit."))

    excerpt_limit_percentage   = models.PositiveSmallIntegerField(blank=True, null=True, validators = [MaxValueValidator(100)],
          # Translators: In the administrator interface, this text is help text for a field where staff can optionally provide a excerpt word limit per article in terms of percentage per article.
          help_text=_("Optional excerpt limit in terms of percentage (%) of an article. Leave empty if no limit."))

    authorization_method = models.IntegerField(choices=AUTHORIZATION_METHODS,
        default=EMAIL,
        # Translators: In the administrator interface, this text is help text for a field where staff can specify which method of account distribution this partner uses.
        help_text=_("Which authorization method does this partner use? "
            "'Email' means the accounts are set up via email, and is the default. "
            "Select 'Access Codes' if we send individual, or group, login details "
            "or access codes. 'Proxy' means access delivered directly via EZProxy, "
            "and Library Bundle is automated proxy-based access."))

    mutually_exclusive = models.NullBooleanField(
        blank=True, null=True,
        default=None,
        # Translators: In the administrator interface, this text is help text for a field where staff can specify whether users can apply for one or multiple collections of resources. Streams means 'collections'.
        help_text=_("If True, users can only apply for one Stream at a time "
        "from this Partner. If False, users can apply for multiple Streams at "
        "a time. This field must be filled in when Partners have multiple "
        "Streams, but may be left blank otherwise."))

    languages = models.ManyToManyField(Language, blank=True,
        # Translators: In the administrator interface, this text is help text for a field where staff can specify the languages a partner has resources in.
        help_text=_("Select all languages in which this partner publishes "
            "content.")
        )

    tags = TaggableManager(through=TaggedTextField, blank=True)

    # This field has to stick around until all servers are using the new tags.
    old_tags = TaggableManager(through=None, blank=True, verbose_name=_('Old Tags'))

    # Non-universal form fields
    # --------------------------------------------------------------------------

    # Some fields are required by all resources for all access grants.
    # Some fields are only required by some resources. This is where we track
    # whether *this* resource requires those optional fields.

    registration_url = models.URLField(blank=True, null=True,
        # Translators: In the administrator interface, this text is help text for a field where staff can link to a partner's registration page.
        help_text=_("Link to registration page. Required if users must sign up "
            "on the partner's website in advance; optional otherwise."))
    real_name = models.BooleanField(default=False,
        # Translators: In the administrator interface, this text is help text for a check box where staff can select whether users must specify their real name when applying
        help_text=_('Mark as true if this partner requires applicant names.'))
    country_of_residence = models.BooleanField(default=False,
        # Translators: In the administrator interface, this text is help text for a check box where staff can select whether users must specify the country in which they live when applying.
        help_text=_('Mark as true if this partner requires applicant countries '
                    'of residence.'))
    specific_title = models.BooleanField(default=False,
        # Translators: In the administrator interface, this text is help text for a check box where staff can select whether users must specify a title for the resource they want to access when applying.
        help_text=_('Mark as true if this partner requires applicants to '
                    'specify the title they want to access.'))
    specific_stream = models.BooleanField(default=False,
        # Translators: In the administrator interface, this text is help text for a check box where staff can select whether users must specify a collection of resources when applying.
        help_text=_('Mark as true if this partner requires applicants to '
                    'specify the database they want to access.'))
    occupation = models.BooleanField(default=False,
        # Translators: In the administrator interface, this text is help text for a check box where staff can select whether users must specify their occupation when applying.
        help_text=_('Mark as true if this partner requires applicants to '
                    'specify their occupation.'))
    affiliation = models.BooleanField(default=False,
        # Translators: In the administrator interface, this text is help text for a check box where staff can select whether users must specify their institutional affiliation (e.g. university) when applying.
        help_text=_('Mark as true if this partner requires applicants to '
                    'specify their institutional affiliation.'))
    agreement_with_terms_of_use = models.BooleanField(default=False,
        # Translators: In the administrator interface, this text is help text for a check box where staff can select whether users must agree to Terms of Use when applying.
        help_text=_("Mark as true if this partner requires applicants to agree "
                    "with the partner's terms of use."))
    account_email = models.BooleanField(default=False,
        # Translators: In the administrator interface, this text is help text for a check box where staff can select whether users must first register at the organisation's website before finishing their application.
        help_text=_("Mark as true if this partner requires applicants to have "
                    "already signed up at the partner website."))


    def __unicode__(self):
        return self.company_name


    def clean(self):
        if self.agreement_with_terms_of_use and not self.terms_of_use:
            raise ValidationError('When agreement with terms of use is '
                'required, a link to terms of use must be provided.')
        if self.streams.count() > 1:
            if self.mutually_exclusive is None:
                raise ValidationError('Since this resource has multiple '
                    'Streams, you must specify a value for mutually_exclusive.')
        if self.account_email and not self.registration_url:
            raise ValidationError('When pre-registration is required, '
                'a link to the registration page must be provided.')


    def get_absolute_url(self):
        return reverse_lazy('partners:detail', kwargs={'pk': self.pk})

    def save(self, *args, **kwargs):
        """Invalidate this partner's pandoc-rendered html from cache"""
        super(Partner, self).save(*args, **kwargs)
        for code in RESOURCE_LANGUAGE_CODES:
          short_description_cache_key = make_template_fragment_key(
              'partner_short_description', [code, self.pk]
          )        
          description_cache_key = make_template_fragment_key(
              'partner_description', [code, self.pk]
          )
          send_instructions_cache_key = make_template_fragment_key(
              'partner_send_instructions', [code, self.pk]
          )
          cache.delete(short_description_cache_key)
          cache.delete(description_cache_key)
          cache.delete(send_instructions_cache_key)

    @property
    def get_languages(self):
        return self.languages.all()


    @property
    def is_waitlisted(self):
        return self.status == self.WAITLIST


    @property
    def is_not_available(self):
        return self.status == self.NOT_AVAILABLE
示例#30
0
class Email(models.Model):
    """
    A model to hold email information.
    """

    PRIORITY_CHOICES = [(PRIORITY.low, _("low")), (PRIORITY.medium, _("medium")),
                        (PRIORITY.high, _("high")), (PRIORITY.now, _("now"))]
    STATUS_CHOICES = [(STATUS.sent, _("sent")), (STATUS.failed, _("failed")),
                      (STATUS.queued, _("queued")), (STATUS.requeued, _("requeued"))]

    from_email = models.CharField(_("Email From"), max_length=254,
                                  validators=[validate_email_with_name])
    to = CommaSeparatedEmailField(_("Email To"))
    cc = CommaSeparatedEmailField(_("Cc"))
    bcc = CommaSeparatedEmailField(_("Bcc"))
    subject = models.CharField(_("Subject"), max_length=989, blank=True)
    message = models.TextField(_("Message"), blank=True)
    html_message = models.TextField(_("HTML Message"), blank=True)
    """
    Emails with 'queued' status will get processed by ``send_queued`` command.
    Status field will then be set to ``failed`` or ``sent`` depending on
    whether it's successfully delivered.
    """
    status = models.PositiveSmallIntegerField(
        _("Status"),
        choices=STATUS_CHOICES, db_index=True,
        blank=True, null=True)
    priority = models.PositiveSmallIntegerField(_("Priority"),
                                                choices=PRIORITY_CHOICES,
                                                blank=True, null=True)
    created = models.DateTimeField(auto_now_add=True, db_index=True)
    last_updated = models.DateTimeField(db_index=True, auto_now=True)
    scheduled_time = models.DateTimeField(_("Scheduled Time"),
                                          blank=True, null=True, db_index=True,
                                          help_text=_("The scheduled sending time"))
    expires_at = models.DateTimeField(_("Expires"),
                                      blank=True, null=True,
                                      help_text=_("Email won't be sent after this timestamp"))
    message_id = models.CharField("Message-ID", null=True, max_length=255, editable=False)
    number_of_retries = models.PositiveIntegerField(null=True, blank=True)
    headers = models.JSONField(_('Headers'), blank=True, null=True)
    template = models.ForeignKey('post_office.EmailTemplate', blank=True,
                                 null=True, verbose_name=_("Email template"),
                                 on_delete=models.CASCADE)
    context = context_field_class(_('Context'), blank=True, null=True)
    backend_alias = models.CharField(_("Backend alias"), blank=True, default='',
                                     max_length=64)

    class Meta:
        app_label = 'post_office'
        verbose_name = pgettext_lazy("Email address", "Email")
        verbose_name_plural = pgettext_lazy("Email addresses", "Emails")

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._cached_email_message = None

    def __str__(self):
        return '%s' % self.to

    def email_message(self):
        """
        Returns Django EmailMessage object for sending.
        """
        if self._cached_email_message:
            return self._cached_email_message

        return self.prepare_email_message()

    def prepare_email_message(self):
        """
        Returns a django ``EmailMessage`` or ``EmailMultiAlternatives`` object,
        depending on whether html_message is empty.
        """
        if get_override_recipients():
            self.to = get_override_recipients()

        if self.template is not None:
            engine = get_template_engine()
            subject = engine.from_string(self.template.subject).render(self.context)
            plaintext_message = engine.from_string(self.template.content).render(self.context)
            multipart_template = engine.from_string(self.template.html_content)
            html_message = multipart_template.render(self.context)

        else:
            subject = smart_str(self.subject)
            plaintext_message = self.message
            multipart_template = None
            html_message = self.html_message

        connection = connections[self.backend_alias or 'default']
        if isinstance(self.headers, dict) or self.expires_at or self.message_id:
            headers = dict(self.headers or {})
            if self.expires_at:
                headers.update({'Expires': self.expires_at.strftime("%a, %-d %b %H:%M:%S %z")})
            if self.message_id:
                headers.update({'Message-ID': self.message_id})
        else:
            headers = None

        if html_message:
            if plaintext_message:
                msg = EmailMultiAlternatives(
                    subject=subject, body=plaintext_message, from_email=self.from_email,
                    to=self.to, bcc=self.bcc, cc=self.cc,
                    headers=headers, connection=connection)
                msg.attach_alternative(html_message, "text/html")
            else:
                msg = EmailMultiAlternatives(
                    subject=subject, body=html_message, from_email=self.from_email,
                    to=self.to, bcc=self.bcc, cc=self.cc,
                    headers=headers, connection=connection)
                msg.content_subtype = 'html'
            if hasattr(multipart_template, 'attach_related'):
                multipart_template.attach_related(msg)

        else:
            msg = EmailMessage(
                subject=subject, body=plaintext_message, from_email=self.from_email,
                to=self.to, bcc=self.bcc, cc=self.cc,
                headers=headers, connection=connection)

        for attachment in self.attachments.all():
            if attachment.headers:
                mime_part = MIMENonMultipart(*attachment.mimetype.split('/'))
                mime_part.set_payload(attachment.file.read())
                for key, val in attachment.headers.items():
                    try:
                        mime_part.replace_header(key, val)
                    except KeyError:
                        mime_part.add_header(key, val)
                msg.attach(mime_part)
            else:
                msg.attach(attachment.name, attachment.file.read(), mimetype=attachment.mimetype or None)
            attachment.file.close()

        self._cached_email_message = msg
        return msg

    def dispatch(self, log_level=None,
                 disconnect_after_delivery=True, commit=True):
        """
        Sends email and log the result.
        """
        try:
            self.email_message().send()
            status = STATUS.sent
            message = ''
            exception_type = ''
        except Exception as e:
            status = STATUS.failed
            message = str(e)
            exception_type = type(e).__name__

            # If run in a bulk sending mode, reraise and let the outer
            # layer handle the exception
            if not commit:
                raise

        if disconnect_after_delivery:
            connections.close()

        if commit:
            self.status = status
            self.save(update_fields=['status'])

            if log_level is None:
                log_level = get_log_level()

            # If log level is 0, log nothing, 1 logs only sending failures
            # and 2 means log both successes and failures
            if log_level == 1:
                if status == STATUS.failed:
                    self.logs.create(status=status, message=message,
                                     exception_type=exception_type)
            elif log_level == 2:
                self.logs.create(status=status, message=message,
                                 exception_type=exception_type)

        return status

    def clean(self):
        if self.scheduled_time and self.expires_at and self.scheduled_time > self.expires_at:
            raise ValidationError(_("The scheduled time may not be later than the expires time."))

    def save(self, *args, **kwargs):
        self.full_clean()
        return super().save(*args, **kwargs)