civics-cdf-validator 1.41.dev2__tar.gz → 1.41.dev4__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.
- {civics_cdf_validator-1.41.dev2/civics_cdf_validator.egg-info → civics_cdf_validator-1.41.dev4}/PKG-INFO +1 -1
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4/civics_cdf_validator.egg-info}/PKG-INFO +1 -1
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/rules.py +24 -12
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/validator.py +2 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/version.py +1 -1
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/CONTRIBUTING.md +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/LICENSE-2.0.txt +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/MANIFEST.in +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/README.md +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/__init__.py +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/base.py +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/civics_cdf_validator.egg-info/SOURCES.txt +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/civics_cdf_validator.egg-info/dependency_links.txt +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/civics_cdf_validator.egg-info/entry_points.txt +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/civics_cdf_validator.egg-info/requires.txt +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/civics_cdf_validator.egg-info/top_level.txt +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/gpunit_rules.py +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/loggers.py +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/office_utils.py +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/setup.cfg +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/setup.py +0 -0
- {civics_cdf_validator-1.41.dev2 → civics_cdf_validator-1.41.dev4}/stats.py +0 -0
|
@@ -1423,7 +1423,7 @@ class MissingPartyAbbreviationTranslation(ValidatePartyCollection):
|
|
|
1423
1423
|
|
|
1424
1424
|
|
|
1425
1425
|
class IndependentPartyName(base.BaseRule):
|
|
1426
|
-
"""Warns on parties that contain common names indicating they are an
|
|
1426
|
+
"""Warns on parties that contain common names indicating they are an independent party.
|
|
1427
1427
|
|
|
1428
1428
|
These should instead supply the IsIndependent attribute.
|
|
1429
1429
|
"""
|
|
@@ -1925,7 +1925,7 @@ class URIValidator(base.BaseRule):
|
|
|
1925
1925
|
raise loggers.ElectionError.from_message("Missing URI value.", [element])
|
|
1926
1926
|
|
|
1927
1927
|
parsed_url = urlparse(url)
|
|
1928
|
-
|
|
1928
|
+
discrepancies = []
|
|
1929
1929
|
social_media_platform = ["facebook", "twitter", "wikipedia", "instagram",
|
|
1930
1930
|
"youtube", "website", "linkedin", "line",
|
|
1931
1931
|
"ballotpedia", "tiktok"]
|
|
@@ -1933,16 +1933,16 @@ class URIValidator(base.BaseRule):
|
|
|
1933
1933
|
try:
|
|
1934
1934
|
url.encode("ascii")
|
|
1935
1935
|
except UnicodeEncodeError:
|
|
1936
|
-
|
|
1936
|
+
discrepancies.append("not ascii encoded")
|
|
1937
1937
|
|
|
1938
1938
|
if parsed_url.scheme not in {"http", "https"}:
|
|
1939
|
-
|
|
1939
|
+
discrepancies.append("protocol - invalid")
|
|
1940
1940
|
if not parsed_url.netloc:
|
|
1941
|
-
|
|
1942
|
-
if
|
|
1941
|
+
discrepancies.append("domain - missing")
|
|
1942
|
+
if discrepancies:
|
|
1943
1943
|
msg = (
|
|
1944
1944
|
"The provided URI, {}, is invalid for the following reasons: {}."
|
|
1945
|
-
.format(url.encode("ascii", "ignore"), ", ".join(
|
|
1945
|
+
.format(url.encode("ascii", "ignore"), ", ".join(discrepancies))
|
|
1946
1946
|
)
|
|
1947
1947
|
raise loggers.ElectionError.from_message(msg, [element])
|
|
1948
1948
|
|
|
@@ -2024,11 +2024,14 @@ class ValidYoutubeURL(base.BaseRule):
|
|
|
2024
2024
|
def check(self, element):
|
|
2025
2025
|
url = element.text.strip()
|
|
2026
2026
|
parsed_url = urlparse(url)
|
|
2027
|
-
if "youtube" in parsed_url.netloc and (
|
|
2028
|
-
|
|
2029
|
-
|
|
2027
|
+
if "youtube" in parsed_url.netloc and (
|
|
2028
|
+
parsed_url.path in ["", "/"]
|
|
2029
|
+
or "watch" in parsed_url.path
|
|
2030
|
+
or "playlist" in parsed_url.path
|
|
2031
|
+
or "hashtag" in parsed_url.path
|
|
2032
|
+
):
|
|
2030
2033
|
raise loggers.ElectionError.from_message(
|
|
2031
|
-
"'{}' is not
|
|
2034
|
+
"'{}' is not an expected value for a youtube channel.".format(url),
|
|
2032
2035
|
[element])
|
|
2033
2036
|
|
|
2034
2037
|
|
|
@@ -3307,7 +3310,7 @@ class ComposingContestIdsAreValidRelatedContests(base.BaseRule):
|
|
|
3307
3310
|
|
|
3308
3311
|
|
|
3309
3312
|
class MultipleInternationalizedTextWithSameLanguageCode(base.BaseRule):
|
|
3310
|
-
"""Checks for
|
|
3313
|
+
"""Checks for multiple InternationalizedText with the same language code."""
|
|
3311
3314
|
|
|
3312
3315
|
def elements(self):
|
|
3313
3316
|
return _INTERNATIONALIZED_TEXT_ELEMENTS
|
|
@@ -3697,6 +3700,7 @@ class RuleSet(enum.Enum):
|
|
|
3697
3700
|
COMMITTEE = 3
|
|
3698
3701
|
ELECTION_DATES = 4
|
|
3699
3702
|
ELECTION_RESULTS = 5
|
|
3703
|
+
METADATA = 6
|
|
3700
3704
|
|
|
3701
3705
|
|
|
3702
3706
|
# To add new rules, create a new class, inherit the base rule,
|
|
@@ -3822,6 +3826,13 @@ ELECTION_DATES_RULES = (
|
|
|
3822
3826
|
COMMON_RULES + ELECTION_RULES + (UnreferencedEntitiesElectionDates,)
|
|
3823
3827
|
)
|
|
3824
3828
|
|
|
3829
|
+
METADATA_RULES = (
|
|
3830
|
+
Schema,
|
|
3831
|
+
Encoding,
|
|
3832
|
+
OptionalAndEmpty,
|
|
3833
|
+
UniqueLabel,
|
|
3834
|
+
)
|
|
3835
|
+
|
|
3825
3836
|
ALL_RULES = frozenset(
|
|
3826
3837
|
COMMON_RULES
|
|
3827
3838
|
+ ELECTION_RULES
|
|
@@ -3829,4 +3840,5 @@ ALL_RULES = frozenset(
|
|
|
3829
3840
|
+ OFFICEHOLDER_RULES
|
|
3830
3841
|
+ COMMITTEE_RULES
|
|
3831
3842
|
+ ELECTION_DATES_RULES
|
|
3843
|
+
+ METADATA_RULES
|
|
3832
3844
|
)
|
|
@@ -255,6 +255,8 @@ def filter_all_rules_using_user_arg(rules_allowlist, rule_set, rules_blocklist):
|
|
|
255
255
|
rule_names = [x.__name__ for x in rules.ELECTION_DATES_RULES]
|
|
256
256
|
elif rule_set == rules.RuleSet.ELECTION_RESULTS:
|
|
257
257
|
rule_names = [x.__name__ for x in rules.ELECTION_RESULTS_RULES]
|
|
258
|
+
elif rule_set == rules.RuleSet.METADATA:
|
|
259
|
+
rule_names = [x.__name__ for x in rules.METADATA_RULES]
|
|
258
260
|
else:
|
|
259
261
|
raise AssertionError("Invalid rule_set: " + rule_set)
|
|
260
262
|
if rules_blocklist:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|