def _transfer_to_user_amendement_on_import(request: Request, lecture: Lecture, amendement: Amendement, item: dict, team: Team) -> None: email = User.normalize_email(item["affectation_email"]) if not User.email_is_well_formed(email): logger.warning("Invalid email address %r", email) return user, created = get_one_or_create(User, email=email) if created: affectation_name = User.normalize_name(item["affectation_name"]) user.name = affectation_name if affectation_name != "" else email user.teams.append(team) user_table, _ = get_one_or_create(UserTable, user=user, lecture=lecture) if amendement.location.user_table is user_table: return old = amendement.table_name_with_email new = str(user) amendement.location.user_table = user_table amendement.location.shared_table = None AmendementTransfere.create(amendement=amendement, old_value=old, new_value=new, request=request)
def fetch_amendements_for_dossier( dossier_ref: DossierRef, chambre: Optional[str], num: Optional[int], settings: Dict[str, Any], ) -> None: dossier, _ = get_one_or_create( Dossier, an_id=dossier_ref.uid, create_kwargs=dict(titre=dossier_ref.titre, slug=dossier_ref.slug), ) for lecture_ref in dossier_ref.lectures: texte_ref = lecture_ref.texte if chambre is not None and texte_ref.chambre.name.lower() != chambre: continue if num is not None and texte_ref.numero != num: continue texte, _ = get_one_or_create( Texte, type_=texte_ref.type_, chambre=texte_ref.chambre, legislature=texte_ref.legislature, session=texte_ref.session, numero=texte_ref.numero, date_depot=texte_ref.date_depot, ) lecture = Lecture.create( phase=lecture_ref.phase, dossier=dossier, texte=texte, partie=lecture_ref.partie, organe=lecture_ref.organe, titre=lecture_ref.titre, ) fetch_amendements_for_lecture(lecture, settings)
def post(self) -> Any: email = self.request.params.get("email") if not email: self.request.session["missing_email"] = True return HTTPFound(location=self.request.route_url("user_login")) email = User.normalize_email(email) if not User.validate_email(email): self.request.session["incorrect_email"] = True return HTTPFound(location=self.request.route_url("user_login")) user, created = get_one_or_create(User, email=email) # Automatically add user without a team to the authenticated team if not user.teams and self.request.team is not None: user.teams.append(self.request.team) if created: DBSession.flush() # so that the DB assigns a value to user.pk # Prevent from impersonating an existing member of another team if self.request.team and self.request.team not in user.teams: self.request.session["already_in_use"] = True return HTTPFound(location=self.request.route_url("user_login")) user.last_login_at = datetime.utcnow() next_url = self.next_url if not user.name: next_url = self.request.route_url("welcome", _query={"source": next_url}) headers = remember(self.request, user.pk) return HTTPFound(location=next_url, headers=headers)
def _find_or_create_users(self, emails: List[str]) -> Tuple[List[User], List[User]]: new_users = [] existing_users = [] for email in emails: user, created = get_one_or_create(User, email=email) if created: new_users.append(user) else: existing_users.append(user) return new_users, existing_users
def _get_article(self, lecture: Lecture) -> Article: article: Article created: bool article, created = get_one_or_create( Article, lecture=lecture, type=self.subdiv.type_, num=self.subdiv.num, mult=self.subdiv.mult, pos=self.subdiv.pos, ) return article
def _create_or_update_amendement( self, lecture: Lecture, article: Optional[Article], parent: Optional[Amendement], amend: OrderedDict, position: Optional[int], id_discussion_commune: Optional[int], id_identique: Optional[int], ) -> Tuple[Amendement, bool]: amendement, created = get_one_or_create( Amendement, create_kwargs={ "article": article, "parent": parent }, lecture=lecture, num=int(amend["numero"]), ) raw_auteur = amend.get("auteur") if not raw_auteur: logger.warning("Unknown auteur for amendement %s", amend["numero"]) matricule, groupe, auteur = "", "", "" else: matricule = raw_auteur["tribunId"] groupe = get_groupe(raw_auteur, amendement.num) auteur = get_auteur(raw_auteur) modified = False modified |= self.update_rectif(amendement, get_rectif(amend)) modified |= self.update_corps( amendement, unjustify(get_str_or_none(amend, "dispositif") or "")) modified |= self.update_expose( amendement, unjustify(get_str_or_none(amend, "exposeSommaire") or "")) modified |= self.update_sort(amendement, get_sort(amend)) modified |= self.update_attributes( amendement, article=article, parent=parent, position=position, id_discussion_commune=id_discussion_commune, id_identique=id_identique, matricule=matricule, groupe=groupe, auteur=auteur, ) DBSession.flush() # make sure foreign keys are updated return amendement, created
def _get_article(lecture: Lecture, division: dict) -> Article: subdiv = parse_division(division) article: Article created: bool article, created = get_one_or_create( Article, lecture=lecture, type=subdiv.type_, num=subdiv.num, mult=subdiv.mult, pos=subdiv.pos, ) return article
def find_or_create_articles(lecture: Lecture, article_data: dict) -> List[Article]: nums_mults = get_article_nums_mults(article_data) return [ get_one_or_create( Article, lecture=lecture, type=article_data["type"], num=num, mult=mult, pos="", )[0] for num, mult in nums_mults ]
def _get_parent(lecture: Lecture, article: Article, amend: OrderedDict) -> Optional[Amendement]: parent_num, parent_rectif = Amendement.parse_num(get_parent_raw_num(amend)) parent: Optional[Amendement] if parent_num: parent, created = get_one_or_create( Amendement, create_kwargs={ "article": article, "rectif": parent_rectif }, lecture=lecture, num=parent_num, ) else: parent = None return parent
def get(self) -> Any: if self.ip_limiter.exceeded(self.request.remote_addr): return HTTPTooManyRequests() if self.request.unauthenticated_userid: return HTTPFound(location=self.next_url) token = self.request.params.get("token") auth = repository.get_auth_token_data(token) if auth is None: self.log_failed_login_attempt(token) self.request.session.flash( Message( cls="error", text="Le lien est invalide ou a expiré. Merci de renouveler votre demande.", # noqa ) ) raise HTTPFound(location=self.request.route_url("login")) # Delete token from repository after it's been used successfully repository.delete_auth_token(token) email = auth["email"] user, created = get_one_or_create(User, email=email) if created: DBSession.flush() # so that the DB assigns a value to user.pk self.log_successful_login_attempt(email) user.last_login_at = datetime.utcnow() next_url = self.next_url if not user.name: next_url = self.request.route_url("welcome", _query={"source": next_url}) # Compute response headers for the session cookie headers = remember(self.request, user.pk) app_name = self.request.registry.settings["zam.app_name"] self.request.session.flash( Message(cls="success", text=f"Bienvenue dans {app_name} !") ) return HTTPFound(location=next_url, headers=headers)
def post(self) -> Response: titre: str = self.request.POST.get("titre") table, created = get_one_or_create(SharedTable, titre=titre, lecture=self.lecture) if created: SharedTableCreee.create(lecture=self.lecture, titre=titre, request=self.request) self.request.session.flash( Message(cls="success", text=f"Boîte « {table.titre} » créée avec succès.")) else: self.request.session.flash( Message(cls="warning", text=f"La boîte « {table.titre} » existe déjà…")) return HTTPFound(location=self.request.resource_url( self.context.lecture_resource, "options", anchor="shared-tables"))
def _transfer_to_box_amendement_on_import(request: Request, lecture: Lecture, amendement: Amendement, item: dict) -> None: shared_table, created = get_one_or_create(SharedTable, titre=item["affectation_box"], lecture=lecture) if amendement.location.shared_table is shared_table: return old = amendement.table_name_with_email new = shared_table.titre amendement.location.shared_table = shared_table amendement.location.user_table = None AmendementTransfere.create(amendement=amendement, old_value=old, new_value=new, request=request)
def transfer_amendement( request: Request, lecture: Lecture, amendement: Amendement, item: dict ) -> None: email = User.normalize_email(item["affectation_email"]) if not User.validate_email(email): logging.warning("Invalid email address %r", email) return user, created = get_one_or_create(User, email=email) if created: affectation_name = User.normalize_name(item["affectation_name"]) user.name = affectation_name if affectation_name != "" else email if lecture.owned_by_team: user.teams.append(lecture.owned_by_team) target_table = user.table_for(lecture) old = str(amendement.user_table.user) if amendement.user_table else "" new = str(target_table.user) if target_table else "" if amendement.user_table is target_table: return amendement.user_table = target_table AmendementTransfere.create(request, amendement, old, new)
def update_lecture_articles(lecture: Lecture, all_article_data: List[dict]) -> bool: changed = False for index, article_data in enumerate(all_article_data): if article_data["type"] in {"texte", "section", "dots"}: continue elif article_data["type"] == "annexe": articles = [ get_one_or_create( Article, lecture=lecture, type=article_data["type"], num=str(index), # To avoid override in case of many annexes. )[0] ] else: if "titre" not in article_data: continue articles = find_or_create_articles(lecture, article_data) for article in articles: changed |= update_article_contents(article, article_data) changed |= set_default_article_title( article, article_data, partial(get_section_title, all_article_data) ) return changed
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)
def post(self) -> Response: dossier_ref = self._get_dossier_ref() lecture_ref = self._get_lecture_ref(dossier_ref) chambre = lecture_ref.chambre.value titre = lecture_ref.titre organe = lecture_ref.organe partie = lecture_ref.partie session = lecture_ref.get_session() texte = lecture_ref.texte assert texte.date_depot is not None texte_model = get_one_or_create( TexteModel, uid=texte.uid, type_=texte.type_, chambre=Chambre.AN if lecture_ref.chambre.value == "an" else Chambre.SENAT, legislature=int(session) if chambre == "an" else None, session=int(session.split("-")[0]) if chambre == "senat" else None, numero=texte.numero, titre_long=texte.titre_long, titre_court=texte.titre_court, date_depot=texte.date_depot, )[0] dossier_model = get_one_or_create(DossierModel, uid=dossier_ref.uid, titre=dossier_ref.titre)[0] if LectureModel.exists(chambre, session, texte_model, partie, organe): self.request.session.flash( Message(cls="warning", text="Cette lecture existe déjà…")) return HTTPFound(location=self.request.resource_url(self.context)) lecture_model: LectureModel = LectureModel.create( owned_by_team=self.request.team, chambre=chambre, session=session, texte=texte_model, partie=partie, titre=titre, organe=organe, dossier=dossier_model, ) get_articles(lecture_model) LectureCreee.create(self.request, lecture=lecture_model) ArticlesRecuperes.create(request=None, lecture=lecture_model) # Call to fetch_* tasks below being asynchronous, we need to make # sure the lecture_model already exists once and for all in the database # for future access. Otherwise, it may create many instances and # thus many objects within the database. transaction.commit() fetch_amendements(lecture_model.pk) self.request.session.flash( Message( cls="success", text= ("Lecture créée avec succès, amendements en cours de récupération." ), )) return HTTPFound(location=self.request.resource_url( self.context[lecture_model.url_key], "amendements"))