J’avance doucement dans l’écriture du formulaire qui permettra de contribuer à panoramax depuis cartes.app, je partage ici avec vous mes choix et vous pose plein de questions, pour être sûr de faire les choses correctement et que ça soit pertinent pour tout le monde.
Principe
Comme cartes.app est très focalisé sur les POIs, je commence par un formulaire, accessible depuis la fiche d’un POI, pour ajouter des photos sur un POI. En ajoutant le tag osm côté panoramax, et le tag panoramax côté OSM. Comme ça elles seront visibles 1 minute après sur la fiche du POI.
Dans une v2, on pourrait étendre à poster des photos liées à 1 position sans forcément être liées à un POI.
En tout cas, on ne gèrera pas les séquences, seulement les lots de qq photos.
Instance
J’ai choisi celle d’osmfr car nos utilisateurs sont très majoritairement en France, et la connexion via l’oauth d’osm.org est directe et évite de devoir se créer un nouveau compte. De toute façon il faut que l’utilisateur ait bien un compte OSM pour pouvoir faire l’édition parallèle du POI dans OSM.
Dans une v2 on pourrait imaginer donner le choix de l’instance à l’utilisateur.
API
Je découvre l’api à cette occasion. J’ai prévu les choses comme suit, d’abord côté api panoramax :
l’utilisateur se connecte à panoramax
question 1 : l’api d’authentification n’a pas de redirect_uri qui permettrait de renvoyer l’utilisateur sur cartes.app à la fin. Pour l’instant il reste sur le site panoramax avec le message “OK Connexion terminée”. Je dois le prévenir à l’avance que ça va être comme ça, pour qu’il revienne lui même en arrière sur cartes.app. On en a déjà parlé dans ce fil, mais je n’ai pas l’impression qu’un ticket ait été créé ? cc @antoine-de
l’utilisateur choisit ses photos, on vérifie si l’EXIF contient des coordonnées, sinon on enverra les coordonnées du POI à la place.
question 2 : est-il nécessaire à cette étape de vérifier que les coordonnées de la photo sont cohérentes avec celles du POI ? Si oui, quelle distance max fixer ?
question 3 : faut-il vérifier aussi qu’il y a une capture date dans les EXIF ? J’ai vu que si il n’y en a pas la photo est refusée. Est-ce acceptable dans ce cas d’imposer la date de l’upload ? ou bien il vaut mieux refuser la photo car c’est suspect une photo sans date ?
on crée un upload set
on ajoute les photos à l’upload set
ici il faudra que je gère l’erreur “photo déjà uploadée” pour transmettre l’info à l’utilisateur qui essayerait de reposter plusieurs fois la même photo (d’expérience avec PlayGuide, ça arrive souvent !)
on marque l’upload set comme complete (au cas où il y aurait une incohérence entre le nb estimé et le nb de photos traitées, car j’ai vu que ça bloque le ready)
question 4 : quand j’ai testé hier soir, j’ai eu beaucoup d’erreurs 504 gateway timeout spécifiquement sur cet endpoint complete. Quelle pourrait être la raison ?
on attend que l’upload set soit ready
sur chaque photo de chaque collection créée, on ajoute le tag osm=type/id
remarque : à cette étape je me suis demandé si on pourrait avoir un endpoint pour éditer une photo sans avoir besoin d’indiquer à quelle collection elle appartient ? En effet j’ai déjà les id des photos dans l’upload set, j’aurais pu éditer directement les tags. Alors que là je dois reparcourir les collections pour trouver à quelle collection appartient chaque photo. Ca m’a embêté sur le moment, mais maintenant que c’est codé c’est pas très grave.
question 5 : si l’élément OSM a aussi un tag wikidata, dois-je ajouter le tag wd|P180=Qxxx aux photos panoramax ? Plus généralement quels autres tags OSM seraient pertinents à transférer automatiquement sur les photos pour une meilleure description ?
puis côté api osm :
on édite l’élément pour rajouter les tags panoramax:n avec les id des photos
question 6 : que mon conseillez-vous : 1 tag panoramax=* multivalué ? ou plusieurs tags panoramax:n ? Dans tous les cas, faudra que je lise les tags déjà existant pour ne pas les écraser.
Voilà ! Est-ce que ce workflow vous parait cohérent ?
question 7 : ça fait beaucoup d’appels successifs à différents endpoint de 2 api. Comment gérer si ça bloque au milieu et que toutes les étapes ne sont pas réalisées ? On envoie l’utilisateur vérifier sur l’interface web de l’instance panoramax ?
Merci par avance pour vos lumières et conseils ! (et désolé pour le message trop long)
OK, je peux imaginer un avertissement après 50m et un blocage après 500m.
OK, je peux faire le même système, avertissement si >1 mois (quelle durée max pour le blocage ?)
très facile en lisant les tags de l’élément OSM, je fais ça. Tu voudrais que je vérifie aussi côté panoramax ? A priori on le fait déjà pour afficher toutes les photos dispo sur la fiche lieu donc j’ai déjà peut-être l’info, il faut que je vérifie ce point.
oui. entre 23h et minuit je dirais. Je me suis demandé si j’appelais complete trop vite après l’upload des photos ?
ah oui en effet je n’avais pas pensé à cet endpoint, mais au final ça fait plus d’appels api car 1 par photo au lieu de 1 par collection.
tant mieux ça m’arrange ! (plutôt que de gérer tous les cas possibles)
bien sûr !
POST /api/upload_sets 1 fois
POST /api/upload_sets/${uploadSetID}/files 1 fois par photo
POST /api/upload_sets/${uploadSetID}/complete 1 fois
GET /api/upload_sets/${uploadSetID} toutes les 3 secondes jusqu’à ready
GET /api/collections/${collectionID}/items 1 fois par collection créée par l’upload set (a priori 1 seule collection si les photos ont été prises à la suite)
PATCH /api/collections/${collectionID}/items/${pictureID}/ 1 fois par photo (pour ajouter le tag)
Ah et j’ai oublié une question sur l’api : tu préfères que je mette User-Agent: Cartes.app à chaque requête ? Ou je laisse celui de l’utilisateur ? Et je mets l’info que ça passe par cartes.app ailleurs, genre un tag de l’upload set ou de la collection ?
Si je comprends bien, tu attends que la séquence soit traitée ?
Cela peut prendre du temps (file d’attente pour le floutage, les traitements, etc).
Il y a l’API “basique” pour les versements qui est peut être plus simple, surtout pour envoyer les photos une à une… on a ajouté toute la partie upload sets pour gérer le découpage, et permettre de modifier les tris ce qui n’a d’intérêt que pour les séquences.
ah bah mince, je me suis compliqué la vie parce que j’ai raté l’info qu’il y avait plus simple ? J’ai suivi ce qui est décrit ici : https://docs.panoramax.fr/backend/api/api/#upload d’où l’utilisation d’upload sets. C’est où que j’aurais dû trouver l’info sur l’api “basique” ?
[edit] ok j’ai compris en relisant le swagger, ce sont les endpoints POST /api/collections et POST /api/collections/{collectionId}/items à utiliser c’est ça ? j’étais tellement focalisé sur les upload sets que je ne les avais pas vus (et de toute façon, le message Note that this is the legacy API, upload should be done using the UploadSet endpoints if possible ne m’aurait pas poussé à les utiliser)
dans le cas basique, on crée une collection, puis on pousse des photos dedans
dans le cas de l’upload set, les photos sont stockées provisoirement dans l’upload set, et les collections sont créées (et les photos réparties dedans) seulement quand on donne le signal complete (qui est automatique si le nombre de photos attendues est atteint)
OK j’ai changé mon code pour utiliser ces 2 endpoints, c’est en effet bien plus rapide pour le développeur comme pour l’utilisateur, merci !
[edit] voila donc la 1ère photo panoramax publiée depuis cartes.app (la version de dev en local sur mon poste)
Il me reste à rajouter la vérif des EXIF, et gérer l’édition parallèle de l’élément dans OSM, ça sera pour après le SOTM !
(on est d’accord qu’on refuse catégoriquement les photos qui n’ont pas de coordonnées dans les EXIF ? on ne met pas celles du POI à la place ?)
Oui oui j’avais remarqué ! À un moment je m’etais dit : si côté cartes.app on repère qu’il manque la geoloc dans les exif, on utilisera override_latitude et override_longitude pour pousser dans l’api les coordonnées de l’élément osm dont l’utilisateur dit avoir une photo. Mais plus j’y pense, plus je me dis que c’est dommage ou suspect et qu’il vaut mieux refuser la photo et afficher un message lui demandant d’activer la geoloc de son appareil photo.
Ma question demandait confirmation de ce choix, mais avec la nuit qui porte conseil, c’est bon, je suis décidé !
désolé j’arrive aprés la bataille, c’était les vacances
question 1 : l’api d’authentification n’a pas de redirect_uri qui permettrait de renvoyer l’utilisateur sur cartes.app à la fin. Pour l’instant il reste sur le site panoramax avec le message “OK Connexion terminée”. Je dois le prévenir à l’avance que ça va être comme ça, pour qu’il revienne lui même en arrière sur cartes.app. On en a déjà parlé dans ce fil, mais je n’ai pas l’impression qu’un ticket ait été créé ? cc @antoine-de
on marque l’upload set comme complete (au cas où il y aurait une incohérence entre le nb estimé et le nb de photos traitées, car j’ai vu que ça bloque le ready)
c’est à toi de voir, tu peux effectivement, mais si tu maitrises la chaine, tu peux aussi te passer de cette étape et renseigner le estimated_nb_files.
sur chaque photo de chaque collection créée, on ajoute le tag osm=type/id
Si toute les photos vont etre associées au meme objet osm, tu peux aussi directement donner les tag à l’envoi, ils seront copiés à toutes les séquences associées (via le champs semantics lors du POST)
remarque : à cette étape je me suis demandé si on pourrait avoir un endpoint pour éditer une photo sans avoir besoin d’indiquer à quelle collection elle appartient ? En effet j’ai déjà les id des photos dans l’upload set, j’aurais pu éditer directement les tags. Alors que là je dois reparcourir les collections pour trouver à quelle collection appartient chaque photo. Ca m’a embêté sur le moment, mais maintenant que c’est codé c’est pas très grave.
Ah c’est un oubli, on a fait des raccourcis (qui ne respectent pas la norme STAC) pour les éditions d’annotations sans avoir l’id de la collection (/api/pictures/<uuid:itemId>/annotations), je pensais qu’on avait la meme chose sur le PATCH d’image, on va rajouter ca
Je ne suis pas certain que ca soit plus compliqué d’utiliser les nouvelles APIs, meme pour envoyer 1 seule photo, ca revient au meme non ?
oui, je sais combien de photos je vais envoyer, mais si une photo est refusée (on ne sait jamais) alors le estimated_nb_files n’est pas atteint. C’est pour ça que j’avais prévu de complete l’upload set dans tous les cas.
ça me perturbe que le tag soit sur la séquence et pas sur la photo. Quand quelqu’un regarde une photo, est-ce que tous les tags de la séquence sont présentés comme si c’était ceux de la photo ? quand on cherche un tag, est-ce que toutes les photos de la collection portant ce tag sont bien des hits ?
Avec le nouveau raccourci pour PATCH picture, ça reviendra au même. Mais sans se raccourci c’était plus compliqué car je devais attendre la fin du traitement de l’upload set pour pouvoir récupérer les numéros des collections.
@PanierAvide j’ai retrouvé le “bug de doc” que j’avais évoqué quand on avait discuté sur le stand panoramax du SOTM, c’est ici pour POST /api/upload_sets. L’exemple de body parle d’une propriété user_agent, mais l’inclure fait planter l’appel.
D’ailleurs, concernant le User-Agent en header, j’ai mis Cartes.app partout. Est-ce que ça permettra d’avoir la statistique de combien de photos ont été envoyée depuis cartes.app ?
OK, j’'ai vu que c’est bien le cas, donc je peux en effet :
créer un upload_set avec les tags
pousser les photos dedans
le marquer comme complete si une photo n’a pas marché
et comme ça c’est encore plus direct que collection puis photos puis tags. (j’ai vu que je ne peux pas créer une collection avec déjà des tags, mais peu importe, ne modifiez pas cette vieille API, je vais utiliser l’upload set)
hum, tu es sur ? si c’est le cas c’est un bug, normalement on attend d’avoir recu le nombre estimé de photo, qu’elles soient bonnes ou pas (par contre si ca plante avant l’envoi, effectivement, ca ne comptera pas dans le nombre de photos recues).
On a corrigé plusieurs trucs pour faciliter l’intégration: (les modifications sont la et la).
Il y a maintenant des raccourcis, on peut patcher les photos directement via PATCH /api/pictures/:id, mais en fait le plus simple pour vous c’est de passer directement les tags lors de l’upload, dans un champ application/json du formulaire (la doc non déployée est la) (on peut aussi maintenant passer des annotations si besoin).
On gère aussi maintenant un next_url lors du claim d’un token, pour être redirigé ailleurs.
On devrait merger et déployer tout ca dans pas trop longtemps sur les instances IGN et OSM-FR (sur le reste de la fédération ca viendra un peu plus tard).