Skip to content
Extraits de code Groupes Projets
Valider edb38feb rédigé par Bastien Le Querrec's avatar Bastien Le Querrec
Parcourir les fichiers

dates au format ISO, versionnement des métadonnées

parent 9e6eae17
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -74,11 +74,11 @@ pep8:
- unprivileged
needs: [install]
script:
- s3/download-from-s3.sh "${PREF}" "${S3_KEY}" "${S3_SECRET}" "${S3_HOST}" "${S3_BUCKET}" data/ || true
- misc/download-from-s3.sh "${PREF}" "${S3_KEY}" "${S3_SECRET}" "${S3_HOST}" "${S3_BUCKET}" data/ || true
- source bin/activate
- /etc/init.d/tor start
- make "${PREF}"
- s3/upload-to-s3.sh "${PREF}" "${S3_KEY}" "${S3_SECRET}" "${S3_HOST}" "${S3_BUCKET}" data/ || true
- misc/upload-to-s3.sh "${PREF}" "${S3_KEY}" "${S3_SECRET}" "${S3_HOST}" "${S3_BUCKET}" data/ || true
- curl "https://${DATA_TRIGGER_UPDATE_HOST}/data/update-hook?secret_key=${DATA_TRIGGER_UPDATE_SECRET_KEY}&administration=${PREF}" || true
cache:
key: $CI_COMMIT_REF_SLUG
......
......@@ -18,6 +18,7 @@ from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
import pytz
import dateparser
import urllib3
......@@ -47,7 +48,6 @@ class Attrap:
url = ""
date = None
date_str = ""
name = ""
sha256 = ""
pdf_creation_date = None
......@@ -58,7 +58,6 @@ class Attrap:
self.url = url
if date is not None:
self.date = Attrap.get_aware_datetime(date)
self.date_str = date.strftime("%d/%m/%Y")
if not name == "":
self.name = name
......@@ -80,13 +79,11 @@ class Attrap:
self.pdf_creation_date = Attrap.get_aware_datetime(pdf_metadata.creation_date)
if self.date is None:
self.date = Attrap.get_aware_datetime(pdf_metadata.creation_date)
self.date_str = self.date.strftime("%d/%m/%Y")
if pdf_metadata.modification_date:
self.pdf_modification_date = Attrap.get_aware_datetime(pdf_metadata.modification_date)
if self.date is None:
self.date = Attrap.get_aware_datetime(pdf_metadata.modification_date)
self.date_str = self.date.strftime("%d/%m/%Y")
def extract_content(self, data_dir):
"""Extrait le contenu du PDF OCRisé pour l'écrire dans le fichier qui servira à faire la recherche de mots-clés. Supprime tous les PDF à la fin."""
......@@ -120,15 +117,16 @@ class Attrap:
pdf_modification_date_json = None
if self.pdf_creation_date:
pdf_creation_date_json = self.pdf_creation_date.strftime("%d/%m/%Y %H:%M:%S%z")
pdf_creation_date_json = self.pdf_creation_date.astimezone(pytz.utc).isoformat(timespec="seconds")
if self.pdf_modification_date:
pdf_modification_date_json = self.pdf_modification_date.strftime("%d/%m/%Y %H:%M:%S%z")
pdf_modification_date_json = self.pdf_modification_date.astimezone(pytz.utc).isoformat(timespec="seconds")
properties = {
'version': 1,
'name': self.name,
'date': self.date_str,
'date': self.date.strftime("%Y-%m-%d"),
'url': quote(self.url, safe='/:'),
'first_seen_on': datetime.datetime.now(datetime.timezone.utc).strftime("%d/%m/%Y %H:%M:%S%z"),
'first_seen_on': datetime.datetime.now(pytz.utc).isoformat(timespec="seconds"),
'pdf_creation_date': pdf_creation_date_json,
'pdf_modification_date': pdf_modification_date_json
}
......@@ -566,6 +564,7 @@ class Attrap:
"""Recherche des mots-clés dans le texte extrait du PDF"""
if keywords and not keywords == '':
text = open(f'{self.data_dir}/raa/{raa.get_sha256()}.txt').read()
date_str = raa.date.strftime("%d/%m/%Y")
found = False
found_keywords = []
......@@ -573,7 +572,7 @@ class Attrap:
if re.search(keyword, text, re.IGNORECASE | re.MULTILINE):
if not found:
url = quote(raa.url, safe='/:')
self.print_output(f'\033[92m{raa.name}\033[0m ({raa.date_str})')
self.print_output(f'\033[92m{raa.name}\033[0m ({date_str})')
self.print_output(f'URL : {url}')
found = True
self.found = True
......@@ -587,7 +586,7 @@ class Attrap:
[str(x) for x in found_keywords]
)
self.mastodon_toot(
f'{raa.name} ({raa.date_str})\n\nLes termes suivants ont '
f'{raa.name} ({date_str})\n\nLes termes suivants ont '
f'été trouvés : {found_keywords_str}.\n\nURL : {url}'
)
......@@ -612,7 +611,8 @@ class Attrap:
# Lorsque la date du RAA n'est pas connue, on a dû télécharger le PDF pour récupérer la date de ses métadonnées.
# Donc on vérifie à nouveau ici si la date correspond à ce qu'on veut analyser
if (raa.date and raa.date >= Attrap.get_aware_datetime(self.not_before)):
logger.info(f'Nouveau fichier : {raa.name} ({raa.date_str}). URL : {url}')
date_str = raa.date.strftime("%d/%m/%Y")
logger.info(f'Nouveau fichier : {raa.name} ({date_str}). URL : {url}')
self.flatten_pdf(raa)
self.ocr(raa, True)
raa.extract_content(self.data_dir)
......@@ -725,10 +725,11 @@ class Attrap:
"""
Retourne un objet datetime avisé.
datetime - L'objet datetime à aviser. Utilise le fuseau horaire du système si datetime est naïf.
datetime - L'objet datetime à aviser. Utilise le fuseau 'Europe/Paris' si datetime est naïf.
"""
if unknown_datetime.tzinfo is not None and unknown_datetime.tzinfo.utcoffset(unknown_datetime) is not None:
return unknown_datetime
else:
return unknown_datetime.replace(tzinfo=datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo)
tz_paris = pytz.timezone('Europe/Paris')
return tz_paris.localize(unknown_datetime)
......@@ -76,4 +76,4 @@ prefidf:
prefpaca:
bin/python3 cli.py prefpaca
lint:
bin/pycodestyle --first --show-source --ignore=E501 *.py
bin/pycodestyle --first --show-source --ignore=E501 *.py misc/*.py
Fichier déplacé
Fichier déplacé
#!/usr/bin/env python3
import argparse
import datetime
import json
import os
import pytz
import sys
import re
tz_paris = pytz.timezone('Europe/Paris')
def fix_raa_date_v0(raa_json):
try:
raa_json['date'] = tz_paris.localize(datetime.datetime.strptime(raa_json['date'], '%d/%m/%Y')).strftime('%Y-%m-%d')
return raa_json
except Exception:
print(f"\033[91m{exc=}, {type(exc)=}\033[0m")
sys.exit(1)
return raa_json
def fix_pdf_date_v0(raa_json, json_key):
if not raa_json[json_key]:
return raa_json
try:
# On tente de parser avec fuseau horaire
raa_json[json_key] = datetime.datetime.strptime(raa_json[json_key], '%d/%m/%Y %H:%M:%S%z').astimezone(pytz.utc).isoformat(timespec="seconds")
return raa_json
except Exception:
try:
# Sinon on tente de parser sans fuseau horaire et on retourne une date avec le fuseau de Paris
raa_json[json_key] = tz_paris.localize(datetime.datetime.strptime(raa_json[json_key], '%d/%m/%Y %H:%M:%S')).astimezone(pytz.utc).isoformat(timespec="seconds")
return raa_json
except Exception as exc:
print(f"\033[91m{exc=}, {type(exc)=}\033[0m")
sys.exit(1)
return raa_json
parser = argparse.ArgumentParser(
prog='./misc/repair_date_format_in_data.py',
description='Met à jour le format des fichiers de métadonnées'
)
parser.add_argument(
'--data-dir',
action='store',
help='dossier de données (par défaut: data/)'
)
parser.add_argument(
'--dry-run',
action='store_true',
help='ne modifie aucun fichier, affiche seulement les modifications nécessaires (par défaut: false)'
)
args = parser.parse_args()
if args.data_dir:
data_dir = args.data_dir
else:
data_dir = 'data/'
dry_run = args.dry_run
if data_dir.startswith('/'):
data_dir = os.path.abspath(data_dir)
else:
data_dir = os.path.abspath(os.path.dirname(os.path.abspath(__file__)) + '/../' + data_dir)
for administration in os.listdir(data_dir):
# On ne cherche que les dossiers ppparis et pref*
if administration.startswith('pref') or administration == 'ppparis':
administration_path = os.path.abspath(data_dir + '/' + administration + '/raa/')
for raa in os.listdir(administration_path):
if raa.endswith('.json'):
raa_id = re.sub('\\.json$', '', raa)
fixed = False
raa_path = os.path.abspath(administration_path + '/' + raa)
raa_file_read = open(raa_path, 'r')
raa_json = json.load(raa_file_read)
raa_file_read.close()
fixed_raa_json = None
# Si le fichier de métadonnées n'a pas de version, il a été généré avant le 14/11/2024 et doit être corrigé
# v0 -> v1 : les dates sont au format YYYY-MM-DD et heure locale
# les heures sont au format YYYY-MM-DD HH:mm:ss±ZZ:ZZ et heure UTC
if not raa_json.get('version') or not raa_json['version']:
fixed = True
date = raa_json['date']
first_seen_on = raa_json['first_seen_on']
pdf_creation_date = raa_json['pdf_creation_date']
pdf_modification_date = raa_json['pdf_modification_date']
print(f"{administration}: {raa_json['name']} ({raa_id}):")
fixed_raa_json = fix_raa_date_v0(raa_json)
if not date == fixed_raa_json['date']:
print(f" date: {date} -> {fixed_raa_json['date']}")
fixed_raa_json = fix_pdf_date_v0(fixed_raa_json, 'first_seen_on')
if not raa_json == fixed_raa_json:
print(f" first_seen_on: {first_seen_on} -> {fixed_raa_json['first_seen_on']}")
fixed_raa_json = fix_pdf_date_v0(fixed_raa_json, 'pdf_creation_date')
if not pdf_creation_date == fixed_raa_json['pdf_creation_date']:
print(f" pdf_creation_date: {pdf_creation_date} -> {fixed_raa_json['pdf_creation_date']}")
fixed_raa_json = fix_pdf_date_v0(fixed_raa_json, 'pdf_modification_date')
if not pdf_modification_date == fixed_raa_json['pdf_modification_date']:
print(f" pdf_modification_date: {pdf_modification_date} -> {fixed_raa_json['pdf_modification_date']}")
ordered_fixed_raa_json = {'version': 1}
for key in fixed_raa_json:
ordered_fixed_raa_json[key] = fixed_raa_json[key]
fixed_raa_json = ordered_fixed_raa_json
if fixed and not dry_run and fixed_raa_json:
raa_file_write = open(raa_path, 'w')
raa_file_write.write(json.dumps(fixed_raa_json))
raa_file_write.close()
else:
print(f'On ignore {administration}...')
Fichier déplacé
Fichier déplacé
......@@ -5,6 +5,7 @@ Mastodon.py>=1.8.1
ocrmypdf<16.4.0
pycodestyle>=2.11.1
pypdf>=4.2.0
pytz>=2024.2
PyVirtualDisplay>=3.0
requests>=2.31.0
selenium>=4.19.0
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter