civics-cdf-validator 1.49.dev13__py3-none-any.whl → 1.49.dev14__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2989,20 +2989,25 @@ class RemovePersonAndOfficeHolderId60DaysAfterEndDate(base.TreeRule):
2989
2989
  info_log = []
2990
2990
  persons = self.get_elements_by_class(self.election_tree, "Person")
2991
2991
  offices = self.get_elements_by_class(self.election_tree, "Office")
2992
+ officeholder_tenure_collection = self.get_elements_by_class(
2993
+ self.election_tree, "OfficeHolderTenureCollection"
2994
+ )
2995
+ is_post_office_split_feed = bool(officeholder_tenure_collection)
2992
2996
  person_office_dict = dict()
2993
2997
  outdated_offices = []
2994
- for office in offices:
2995
- ohpid = office.find("OfficeHolderPersonIds").text
2996
- if ohpid in person_office_dict:
2997
- person_office_dict[ohpid].append(office.get("objectId"))
2998
- else:
2999
- person_office_dict[ohpid] = [office.get("objectId")]
3000
- term = office.find(".//Term")
3001
- if term is not None:
2998
+ outdated_officeholder_tenures = []
2999
+ outdated_officetenure_persons = dict()
3000
+ if is_post_office_split_feed:
3001
+ officeholder_tenures = self.get_elements_by_class(
3002
+ self.election_tree, "OfficeHolderTenure"
3003
+ )
3004
+ for officeholder_tenure in officeholder_tenures:
3005
+ person_id = officeholder_tenure.find("OfficeHolderPersonId").text
3006
+ object_id = officeholder_tenure.get("objectId")
3002
3007
  date_validator = base.DateRule(None, None)
3003
- date_validator.gather_dates(term)
3004
- end_date_person = date_validator.end_date
3005
- if end_date_person is not None:
3008
+ date_validator.gather_dates(officeholder_tenure)
3009
+ end_date = date_validator.end_date
3010
+ if end_date is not None:
3006
3011
  sixty_days_earlier = datetime.datetime.now() + datetime.timedelta(
3007
3012
  days=-60
3008
3013
  )
@@ -3011,21 +3016,80 @@ class RemovePersonAndOfficeHolderId60DaysAfterEndDate(base.TreeRule):
3011
3016
  sixty_days_earlier.month,
3012
3017
  sixty_days_earlier.day,
3013
3018
  )
3014
- if end_date_person < partial_date_sixty_days:
3015
- outdated_offices.append(office.get("objectId"))
3016
- for person in persons:
3017
- pid = person.get("objectId")
3018
- if person_office_dict.get(pid) is not None:
3019
- check_person_outdated = all(
3020
- item in outdated_offices for item in person_office_dict.get(pid)
3019
+ if end_date < partial_date_sixty_days:
3020
+ outdated_officeholder_tenures.append(object_id)
3021
+ if person_id in outdated_officetenure_persons.keys():
3022
+ outdated_officetenure_persons[person_id].append(
3023
+ (object_id, end_date)
3024
+ )
3025
+ else:
3026
+ outdated_officetenure_persons[person_id] = [(object_id, end_date)]
3027
+ for outdated_officeholder_tenure in outdated_officeholder_tenures:
3028
+ info_message = (
3029
+ "The officeholder tenure end date is more than 60 days"
3030
+ " in the past; this OfficeHolderTenure element can be removed"
3031
+ " from the feed."
3021
3032
  )
3022
- if check_person_outdated:
3033
+ info_log.append(
3034
+ loggers.LogEntry(info_message, [outdated_officeholder_tenure])
3035
+ )
3036
+ for person_id, value_list in outdated_officetenure_persons.items():
3037
+ has_recent_tenure = False
3038
+ for value in value_list:
3039
+ end_date = value[1]
3040
+ sixty_days_earlier = datetime.datetime.now() + datetime.timedelta(
3041
+ days=-60
3042
+ )
3043
+ partial_date_sixty_days = base.PartialDate(
3044
+ sixty_days_earlier.year,
3045
+ sixty_days_earlier.month,
3046
+ sixty_days_earlier.day,
3047
+ )
3048
+ if end_date > partial_date_sixty_days:
3049
+ has_recent_tenure = True
3050
+ if not has_recent_tenure:
3023
3051
  info_message = (
3024
- "The officeholder mandates ended more than 60 days ago. "
3025
- "Therefore, you can remove the person and the related offices "
3026
- "from the feed."
3052
+ "All officeholder tenures ended more than 60 days ago. "
3053
+ "Therefore, you can remove the person and the related "
3054
+ "officeholder tenures from the feed."
3027
3055
  )
3028
- info_log.append(loggers.LogEntry(info_message, [person]))
3056
+ info_log.append(loggers.LogEntry(info_message, [person_id]))
3057
+ else:
3058
+ for office in offices:
3059
+ person_id = office.find("OfficeHolderPersonIds").text
3060
+ if person_id in person_office_dict:
3061
+ person_office_dict[person_id].append(office.get("objectId"))
3062
+ else:
3063
+ person_office_dict[person_id] = [office.get("objectId")]
3064
+ term = office.find(".//Term")
3065
+ if term is not None:
3066
+ date_validator = base.DateRule(None, None)
3067
+ date_validator.gather_dates(term)
3068
+ end_date_person = date_validator.end_date
3069
+ if end_date_person is not None:
3070
+ sixty_days_earlier = datetime.datetime.now() + datetime.timedelta(
3071
+ days=-60
3072
+ )
3073
+ partial_date_sixty_days = base.PartialDate(
3074
+ sixty_days_earlier.year,
3075
+ sixty_days_earlier.month,
3076
+ sixty_days_earlier.day,
3077
+ )
3078
+ if end_date_person < partial_date_sixty_days:
3079
+ outdated_offices.append(office.get("objectId"))
3080
+ for person in persons:
3081
+ pid = person.get("objectId")
3082
+ if person_office_dict.get(pid) is not None:
3083
+ check_person_outdated = all(
3084
+ item in outdated_offices for item in person_office_dict.get(pid)
3085
+ )
3086
+ if check_person_outdated:
3087
+ info_message = (
3088
+ "The officeholder mandates ended more than 60 days ago. "
3089
+ "Therefore, you can remove the person and the related offices "
3090
+ "from the feed."
3091
+ )
3092
+ info_log.append(loggers.LogEntry(info_message, [person]))
3029
3093
  if info_log:
3030
3094
  raise loggers.ElectionInfo(info_log)
3031
3095
 
@@ -5,4 +5,4 @@ No dependencies should be added to this module.
5
5
  See https://packaging.python.org/guides/single-sourcing-package-version/
6
6
  """
7
7
 
8
- __version__ = '1.49.dev13'
8
+ __version__ = '1.49.dev14'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: civics_cdf_validator
3
- Version: 1.49.dev13
3
+ Version: 1.49.dev14
4
4
  Summary: Checks if an election feed follows best practices
5
5
  Home-page: https://github.com/google/civics_cdf_validator
6
6
  Author: Google Civics
@@ -3,13 +3,13 @@ civics_cdf_validator/base.py,sha256=5zntjAdAA-bdwYOOStFgUle9LGX_ccelS--thMhUG9A,
3
3
  civics_cdf_validator/gpunit_rules.py,sha256=Cg-qlOeVKTCQ5qUKYSxbVrrh3tdLt1X5Eg-7uyyR_SY,9487
4
4
  civics_cdf_validator/loggers.py,sha256=LS6U9YWzu72V2Q0PwyE9xE03Ul392UAPRnrp2uRBMLA,6923
5
5
  civics_cdf_validator/office_utils.py,sha256=aFxcFQZF2oBn0gPXt_kv1LxHGvwzABScT8X5yaYtVLw,2705
6
- civics_cdf_validator/rules.py,sha256=Ucw1vURByvUoyMVdBUDnzggO15kExbnpsBZU0Wlg-EE,159895
6
+ civics_cdf_validator/rules.py,sha256=FZmaGEm52iPFbvDQqvVFc3BZT7SyNOARJ-x7_3qVKwo,162747
7
7
  civics_cdf_validator/stats.py,sha256=YNqv3Khkt_hJxCIunFBRSl23oXqu5gNjCmWMHFbAcSU,3819
8
8
  civics_cdf_validator/validator.py,sha256=2nwlFfQ9AmpTaO5n5ekaO845Rm0JPjNF-Il6FJW_50k,12678
9
- civics_cdf_validator/version.py,sha256=VFMdAjvjwr34E1vqDkhcL8mmJWGxF_XUDagoSEfJ11Y,189
10
- civics_cdf_validator-1.49.dev13.dist-info/licenses/LICENSE-2.0.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
11
- civics_cdf_validator-1.49.dev13.dist-info/METADATA,sha256=MBpl8nej6fgkR0c0jy0owtovKInrOYSLDPpp1k8viaw,1009
12
- civics_cdf_validator-1.49.dev13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
- civics_cdf_validator-1.49.dev13.dist-info/entry_points.txt,sha256=QibgvtMOocwDi7fQ1emgMJ2lIlI41sW0__KIQdnVn90,77
14
- civics_cdf_validator-1.49.dev13.dist-info/top_level.txt,sha256=PYT5Eclxbop5o6DJIcgs4IeU6Ds5jqyftjoFbgkkJYo,21
15
- civics_cdf_validator-1.49.dev13.dist-info/RECORD,,
9
+ civics_cdf_validator/version.py,sha256=3STupAz7hHTsISiw-I-GyuKq9Tt4pHJgyls1yJfSqWM,189
10
+ civics_cdf_validator-1.49.dev14.dist-info/licenses/LICENSE-2.0.txt,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
11
+ civics_cdf_validator-1.49.dev14.dist-info/METADATA,sha256=GsP5SO8H7qeVl2huG8vo976TUBpIWNu8Jh8JtXJioY8,1009
12
+ civics_cdf_validator-1.49.dev14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
+ civics_cdf_validator-1.49.dev14.dist-info/entry_points.txt,sha256=QibgvtMOocwDi7fQ1emgMJ2lIlI41sW0__KIQdnVn90,77
14
+ civics_cdf_validator-1.49.dev14.dist-info/top_level.txt,sha256=PYT5Eclxbop5o6DJIcgs4IeU6Ds5jqyftjoFbgkkJYo,21
15
+ civics_cdf_validator-1.49.dev14.dist-info/RECORD,,