Directus API et image : question de content-type

Hello !

J’ai besoin de récupérer les infos d’une image présente dans une instance Directus sur un VPS (afin de les exploiter dans une app Flutter Windows), je m’y prends donc ainsi :

 http.Response response =
          await http.get(Uri.parse("${AppConstants.apiUrl}/assets/$idImage"));
      final bytes = response.bodyBytes;
      final contentType = MediaType.parse(response.headers['content-type']!);
      final extension = contentType.subtype;
      final fileName = idImage;
      print("type: $extension / fileName: $fileName / bytes: $bytes");

le problème est que le contentType est systématiquement de type « Json » et non « image/jpg », pourtant si on affiche l’image dans un navigation, le contentType est bon. J’ai essayé différentes méthodes, mais pas moyen de récupérer cette info !

une idée ? Merci.

Finalement, je mets de côté en forçant le type, mais je me heurte à une nouvelle difficulté :

 List<int> bytesImage =
              await downloadPicture(idImage: myListWeb[i].image.toString());
          DirectusFile picToUpload = await uploadFile(
              fileBytes: bytesImage,
              filename: myListWeb[i].image.toString(),
              contentTypeFile: "image/jpeg");

me donne :

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Exception: Server denied this action HTTP code : 500. Internal Server Error. {"errors":[{"message":"Input buffer contains unsupported image format","extensions":{"code":"INTERNAL_SERVER_ERROR"}}]}

si je passe en contentTypeFile: « image/jpg » (ce qui à priori n’existe pas - Types MIME - HTTP | MDN (mozilla.org), l’opération passe mais le fichier a une extention « .false ».

tu peux aussi faire une requête sur directus_files. Depuis la dernière mise à jour DirectusFile fonctionne comme les autres collections. Tu obtiendras les informations de base.

  String? get title => getValue(forKey: "title");
  String? get type => getValue(forKey: "type");
  DateTime? get uploadedOn => getOptionalDateTime(forKey: "uploaded_on");
  int? get fileSize => getValue(forKey: "filesize");
  int? get width => getValue(forKey: "width");
  int? get height => getValue(forKey: "height");
  int? get duration => getValue(forKey: "duration");
  String? get description => getValue(forKey: "description");
  Map<String, dynamic>? get metadata => getValue(forKey: "metadata");

C’était bien mon intention (je cherche à synchroniser des mises à jour de médias entre un Directus web et un local), mais lorsque j’utilise :

 DirectusFile? myfile =
            await apiDirectusLocal.getSpecificItem(id: localID.toString());
        if (myfile != null) {
          contentLength2 = int.parse(myfile.fileSize.toString());
        }

J’obtiens l’erreur suivante (au sein d’une classe toute bête dans laquelle je passe mon objet DirectusApiManager) :

flutter: Error: Exception: No class mirror found for type DirectusFile. Please add the @DirectusCollection annotation to the class

Oui normal, les annotations ont été rajouté le 15 juin et le master de Maxime est un plus vieux.

Pour palier le truc, tu peux faire une classe qui représente tes fichiers qui étend DirectusFile et tu ajoutes les annotations.

@DirectusCollection()
@CollectionMetadata(
    endpointName: "files",
    endpointPrefix: "/")
class MaClassePourMesFichiers extends DirectusFile {
MaClassePourMesFichiers(Map<String, dynamic> rawReceivedData) : super(rawReceivedData);
}

ou mettre à jour la version de l’API Directus :thinking:?

ou mettre à jour la version de l’API Directus :thinking:?

cela dépend de la validation de @mbritto et en cadeau bonus, il a la gestion des web sockets aussi.

1 « J'aime »

Question toute bête : j’ai effectué les modifs, mais je ne vois pas comment utiliser la classe :

Capture d’écran 2023-07-06 091806

c’est un peu court pour t’aider. C’est quoi Downloader et areFilesEqual ?

ah oui :joy: clairement ! Downloader est la class que j’ai modifiée pour étendre DirectusFile selon ton précédent conseil et areFilesEqual est ma fonction de comparaison. Auparavant je déclarais ma classe en static pour accéder à la fonction, mais ce n’est plus possible dans la combinaison suivante :

Capture d’écran 2023-07-06 163231

Je verrai plus un truc du style :

@DirectusCollection()
@CollectionMetadata(endpointName: "files", endpointPrefix: "/")
class Downloader extends Directusfile {
Downloader (Map<String, dynamic> rawreceivedData) : super (rawReceivedData);
Future<bool› areFilesEqual(
{required String webImageID}) {
return id == webImageId // par exemple

et tu l’appelle de cette façon

final Downloader downloader = Downloader(les données de ton objet)
if(downloader.areFilesEqual(webImageId: "toto")) {
    // Si c'est vrai
}
else {
    // Si c'est faux
}

Excuse la question (j’ai honte), mais je n’ai pas de données à faire passer, c’est juste une classe avec des fonctions utilisant le DirectusFile, je ne sais donc pas quoi passer en paramètres :

final Downloader downloader = Downloader(les données de ton objet)

:grimacing: :grimacing: :grimacing: