Enregistrement et renommage images

Bonjour à tous, je continu à développer mon application !!
Je souhaiterai pour une meilleur lisibilité des données avoir la possibilité de renommer automatiquement les images de mes items.
Quand je fais l’upload (par un liens par exemple) le nom du fichier ne correspond pas à ce que je souhaite.

Je voudrais enregistrer toutes ces images dans un dossier items et qu’ils aient le nom de l’article, et idéalement tous les redimensionner à la même taille.

Avez-vous des solutions. Sinon, je pensais à un hook de la fonction upload_file, mais je ne souhaite pas recopier toutes cette fonction, est-il possible d’apporter une surcouche, la question est aussi ouvertes pour d’autres fonctions.

Pour l’instant, j’ai déjà écris un hook de download_pdf pour changer les noms des pdf, mais je ne sais pas si je procède de la bonne manière de procéder car je duplique la fonction.

@frappe.whitelist(allow_guest=True)
def download_pdf(
	doctype: str, name: str, format=None, doc=None, no_letterhead=0, language=None, letterhead=None
):
	doc = doc or frappe.get_doc(doctype, name)
	validate_print_permission(doc)

	with print_language(language):
		pdf_file = frappe.get_print(
			doctype, name, format, doc=doc, as_pdf=True, letterhead=letterhead, no_letterhead=no_letterhead
		)
	frappe.local.response.filename = "{date}{company_abbr}{label}{name}.pdf".format(
		date=(doc.transaction_date.__str__() + "_") if hasattr(doc, "transaction_date") else "",
		company_abbr=(doc.company_abbr.replace(" ", "-").replace("/", "-") + "_")
		if hasattr(doc, "company_abbr")
		else "",
		label=(doc.sje_pdf_label.replace(" ", "-").replace("/", "-") + "_")
		if hasattr(doc, "sje_pdf_label")
		else "",
		name=name.replace(" ", "-").replace("/", "-"),
	)
	frappe.local.response.filecontent = pdf_file
	frappe.local.response.type = "pdf"

Merci encore pour tout le travail que vous faites et votre présence sur le forum, vos réponses sont toujours très éclairantes.

Bonjour @oryx,

Tu peux utiliser le hook suivant pour personnaliser la manière dont ton fichier est enregistré sur le disque:

Exemple

Fichier hooks.py

Méthode personnalisée:

Tu peux aussi modifier upload_file de la manière suivante:


Ici on ne voulait pas que le système optimise les images avec la méthode standard, même si l’utilisateur a coché l’option sur l’interface.

Tu as également un hook before_write_file appelé juste avant write_file:

Bonne journée


@frappe.whitelist()
def upload_file():
	import os

	from frappe.handler import upload_file as _upload_file

	file_name: str = frappe.form_dict.file_name or ""  # type: ignore
	if frappe.request.files and "file" in frappe.request.files:
		file_name = frappe.request.files["file"].filename  # type: ignore

	file_name, extension = os.path.splitext(file_name)
	file_name = "mon_nom_personnalisé_" + frappe.generate_hash(length=16)
	file_name = file_name + "." + extension.strip(".")
	file_name = file_name.strip(".")

	frappe.form_dict.file_name = file_name
	# frappe.form_dict.is_private = True

	if frappe.request.files and "file" in frappe.request.files:
		frappe.request.files["file"].filename = file_name

	return _upload_file()

merci et le reste de la fonction upload continue de fonctionner ou il faut recopier intégralement la fonction ?

Dans le code que je viens d’envoyer, on intervient « autour Â» de la fonction standard qu’il n’y a pas besoin de modifier je pense.

ok, pour bien comprendre le fonctionnement, a quel endroit on appelle la fonction de base ? ce hook intervient comment ?

Un exemple basique de modification revient Ă  faire :

# mon_appli/mes_overrides.py
import frappe

@frappe.whitelist()
def upload_file():
	from frappe.handler import upload_file as _upload_file  # fonction originale

	frappe.form_dict.file_name = "test.jpg"  # on modifie ce qu'on veut
	print(frappe.form_dict)

	# édit. : On applique le changement de nom de fichier
	if frappe.request.files and "file" in frappe.request.files:
		frappe.request.files["file"].filename = file_name

	return _upload_file()  # on continue avec le comportement standard

En ajoutant dans les hooks en override_whitelisted_method.

override_whitelisted_methods = {
    "upload_file": "mon_appli.mes_overrides.upload_file"
}

super, merci je vais tester

je n’arrive pas a changer le nom du fichier, je passe par le hook de upload_file:

def upload_file():
    from frappe.handler import upload_file as _upload_file  # fonction originale

    file_name: str = frappe.form_dict.file_name or "" 
    docname: str = frappe.form_dict.docname or ""
    folder: str = frappe.form_dict.folder or ""
    doctype: str = frappe.form_dict.doctype or ""
    if frappe.request.files and "file" in frappe.request.files:
        file_name = frappe.request.files["file"].filename
        
    file_name, extension = os.path.splitext(file_name)
    file_name = f"{docname}{extension}"
    folder = f"{folder}/{doctype}"
    
    
    frappe.form_dict.file_name = file_name
    frappe.form_dict.folder = folder
    
    print(frappe.form_dict)

    return _upload_file()  # on continue avec le comportement standard```

jusque là tout va bien, mais j’ai 2 lignes le code standard qui me pose problème et qui écrase mon nouveau nom.

if "file" in files:
		file = files["file"]
		content = file.stream.read()
		filename = file.filename

Avez vous une idée de comment faire ?
Merci

Ah oui désolé, dans mon exemple minimal il manque un bout du code, l’exemple complet le mentionne.

	print(frappe.form_dict)

	# ↓↓↓↓
	if frappe.request.files and "file" in frappe.request.files:
		frappe.request.files["file"].filename = file_name
	# ↑↑↑↑

	return _upload_file()

super, merci j’ai hésité à faire cette écriture mais j’ai cru que c’était un objet immuable, du coup que je ne pouvais pas le modifier.