civics-cdf-validator 1.60.dev3__tar.gz → 1.60.dev5__tar.gz

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.
Files changed (22) hide show
  1. {civics_cdf_validator-1.60.dev3/civics_cdf_validator.egg-info → civics_cdf_validator-1.60.dev5}/PKG-INFO +1 -1
  2. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5/civics_cdf_validator.egg-info}/PKG-INFO +1 -1
  3. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/rules.py +49 -21
  4. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/version.py +1 -1
  5. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/CONTRIBUTING.md +0 -0
  6. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/LICENSE-2.0.txt +0 -0
  7. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/MANIFEST.in +0 -0
  8. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/README.md +0 -0
  9. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/__init__.py +0 -0
  10. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/base.py +0 -0
  11. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/civics_cdf_validator.egg-info/SOURCES.txt +0 -0
  12. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/civics_cdf_validator.egg-info/dependency_links.txt +0 -0
  13. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/civics_cdf_validator.egg-info/entry_points.txt +0 -0
  14. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/civics_cdf_validator.egg-info/requires.txt +0 -0
  15. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/civics_cdf_validator.egg-info/top_level.txt +0 -0
  16. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/gpunit_rules.py +0 -0
  17. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/loggers.py +0 -0
  18. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/office_utils.py +0 -0
  19. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/setup.cfg +0 -0
  20. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/setup.py +0 -0
  21. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/stats.py +0 -0
  22. {civics_cdf_validator-1.60.dev3 → civics_cdf_validator-1.60.dev5}/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: civics_cdf_validator
3
- Version: 1.60.dev3
3
+ Version: 1.60.dev5
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: civics_cdf_validator
3
- Version: 1.60.dev3
3
+ Version: 1.60.dev5
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
@@ -1365,42 +1365,70 @@ class ValidateDuplicateColors(base.TreeRule):
1365
1365
  """
1366
1366
 
1367
1367
  def check(self):
1368
- party_color_mapping = {}
1368
+ party_colors_by_id = {}
1369
+ party_objects = {}
1369
1370
  for party in self.get_elements_by_class(self.election_tree, "Party"):
1371
+ party_id = party.get("objectId")
1372
+ party_objects[party_id] = party
1373
+ party_colors_by_id[party_id] = {}
1370
1374
  color_element = party.find("Color")
1371
- if color_element is None or not color_element.text:
1372
- continue
1373
- party_color_mapping[party.get("objectId")] = (color_element.text, party)
1375
+ if element_has_text(color_element):
1376
+ party_colors_by_id[party_id]["Color"] = color_element.text.lower()
1377
+ colors_element = party.find("Colors")
1378
+ if colors_element is not None:
1379
+ for color_field in ("DarkThemeColor", "LightThemeColor"):
1380
+ sub_color_element = colors_element.find(color_field)
1381
+ if element_has_text(sub_color_element):
1382
+ party_colors_by_id[party_id][
1383
+ color_field
1384
+ ] = sub_color_element.text.lower()
1374
1385
 
1375
1386
  warning_log = []
1376
1387
  for party_contest in self.get_elements_by_class(
1377
1388
  element=self.election_tree, element_name="PartyContest"
1378
1389
  ):
1379
- contest_colors = {}
1390
+ contest_colors = {
1391
+ "Color": collections.defaultdict(list),
1392
+ "DarkThemeColor": collections.defaultdict(list),
1393
+ "LightThemeColor": collections.defaultdict(list),
1394
+ }
1380
1395
  for party_ids_element in self.get_elements_by_class(
1381
1396
  element=party_contest, element_name="PartyIds"
1382
1397
  ):
1383
1398
  for party_id in party_ids_element.text.split():
1384
- if party_id not in party_color_mapping:
1399
+ if party_id not in party_colors_by_id:
1400
+ continue
1401
+ party_colors = party_colors_by_id[party_id]
1402
+ party_element = party_objects[party_id]
1403
+
1404
+ has_party_colors = "Color" in party_colors or (
1405
+ "DarkThemeColor" in party_colors
1406
+ and "LightThemeColor" in party_colors
1407
+ )
1408
+ if not has_party_colors:
1385
1409
  warning_log.append(
1386
1410
  loggers.LogEntry(
1387
- "Party (%s) in PartyContest should have an assigned color."
1388
- % party_id
1411
+ f"Party ({party_id}) in PartyContest should have either"
1412
+ " Color or Colors.DarkThemeColor and Colors.LightThemeColor"
1413
+ " set.",
1414
+ [party_element],
1415
+ )
1416
+ )
1417
+
1418
+ for color_field in ("Color", "DarkThemeColor", "LightThemeColor"):
1419
+ if color_field in party_colors:
1420
+ color_val = party_colors[color_field]
1421
+ contest_colors[color_field][color_val].append(party_element)
1422
+
1423
+ for color_field in ("Color", "DarkThemeColor", "LightThemeColor"):
1424
+ for color, parties in contest_colors[color_field].items():
1425
+ if len(parties) > 1:
1426
+ warning_log.append(
1427
+ loggers.LogEntry(
1428
+ f"Parties have the same {color_field} {color}.",
1429
+ parties,
1389
1430
  )
1390
1431
  )
1391
- continue
1392
- party_color = party_color_mapping[party_id][0]
1393
- if party_color in contest_colors:
1394
- contest_colors[party_color].append(party_color_mapping[party_id][1])
1395
- else:
1396
- contest_colors[party_color] = [party_color_mapping[party_id][1]]
1397
- for color, parties in contest_colors.items():
1398
- if len(parties) > 1:
1399
- warning_log.append(
1400
- loggers.LogEntry(
1401
- "Parties have the same color %s." % color, parties
1402
- )
1403
- )
1404
1432
  if warning_log:
1405
1433
  raise loggers.ElectionWarning(warning_log)
1406
1434
 
@@ -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.60.dev3'
8
+ __version__ = '1.60.dev5'