1818from django .db .models .signals import post_delete , post_save
1919from django .dispatch .dispatcher import receiver
2020from django .utils import timezone
21- from enumfields import Enum , EnumField
21+ from django_stubs_ext . db . models import TypedModelMeta
2222
2323from webcompat .models import Report , Signature
2424from webcompat .symptoms import URLSymptom , ValueMatcher
3636
3737
3838class App (models .Model ):
39- channel = models .CharField (max_length = 63 , null = True )
40- name = models .CharField (max_length = 63 )
41- version = models .CharField (max_length = 127 )
39+ channel : models . CharField = models .CharField (max_length = 63 , null = True )
40+ name : models . CharField = models .CharField (max_length = 63 )
41+ version : models . CharField = models .CharField (max_length = 127 )
4242
43- class Meta :
43+ class Meta ( TypedModelMeta ) :
4444 constraints = (
4545 models .UniqueConstraint (
4646 fields = ("channel" , "name" , "version" ), name = "unique_app"
@@ -49,29 +49,32 @@ class Meta:
4949
5050
5151class BreakageCategory (models .Model ):
52- value = models .CharField (max_length = 63 , unique = True )
52+ value : models . CharField = models .CharField (max_length = 63 , unique = True )
5353
5454
5555class Bucket (models .Model ):
56- bug = models .ForeignKey ("Bug" , null = True , on_delete = models .deletion .CASCADE )
57- color = models .ForeignKey (
56+ id : models .AutoField = models .AutoField (primary_key = True )
57+ bug : models .ForeignKey = models .ForeignKey (
58+ "Bug" , null = True , on_delete = models .deletion .CASCADE
59+ )
60+ color : models .ForeignKey = models .ForeignKey (
5861 "BucketColor" , null = True , on_delete = models .deletion .CASCADE
5962 )
60- description = models .TextField ()
63+ description : models . TextField = models .TextField ()
6164 # store the domain outside the signature only if the signature includes
6265 # a non-regex domain symptom and no other symptoms (for quick exclusion)
63- domain = models .CharField (max_length = 255 , null = True )
66+ domain : models . CharField = models .CharField (max_length = 255 , null = True )
6467 # bucket can be hidden from view until given date, without being logged
65- hide_until = models .DateTimeField (blank = True , null = True )
68+ hide_until : models . DateTimeField = models .DateTimeField (blank = True , null = True )
6669 # higher priority = earlier match
67- priority = models .IntegerField (
70+ priority : models . IntegerField = models .IntegerField (
6871 default = 0 , validators = (MinValueValidator (- 2 ), MaxValueValidator (2 ))
6972 )
7073 # Raw signature JSON (see webcompat.models.Signature)
71- signature = models .TextField ()
72- reassign_in_progress = models .BooleanField (default = False )
74+ signature : models . TextField = models .TextField ()
75+ reassign_in_progress : models . BooleanField = models .BooleanField (default = False )
7376
74- class Meta :
77+ class Meta ( TypedModelMeta ) :
7578 constraints = (
7679 models .CheckConstraint (
7780 condition = models .Q (priority__gte = - 2 ) & models .Q (priority__lte = 2 ),
@@ -295,12 +298,12 @@ def optimize_signature(self, unbucketed_entries):
295298
296299
297300class BucketColor (models .Model ):
298- name = models .CharField (max_length = 255 , unique = True )
299- value = models .IntegerField (
301+ name : models . CharField = models .CharField (max_length = 255 , unique = True )
302+ value : models . IntegerField = models .IntegerField (
300303 unique = True , validators = (MinValueValidator (0 ), MaxValueValidator (0xFFFFFF ))
301304 )
302305
303- class Meta :
306+ class Meta ( TypedModelMeta ) :
304307 constraints = (
305308 models .CheckConstraint (
306309 condition = models .Q (value__gte = 0 ) & models .Q (value__lte = 0xFFFFFF ),
@@ -310,11 +313,11 @@ class Meta:
310313
311314
312315class BugProvider (models .Model ):
313- classname = models .CharField (max_length = 255 , blank = False )
314- hostname = models .CharField (max_length = 255 , blank = False )
316+ classname : models . CharField = models .CharField (max_length = 255 , blank = False )
317+ hostname : models . CharField = models .CharField (max_length = 255 , blank = False )
315318
316319 # This is used to annotate bugs with the URL linking to them
317- url_template = models .CharField (max_length = 1023 , blank = False )
320+ url_template : models . CharField = models .CharField (max_length = 1023 , blank = False )
318321
319322 def get_instance (self ):
320323 # Dynamically instantiate the provider as requested
@@ -329,19 +332,25 @@ def __str__(self):
329332
330333
331334class Bug (models .Model ):
332- external_id = models .CharField (max_length = 255 , blank = True )
333- external_type = models .ForeignKey (BugProvider , on_delete = models .deletion .CASCADE )
334- closed = models .DateTimeField (blank = True , null = True )
335+ external_id : models .CharField = models .CharField (max_length = 255 , blank = True )
336+ external_type : models .ForeignKey = models .ForeignKey (
337+ BugProvider , on_delete = models .deletion .CASCADE
338+ )
339+ closed : models .DateTimeField = models .DateTimeField (blank = True , null = True )
335340
336341
337342def buckethit_default_range_begin ():
338343 return timezone .now ().replace (microsecond = 0 , second = 0 , minute = 0 )
339344
340345
341346class BucketHit (models .Model ):
342- bucket = models .ForeignKey (Bucket , on_delete = models .deletion .CASCADE )
343- begin = models .DateTimeField (default = buckethit_default_range_begin )
344- count = models .IntegerField (default = 0 )
347+ bucket : models .ForeignKey = models .ForeignKey (
348+ Bucket , on_delete = models .deletion .CASCADE
349+ )
350+ begin : models .DateTimeField = models .DateTimeField (
351+ default = buckethit_default_range_begin
352+ )
353+ count : models .IntegerField = models .IntegerField (default = 0 )
345354
346355 @classmethod
347356 @transaction .atomic
@@ -369,7 +378,7 @@ def increment_count(cls, bucket_id, begin):
369378 counter .count += 1
370379 counter .save ()
371380
372- class Meta :
381+ class Meta ( TypedModelMeta ) :
373382 constraints = (
374383 models .UniqueConstraint (
375384 fields = ["bucket" , "begin" ],
@@ -379,21 +388,25 @@ class Meta:
379388
380389
381390class BucketWatch (models .Model ):
382- user = models .ForeignKey ("User" , on_delete = models .deletion .CASCADE )
383- bucket = models .ForeignKey (Bucket , on_delete = models .deletion .CASCADE )
391+ user : models .ForeignKey = models .ForeignKey (
392+ "User" , on_delete = models .deletion .CASCADE
393+ )
394+ bucket : models .ForeignKey = models .ForeignKey (
395+ Bucket , on_delete = models .deletion .CASCADE
396+ )
384397 # This is the primary key of last crash marked viewed by the user
385398 # Store as an integer to prevent problems if the particular crash
386399 # is deleted later. We only care about its place in the ordering.
387- last_report = models .IntegerField (default = 0 )
400+ last_report : models . IntegerField = models .IntegerField (default = 0 )
388401
389402
390403class OS (models .Model ):
391- name = models .CharField (max_length = 63 , unique = True )
404+ name : models . CharField = models .CharField (max_length = 63 , unique = True )
392405
393406
394407class ReportHit (models .Model ):
395- last_update = models .DateTimeField (default = timezone .now )
396- count = models .BigIntegerField (default = 0 )
408+ last_update : models . DateTimeField = models .DateTimeField (default = timezone .now )
409+ count : models . BigIntegerField = models .BigIntegerField (default = 0 )
397410
398411 @staticmethod
399412 def get_period (time ):
@@ -411,7 +424,7 @@ def get_period(time):
411424 microseconds = - time .microsecond ,
412425 )
413426
414- class Meta :
427+ class Meta ( TypedModelMeta ) :
415428 constraints = (
416429 models .UniqueConstraint (
417430 fields = ["last_update" ],
@@ -452,20 +465,22 @@ def create_from_report(self, report, bucket_id=None):
452465
453466
454467class ReportEntry (models .Model ):
455- app = models .ForeignKey (App , on_delete = models .deletion .CASCADE )
456- breakage_category = models .ForeignKey (
468+ app : models . ForeignKey = models .ForeignKey (App , on_delete = models .deletion .CASCADE )
469+ breakage_category : models . ForeignKey = models .ForeignKey (
457470 BreakageCategory , null = True , on_delete = models .deletion .CASCADE
458471 )
459- bucket = models .ForeignKey (Bucket , null = True , on_delete = models .deletion .CASCADE )
460- comments = models .TextField ()
461- comments_translated = models .TextField (null = True )
462- comments_original_language = models .TextField (null = True )
463- details = models .JSONField ()
464- os = models .ForeignKey (OS , on_delete = models .deletion .CASCADE )
465- reported_at = models .DateTimeField ()
466- url = models .URLField (max_length = 8192 )
467- uuid = models .UUIDField (unique = True )
468- ml_valid_probability = models .FloatField (null = True )
472+ bucket : models .ForeignKey = models .ForeignKey (
473+ Bucket , null = True , on_delete = models .deletion .CASCADE
474+ )
475+ comments : models .TextField = models .TextField ()
476+ comments_translated : models .TextField = models .TextField (null = True )
477+ comments_original_language : models .TextField = models .TextField (null = True )
478+ details : models .JSONField = models .JSONField ()
479+ os : models .ForeignKey = models .ForeignKey (OS , on_delete = models .deletion .CASCADE )
480+ reported_at : models .DateTimeField = models .DateTimeField ()
481+ url : models .URLField = models .URLField (max_length = 8192 )
482+ uuid : models .UUIDField = models .UUIDField (unique = True )
483+ ml_valid_probability : models .FloatField = models .FloatField (null = True )
469484
470485 objects = ReportEntryManager ()
471486
@@ -574,43 +589,43 @@ def ReportEntry_save(sender, instance, created, **kwargs):
574589 triage_new_report .apply_async ((instance .pk ,), countdown = 0.1 )
575590
576591
577- class BugzillaTemplateMode (Enum ):
592+ class BugzillaTemplateMode (models . TextChoices ):
578593 Bug = "bug"
579594 Comment = "comment"
580595
581596
582597class BugzillaTemplate (models .Model ):
583- mode = EnumField ( BugzillaTemplateMode , max_length = 30 )
584- name = models .TextField ()
585- product = models .TextField ()
586- component = models .TextField ()
587- summary = models .TextField (blank = True )
588- version = models .TextField ()
589- description = models .TextField (blank = True )
590- whiteboard = models .TextField (blank = True )
591- keywords = models .TextField (blank = True )
592- op_sys = models .TextField (blank = True )
593- platform = models .TextField (blank = True )
594- priority = models .TextField (blank = True )
595- severity = models .TextField (blank = True )
596- alias = models .TextField (blank = True )
597- cc = models .TextField (blank = True )
598- assigned_to = models .TextField (blank = True )
599- qa_contact = models .TextField (blank = True )
600- target_milestone = models .TextField (blank = True )
601- attrs = models .TextField (blank = True )
602- security = models .BooleanField (blank = False , default = False )
603- security_group = models .TextField (blank = True )
604- comment = models .TextField (blank = True )
605- blocks = models .TextField (blank = True )
606- dependson = models .TextField (blank = True )
598+ mode : models . TextField = models . TextField ( choices = BugzillaTemplateMode , max_length = 30 )
599+ name : models . TextField = models .TextField ()
600+ product : models . TextField = models .TextField ()
601+ component : models . TextField = models .TextField ()
602+ summary : models . TextField = models .TextField (blank = True )
603+ version : models . TextField = models .TextField ()
604+ description : models . TextField = models .TextField (blank = True )
605+ whiteboard : models . TextField = models .TextField (blank = True )
606+ keywords : models . TextField = models .TextField (blank = True )
607+ op_sys : models . TextField = models .TextField (blank = True )
608+ platform : models . TextField = models .TextField (blank = True )
609+ priority : models . TextField = models .TextField (blank = True )
610+ severity : models . TextField = models .TextField (blank = True )
611+ alias : models . TextField = models .TextField (blank = True )
612+ cc : models . TextField = models .TextField (blank = True )
613+ assigned_to : models . TextField = models .TextField (blank = True )
614+ qa_contact : models . TextField = models .TextField (blank = True )
615+ target_milestone : models . TextField = models .TextField (blank = True )
616+ attrs : models . TextField = models .TextField (blank = True )
617+ security : models . BooleanField = models .BooleanField (blank = False , default = False )
618+ security_group : models . TextField = models .TextField (blank = True )
619+ comment : models . TextField = models .TextField (blank = True )
620+ blocks : models . TextField = models .TextField (blank = True )
621+ dependson : models . TextField = models .TextField (blank = True )
607622
608623 def __str__ (self ):
609624 return self .name
610625
611626
612627class User (models .Model ):
613- class Meta :
628+ class Meta ( TypedModelMeta ) :
614629 permissions = (
615630 (
616631 "reportmanager_visible" ,
@@ -620,16 +635,16 @@ class Meta:
620635 ("reportmanager_read" , "Read access to ReportManager" ),
621636 )
622637
623- user = models .OneToOneField (DjangoUser , on_delete = models .deletion .CASCADE )
638+ user : models . OneToOneField = models .OneToOneField (DjangoUser , on_delete = models .deletion .CASCADE )
624639 # Explicitly do not store this as a ForeignKey to e.g. BugzillaTemplate
625640 # because the bug provider has to decide how to interpret this ID.
626- default_template_id = models .IntegerField (default = 0 )
627- default_provider_id = models .IntegerField (default = 1 )
628- buckets_watching = models .ManyToManyField (Bucket , through = "BucketWatch" )
641+ default_template_id : models . IntegerField = models .IntegerField (default = 0 )
642+ default_provider_id : models . IntegerField = models .IntegerField (default = 1 )
643+ buckets_watching : models . ManyToManyField = models .ManyToManyField (Bucket , through = "BucketWatch" )
629644
630645 # Notifications
631- bucket_hit = models .BooleanField (blank = False , default = False )
632- inaccessible_bug = models .BooleanField (blank = False , default = False )
646+ bucket_hit : models . BooleanField = models .BooleanField (blank = False , default = False )
647+ inaccessible_bug : models . BooleanField = models .BooleanField (blank = False , default = False )
633648
634649
635650@receiver (post_save , sender = DjangoUser )
0 commit comments