2017-01-18 02:25:12 +01:00
from __future__ import unicode_literals
2017-01-26 19:14:58 +01:00
import datetime
2017-01-18 02:25:12 +01:00
from django . db import models
from django . contrib . auth . models import AbstractUser
2017-01-21 01:52:19 +01:00
from django . core . validators import RegexValidator
2017-01-26 19:14:58 +01:00
from django . db . models import Q
2017-01-18 02:25:12 +01:00
2017-01-19 18:42:11 +01:00
from . validators import CallUsernameValidator
class Contest ( models . Model ) :
name = models . CharField ( max_length = 20 )
shortName = models . CharField ( max_length = 20 , unique = True )
2017-01-23 02:40:44 +01:00
callQrg = models . ForeignKey ( " Frequency " , models . SET_NULL , null = True , blank = True )
2017-01-26 20:51:22 +01:00
deadline = models . DateTimeField ( )
2017-01-19 18:42:11 +01:00
def __str__ ( self ) :
return self . name
2017-01-18 02:25:12 +01:00
class Reference ( models . Model ) :
2017-01-23 02:40:44 +01:00
name = models . CharField ( max_length = 20 , unique = True , db_index = True )
2017-01-18 02:25:12 +01:00
description = models . TextField ( )
2017-01-19 18:42:11 +01:00
def __str__ ( self ) :
return self . name
2017-01-26 20:36:55 +01:00
class EntryCategory ( models . Model ) :
name = models . CharField ( max_length = 64 , unique = True )
description = models . TextField ( blank = True )
def __str__ ( self ) :
return self . name
2017-01-25 01:53:22 +01:00
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 )
def __str__ ( self ) :
return self . username
2017-01-18 02:25:12 +01:00
class User ( AbstractUser ) :
2017-01-26 20:36:55 +01:00
ref = models . ForeignKey ( Reference , models . SET_NULL , null = True , blank = True )
cat = models . ForeignKey ( EntryCategory , models . SET_NULL , null = True , blank = True )
2017-01-18 02:25:12 +01:00
2017-01-19 18:42:11 +01:00
def __init__ ( self , * args , * * kwargs ) :
super ( User , self ) . __init__ ( * args , * * kwargs )
self . _meta . get_field ( " username " ) . validators = [ CallUsernameValidator ( ) ]
2017-01-18 02:25:12 +01:00
2017-01-26 19:14:58 +01:00
def getQSOCount ( self ) :
return self . qso_set . count ( )
def getCfmdQSOCount ( self ) :
return self . qso_set . filter ( ~ Q ( cfmdQSO = None ) ) . count ( )
def getCfmdRefCount ( self ) :
return len ( set ( map ( lambda _x : _x [ " refStr " ] , self . qso_set . filter ( ref__isnull = False ) . values ( " ref " , " refStr " ) ) ) )
2017-01-18 02:25:12 +01:00
class Band ( models . Model ) :
name = models . CharField ( max_length = 10 )
2017-01-19 18:42:11 +01:00
contest = models . ForeignKey ( Contest )
2017-01-18 02:25:12 +01:00
def __str__ ( self ) :
return self . name
class Frequency ( models . Model ) :
# qrg
# band
channel = models . CharField ( max_length = 3 )
qrg = models . DecimalField ( max_digits = 7 , decimal_places = 3 )
band = models . ForeignKey ( Band )
2017-01-20 17:28:14 +01:00
note = models . CharField ( max_length = 50 , blank = True )
2017-01-19 18:42:11 +01:00
2017-01-18 02:25:12 +01:00
def __str__ ( self ) :
return " Channel %s : %s MHz " % ( self . channel , self . qrg )
2017-01-19 18:42:11 +01:00
class QSO ( models . Model ) :
2017-01-21 01:52:19 +01:00
reportValidator = RegexValidator ( " [1-5][1-9] " )
2017-01-23 02:40:44 +01:00
class Meta :
index_together = [
[ " owner " , " call " ] ,
]
owner = models . ForeignKey ( User , db_index = True )
2017-01-19 18:42:11 +01:00
time = models . DateTimeField ( blank = True )
2017-01-23 02:40:44 +01:00
call = models . CharField ( max_length = 20 , db_index = True )
2017-01-26 19:14:58 +01:00
callRef = models . ForeignKey ( User , models . SET_NULL , related_name = ' qsoref ' , null = True , blank = True , default = None )
2017-01-19 18:42:11 +01:00
band = models . ForeignKey ( Band )
2017-01-21 01:52:19 +01:00
reportTX = models . CharField ( max_length = 7 , default = 59 , verbose_name = ' RST-S ' , validators = [ reportValidator ] )
reportRX = models . CharField ( max_length = 7 , default = 59 , verbose_name = ' RST-R ' , validators = [ reportValidator ] )
2017-01-19 18:42:11 +01:00
2017-01-26 21:15:30 +01:00
ownNo = models . IntegerField ( verbose_name = ' No-S ' )
2017-01-26 21:24:23 +01:00
otherNo = models . IntegerField ( verbose_name = ' No-R ' , null = True , blank = True )
2017-01-19 18:42:11 +01:00
2017-01-21 04:26:47 +01:00
refStr = models . CharField ( max_length = 20 , verbose_name = " EXC " )
2017-01-23 02:40:44 +01:00
ref = models . ForeignKey ( Reference , models . SET_NULL , null = True , blank = True )
2017-01-19 18:42:11 +01:00
2017-01-26 19:14:58 +01:00
remarks = models . CharField ( max_length = 50 , blank = True , default = None )
cfmdQSO = models . ForeignKey ( " QSO " , models . SET_NULL , null = True , blank = True , default = None )
CFMD_SEC = 300
def checkQSOData ( self ) :
""" Match strdata to log rows. Only call, if you intent to save this object if we return True! """
# find reference
changed = False
if self . refStr :
# Old reference exists?
if self . ref and self . ref . name != self . refStr :
self . ref = None
changed = True
if not self . ref :
# find matching ref
try :
self . ref = Reference . objects . get ( name = self . refStr )
changed = True
except Reference . DoesNotExist :
pass
# find call
if not self . callRef or self . callRef . username != self . call :
try :
self . callRef = User . objects . get ( username = self . call )
changed = True
except User . DoesNotExist :
if self . callRef :
changed = True
self . callRef = None
# find matching qso
if self . cfmdQSO :
# check if this still checks out
q = self . cfmdQSO
if ( self . time - q . time ) . total_seconds ( ) < = self . CFMD_SEC and \
self . ref and self . owner . ref and \
self . ref == q . owner . ref and self . owner . ref == q . ref and \
self . band == q . band :
# checks out
pass
else :
changed = True
self . cfmdQSO . cfmdQSO = None
self . cfmdQSO = None
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__gte = self . time + datetime . timedelta ( 0 , self . CFMD_SEC ) ) | Q ( time__gte = self . time - datetime . timedelta ( 0 , self . CFMD_SEC ) ) ) ,
owner__ref = self . ref ,
ref = self . owner . ref ,
band = self . band )
if q . count ( ) == 1 :
changed = True
q [ 0 ] . cfmdQSO = self
q [ 0 ] . save ( checkQSO = False )
self . cfmdQSO = q [ 0 ]
return changed
def save ( self , checkQSO = True , * args , * * kwargs ) :
if checkQSO :
self . checkQSOData ( )
super ( QSO , self ) . save ( * args , * * kwargs )
2017-01-21 01:08:40 +01:00
def __str__ ( self ) :
2017-01-26 19:14:58 +01:00
return " QSO no %s at from %s %s with %s @ %s %s / %s " % ( self . ownNo , self . time . strftime ( " % H: % M " ) , self . owner . username , self . call , self . refStr , self . reportTX , self . reportRX )