@@ -660,7 +660,10 @@ def generic_qso_validator(self):
660
660
self .errors .append ((self .line_nr , 'Qso WWL is invalid: {}' .format (self .qso_fields ['wwl' ])))
661
661
662
662
# validate 'duplicate_qso' format
663
- # TODO
663
+ if self .qso_fields ['duplicate_qso' ].upper () == 'D' :
664
+ self .valid = False
665
+ self .errors .append ((self .line_nr , 'Qso marked as dupplicate' ))
666
+
664
667
return None
665
668
666
669
def rules_based_qso_validator (self ):
@@ -694,7 +697,31 @@ def rules_based_qso_validator(self):
694
697
'Qso hour is invalid: after contest end hour (>{})' .format (self .rules .contest_end_hour )))
695
698
696
699
# validate date & hour based on period
700
+ inside_period , _ = self .qso_inside_period ()
701
+
702
+ if not inside_period :
703
+ self .valid = False
704
+ self .errors .append ((self .line_nr ,
705
+ 'Qso date/hour is invalid: not inside contest periods' ))
706
+
707
+ # validate qso mode
708
+ if int (self .qso_fields ['mode' ]) not in self .rules .contest_qso_modes :
709
+ self .valid = False
710
+ self .errors .append ((self .line_nr ,
711
+ 'Qso mode is invalid: not in defined modes ({})' .format (self .rules .contest_qso_modes )))
712
+ return None
713
+
714
+ def qso_inside_period (self ):
715
+ """
716
+ :return: True, period_number
717
+ False, None
718
+ """
697
719
inside_period = False
720
+ inside_period_nr = None
721
+
722
+ if not self .rules or self .valid is False :
723
+ return inside_period , inside_period_nr
724
+
698
725
for period in range (1 , self .rules .contest_periods_nr + 1 ):
699
726
# if date is not in period, check next period
700
727
if not (self .rules .contest_period (period )['begindate' ][2 :] <= self .qso_fields ['date' ] <= self .rules .contest_period (period )['enddate' ][2 :]):
@@ -705,30 +732,24 @@ def rules_based_qso_validator(self):
705
732
# if period is in same day
706
733
if delta_days == timedelta (0 ) and self .rules .contest_period (period )['beginhour' ] <= self .qso_fields ['hour' ] <= self .rules .contest_period (period )['endhour' ]:
707
734
inside_period = True
735
+ inside_period_nr = period
708
736
break
709
737
# if period is in multiple days
710
738
elif delta_days > timedelta (0 ):
711
739
if self .rules .contest_period (period )['begindate' ][2 :] == self .qso_fields ['date' ] and self .rules .contest_period (period )['beginhour' ] <= self .qso_fields ['hour' ]:
712
740
inside_period = True
741
+ inside_period_nr = period
713
742
break
714
743
if self .qso_fields ['date' ] == self .rules .contest_period (period )['enddate' ][2 :] and self .qso_fields ['hour' ] <= self .rules .contest_period (period )['endhour' ]:
715
744
inside_period = True
745
+ inside_period_nr = period
716
746
break
717
747
# if begin_period < qso_date < end_period
718
748
if self .rules .contest_period (period )['begindate' ][2 :] < self .qso_fields ['date' ] < self .rules .contest_period (period )['enddate' ][2 :]:
719
749
inside_period = True
750
+ inside_period_nr = period
720
751
break
721
- if not inside_period :
722
- self .valid = False
723
- self .errors .append ((self .line_nr ,
724
- 'Qso date/hour is invalid: not inside contest periods' ))
725
-
726
- # validate qso mode
727
- if int (self .qso_fields ['mode' ]) not in self .rules .contest_qso_modes :
728
- self .valid = False
729
- self .errors .append ((self .line_nr ,
730
- 'Qso mode is invalid: not in defined modes ({})' .format (self .rules .contest_qso_modes )))
731
- return None
752
+ return inside_period , inside_period_nr
732
753
733
754
734
755
class LogException (Exception ):
@@ -800,11 +821,10 @@ def crosscheck_logs(operator_instances, rules, band_nr):
800
821
:return: TODO
801
822
"""
802
823
for callsign1 , ham1 in operator_instances .items ():
803
- # print('CHECK LOGS OF : ', callsign1, ham1.callsign)
804
-
824
+ # set a list for this ham with already made contacts
825
+ _had_qso_with = []
805
826
# get logs for band
806
827
_logs1 = ham1 .logs_by_band_regexp (rules .contest_band (band_nr )['regexp' ])
807
- # print(' LOG PATH : ', [x.path for x in _logs1])
808
828
809
829
if not _logs1 :
810
830
continue
@@ -821,20 +841,21 @@ def crosscheck_logs(operator_instances, rules, band_nr):
821
841
if qso1 .confirmed is True :
822
842
continue
823
843
824
- # TODO : ignore duplicate qso (with flag)
825
- # TODO : check if this qso is present multiple times here in same period
826
- # and in other ham log to avoid 'dupplicate hacks'
827
-
828
844
# check if we have some logs from 2nd ham
829
845
callsign2 = qso1 .qso_fields ['call' ]
830
846
ham2 = operator_instances .get (callsign2 , None )
831
847
if not ham2 :
832
848
qso1 .confirmed = False
833
849
continue
834
850
851
+ # validate that this qso wasn't already validated
852
+ _ , inside_period_nr = qso1 .qso_inside_period ()
853
+ if '{}-period{}' .format (callsign2 , inside_period_nr ) in _had_qso_with :
854
+ qso1 .confirmed = False
855
+ continue
856
+
835
857
# check if we have proper band logs from 2nd ham
836
858
_logs2 = ham2 .logs_by_band_regexp (rules .contest_band (band_nr )['regexp' ])
837
- # print(' HAM2 LOGS : ', [x.path for x in _logs2])
838
859
if not _logs2 :
839
860
qso1 .confirmed = False
840
861
continue
@@ -845,8 +866,6 @@ def crosscheck_logs(operator_instances, rules, band_nr):
845
866
if qso2 .valid is False :
846
867
continue
847
868
848
- # TODO : ignore duplicate qso
849
-
850
869
_callsign = qso2 .qso_fields ['call' ]
851
870
if callsign1 != _callsign :
852
871
continue
@@ -855,9 +874,11 @@ def crosscheck_logs(operator_instances, rules, band_nr):
855
874
except ValueError as e :
856
875
qso1 .errors .append (e )
857
876
858
- # print(' *** COMPARAM : {} vs {} SI {} cu {} = {}'.format(callsign1, callsign2, qso1.qso_line, qso2.qso_line, distance))
859
877
if distance < 0 :
860
878
continue
879
+ # add this qso in _had_qso_with list
880
+ _ , inside_period_nr = qso2 .qso_inside_period ()
881
+ _had_qso_with .append ('{}-period{}' .format (callsign2 , inside_period_nr ))
861
882
qso1 .points = distance * int (rules .contest_band (band_nr )['multiplier' ])
862
883
qso1 .confirmed = True
863
884
0 commit comments