mirror of
https://github.com/Ladebeze66/llm_ticket3.git
synced 2025-12-13 15:56:50 +01:00
1504-16:12
This commit is contained in:
parent
4cd697e11a
commit
43da046555
@ -1152,11 +1152,221 @@ Read file: extracted_message/message_228942_clean.html
|
||||
|
||||
---
|
||||
|
||||
Cancelled
|
||||
|
||||
---
|
||||
|
||||
|
||||
```bash
|
||||
python extract_text_from_html.py
|
||||
```
|
||||
|
||||
```
|
||||
fgras-ca@PC-DEV:~/llm-ticket3$ python extract_text_from_html.py
|
||||
✅ Texte extrait et sauvegardé dans : extracted_message/message_text.txt
|
||||
fgras-ca@PC-DEV:~/llm-ticket3$
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Read file: extracted_message/message_text.txt
|
||||
|
||||
---
|
||||
|
||||
Parfait ! J'ai créé un script `extract_text_from_html.py` qui extrait uniquement le texte de votre message HTML, en supprimant toutes les balises et le formatage, tout en conservant la structure du message.
|
||||
|
||||
Voici le texte extrait de votre message :
|
||||
|
||||
```
|
||||
Bonjour,
|
||||
|
||||
Je ne parviens pas à accéder au l'essai au bleu :
|
||||
|
||||
Merci par avance pour votre.
|
||||
|
||||
Cordialement
|
||||
```
|
||||
|
||||
Le script a correctement extrait le texte du message HTML tout en préservant sa structure avec les sauts de ligne entre les paragraphes. Notez que par défaut, les références aux images ne sont pas incluses. Si vous souhaitez les inclure, vous pouvez utiliser l'option `--preserve-images` ou `-p` :
|
||||
|
||||
```bash
|
||||
python extract_text_from_html.py --preserve-images
|
||||
```
|
||||
|
||||
Cela ajoutera des marqueurs pour les images dans le texte, comme :
|
||||
```
|
||||
[IMAGE: https://odoo.cbao.fr/web/image/145435?access_token=608ac9e7-3627-4a13-a8ec-06ff5046ebf3]
|
||||
```
|
||||
|
||||
Vous pouvez également spécifier des fichiers d'entrée et de sortie différents :
|
||||
|
||||
```bash
|
||||
python extract_text_from_html.py --input mon_fichier.html --output resultat.txt
|
||||
```
|
||||
|
||||
Ce script fonctionne bien pour filtrer complètement le code HTML et produire un texte propre que vous pouvez facilement intégrer dans votre fil de discussion.
|
||||
|
||||
---
|
||||
|
||||
_**User**_
|
||||
|
||||
je voudrai fusionner ces deux scprits en un seul afin d'effectuer toutes les actions en un seul script
|
||||
|
||||
---
|
||||
|
||||
_**Assistant**_
|
||||
|
||||
Pour fusionner les deux scripts (`extract_single_message.py` et `extract_text_from_html.py`) en un seul, nous allons combiner les fonctionnalités d'extraction de message et de nettoyage du HTML en un seul processus. Voici comment cela peut être fait :
|
||||
|
||||
### Script fusionné
|
||||
|
||||
```python
|
||||
import json
|
||||
import os
|
||||
import argparse
|
||||
import requests
|
||||
from bs4 import BeautifulSoup, Tag
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description="Extrait un message et son texte pur d'un fichier JSON et HTML.")
|
||||
parser.add_argument("--input", "-i", default="messages_raw.json", help="Fichier JSON des messages")
|
||||
parser.add_argument("--message-id", "-m", type=int, default=228942, help="ID du message à traiter")
|
||||
parser.add_argument("--output-html", "-o", default="extracted_message", help="Répertoire de sortie pour le HTML")
|
||||
parser.add_argument("--output-text", "-t", default="extracted_message/message_text.txt", help="Fichier texte de sortie")
|
||||
parser.add_argument("--preserve-images", action="store_true", help="Préserver les références aux images")
|
||||
return parser.parse_args()
|
||||
|
||||
def clean_message_html(html, keep_img=True):
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
|
||||
# Supprimer les balises inutiles
|
||||
for tag in soup.select(".o_mail_info, .recipients_info, .o_mail_tracking, .o_thread_icons, .o_thread_tooltip_container, .o_thread_full_spand_icon"):
|
||||
tag.decompose()
|
||||
|
||||
# Supprimer les images inutiles
|
||||
for img in soup.find_all("img"):
|
||||
if not isinstance(img, Tag):
|
||||
continue
|
||||
if not img.has_attr("src"):
|
||||
continue
|
||||
src = img["src"]
|
||||
if not isinstance(src, str):
|
||||
continue
|
||||
if "font_to_img" in src:
|
||||
img.decompose()
|
||||
elif keep_img and not src.startswith("http") and "/web/image/" not in src:
|
||||
img.decompose()
|
||||
|
||||
return str(soup)
|
||||
|
||||
def download_image(url, output_dir, filename="image.png"):
|
||||
try:
|
||||
r = requests.get(url, stream=True, timeout=10)
|
||||
if r.status_code == 200:
|
||||
path = os.path.join(output_dir, filename)
|
||||
with open(path, "wb") as f:
|
||||
for chunk in r.iter_content(1024):
|
||||
f.write(chunk)
|
||||
return path
|
||||
else:
|
||||
print(f"⚠️ Échec du téléchargement de l'image ({r.status_code}): {url}")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Erreur lors du téléchargement de l'image: {e}")
|
||||
return None
|
||||
|
||||
def extract_and_clean(input_file, message_id, output_html_dir, output_text_file, preserve_images=False):
|
||||
if not os.path.exists(input_file):
|
||||
print(f"❌ Fichier non trouvé : {input_file}")
|
||||
return
|
||||
|
||||
os.makedirs(output_html_dir, exist_ok=True)
|
||||
|
||||
with open(input_file, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
messages = data.get("messages", [])
|
||||
msg = next((m for m in messages if m["id"] == message_id), None)
|
||||
|
||||
if not msg:
|
||||
print(f"❌ Message ID {message_id} non trouvé.")
|
||||
return
|
||||
|
||||
print(f"✅ Message trouvé : {msg.get('subject')}")
|
||||
|
||||
# Nettoyer le HTML
|
||||
original_html = msg.get("body", "")
|
||||
clean_html = clean_message_html(original_html)
|
||||
|
||||
# Sauvegarder le HTML nettoyé
|
||||
html_path = os.path.join(output_html_dir, f"message_{message_id}_clean.html")
|
||||
with open(html_path, "w", encoding="utf-8") as f:
|
||||
f.write(clean_html)
|
||||
|
||||
print(f"📄 HTML nettoyé sauvegardé : {html_path}")
|
||||
|
||||
# Extraire les images utiles
|
||||
soup = BeautifulSoup(clean_html, "html.parser")
|
||||
image_urls = []
|
||||
|
||||
for img in soup.find_all("img"):
|
||||
if isinstance(img, Tag) and img.has_attr("src"):
|
||||
src = img["src"]
|
||||
if isinstance(src, str) and (src.startswith("http") or "/web/image/" in src):
|
||||
image_urls.append(src)
|
||||
|
||||
# Télécharger la 1ère image
|
||||
downloaded = None
|
||||
for url in image_urls:
|
||||
if isinstance(url, str) and url.startswith("http"):
|
||||
downloaded = download_image(url, output_html_dir, "image.png")
|
||||
break
|
||||
|
||||
# Extraire le texte
|
||||
paragraphs = []
|
||||
for p in soup.find_all("p"):
|
||||
if isinstance(p, Tag):
|
||||
text = p.get_text(strip=True)
|
||||
if text: # Ignorer les paragraphes vides
|
||||
paragraphs.append(text)
|
||||
|
||||
# Traiter les images si demandé
|
||||
if preserve_images:
|
||||
for img in soup.find_all("img"):
|
||||
if isinstance(img, Tag) and img.has_attr("src"):
|
||||
paragraphs.append(f"[IMAGE: {img['src']}]")
|
||||
|
||||
# Créer le texte final avec une structure claire
|
||||
text_content = "\n\n".join(paragraphs)
|
||||
|
||||
# Sauvegarder le texte
|
||||
with open(output_text_file, "w", encoding="utf-8") as f:
|
||||
f.write(text_content)
|
||||
|
||||
print(f"✅ Texte extrait et sauvegardé dans : {output_text_file}")
|
||||
if downloaded:
|
||||
print(f"🖼️ Image téléchargée dans : {downloaded}")
|
||||
else:
|
||||
print(f"❗Aucune image HTTP directe n'a été téléchargée (images internes Odoo seulement ?)")
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
extract_and_clean(args.input, args.message_id, args.output_html, args.output_text, args.preserve_images)
|
||||
```
|
||||
|
||||
### Fonctionnalités du script fusionné :
|
||||
1. **Extraction du message** : Le script extrait le message spécifié par son ID à partir d'un fichier JSON.
|
||||
2. **Nettoyage du HTML** : Il nettoie le contenu HTML pour supprimer les balises inutiles et les images non pertinentes.
|
||||
3. **Téléchargement d'images** : Il télécharge la première image externe trouvée dans le message.
|
||||
4. **Extraction de texte** : Il extrait le texte pur du message et le sauvegarde dans un fichier texte.
|
||||
5. **Options de ligne de commande** : Vous pouvez spécifier le fichier d'entrée, l'ID du message, le répertoire de sortie pour le HTML et le fichier texte, ainsi qu'une option pour préserver les références aux images.
|
||||
|
||||
### Exemples d'utilisation :
|
||||
- Pour exécuter le script avec les paramètres par défaut :
|
||||
```bash
|
||||
python extract_single_message.py
|
||||
```
|
||||
|
||||
- Pour spécifier un fichier d'entrée et filtrer les images externes :
|
||||
```bash
|
||||
python extract_single_message.py --input /chemin/vers/messages_raw.json --message-id 228942 --preserve-images
|
||||
```
|
||||
|
||||
Ce script fusionné vous permettra d'effectuer toutes les actions nécessaires en une seule exécution. N'hésitez pas à l'adapter selon vos besoins spécifiques !
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -1,142 +0,0 @@
|
||||
# extract_single_message.py
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from bs4 import BeautifulSoup, Tag
|
||||
|
||||
def parse_args():
|
||||
"""Parse les arguments de ligne de commande."""
|
||||
parser = argparse.ArgumentParser(description="Extrait un message spécifique et ses images depuis un fichier JSON.")
|
||||
|
||||
parser.add_argument("--input", "-i",
|
||||
help="Chemin vers le fichier JSON contenant les messages (par défaut: messages_raw.json)",
|
||||
default="messages_raw.json")
|
||||
|
||||
parser.add_argument("--message-id", "-m",
|
||||
help="ID du message à extraire (par défaut: 228942)",
|
||||
type=int, default=228942)
|
||||
|
||||
parser.add_argument("--output", "-o",
|
||||
help="Répertoire de sortie (par défaut: extracted_message)",
|
||||
default="extracted_message")
|
||||
|
||||
parser.add_argument("--create-test", "-t",
|
||||
help="Créer un fichier de test si le fichier d'entrée n'existe pas",
|
||||
action="store_true")
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
def create_test_data(input_file, message_id):
|
||||
"""Crée un fichier de test contenant un message avec une image."""
|
||||
print(f"⚠️ Le fichier {input_file} n'existe pas. Création d'un exemple de test...")
|
||||
|
||||
test_data = {
|
||||
"messages": [
|
||||
{
|
||||
"id": message_id,
|
||||
"body": "<p>Voici une image de test:</p><img src='https://example.com/image.jpg' alt='Test'>",
|
||||
"author_id": [1, "Utilisateur Test"],
|
||||
"date": "2023-01-01 12:00:00",
|
||||
"subject": "Message de test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
try:
|
||||
# Créer le répertoire parent si nécessaire
|
||||
parent_dir = os.path.dirname(input_file)
|
||||
if parent_dir and not os.path.exists(parent_dir):
|
||||
os.makedirs(parent_dir, exist_ok=True)
|
||||
|
||||
with open(input_file, "w", encoding="utf-8") as f:
|
||||
json.dump(test_data, f, indent=2, ensure_ascii=False)
|
||||
|
||||
print(f"✅ Fichier de test créé : {input_file}")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"❌ Erreur lors de la création du fichier de test : {e}")
|
||||
return False
|
||||
|
||||
def extract_message(input_file, message_id, output_dir, create_test=False):
|
||||
"""Extrait un message spécifique et ses images depuis un fichier JSON."""
|
||||
# Vérifier si le fichier d'entrée existe
|
||||
if not os.path.exists(input_file):
|
||||
if create_test:
|
||||
created = create_test_data(input_file, message_id)
|
||||
if not created:
|
||||
print(f"❌ Impossible de créer le fichier de test {input_file}")
|
||||
return False
|
||||
else:
|
||||
print(f"❌ Le fichier {input_file} n'existe pas. Utilisez --create-test pour créer un exemple.")
|
||||
return False
|
||||
|
||||
try:
|
||||
# Créer le répertoire de sortie
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
# Charger les données
|
||||
with open(input_file, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
|
||||
messages = data.get("messages", [])
|
||||
found = next((m for m in messages if m["id"] == message_id), None)
|
||||
|
||||
if not found:
|
||||
print(f"❌ Message ID {message_id} non trouvé.")
|
||||
return False
|
||||
|
||||
print(f"✅ Message ID {message_id} trouvé.")
|
||||
|
||||
# 1. Sauvegarder le HTML brut
|
||||
body_html = found.get("body", "")
|
||||
html_path = os.path.join(output_dir, f"message_{message_id}.html")
|
||||
with open(html_path, "w", encoding="utf-8") as f:
|
||||
f.write(body_html)
|
||||
print(f"📄 HTML sauvegardé dans : {html_path}")
|
||||
|
||||
# 2. Extraire les images depuis le HTML
|
||||
soup = BeautifulSoup(body_html, "html.parser")
|
||||
image_urls = []
|
||||
|
||||
# Extraction sécurisée des URLs d'images
|
||||
for img in soup.find_all("img"):
|
||||
if isinstance(img, Tag) and img.has_attr("src"):
|
||||
image_urls.append(img["src"])
|
||||
|
||||
image_data = {
|
||||
"message_id": message_id,
|
||||
"author": found.get("author_id", [None, None])[1],
|
||||
"date": found.get("date"),
|
||||
"subject": found.get("subject"),
|
||||
"image_urls": image_urls
|
||||
}
|
||||
|
||||
# 3. Sauvegarder sous forme JSON
|
||||
json_path = os.path.join(output_dir, f"message_{message_id}_meta.json")
|
||||
with open(json_path, "w", encoding="utf-8") as f:
|
||||
json.dump(image_data, f, indent=2, ensure_ascii=False)
|
||||
print(f"🧾 Métadonnées sauvegardées dans : {json_path}")
|
||||
|
||||
print("\n✅ Extraction terminée.")
|
||||
print("🖼️ Images détectées :")
|
||||
for url in image_urls:
|
||||
print(f" - {url}")
|
||||
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"❌ Erreur lors de l'extraction : {e}")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
success = extract_message(
|
||||
input_file=args.input,
|
||||
message_id=args.message_id,
|
||||
output_dir=args.output,
|
||||
create_test=args.create_test
|
||||
)
|
||||
|
||||
if not success:
|
||||
sys.exit(1)
|
||||
@ -1,5 +1,3 @@
|
||||
# extract_clean_message_with_image.py
|
||||
|
||||
import json
|
||||
import os
|
||||
import argparse
|
||||
@ -7,31 +5,30 @@ import requests
|
||||
from bs4 import BeautifulSoup, Tag
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description="Extrait un message filtré et nettoyé avec son image utile.")
|
||||
parser = argparse.ArgumentParser(description="Extrait un message et son texte pur d'un fichier JSON et HTML.")
|
||||
parser.add_argument("--input", "-i", default="messages_raw.json", help="Fichier JSON des messages")
|
||||
parser.add_argument("--message-id", "-m", type=int, default=228942, help="ID du message à traiter")
|
||||
parser.add_argument("--output", "-o", default="extracted_message", help="Répertoire de sortie")
|
||||
parser.add_argument("--output-html", "-o", default="extracted_message", help="Répertoire de sortie pour le HTML")
|
||||
parser.add_argument("--output-text", "-t", default="extracted_message/message_text.txt", help="Fichier texte de sortie")
|
||||
parser.add_argument("--preserve-images", action="store_true", help="Préserver les références aux images")
|
||||
return parser.parse_args()
|
||||
|
||||
def clean_message_html(html, keep_img=True):
|
||||
soup = BeautifulSoup(html, "html.parser")
|
||||
|
||||
# Supprimer les balises inutiles (tooltips, tracking, etc.)
|
||||
# Supprimer les balises inutiles
|
||||
for tag in soup.select(".o_mail_info, .recipients_info, .o_mail_tracking, .o_thread_icons, .o_thread_tooltip_container, .o_thread_full_spand_icon"):
|
||||
tag.decompose()
|
||||
|
||||
# Supprimer les images inutiles (font_to_img, sauf si /web/image/)
|
||||
# Supprimer les images inutiles
|
||||
for img in soup.find_all("img"):
|
||||
if not isinstance(img, Tag):
|
||||
continue
|
||||
|
||||
if not img.has_attr("src"):
|
||||
continue
|
||||
|
||||
src = img["src"]
|
||||
if not isinstance(src, str):
|
||||
continue
|
||||
|
||||
if "font_to_img" in src:
|
||||
img.decompose()
|
||||
elif keep_img and not src.startswith("http") and "/web/image/" not in src:
|
||||
@ -54,12 +51,12 @@ def download_image(url, output_dir, filename="image.png"):
|
||||
print(f"⚠️ Erreur lors du téléchargement de l'image: {e}")
|
||||
return None
|
||||
|
||||
def extract_and_clean(input_file, message_id, output_dir):
|
||||
def extract_and_clean(input_file, message_id, output_html_dir, output_text_file, preserve_images=False):
|
||||
if not os.path.exists(input_file):
|
||||
print(f"❌ Fichier non trouvé : {input_file}")
|
||||
return
|
||||
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
os.makedirs(output_html_dir, exist_ok=True)
|
||||
|
||||
with open(input_file, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
@ -77,10 +74,17 @@ def extract_and_clean(input_file, message_id, output_dir):
|
||||
original_html = msg.get("body", "")
|
||||
clean_html = clean_message_html(original_html)
|
||||
|
||||
# Sauvegarder le HTML nettoyé
|
||||
html_path = os.path.join(output_html_dir, f"message_{message_id}_clean.html")
|
||||
with open(html_path, "w", encoding="utf-8") as f:
|
||||
f.write(clean_html)
|
||||
|
||||
print(f"📄 HTML nettoyé sauvegardé : {html_path}")
|
||||
|
||||
# Extraire les images utiles
|
||||
soup = BeautifulSoup(clean_html, "html.parser")
|
||||
image_urls = []
|
||||
|
||||
|
||||
for img in soup.find_all("img"):
|
||||
if isinstance(img, Tag) and img.has_attr("src"):
|
||||
src = img["src"]
|
||||
@ -91,15 +95,31 @@ def extract_and_clean(input_file, message_id, output_dir):
|
||||
downloaded = None
|
||||
for url in image_urls:
|
||||
if isinstance(url, str) and url.startswith("http"):
|
||||
downloaded = download_image(url, output_dir, "image.png")
|
||||
downloaded = download_image(url, output_html_dir, "image.png")
|
||||
break
|
||||
|
||||
# Sauvegarde HTML nettoyé
|
||||
html_path = os.path.join(output_dir, f"message_{message_id}_clean.html")
|
||||
with open(html_path, "w", encoding="utf-8") as f:
|
||||
f.write(clean_html)
|
||||
# Extraire le texte
|
||||
paragraphs = []
|
||||
for p in soup.find_all("p"):
|
||||
if isinstance(p, Tag):
|
||||
text = p.get_text(strip=True)
|
||||
if text: # Ignorer les paragraphes vides
|
||||
paragraphs.append(text)
|
||||
|
||||
print(f"📄 HTML nettoyé sauvegardé : {html_path}")
|
||||
# Traiter les images si demandé
|
||||
if preserve_images:
|
||||
for img in soup.find_all("img"):
|
||||
if isinstance(img, Tag) and img.has_attr("src"):
|
||||
paragraphs.append(f"[IMAGE: {img['src']}]")
|
||||
|
||||
# Créer le texte final avec une structure claire
|
||||
text_content = "\n\n".join(paragraphs)
|
||||
|
||||
# Sauvegarder le texte
|
||||
with open(output_text_file, "w", encoding="utf-8") as f:
|
||||
f.write(text_content)
|
||||
|
||||
print(f"✅ Texte extrait et sauvegardé dans : {output_text_file}")
|
||||
if downloaded:
|
||||
print(f"🖼️ Image téléchargée dans : {downloaded}")
|
||||
else:
|
||||
@ -107,4 +127,4 @@ def extract_and_clean(input_file, message_id, output_dir):
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
extract_and_clean(args.input, args.message_id, args.output)
|
||||
extract_and_clean(args.input, args.message_id, args.output_html, args.output_text, args.preserve_images)
|
||||
@ -1,68 +0,0 @@
|
||||
# extract_text_from_html.py
|
||||
|
||||
import os
|
||||
import argparse
|
||||
from bs4 import BeautifulSoup, Tag
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description="Extrait le texte pur d'un fichier HTML.")
|
||||
parser.add_argument("--input", "-i", default="extracted_message/message_228942_clean.html",
|
||||
help="Fichier HTML à traiter")
|
||||
parser.add_argument("--output", "-o", default="extracted_message/message_text.txt",
|
||||
help="Fichier texte de sortie")
|
||||
parser.add_argument("--preserve-images", "-p", action="store_true",
|
||||
help="Préserver les références aux images")
|
||||
return parser.parse_args()
|
||||
|
||||
def extract_text(html_file, output_file, preserve_images=False):
|
||||
"""Extrait le texte d'un fichier HTML et le sauvegarde dans un fichier texte."""
|
||||
if not os.path.exists(html_file):
|
||||
print(f"❌ Fichier non trouvé : {html_file}")
|
||||
return False
|
||||
|
||||
# Créer le répertoire de sortie si nécessaire
|
||||
output_dir = os.path.dirname(output_file)
|
||||
if output_dir and not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
# Charger et parser le HTML
|
||||
with open(html_file, "r", encoding="utf-8") as f:
|
||||
html_content = f.read()
|
||||
|
||||
soup = BeautifulSoup(html_content, "html.parser")
|
||||
|
||||
# Supprimer les balises vides et inutiles
|
||||
for tag in soup.find_all():
|
||||
if isinstance(tag, Tag):
|
||||
if not tag.get_text(strip=True):
|
||||
tag.decompose()
|
||||
|
||||
# Extraire le texte avec une meilleure mise en forme
|
||||
paragraphs = []
|
||||
|
||||
# Traiter les paragraphes
|
||||
for p in soup.find_all("p"):
|
||||
if isinstance(p, Tag):
|
||||
text = p.get_text(strip=True)
|
||||
if text: # Ignorer les paragraphes vides
|
||||
paragraphs.append(text)
|
||||
|
||||
# Traiter les images si demandé
|
||||
if preserve_images:
|
||||
for img in soup.find_all("img"):
|
||||
if isinstance(img, Tag) and img.has_attr("src"):
|
||||
paragraphs.append(f"[IMAGE: {img['src']}]")
|
||||
|
||||
# Créer le texte final avec une structure claire
|
||||
text_content = "\n\n".join(paragraphs)
|
||||
|
||||
# Sauvegarder le texte
|
||||
with open(output_file, "w", encoding="utf-8") as f:
|
||||
f.write(text_content)
|
||||
|
||||
print(f"✅ Texte extrait et sauvegardé dans : {output_file}")
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = parse_args()
|
||||
extract_text(args.input, args.output, args.preserve_images)
|
||||
@ -1,52 +0,0 @@
|
||||
# extract_tracking_values_by_id.py
|
||||
|
||||
import json
|
||||
import os
|
||||
from odoo.auth_manager import AuthManager
|
||||
|
||||
CONFIG_FILE = "config.json"
|
||||
|
||||
def load_config(path=CONFIG_FILE):
|
||||
with open(path, "r") as f:
|
||||
return json.load(f)
|
||||
|
||||
def fetch_tracking_values(ids, config_file=CONFIG_FILE):
|
||||
config = load_config(config_file)
|
||||
odoo_cfg = config["odoo"]
|
||||
|
||||
auth = AuthManager(
|
||||
url=odoo_cfg["url"],
|
||||
db=odoo_cfg["db"],
|
||||
username=odoo_cfg["username"],
|
||||
api_key=odoo_cfg["api_key"]
|
||||
)
|
||||
if not auth.login():
|
||||
print("❌ Échec de l'authentification.")
|
||||
return
|
||||
|
||||
result = auth.read(
|
||||
model="mail.tracking.value",
|
||||
ids=ids,
|
||||
fields=["field", "field_desc", "old_value_char", "new_value_char"]
|
||||
)
|
||||
|
||||
# Sauvegarde JSON
|
||||
out_path = "tracking_value_result.json"
|
||||
with open(out_path, "w", encoding="utf-8") as f:
|
||||
json.dump(result, f, indent=2, ensure_ascii=False)
|
||||
|
||||
print(f"✅ Résultat enregistré dans {out_path}")
|
||||
for entry in result:
|
||||
print(f"- Champ : {entry['field_desc']}")
|
||||
print(f" Ancienne valeur : {entry['old_value_char']}")
|
||||
print(f" Nouvelle valeur : {entry['new_value_char']}")
|
||||
print()
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description="Lire les valeurs de suivi (mail.tracking.value)")
|
||||
parser.add_argument("ids", nargs="+", type=int, help="IDs à interroger (ex: 179095)")
|
||||
parser.add_argument("--config", "-c", default=CONFIG_FILE, help="Chemin vers le fichier config")
|
||||
args = parser.parse_args()
|
||||
|
||||
fetch_tracking_values(args.ids, args.config)
|
||||
71
track.py
71
track.py
@ -1,71 +0,0 @@
|
||||
# extract_tracking_values.py
|
||||
import json
|
||||
import os
|
||||
from odoo.auth_manager import AuthManager
|
||||
from odoo.ticket_manager import TicketManager
|
||||
from odoo.message_manager import MessageManager
|
||||
|
||||
CONFIG_FILE = "config.json"
|
||||
|
||||
def load_config(path=CONFIG_FILE):
|
||||
with open(path, "r") as f:
|
||||
return json.load(f)
|
||||
|
||||
def extract_tracking_values(ticket_code: str, config_file: str = CONFIG_FILE):
|
||||
config = load_config(config_file)
|
||||
odoo = config["odoo"]
|
||||
|
||||
# Auth
|
||||
auth = AuthManager(
|
||||
url=odoo["url"],
|
||||
db=odoo["db"],
|
||||
username=odoo["username"],
|
||||
api_key=odoo["api_key"]
|
||||
)
|
||||
if not auth.login():
|
||||
print("❌ Authentification échouée.")
|
||||
return
|
||||
|
||||
# Get ticket
|
||||
ticket_manager = TicketManager(auth)
|
||||
ticket = ticket_manager.get_ticket_by_code(ticket_code)
|
||||
if not ticket or "id" not in ticket:
|
||||
print(f"❌ Ticket non trouvé : {ticket_code}")
|
||||
return
|
||||
ticket_id = ticket["id"]
|
||||
|
||||
# Get messages
|
||||
msg_manager = MessageManager(auth)
|
||||
messages = msg_manager.get_ticket_messages(ticket_id)
|
||||
|
||||
# Collect tracking IDs
|
||||
tracking_ids = []
|
||||
for msg in messages:
|
||||
tracking_ids.extend(msg.get("tracking_value_ids", []))
|
||||
|
||||
if not tracking_ids:
|
||||
print(f"ℹ️ Aucun changement détecté pour le ticket {ticket_code}")
|
||||
return
|
||||
|
||||
# Fetch tracking values
|
||||
tracking_data = auth.read(
|
||||
model="mail.tracking.value",
|
||||
ids=tracking_ids,
|
||||
fields=["field", "field_desc", "old_value_char", "new_value_char"]
|
||||
)
|
||||
|
||||
# Export JSON
|
||||
output_path = os.path.join("output", f"tracking_values_{ticket_code}.json")
|
||||
os.makedirs("output", exist_ok=True)
|
||||
with open(output_path, "w", encoding="utf-8") as f:
|
||||
json.dump(tracking_data, f, indent=2, ensure_ascii=False)
|
||||
|
||||
print(f"✅ Modifications sauvegardées dans : {output_path}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description="Extract tracking changes for an Odoo ticket.")
|
||||
parser.add_argument("ticket_code", help="Code du ticket Odoo (ex: T12345)")
|
||||
parser.add_argument("--config", "-c", help="Fichier config", default=CONFIG_FILE)
|
||||
args = parser.parse_args()
|
||||
extract_tracking_values(args.ticket_code, args.config)
|
||||
@ -1,9 +0,0 @@
|
||||
[
|
||||
{
|
||||
"id": 179095,
|
||||
"field": "user_id",
|
||||
"field_desc": "Assigné à",
|
||||
"old_value_char": "",
|
||||
"new_value_char": "Fabien LAFAY"
|
||||
}
|
||||
]
|
||||
Loading…
x
Reference in New Issue
Block a user