def check(self, element): if "language" not in element.attrib: return elem_lang = element.get("language") if (not elem_lang or elem_lang.strip() == "" or not language_tags.tags.check(elem_lang)): raise base.ElectionError( "Line %d. %s is not a valid language code" % (element.sourceline, elem_lang))
def check(self, element): primary_party_ids = element.find("PrimaryPartyIds") if (primary_party_ids is None or not primary_party_ids.text or not primary_party_ids.text.strip()): raise base.ElectionError( "Line %d. Election is of ElectionType %s but PrimaryPartyIds " "is not present or is empty" % ( primary_party_ids.sourceline, self.election_type))
def check(self, element): if element.text: id_references = element.text.split() for id_ref in id_references: if id_ref not in self.all_object_ids: raise base.ElectionError( "Line %d. %s is not a valid IDREF." % ( element.sourceline, id_ref))
def check(self, element): if element.getparent().tag != "Contest": return contest_id = element.getparent().get("objectId") if not contest_id: return valid_ocd_id = False referenced_gpunit = None external_ids = [] for gpunit in self.gpunits: if gpunit.get("objectId", None) == element.text: referenced_gpunit = gpunit external_ids = gpunit.findall(".//ExternalIdentifier") for extern_id in external_ids: id_type = extern_id.find("Type") if id_type is not None and id_type.text == "ocd-id": value = extern_id.find("Value") if value is None or not hasattr(value, 'text'): continue if value.text in self.ocds: valid_ocd_id = True if (id_type is not None and id_type.text != "ocd-id" and id_type.text.lower() == "ocd-id"): raise base.ElectionError( "Line %d. The External Identifier case is incorrect" ". Should be ocd-id and not %s" % ( id_type.sourceline, id_type.text) ) if referenced_gpunit is None: raise base.ElectionError( "Line %d. The ElectoralDistrictId element for contest %s does " "not refer to a GpUnit. Every ElectoralDistrictId MUST " "reference a GpUnit" % (element.sourceline, contest_id)) if referenced_gpunit is not None and not external_ids: raise base.ElectionError( "Line %d. The GpUnit %s on line %d referenced by contest %s " "does not have any external identifiers" % (element.sourceline, element.text, referenced_gpunit.sourceline, contest_id)) if not valid_ocd_id and referenced_gpunit is not None: raise base.ElectionError( "Line %d. The ElectoralDistrictId element for contest %s " "refers to GpUnit %s on line %d that does not have a valid OCD " "ID" % (element.sourceline, contest_id, element.text, referenced_gpunit.sourceline))
def check(self, element): element_label = element.get("label", None) if element_label: if element_label in self.labels: raise base.ElectionError( "Line %d. Duplicate label '%s'. Label already defined" % (element.sourceline, element_label)) else: self.labels.add(element_label)
def check(self): coalitions = self.get_elements_by_class(self.election_tree, "Coalition") for coalition in coalitions: party_id = coalition.find("PartyIds") if (party_id is None or not party_id.text or not party_id.text.strip()): raise base.ElectionError( "Line %d. Coalition %s must define PartyIDs" % (coalition.sourceline, coalition.get("objectId", None)))
def check(self, element): type_element = element.find("Type") if type_element is not None and type_element.text == "other": other_type_element = element.find("OtherType") if other_type_element is None: raise base.ElectionError( "Line %d. Type on element %s is set to 'other' but " "OtherType element is not defined" % ( element.sourceline, element.tag))
def check(self, element): type_element = element.find("Type") if type_element is not None and type_element.text == "other": other_type_element = element.find("OtherType") if other_type_element is not None: if other_type_element.text in self.valid_enumerations: raise base.ElectionError( "Line %d. Type of element %s is set to 'other' even though " "'%s' is a valid enumeration" % ( element.sourceline, element.tag, other_type_element.text))
def find_duplicates(self): tags = dict() for object_id in self.children: sorted_children = " ".join(sorted(self.children[object_id])) if sorted_children in tags: tags[sorted_children].append(object_id) else: tags[sorted_children] = [object_id] for tag in tags: if len(tags[tag]) == 1: continue raise base.ElectionError( "GpUnits [%s] are duplicates" % (", ".join(tags[tag])))
def _download_data(self, file_path): """Makes a request to Github to download the file.""" ocdid_url = "https://raw.github.com/{0}/master/{1}/{2}".format( self.GITHUB_REPO, self.GITHUB_DIR, self.github_file) r = requests.get(ocdid_url) with io.open("{0}.tmp".format(file_path), "wb") as fd: for chunk in r.iter_content(): fd.write(chunk) valid = self._verify_data("{0}.tmp".format(file_path)) if not valid: raise base.ElectionError( "Could not successfully download OCD ID data files. " "Please try downloading the file manually and " "place it in ~/.cache") else: copyfile("{0}.tmp".format(file_path), file_path)
def check(self, element): tag = self.get_element_class(element) selections = [] for c in self.con_sel_mapping.keys(): selections += self.get_elements_by_class(element, self.con_sel_mapping[c]) for selection in selections: selection_tag = self.get_element_class(selection) contest_id = element.get("objectId", None) selection_id = selection.get("objectId", None) if (selection_tag != self.con_sel_mapping[tag]): raise base.ElectionError( "Line %d. The Contest %s does not contain the right " "BallotSelection. %s must have a %s but contains a " "%s, %s" % ( element.sourceline, contest_id, tag, self.con_sel_mapping[tag], selection_tag, selection_id))
def check(self): candidate_selections = self.get_elements_by_class( self.election_tree, "CandidateSelection") for candidate_selection in candidate_selections: candidate_selection_id = candidate_selection.get("objectId", None) candidate_ids = candidate_selection.find("CandidateIds") if candidate_ids is None: break for candidate_id in candidate_ids.text.split(): if candidate_selection_id: self.seen_candidates.setdefault( candidate_id, []).append(candidate_selection_id) for cand_id, cand_select_ids in self.seen_candidates.iteritems(): if len(cand_select_ids) > 1: raise base.ElectionError( "A Candidate object should only ever be referenced from one" " CandidateSelection. Candidate %s is referenced by the" " following CandidateSelections :- %s" % (cand_id, ", ".join(cand_select_ids)))
def check(self): schema_tree = etree.parse(self.schema_file) try: schema = etree.XMLSchema(etree=schema_tree) except etree.XMLSchemaParseError as e: raise base.ElectionError( "The schema file could not be parsed correctly %s" % str(e)) valid_xml = True try: schema.assertValid(self.election_tree) except etree.DocumentInvalid as e: valid_xml = False if not valid_xml: errors = [] for error in schema.error_log: errors.append( base.ErrorLogEntry(error.line, error.message.encode("utf-8"))) raise base.ElectionTreeError( "The election file didn't validate against schema.", errors)
def check(self): docinfo = self.election_tree.docinfo if docinfo.encoding != "UTF-8": raise base.ElectionError("Encoding on file is not UTF-8")