Merge branch 'excel_in' into 'master'
Release 6.0 Closes #11, #12, and #13 See merge request sdjgeek/purge-registres-deces-insee!4
This commit is contained in:
commit
35fbec4fff
|
@ -1,5 +1,13 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
### [v6.0] 2020-07-29
|
||||||
|
- Lecture de la liste des membres à partir d'un fichier Excel
|
||||||
|
- Écriture de la liste des membres décédés dans un fichier Excel
|
||||||
|
- Vider le texte de l'IHM lorsqu'on clique sur OK
|
||||||
|
- Fichier BAT pour installer et lancer l'IHM sous Windows
|
||||||
|
- BUG: le traitement rend la main à l'IHM losque terminé
|
||||||
|
- BUG: la barre de progression est remise à zero entre chaque traitement
|
||||||
|
|
||||||
### [v5.0] 2020-07-17
|
### [v5.0] 2020-07-17
|
||||||
- Mise en place d'une interface graphique
|
- Mise en place d'une interface graphique
|
||||||
- Ajout d'un fichier install.py
|
- Ajout d'un fichier install.py
|
||||||
|
|
27
install.py
27
install.py
|
@ -26,6 +26,27 @@ except ImportError:
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
print(p.communicate())
|
print(p.communicate())
|
||||||
|
|
||||||
url = "https://git.roflcopter.fr/sdjgeek/purge-registres-deces-insee/-/archive/v5.0/purge-registres-deces-insee-v5.0.zip"
|
try:
|
||||||
myfile = requests.get(url)
|
import pandas
|
||||||
open('purge-registres-deces-insee-v5.0.zip', 'wb').write(myfile.content)
|
except ImportError:
|
||||||
|
print("Installing pandas")
|
||||||
|
p = subprocess.Popen([sys.executable, "-m", "pip", "install", "-U", "pandas"],
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
print(p.communicate())
|
||||||
|
|
||||||
|
try:
|
||||||
|
import xlrd
|
||||||
|
except ImportError:
|
||||||
|
print("Installing xlrd")
|
||||||
|
p = subprocess.Popen([sys.executable, "-m", "pip", "install", "-U", "xlrd"],
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
print(p.communicate())
|
||||||
|
|
||||||
|
try:
|
||||||
|
import numpy
|
||||||
|
except ImportError:
|
||||||
|
print("Installing numpy")
|
||||||
|
p = subprocess.Popen([sys.executable, "-m", "pip", "install", "-U", "numpy"],
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
print(p.communicate())
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
"""
|
||||||
|
Copyright (c) 2020 Sdj Geek
|
||||||
|
Voir le fichier LICENSE
|
||||||
|
|
||||||
|
Classe d'accès aux données du site de l'Église
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import pandas as pd
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from membre_base import MembreBase, MembreProvider
|
||||||
|
|
||||||
|
|
||||||
|
class ExcelIn(MembreProvider):
|
||||||
|
|
||||||
|
def __init__(self, excel_path):
|
||||||
|
self.excel_path = excel_path
|
||||||
|
self.dataframe = None
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.dataframe)
|
||||||
|
|
||||||
|
class Member(MembreBase):
|
||||||
|
|
||||||
|
def __init__(self, provider, row):
|
||||||
|
super().__init__(provider)
|
||||||
|
self.r_id = str(row["id"])
|
||||||
|
self.r_first_name = str(row["first_name"]).strip().split(' ')[0].upper()
|
||||||
|
self.r_last_name = str(row["last_name"]).strip().split(' ')[0].upper()
|
||||||
|
self.r_maiden_name = str(row["maiden_name"]).strip().split(' ')[0].upper() if type(row["maiden_name"]) == np.str else None
|
||||||
|
self.r_annee = str(row["annee"])
|
||||||
|
self.r_mois = str(row["mois"])
|
||||||
|
self.r_jour = str(row["jour"])
|
||||||
|
self.r_ville = "<VIDE>"
|
||||||
|
self.r_sexe = "F" if str(row["status"]) == "Female" else "M"
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
return os.path.basename(self.excel_path)
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
self.dataframe = pd.read_excel(self.excel_path, skiprows=[0, 1], usecols="B:E,G:I,K", header=None,
|
||||||
|
names=["last_name", "first_name", "maiden_name", "id", "jour", "mois", "annee",
|
||||||
|
"status"])
|
||||||
|
return len(self.dataframe)
|
||||||
|
|
||||||
|
def get_member_list(self):
|
||||||
|
for index, row in self.dataframe.iterrows():
|
||||||
|
try:
|
||||||
|
yield self.Member(self, row)
|
||||||
|
except ValueError:
|
||||||
|
print(f"Error with member [{row}]")
|
||||||
|
continue
|
|
@ -0,0 +1,30 @@
|
||||||
|
"""
|
||||||
|
Copyright (c) 2020 Sdj Geek
|
||||||
|
Voir le fichier LICENSE
|
||||||
|
|
||||||
|
Classe d'accès aux données INSEE dans la base SQLite
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
|
||||||
|
class ExcelOut:
|
||||||
|
|
||||||
|
def __init__(self, out_path):
|
||||||
|
self.out_path = out_path
|
||||||
|
self.data = list()
|
||||||
|
|
||||||
|
def add_member(self, member):
|
||||||
|
self.data.append({
|
||||||
|
'nom_registres': member.get_nom_registres(),
|
||||||
|
'nom_insee': member.get_nom_insee(),
|
||||||
|
'mrn': member.r_id,
|
||||||
|
'death_year': member.i_annee_deces,
|
||||||
|
'death_month': member.i_mois_deces,
|
||||||
|
'death_day': member.i_jour_deces
|
||||||
|
})
|
||||||
|
|
||||||
|
def generate_output(self):
|
||||||
|
df = pd.DataFrame(self.data)
|
||||||
|
df.to_excel(self.out_path)
|
|
@ -37,38 +37,50 @@ class MainApplication(tk.Frame):
|
||||||
self.entry_bdd_insee.grid(row=0, column=1, sticky='ew')
|
self.entry_bdd_insee.grid(row=0, column=1, sticky='ew')
|
||||||
self.button_bdd_insee = tk.Button(self.frame, text="...", command=self.command_button_bdd_insee)
|
self.button_bdd_insee = tk.Button(self.frame, text="...", command=self.command_button_bdd_insee)
|
||||||
self.button_bdd_insee.grid(row=0, column=2, sticky='w')
|
self.button_bdd_insee.grid(row=0, column=2, sticky='w')
|
||||||
|
|
||||||
|
# Sélection fichier Excel
|
||||||
|
self.label_fichier_excel = tk.Label(self.frame, text="Fichier Excel")
|
||||||
|
self.label_fichier_excel.grid(row=1, column=0, sticky='e')
|
||||||
|
self.value_fichier_excel = tk.StringVar()
|
||||||
|
self.entry_fichier_excel = tk.Entry(self.frame, state='disabled', textvariable=self.value_fichier_excel)
|
||||||
|
self.entry_fichier_excel.grid(row=1, column=1, sticky='ew')
|
||||||
|
self.button_fichier_excel = tk.Button(self.frame, text="...", command=self.command_button_fichier_excel)
|
||||||
|
self.button_fichier_excel.grid(row=1, column=2, sticky='w')
|
||||||
|
|
||||||
# Sélection répertoire sortie
|
# Sélection répertoire sortie
|
||||||
self.label_dir_out = tk.Label(self.frame, text="Répertoire de sortie")
|
self.label_dir_out = tk.Label(self.frame, text="Répertoire de sortie")
|
||||||
self.label_dir_out.grid(row=1, column=0, sticky='e')
|
self.label_dir_out.grid(row=2, column=0, sticky='e')
|
||||||
self.value_dir_out = tk.StringVar()
|
self.value_dir_out = tk.StringVar()
|
||||||
self.entry_dir_out = tk.Entry(self.frame, state='disabled', textvariable=self.value_dir_out)
|
self.entry_dir_out = tk.Entry(self.frame, state='disabled', textvariable=self.value_dir_out)
|
||||||
self.entry_dir_out.grid(row=1, column=1, sticky='ew')
|
self.entry_dir_out.grid(row=2, column=1, sticky='ew')
|
||||||
self.button_dir_out = tk.Button(self.frame, text="...", command=self.command_button_dir_out)
|
self.button_dir_out = tk.Button(self.frame, text="...", command=self.command_button_dir_out)
|
||||||
self.button_dir_out.grid(row=1, column=2, sticky='w')
|
self.button_dir_out.grid(row=2, column=2, sticky='w')
|
||||||
|
|
||||||
# Sélection des unités à traiter
|
# Sélection des unités à traiter
|
||||||
self.label_units = tk.Label(self.frame, text="Unités à purger")
|
self.label_units = tk.Label(self.frame, text="Unités à purger")
|
||||||
self.label_units.grid(row=2, column=0, sticky='e')
|
self.label_units.grid(row=3, column=0, sticky='e')
|
||||||
self.value_units = tk.StringVar()
|
self.value_units = tk.StringVar()
|
||||||
self.entry_units = tk.Entry(self.frame, textvariable=self.value_units)
|
self.entry_units = tk.Entry(self.frame, textvariable=self.value_units)
|
||||||
self.entry_units.grid(row=2, column=1, sticky='ew', columnspan="2")
|
self.entry_units.grid(row=3, column=1, sticky='ew', columnspan="2")
|
||||||
|
|
||||||
# Bouton validation
|
# Bouton validation
|
||||||
self.button_valid = tk.Button(self.frame, text="Ok", command=self.command_button_valid)
|
self.button_valid = tk.Button(self.frame, text="Ok", command=self.command_button_valid)
|
||||||
self.button_valid.grid(row=3, column=0, columnspan=3)
|
self.button_valid.grid(row=4, column=0, columnspan=3)
|
||||||
|
|
||||||
# Barre de progression
|
# Barre de progression
|
||||||
self.progressbar = ttk.Progressbar(self.frame, orient=tk.HORIZONTAL, mode='determinate')
|
self.progressbar = ttk.Progressbar(self.frame, orient=tk.HORIZONTAL, mode='determinate')
|
||||||
self.progressbar.grid(row=4, column=0, columnspan=3, sticky='ew')
|
self.progressbar.grid(row=5, column=0, columnspan=3, sticky='ew')
|
||||||
|
|
||||||
# Affichage des logs
|
# Affichage des logs
|
||||||
self.text_log = tk.Text(self.frame, state='disabled')
|
self.text_log = tk.Text(self.frame, state='disabled')
|
||||||
self.text_log.grid(row=0, column=3, rowspan=5, sticky='nesw')
|
self.text_log.grid(row=0, column=3, rowspan=6, sticky='nesw')
|
||||||
|
|
||||||
def command_button_bdd_insee(self):
|
def command_button_bdd_insee(self):
|
||||||
self.value_bdd_insee.set(tkfiledialog.askopenfilename(title="Fichier de l'INSEE"))
|
self.value_bdd_insee.set(tkfiledialog.askopenfilename(title="Fichier de l'INSEE"))
|
||||||
|
|
||||||
|
def command_button_fichier_excel(self):
|
||||||
|
self.value_fichier_excel.set(tkfiledialog.askopenfilename(title="Fichier Excel"))
|
||||||
|
|
||||||
def command_button_dir_out(self):
|
def command_button_dir_out(self):
|
||||||
self.value_dir_out.set(tkfiledialog.askdirectory(title="Répertoire de sortie"))
|
self.value_dir_out.set(tkfiledialog.askdirectory(title="Répertoire de sortie"))
|
||||||
|
|
||||||
|
@ -77,6 +89,11 @@ class MainApplication(tk.Frame):
|
||||||
self.text_log.insert(tk.END, text)
|
self.text_log.insert(tk.END, text)
|
||||||
self.text_log.configure(state='disabled')
|
self.text_log.configure(state='disabled')
|
||||||
|
|
||||||
|
def clear_log(self):
|
||||||
|
self.text_log.configure(state='normal')
|
||||||
|
self.text_log.delete('1.0', tk.END)
|
||||||
|
self.text_log.configure(state='disabled')
|
||||||
|
|
||||||
def watch(self):
|
def watch(self):
|
||||||
if self.run:
|
if self.run:
|
||||||
if self.pipe.poll():
|
if self.pipe.poll():
|
||||||
|
@ -84,47 +101,52 @@ class MainApplication(tk.Frame):
|
||||||
if message.get('step', False):
|
if message.get('step', False):
|
||||||
self.progressbar.step(message['step'])
|
self.progressbar.step(message['step'])
|
||||||
elif message.get('text', False):
|
elif message.get('text', False):
|
||||||
print(message['text'])
|
|
||||||
self.add_log(message['text'])
|
self.add_log(message['text'])
|
||||||
elif message.get('running', False):
|
elif 'running' in message:
|
||||||
self.run = message['running']
|
self.run = message['running']
|
||||||
elif message.get('set_max', False):
|
elif message.get('set_max', False):
|
||||||
|
self.progressbar["value"] = 0
|
||||||
self.progressbar['maximum'] = message['set_max']
|
self.progressbar['maximum'] = message['set_max']
|
||||||
self.parent.after(100, self.watch)
|
self.parent.after(100, self.watch)
|
||||||
else:
|
else:
|
||||||
print("Recherche terminée")
|
|
||||||
self.add_log("\nRecherche terminée\n")
|
self.add_log("\nRecherche terminée\n")
|
||||||
self.button_valid.configure(state='normal')
|
self.button_valid.configure(state='normal')
|
||||||
|
|
||||||
def command_button_valid(self):
|
def command_button_valid(self):
|
||||||
self.button_valid.configure(state='disabled')
|
self.button_valid.configure(state='disabled')
|
||||||
|
self.clear_log()
|
||||||
self.run = True
|
self.run = True
|
||||||
(conn1, conn2) = Pipe()
|
(conn1, conn2) = Pipe()
|
||||||
self.pipe = conn1
|
self.pipe = conn1
|
||||||
Worker(conn2, self.value_bdd_insee.get(), self.value_dir_out.get(), self.value_units.get().split(',')).start()
|
unite = self.value_units.get().split(',')
|
||||||
|
if unite == ['']:
|
||||||
|
unite = None
|
||||||
|
Worker(conn2, self.value_bdd_insee.get(), self.value_fichier_excel.get(), self.value_dir_out.get(), unite).start()
|
||||||
self.watch()
|
self.watch()
|
||||||
|
|
||||||
|
|
||||||
class Worker(Process):
|
class Worker(Process):
|
||||||
def __init__(self, pipe, bdd_insee, dir_out, units):
|
def __init__(self, pipe, bdd_insee, fichier_excel, dir_out, units):
|
||||||
Process.__init__(self)
|
Process.__init__(self)
|
||||||
self.pipe = pipe
|
self.pipe = pipe
|
||||||
self.bdd_insee = bdd_insee
|
self.bdd_insee = bdd_insee
|
||||||
|
self.fichier_excel = fichier_excel
|
||||||
self.dir_out = dir_out
|
self.dir_out = dir_out
|
||||||
self.units = units
|
self.units = units
|
||||||
|
|
||||||
def tracker(self, step=None, text=None, set_max=None, running=None):
|
def tracker(self, step=None, text=None, set_max=None, running=None):
|
||||||
if step:
|
if step is not None:
|
||||||
self.pipe.send({'step': step})
|
self.pipe.send({'step': step})
|
||||||
elif text:
|
elif text is not None:
|
||||||
self.pipe.send({'text': text})
|
self.pipe.send({'text': text})
|
||||||
elif set_max:
|
elif set_max is not None:
|
||||||
self.pipe.send({'set_max': set_max})
|
self.pipe.send({'set_max': set_max})
|
||||||
elif done:
|
elif running is not None:
|
||||||
self.pipe.send({'running': running})
|
self.pipe.send({'running': running})
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
trouver_decedes(chemin_base_donnees=self.bdd_insee,
|
trouver_decedes(chemin_base_donnees=self.bdd_insee,
|
||||||
|
excel_path=self.fichier_excel,
|
||||||
chemin_repertoire_sortie=self.dir_out,
|
chemin_repertoire_sortie=self.dir_out,
|
||||||
numeros_unites=self.units,
|
numeros_unites=self.units,
|
||||||
tracker=self.tracker)
|
tracker=self.tracker)
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
"""
|
||||||
|
Copyright (c) 2020 Sdj Geek
|
||||||
|
Voir le fichier LICENSE
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
class MembreBase(ABC):
|
||||||
|
|
||||||
|
def __init__(self, provider):
|
||||||
|
self.provider = provider
|
||||||
|
# Données issues des registres
|
||||||
|
self.r_id = None
|
||||||
|
self.r_first_name = None
|
||||||
|
self.r_last_name = None
|
||||||
|
self.r_maiden_name = None
|
||||||
|
self.r_annee = None
|
||||||
|
self.r_mois = None
|
||||||
|
self.r_jour = None
|
||||||
|
self.r_ville = None
|
||||||
|
self.r_sexe = None
|
||||||
|
|
||||||
|
# Données issues de l'INSEE
|
||||||
|
self.i_first_name = None
|
||||||
|
self.i_last_name = None
|
||||||
|
self.i_annee_naissance = None
|
||||||
|
self.i_mois_naissance = None
|
||||||
|
self.i_jour_naissance = None
|
||||||
|
self.i_ville_naissance = None
|
||||||
|
self.i_annee_deces = None
|
||||||
|
self.i_mois_deces = None
|
||||||
|
self.i_jour_deces = None
|
||||||
|
self.i_ville_deces = None
|
||||||
|
|
||||||
|
def get_nom_registres(self):
|
||||||
|
nom_registres = f"{self.r_last_name}, {self.r_first_name}"
|
||||||
|
if self.r_maiden_name:
|
||||||
|
nom_registres = f"{nom_registres} née {self.r_maiden_name.upper()}"
|
||||||
|
return nom_registres
|
||||||
|
|
||||||
|
def get_nom_insee(self):
|
||||||
|
return f"{self.i_last_name}, {self.i_first_name}"
|
||||||
|
|
||||||
|
def set_insee(self, insee):
|
||||||
|
self.i_first_name = insee.first_name
|
||||||
|
self.i_last_name = insee.last_name
|
||||||
|
self.i_annee_naissance = insee.annee_naissance
|
||||||
|
self.i_mois_naissance = insee.mois_naissance
|
||||||
|
self.i_jour_naissance = insee.jour_naissance
|
||||||
|
self.i_ville_naissance = insee.code_lieu_naissance
|
||||||
|
self.i_annee_deces = insee.annee_deces
|
||||||
|
self.i_mois_deces = insee.mois_deces
|
||||||
|
self.i_jour_deces = insee.jour_deces
|
||||||
|
self.i_ville_deces = insee.code_lieu_deces
|
||||||
|
|
||||||
|
def get_texte_decede(self):
|
||||||
|
if self.r_sexe == "F":
|
||||||
|
feminin = "e"
|
||||||
|
elif self.r_sexe == "M":
|
||||||
|
feminin = ""
|
||||||
|
else:
|
||||||
|
feminin = "(e)"
|
||||||
|
return f"""
|
||||||
|
Le membre {self.get_nom_registres()} ({self.r_id}),
|
||||||
|
né{feminin} le {self.r_jour:0>2}/{self.r_mois:0>2}/{self.r_annee:0>4} à {self.r_ville.upper()}
|
||||||
|
semble être décédé{feminin}.
|
||||||
|
Dans le fichier de l'INSEE on peut trouver {self.get_nom_insee()}
|
||||||
|
né{feminin} le {self.i_jour_naissance:0>2}/{self.i_mois_naissance:0>2}/{self.i_annee_naissance:0>4} à {self.i_ville_naissance}
|
||||||
|
décédé{feminin} le {self.i_jour_deces:0>2}/{self.i_mois_deces:0>2}/{self.i_annee_deces:0>4} à {self.i_ville_deces}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class MembreProvider(ABC):
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def load(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_name(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def __len__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_member_list(self):
|
||||||
|
pass
|
|
@ -9,29 +9,77 @@ Classe d'accès aux données du site de l'Église
|
||||||
import requests
|
import requests
|
||||||
import browser_cookie3
|
import browser_cookie3
|
||||||
|
|
||||||
|
from membre_base import MembreBase, MembreProvider
|
||||||
|
|
||||||
class SiteEglise:
|
|
||||||
|
|
||||||
def __init__(self, cookie_path=None):
|
class SiteEglise(MembreProvider):
|
||||||
|
|
||||||
|
def __init__(self, unite, cookie_path=None):
|
||||||
"""
|
"""
|
||||||
|
:param unite: numéro de l'unité (paroisse, branche)
|
||||||
:param cookie_path: chemin vers le répertoire où inscrire les fichiers de sortie
|
:param cookie_path: chemin vers le répertoire où inscrire les fichiers de sortie
|
||||||
"""
|
"""
|
||||||
|
self.unite = unite
|
||||||
self.cookie_jar = browser_cookie3.firefox(cookie_file=cookie_path)
|
self.cookie_jar = browser_cookie3.firefox(cookie_file=cookie_path)
|
||||||
|
self.as_json = None
|
||||||
|
|
||||||
def get_member_list(self, unit_number):
|
def __len__(self):
|
||||||
"""Recevoir la liste des membres
|
return len(self.as_json)
|
||||||
|
|
||||||
:param unit_number: numéro de l'unité (paroisse, branche)
|
class Membre(MembreBase):
|
||||||
:returns: la liste des membres sous forme d'objet JSON
|
|
||||||
|
|
||||||
"""
|
def __init__(self, provider, data):
|
||||||
|
super().__init__(provider)
|
||||||
|
self.completed = False
|
||||||
|
# Données fournies
|
||||||
|
self.r_id = data['legacyCmisId']
|
||||||
|
self.r_last_name, self.r_first_name = data['nameListPreferredLocal'].upper().split(',')
|
||||||
|
self.r_last_name = self.r_last_name.strip().split(' ')[0]
|
||||||
|
self.r_first_name = self.r_first_name.strip().split(' ')[0]
|
||||||
|
self.r_annee, self.r_mois, self.r_jour = data['birth']['date']['date'].split('-')
|
||||||
|
self.r_sexe = data['sex']
|
||||||
|
# Rechercher le nom de jeune fille si besoin
|
||||||
|
if data['isSpouse']:
|
||||||
|
self.complete()
|
||||||
|
|
||||||
|
def complete(self):
|
||||||
|
if not self.completed:
|
||||||
|
member_profile = self.provider.get_member_profile(self.r_id)
|
||||||
|
self.r_maiden_name = member_profile['individual']['maidenNameGroup']['name1']['family'].strip().split(' ')[0].upper()
|
||||||
|
self.r_ville = member_profile['individual']['birthPlace']
|
||||||
|
if not self.r_ville:
|
||||||
|
self.r_ville = "<VIDE>"
|
||||||
|
self.completed = True
|
||||||
|
|
||||||
|
def set_insee(self, insee):
|
||||||
|
self.complete()
|
||||||
|
super().set_insee(insee)
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
return f"Unité_{self.unite}"
|
||||||
|
|
||||||
|
def load(self):
|
||||||
r = requests.get('https://lcr.churchofjesuschrist.org/services/umlu/report/member-list',
|
r = requests.get('https://lcr.churchofjesuschrist.org/services/umlu/report/member-list',
|
||||||
params={'lang': "fra", 'unitNumber': unit_number},
|
params={'lang': "fra", 'unitNumber': self.unite},
|
||||||
headers={'Accept': "application/json"},
|
headers={'Accept': "application/json"},
|
||||||
cookies=self.cookie_jar)
|
cookies=self.cookie_jar)
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
return r.json()
|
self.as_json = r.json()
|
||||||
|
return len(self.as_json)
|
||||||
|
|
||||||
|
def get_member_list(self):
|
||||||
|
"""Recevoir la liste des membres
|
||||||
|
|
||||||
|
|
||||||
|
:returns: la liste des membres sous forme d'objet JSON
|
||||||
|
|
||||||
|
"""
|
||||||
|
for member in self.as_json:
|
||||||
|
try:
|
||||||
|
yield self.Membre(self, member)
|
||||||
|
except ValueError:
|
||||||
|
print(f"Error with member [{member['nameListPreferredLocal']}, {member['birth']['date']['date']}]")
|
||||||
|
continue
|
||||||
|
|
||||||
def get_member_profile(self, member_id):
|
def get_member_profile(self, member_id):
|
||||||
"""Recevoir les informations sur un membre
|
"""Recevoir les informations sur un membre
|
||||||
|
|
|
@ -15,91 +15,83 @@ import os
|
||||||
|
|
||||||
from bdd_insee import BddInsee
|
from bdd_insee import BddInsee
|
||||||
from site_eglise import SiteEglise
|
from site_eglise import SiteEglise
|
||||||
|
from excel_in import ExcelIn
|
||||||
|
from excel_out import ExcelOut
|
||||||
|
|
||||||
|
|
||||||
def default_tracker(step=None, text=None, set_max=None):
|
def default_tracker(step=None, text=None, set_max=None, running=None):
|
||||||
if text:
|
if text:
|
||||||
print(text)
|
print(text)
|
||||||
|
|
||||||
|
|
||||||
def trouver_decedes(chemin_base_donnees, numeros_unites, chemin_repertoire_sortie, cookie_path=None, tracker=None):
|
def trouver_decedes(chemin_base_donnees, numeros_unites, chemin_repertoire_sortie, cookie_path=None, excel_path=None,
|
||||||
|
tracker=None):
|
||||||
"""Recherche les personnes décédées dans les registres
|
"""Recherche les personnes décédées dans les registres
|
||||||
|
|
||||||
:param chemin_base_donnees: chemin vers le fichier SQLite
|
:param chemin_base_donnees: chemin vers le fichier SQLite
|
||||||
:param numeros_unites: liste des numéros d'unités à analyser
|
:param numeros_unites: liste des numéros d'unités à analyser
|
||||||
:param chemin_repertoire_sortie: chemin vers le répertoire où inscrire les fichiers de sortie
|
:param chemin_repertoire_sortie: chemin vers le répertoire où inscrire les fichiers de sortie
|
||||||
:param cookie_path: chemin vers la base de donnée des cookies
|
:param cookie_path: chemin vers la base de donnée des cookies
|
||||||
|
:param excel_path: chemin vers le fichier Excel contenant la liste des membres à rechercher
|
||||||
|
:param tracker: Objet permettant de suivre l'avancée du traitement
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# Tracker par défaut
|
# Tracker par défaut
|
||||||
if tracker is None:
|
if tracker is None:
|
||||||
tracker = default_tracker
|
tracker = default_tracker
|
||||||
# Initialiser les accès aux données (INSEE et site de l'Église)
|
# Initialiser les accès aux données INSEE
|
||||||
base_insee = BddInsee(chemin_base_donnees)
|
base_insee = BddInsee(chemin_base_donnees)
|
||||||
site_eglise = SiteEglise(cookie_path)
|
# Initialiser les fournisseurs de liste de membres
|
||||||
# Boucler sur la liste des unités
|
fournisseurs_membres = list()
|
||||||
for unite in numeros_unites:
|
if excel_path:
|
||||||
tracker(text=f"Unité {unite}")
|
fournisseurs_membres.append(ExcelIn(excel_path))
|
||||||
|
if numeros_unites:
|
||||||
|
for unite in numeros_unites:
|
||||||
|
fournisseurs_membres.append(SiteEglise(unite, cookie_path))
|
||||||
|
# Boucler sur la liste fournisseurs
|
||||||
|
for member_provider in fournisseurs_membres:
|
||||||
|
tracker(set_max=member_provider.load())
|
||||||
|
tracker(text=f"Recherche dans {member_provider.get_name()}\n")
|
||||||
# Récupérer la liste des membres
|
# Récupérer la liste des membres
|
||||||
members = site_eglise.get_member_list(unite)
|
members = member_provider.get_member_list()
|
||||||
|
# Préparer les fichiers de sortie
|
||||||
# Préparer le fichier de sortie
|
output_base_name = os.path.join(chemin_repertoire_sortie, f"liste_membres_decedes_{member_provider.get_name()}")
|
||||||
output_file = os.path.join(chemin_repertoire_sortie, f"liste_membres_decedes_unite_{unite}.txt")
|
output_txt = open(output_base_name + ".txt", 'w')
|
||||||
with open(output_file, 'w') as out_file:
|
output_xls = ExcelOut(output_base_name + ".xlsx")
|
||||||
out_file.write("Les lieux dans le fichier de l'INSEE sont donnés en Code Officiel Géographique en vigueur au moment de la prise en compte du décès\n")
|
output_txt.write("Les lieux dans le fichier de l'INSEE sont donnés en Code Officiel Géographique en vigueur au moment de la prise en compte du décès\n")
|
||||||
# Boucler sur la liste des membres
|
# Boucler sur la liste des membres
|
||||||
tracker(set_max=len(members))
|
for member in members:
|
||||||
for member in members:
|
query = base_insee.find_person(member.r_first_name, member.r_last_name, member.r_maiden_name,
|
||||||
# Lire les noms et date de naissance
|
member.r_annee, member.r_mois, member.r_jour)
|
||||||
name_registre = member['nameListPreferredLocal']
|
for person in query:
|
||||||
full_birthdate = member['birth']['date']['date']
|
member.set_insee(person)
|
||||||
maiden_name = None
|
text = member.get_texte_decede()
|
||||||
ville_registre = None
|
tracker(text=text)
|
||||||
# S'il s'agit d'une femme mariée, trouver son nom de jeune fille
|
output_txt.write(text)
|
||||||
if member['isSpouse']:
|
output_xls.add_member(member)
|
||||||
member_profile = site_eglise.get_member_profile(member['legacyCmisId'])
|
tracker(step=1)
|
||||||
maiden_name = member_profile['individual']['maidenNameGroup']['name1']['family']
|
# Clore les fichiers de sortie
|
||||||
ville_registre = member_profile['individual']['birthPlace']
|
output_txt.close()
|
||||||
try:
|
output_xls.generate_output()
|
||||||
last_name, first_name = name_registre.split(',')
|
tracker(running=False)
|
||||||
annee_registre, mois_registre, jour_registre = full_birthdate.split('-')
|
|
||||||
except ValueError:
|
|
||||||
print(f"Error with member [{name_registre}, {full_birthdate}]")
|
|
||||||
continue
|
|
||||||
first_name = first_name.strip().split(' ')[0]
|
|
||||||
last_name = last_name.strip().split(' ')[0]
|
|
||||||
query = base_insee.find_person(first_name, last_name, maiden_name, annee_registre, mois_registre, jour_registre)
|
|
||||||
name_registre = name_registre.upper()
|
|
||||||
if maiden_name:
|
|
||||||
name_registre = f"{name_registre} née {maiden_name.upper()}"
|
|
||||||
if member['sex'] == "F":
|
|
||||||
feminin = "e"
|
|
||||||
else:
|
|
||||||
feminin = ""
|
|
||||||
for person in query:
|
|
||||||
if not ville_registre:
|
|
||||||
member_profile = site_eglise.get_member_profile(member['legacyCmisId'])
|
|
||||||
ville_registre = member_profile['individual']['birthPlace']
|
|
||||||
if not ville_registre:
|
|
||||||
ville_registre = "<VIDE>"
|
|
||||||
text = f"""
|
|
||||||
Le membre {name_registre},
|
|
||||||
né{feminin} le {jour_registre:0>2}/{mois_registre:0>2}/{annee_registre:0>4} à {ville_registre.upper()}
|
|
||||||
semble être décédé{feminin}.
|
|
||||||
Dans le fichier de l'INSEE on peut trouver {person.last_name}, {person.first_name}
|
|
||||||
né{feminin} le {person.jour_naissance:0>2}/{person.mois_naissance:0>2}/{person.annee_naissance:0>4} à {person.code_lieu_naissance}
|
|
||||||
décédé{feminin} le {person.jour_deces:0>2}/{person.mois_deces:0>2}/{person.annee_deces:0>4} à {person.code_lieu_deces}
|
|
||||||
"""
|
|
||||||
tracker(text=text)
|
|
||||||
out_file.write(text)
|
|
||||||
tracker(step=1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description='Recherche des personnes décédées dans les registres.')
|
parser = argparse.ArgumentParser(description='Recherche des personnes décédées dans les registres.')
|
||||||
parser.add_argument('chemin_base_donnees', type=str, help="chemin vers la base de données")
|
parser.add_argument('chemin_base_donnees', type=str, help="chemin vers la base de données")
|
||||||
parser.add_argument('chemin_repertoire_sortie', type=str, help="chemin vers le répertoire de sortie")
|
parser.add_argument('chemin_repertoire_sortie', type=str, help="chemin vers le répertoire de sortie")
|
||||||
parser.add_argument('numeros_unites', type=str, help="numéros des l'unités à traiter, séparés par des virgules (ex: 123,753,469)")
|
parser.add_argument('--numeros_unites', '-u', type=str, help="numéros des l'unités à traiter, séparés par des virgules (ex: 123,753,469)")
|
||||||
parser.add_argument('--cookie', '-c', type=str, help='chemin vers la base de donnée des cookies de Firefox')
|
parser.add_argument('--cookie', '-c', type=str, help="chemin vers la base de donnée des cookies de Firefox")
|
||||||
|
parser.add_argument('--excel', '-e', type=str, help="chemin vers le fichier Excel contenant la liste des membres à rechercher")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
trouver_decedes(args.chemin_base_donnees, args.numeros_unites.split(','), args.chemin_repertoire_sortie, args.cookie)
|
|
||||||
|
if args.numeros_unites:
|
||||||
|
numeros_unites = args.numeros_unites.split(',')
|
||||||
|
else:
|
||||||
|
numeros_unites = list()
|
||||||
|
|
||||||
|
trouver_decedes(chemin_base_donnees=args.chemin_base_donnees,
|
||||||
|
numeros_unites=numeros_unites,
|
||||||
|
chemin_repertoire_sortie=args.chemin_repertoire_sortie,
|
||||||
|
cookie_path=args.cookie,
|
||||||
|
excel_path=args.excel)
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
peewee
|
peewee
|
||||||
requests
|
requests
|
||||||
browser_cookie3
|
browser_cookie3
|
||||||
|
pandas
|
||||||
|
xlrd
|
||||||
|
numpy
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
python install.py
|
||||||
|
python purge-registres-deces-insee\gui_trouver_decedes.py
|
Loading…
Reference in New Issue