def post(self) -> Response: self.amendement.avis = self.request.POST["avis"] self.amendement.observations = clean_html( self.request.POST["observations"]) self.amendement.reponse = clean_html(self.request.POST["reponse"]) self.lecture.modified_at = datetime.utcnow() collection: AmendementCollection = self.context.parent return HTTPFound(location=self.request.resource_url(collection))
def post(self) -> Response: avis = self.request.POST.get("avis", "") objet = clean_html(self.request.POST.get("objet", "")) reponse = clean_html(self.request.POST.get("reponse", "")) comments = clean_html(self.request.POST.get("comments", "")) avis_changed = avis != (self.amendement.user_content.avis or "") objet_changed = objet != (self.amendement.user_content.objet or "") reponse_changed = reponse != (self.amendement.user_content.reponse or "") comments_changed = comments != (self.amendement.user_content.comments or "") if not self.is_on_my_table: message = ( "Les modifications n’ont PAS été enregistrées " "car l’amendement n’est plus sur votre table." ) if self.amendement.user_table: message += ( f" Il est actuellement sur la table de " f"{self.amendement.user_table.user}." ) self.request.session.flash(Message(cls="danger", text=message)) return HTTPFound(location=self.my_table_url) if avis_changed: AvisAmendementModifie.create(self.request, self.amendement, avis) if objet_changed: ObjetAmendementModifie.create(self.request, self.amendement, objet) if reponse_changed: ReponseAmendementModifiee.create(self.request, self.amendement, reponse) if comments_changed: CommentsAmendementModifie.create(self.request, self.amendement, comments) self.amendement.stop_editing() self.request.session.flash( Message(cls="success", text="Les modifications ont bien été enregistrées.") ) if "save-and-transfer" in self.request.POST: return HTTPFound( location=self.request.resource_url( self.context.parent.parent, "transfer_amendements", query={ "nums": self.amendement.num, "from_save": 1, "back": self.back_url, }, ) ) else: self.request.session["highlighted_amdt"] = self.amendement.slug return HTTPFound(location=self.back_url)
def import_amendement( request: Request, lecture: Lecture, amendements: Dict[int, Amendement], item: dict, counter: Counter, previous_reponse: str, ) -> None: try: numero = item["num"] avis = item["avis"] or "" objet = item["objet"] or "" reponse = item["reponse"] or "" except KeyError: counter["reponses_errors"] += 1 return try: num = normalize_num(numero) except ValueError: logging.warning("Invalid amendement number %r", numero) counter["reponses_errors"] += 1 return amendement = amendements.get(num) if not amendement: logging.warning("Could not find amendement number %r", num) counter["reponses_errors"] += 1 return avis = normalize_avis(avis) if avis != (amendement.user_content.avis or ""): AvisAmendementModifie.create(request, amendement, avis) objet = clean_html(objet) if objet != (amendement.user_content.objet or ""): ObjetAmendementModifie.create(request, amendement, objet) reponse = clean_html(normalize_reponse(reponse, previous_reponse)) if reponse != (amendement.user_content.reponse or ""): ReponseAmendementModifiee.create(request, amendement, reponse) if "comments" in item: comments = clean_html(item["comments"]) if comments != (amendement.user_content.comments or ""): CommentsAmendementModifie.create(request, amendement, comments) if "affectation_email" in item and item["affectation_email"]: transfer_amendement(request, lecture, amendement, item) previous_reponse = reponse counter["reponses"] += 1
def post(self) -> Response: changed = False new_title = self.request.POST["title"] if new_title != self.article.user_content.title: TitreArticleModifie.create( request=self.request, article=self.article, title=new_title ) changed = True new_presentation = clean_html(self.request.POST["presentation"]) if new_presentation != self.article.user_content.presentation: PresentationArticleModifiee.create( request=self.request, article=self.article, presentation=new_presentation, ) changed = True if changed: self.request.session.flash( Message(cls="success", text="Article mis à jour avec succès.") ) return HTTPFound(location=self.next_url())
def _import_reponses_from_csv_file( reponses_file: BinaryIO, amendements: Dict[int, Amendement]) -> Tuple[int, int]: previous_reponse = "" reponses_count = 0 errors_count = 0 reponses_text_file = io.TextIOWrapper(reponses_file, encoding="utf-8-sig") delimiter = ListAmendements._guess_csv_delimiter(reponses_text_file) for line in csv.DictReader(reponses_text_file, delimiter=delimiter): try: numero = line["Nº amdt"] avis = line["Avis du Gouvernement"] or "" objet = line["Objet amdt"] or "" reponse = line["Réponse"] or "" except KeyError: errors_count += 1 continue try: num = normalize_num(numero) except ValueError: logging.warning("Invalid amendement number %r", num) errors_count += 1 continue amendement = amendements.get(num) if not amendement: logging.warning("Could not find amendement number %r", num) errors_count += 1 continue amendement.avis = normalize_avis(avis) amendement.observations = clean_html(objet) reponse = normalize_reponse(reponse, previous_reponse) amendement.reponse = clean_html(reponse) if "Commentaires" in line: amendement.comments = clean_html(line["Commentaires"]) previous_reponse = reponse reponses_count += 1 return reponses_count, errors_count
def post(self) -> Response: subdiv_titre = self.request.POST["subdiv_titre"] subdiv_jaune = clean_html(self.request.POST["subdiv_jaune"]) for amendement in self.amendements: amendement.subdiv_titre = subdiv_titre amendement.subdiv_jaune = subdiv_jaune self.request.session.flash( ("success", "Article mis à jour avec succès.")) resource = self.context.lecture_resource["amendements"] return HTTPFound(location=self.request.resource_url(resource))
def _make_amendement(node: etree.Element, uid_map: Dict[str, Amendement]) -> Amendement: extract = partial(extract_from_node, node) subdiv = _parse_division(node) texte_uid = extract("identifiant", "saisine", "refTexteLegislatif") if texte_uid is None: raise ValueError("Missing refTexteLegislatif") auteur_uid = extract("signataires", "auteur", "acteurRef") if auteur_uid is None: raise ValueError("Missing auteur acteurRef") groupe_uid = extract("signataires", "auteur", "groupePolitiqueRef") if groupe_uid is None: raise ValueError("Missing auteur groupePolitiqueRef") parent_num, parent_rectif = get_parent(extract("amendementParent"), uid_map) return Amendement( # type: ignore chambre=Chambre.AN.value, session=extract("identifiant", "legislature"), num_texte=get_texte_number(texte_uid), organe=extract("identifiant", "saisine", "organeExamen"), subdiv_type=subdiv.type_, subdiv_num=subdiv.num, subdiv_mult=subdiv.mult, subdiv_pos=subdiv.pos, alinea=to_int(extract("pointeurFragmentTexte", "alinea", "numero")), num=to_int(extract("identifiant", "numero")), auteur=get_auteur_name(auteur_uid), matricule=auteur_uid, groupe=get_groupe_name(groupe_uid), date_depot=to_date(extract("dateDepot")), sort=get_sort(sort=extract("sort", "sortEnSeance"), etat=extract("etat")), parent_num=parent_num, parent_rectif=parent_rectif, dispositif=clean_html(extract("corps", "dispositif") or ""), objet=clean_html(extract("corps", "exposeSommaire") or ""), )
def parse_from_csv(self, row: dict, lecture: Lecture) -> Tuple[Amendement, bool]: subdiv = parse_subdiv(row["Subdivision "], texte=lecture.texte) article, _ = lecture.find_or_create_article(subdiv) num, rectif = Amendement.parse_num(row["Numéro "]) amendement, created = lecture.find_or_create_amendement(num, article) modified = False modified |= self.update_rectif(amendement, rectif) modified |= self.update_corps(amendement, clean_html(row["Dispositif "])) modified |= self.update_expose(amendement, clean_html(row["Objet "])) modified |= self.update_sort(amendement, row["Sort "]) modified |= self.update_attributes( amendement, article=article, alinea=row["Alinéa"].strip(), auteur=row["Auteur "], matricule=extract_matricule(row["Fiche Sénateur"]), date_depot=parse_date(row["Date de dépôt "]), ) return amendement, created
def parse_from_csv(row: dict, session: str, num_texte: int, organe: str) -> Amendement: num, rectif = Amendement.parse_num(row["Numéro "]) subdiv_type, subdiv_num, subdiv_mult, subdiv_pos = _parse_subdiv( row["Subdivision "]) return Amendement( # type: ignore chambre="senat", session=session, num_texte=num_texte, organe=organe, num=num, rectif=rectif, subdiv_type=subdiv_type, subdiv_num=subdiv_num, subdiv_mult=subdiv_mult, subdiv_pos=subdiv_pos, alinea=row["Alinéa"].strip(), auteur=row["Auteur "], matricule=extract_matricule(row["Fiche Sénateur"]), date_depot=parse_date(row["Date de dépôt "]), sort=row["Sort "], dispositif=clean_html(row["Dispositif "]), objet=clean_html(row["Objet "]), )
def test_not_allowed_tags_are_removed(tag): from zam_repondeur.clean import clean_html html = f"<{tag}>foo</{tag}>" assert clean_html(html) == "foo"
def test_table_tags_are_preserved(): from zam_repondeur.clean import clean_html html = "<table><tr><td>foo</td></tr></table>" assert clean_html(html) == "<table><tbody><tr><td>foo</td></tr></tbody></table>"
def test_whitespace_is_stripped(): assert clean_html(" foo ") == "foo"
def test_style_attributes_are_removed(): html = '<p style="text-align: justify">foo</p>' assert clean_html(html) == "<p>foo</p>"
def test_not_allowed_tags_are_removed(tag): html = f"<{tag}>foo</{tag}>" assert clean_html(html) == "foo"
def test_allowed_tags_are_preserved(tag): html = f"<{tag}>foo</{tag}>" assert clean_html(html) == f"<{tag}>foo</{tag}>"
def test_whitespace_is_stripped(): from zam_repondeur.clean import clean_html assert clean_html(" foo ") == "foo"
def test_style_attributes_are_removed(): from zam_repondeur.clean import clean_html html = '<p style="text-align: justify">foo</p>' assert clean_html(html) == "<p>foo</p>"
def _make_amendement( node: etree.Element, uid_map: Dict[str, Amendement], lecture: Lecture ) -> Amendement: extract = partial(extract_from_node, node) subdiv = _parse_division(node) texte_uid = extract("identifiant", "saisine", "refTexteLegislatif") if texte_uid is None: raise ValueError("Missing refTexteLegislatif") is_gouvernemental = extract("signataires", "auteur", "typeAuteur") == "Gouvernement" if is_gouvernemental: auteur_name = "LE GOUVERNEMENT" groupe_name = None matricule = None else: auteur_uid = extract("signataires", "auteur", "acteurRef") if auteur_uid is None: raise ValueError("Missing auteur acteurRef") auteur_name = get_auteur_name(auteur_uid) matricule = auteur_uid groupe_uid = extract("signataires", "auteur", "groupePolitiqueRef") if groupe_uid is None: raise ValueError("Missing auteur groupePolitiqueRef") groupe_name = get_groupe_name(groupe_uid) check_same_lecture( lecture=lecture, session=extract("identifiant", "legislature"), partie=extract_partie(node), organe=extract("identifiant", "saisine", "organeExamen"), texte_uid=texte_uid, ) article, created = get_one_or_create( Article, lecture=lecture, type=subdiv.type_, num=subdiv.num, mult=subdiv.mult, pos=subdiv.pos, ) parent = get_parent(extract("amendementParent"), uid_map, lecture) amendement, created = get_one_or_create( Amendement, create_kwargs={"article": article, "parent": parent}, lecture=lecture, num=to_int(extract("identifiant", "numero")), ) if not created: amendement.article = article amendement.parent = parent amendement.alinea = to_int(extract("pointeurFragmentTexte", "alinea", "numero")) amendement.auteur = auteur_name amendement.matricule = matricule amendement.groupe = groupe_name amendement.date_depot = to_date(extract("dateDepot")) amendement.sort = get_sort( sort=extract("sort", "sortEnSeance"), etat=extract("etat") ) amendement.corps = clean_html(extract("corps", "dispositif") or "") amendement.expose = clean_html(extract("corps", "exposeSommaire") or "") return cast(Amendement, amendement)