@ -2,13 +2,14 @@ from __future__ import unicode_literals
import datetime
from django . db import models
from django . contrib . auth . models import AbstractUser
from django . core . validators import RegexValidator , MinValueValidator , MaxValueValidator
from django . db import models
from django . db . models import Q , signals
from . validators import CallUsernameValidator
from . signals import checkForShadowCall
from . validators import CallUsernameValidator
class Contest ( models . Model ) :
name = models . CharField ( max_length = 20 )
@ -34,6 +35,7 @@ class Reference(models.Model):
def __str__ ( self ) :
return self . name
class EntryCategory ( models . Model ) :
name = models . CharField ( max_length = 64 , unique = True )
description = models . TextField ( blank = True )
@ -41,9 +43,10 @@ class EntryCategory(models.Model):
def __str__ ( self ) :
return self . name
class ShadowCall ( models . Model ) :
username = models . CharField ( max_length = 20 , unique = True , db_index = True , validators = [ CallUsernameValidator ( ) ] )
ref = models . ForeignKey ( Reference , models . SET_NULL , null = True , blank = True )
ref = models . ForeignKey ( Reference , models . SET_NULL , null = True , blank = True )
location = models . CharField ( max_length = 128 , default = " " , blank = True )
opName = models . CharField ( max_length = 128 , default = " " , blank = True )
@ -52,6 +55,7 @@ class ShadowCall(models.Model):
def __str__ ( self ) :
return self . username
class User ( AbstractUser ) :
ref = models . ForeignKey ( Reference , models . SET_NULL , null = True , blank = True )
cat = models . ForeignKey ( EntryCategory , models . SET_NULL , null = True , blank = True )
@ -67,17 +71,18 @@ class User(AbstractUser):
# extra profile stuff so DL7BST can sleep well without his doodles
editedProfile = models . BooleanField ( default = False )
dncall = models . CharField ( max_length = 16 , default = ' ' , blank = True ,
verbose_name = " DN-Call " ,
help_text = " If you have a DN call that you will offer to SWLs please enter it here " )
verbose_name = " DN-Call " ,
help_text = " If you have a DN call that you will offer to SWLs please enter it here " )
qrv2m = models . BooleanField ( default = False ,
verbose_name = " QRV on 2m " ,
help_text = " Will you be QRV on 2m during the contest? " )
qrv70cm = models . BooleanField ( default = False ,
verbose_name = " QRV on 70cm " ,
help_text = " Will you be QRV on 70cm during the contest? " )
verbose_name = " QRV on 70cm " ,
help_text = " Will you be QRV on 70cm during the contest? " )
extra2m70cm = models . BooleanField ( default = False ,
verbose_name = " Additional 2m/70cm TRX " ,
help_text = " Will you bring an additional 2m/70cm TRX to lend to other participants? " )
verbose_name = " Additional 2m/70cm TRX " ,
help_text = " Will you bring an additional 2m/70cm TRX to lend to "
" other participants? " )
def __init__ ( self , * args , * * kwargs ) :
super ( User , self ) . __init__ ( * args , * * kwargs )
@ -124,8 +129,11 @@ class User(AbstractUser):
" qsoCount " : qsos . count ( ) ,
" refCount " : len ( refs )
}
signals . post_save . connect ( checkForShadowCall , sender = User )
class Band ( models . Model ) :
name = models . CharField ( max_length = 10 )
contest = models . ForeignKey ( Contest )
@ -133,6 +141,7 @@ class Band(models.Model):
def __str__ ( self ) :
return self . name
class Frequency ( models . Model ) :
# qrg
# band
@ -145,6 +154,7 @@ class Frequency(models.Model):
def __str__ ( self ) :
return " Channel %s : %s MHz " % ( self . channel , self . qrg )
class QSO ( models . Model ) :
MAX_NO_VALUE = 1000000
reportValidator = RegexValidator ( " [1-5][1-9] " )
@ -174,7 +184,7 @@ class QSO(models.Model):
cfmdQSO = models . ForeignKey ( " QSO " , models . SET_NULL , null = True , blank = True , default = None )
CFMD_SEC = 5 * 60
CFMD_SEC = 5 * 60
def checkQSOData ( self ) :
""" Match strdata to log rows. Only call, if you intent to save this object if we return True! """
@ -213,10 +223,10 @@ class QSO(models.Model):
# check if this still checks out
q = self . cfmdQSO
if abs ( ( self . time - q . time ) . total_seconds ( ) ) < = self . CFMD_SEC and \
self . ref and self . owner . ref and self . callRef and q . callRef and \
q . owner == self . callRef and q . callRef == self . owner and \
self . ref == q . owner . ref and self . owner . ref == q . ref and \
self . band == q . band :
self . ref and self . owner . ref and self . callRef and q . callRef and \
q . owner == self . callRef and q . callRef == self . owner and \
self . ref == q . owner . ref and self . owner . ref == q . ref and \
self . band == q . band :
# checks out
pass
else :
@ -228,7 +238,8 @@ class QSO(models.Model):
if self . ref and self . callRef and self . callRef . ref and not self . cfmdQSO :
# look for a matching line
q = QSO . objects . filter (
( Q ( time__lte = self . time + datetime . timedelta ( seconds = self . CFMD_SEC ) ) & Q ( time__gte = self . time - datetime . timedelta ( seconds = self . CFMD_SEC ) ) ) ,
( Q ( time__lte = self . time + datetime . timedelta ( seconds = self . CFMD_SEC ) ) &
Q ( time__gte = self . time - datetime . timedelta ( seconds = self . CFMD_SEC ) ) ) ,
owner = self . callRef ,
callRef = self . owner ,
owner__ref = self . ref ,
@ -250,4 +261,6 @@ class QSO(models.Model):
super ( QSO , self ) . save ( * args , * * kwargs )
def __str__ ( self ) :
return " QSO no %s at %s on band %s from %s with %s @ %s %s / %s " % ( self . ownNo , self . time . strftime ( " % H: % M " ) , self . band , self . owner . username , self . call , self . refStr , self . reportTX , self . reportRX )
return " QSO no %s at %s on band %s from %s with %s @ %s %s / %s " % ( self . ownNo , self . time . strftime ( " % H: % M " ) ,
self . band , self . owner . username , self . call ,
self . refStr , self . reportTX , self . reportRX )