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