• Aktuell
    • Tags
    • Beliebt
    • Benutzer
    • Gruppen
    • Suche
    • Registrieren
    • Anmelden

    Song Import über die REST-Api

    ChurchTools Schnittstellen
    songs anlegen import api
    7
    15
    1.1k
    Lade mehr Beiträge
    • Älteste zuerst
    • Neuste zuerst
    • Meiste Stimmen
    Antworten
    • In einem neuen Thema antworten
    Anmelden zum Antworten
    Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
    • ben steB
      ben ste
      zuletzt editiert von

      Hallo zusammen,
      müsste man nicht in der REST API über den Files Endpoint

      /files/{domainType}/{domainIdentifier}
      

      als POST neue Dateien hochladen können, bzw. mit DELETE auch entfernen? Als DomainType hätte ich hier "Song_Arrangement" erwartet.

      Wenn ich das ganz konkret ausprobiere, also z.B.

      curl -X 'POST' \ 'https://elkw1610.krz.tools/api/files/song_arrangement/394' \ -H 'accept: application/json' \ -H 'Content-Type: multipart/form-data' \ -F 'files=@20220513_203630.jpg;type=image/jpeg'
      

      bekomme ich jedoch einen Fehler

      { "message": "There are validation errors", "messageKey": "validation.error", "translatedMessage": "Die eingegebenen Daten waren nicht korrekt.", "args": [], "errors": [ { "fieldId": "files", "message": "Nur eine Datei darf für diesen Domain Typ hochgeladen werden.", "messageKey": "validation.domainfiles", "args": { "name": "files", "value": {} } } ] }
      

      Außerdem stellt sich die Frage in wie weit immer ALLE Attachments eines Song_Arragements gelöscht werden oder auch durch gezieltes löschen und neu hoch landen ein entpsprechender Sync möglich wäre ...

      Langsam frage ich mich ob die API überhaupt schon im bisher dokumentierten Teil funktioniert ...

      Also für das Beispiel kurz zum Kontext ...

      Ich habe einen test song mit 3 arrangements angelegt, das 3. hat noch keine Datei und die ID 394, die anderen 385 und 383. Der Song selber hat entpsrechend die ID 383

      Vom Handy aus versuche ich angemeldet ein neues attachement hoch zu laden. (Über die Swagger Demo auf /api) wird angezeigt als curl Parameter "song_arrangement" und der domainIdentifier "394" ist darin auch zu erkennen.

      davidschillingD 1 Antwort Letzte Antwort Antworten Zitieren 0
      • davidschillingD
        davidschilling ChurchToolsMitarbeiter @ben ste
        zuletzt editiert von davidschilling

        @ben-ste Die Fehlermeldung ist hier etwas irreführend.

        Problem ist aber, dass der Parameter files[] heißen muss und nicht file.
        Damit sollte es funktionieren.

        Also in deinem Beispiel dann: curl -X 'POST' \ 'https://elkw1610.krz.tools/api/files/song_arrangement/394' \ -H 'accept: application/json' \ -H 'Content-Type: multipart/form-data' \ -F 'files[]=@20220513_203630.jpg;type=image/jpeg'

        ben steB 2 Antworten Letzte Antwort Antworten Zitieren 0
        • ben steB
          ben ste @davidschilling
          zuletzt editiert von

          @davidschilling
          Hallo David,
          das kann ich leider auf die schnelle so nicht prüfen - wie gesagt probiert hatte ich es mit der offiziellen Interaktiven Swagger Doku der REST API - kann das sein das das Attribut dann da falsch drin steht wenn du sagst das es auf die [] ankommt?

          Normal würde ich die REST API kurz in RESTED probieren, nur kann ich da nicht so schnell mal eine Datei einbauen ...

          1 Antwort Letzte Antwort Antworten Zitieren 0
          • ben steB
            ben ste @davidschilling
            zuletzt editiert von ben ste

            Hi @davidschilling
            ich habe es mittlerweile mit folgendem Python Code probiert ...
            Die Verbindung ist via token in der Session gespeichert (und mit /whoami getestet)

            headers = {
                   'Content-Type': 'multipart/form-data',
                   'accept': 'application/json',
                   'CSRF-Token': csrf_token
               }
            url = domain + '/api/files/{}/{}'.format(domain_type, domain_identifier)
            
            file = open('test.pdf', 'rb')
            data = {'files[]': file}
            
            response = session.post(url=url, headers=headers, data=data)
            

            Der Fehler bleibt der gleiche

            {"message":"There are validation errors","messageKey":"validation.error","translatedMessage":"Die eingegebenen Daten waren nicht korrekt.","args":[],"errors":[{"fieldId":"files","message":"Nur eine Datei darf f\\u00fcr diesen Domain Typ hochgeladen werden.","messageKey":"validation.domainfiles","args":{"name":"files","value":null}}]}
            

            Alternativ habe ich auch mit files statt files[] (als Key) und mit file als [] als Attribut in dem Data Dict probiert sogar im post request "files=" statt "data=" probiert
            Sorry beim besten willen - irgendwie ist die API an der Stelle etwas sagen wir mal "ungünstig" dokumentiert.
            Kann das sein, dass hier ein Array mit allen Parametern für einen File erwartet wird statt nur einer einzigen Datei? Das würde auch erklären warum je ID, obwohl es mehrere Files geben kann, jeweils nur ein Aufruf möglich ist. Wie zuvor geschrieben klingt das ja fast danach als das beim löschen alle Dateien mit dem Identifier entfernt werden.
            Falls du Zeit hättest das gemeinsam weiter zu verfolgen könnte man ja anschließend die REST-API Doku ggf. etwas erweitern damit nicht noch andere in das selbe Problem laufen.

            Ergänzung - ich habe in der Zwischenzeit einen anderen DomainType (GroupImage) probiert und stoße auf das gleiche Problem

            davidschillingD 1 Antwort Letzte Antwort Antworten Zitieren 0
            • davidschillingD
              davidschilling ChurchToolsMitarbeiter @ben ste
              zuletzt editiert von davidschilling

              @ben-ste

              Ich hab es gerade nochmal getestet. Genau dieser curl Aufruf funktioniert bei mir:

              curl -X POST http://churchtools.test/api/files/avatar/1 -H 'cookie: ChurchTools_template=nmtncfh5kushiqp9ikidn27n66' -H 'content-type: multipart/form-data' -F 'files[]=@/Users/david/Downloads/8BS_6600.JPG;type=image/jpeg' -H 'csrf-token: db639402f593da794d99aa2706339314da62a7c0dbcc3bb8c505d82d6702b73e'

              Es müssen natürlich Cookie, Url und CSRF Token angepasst werden.

              Auch mit dem DomainType song_arrangement habe ich es erfolgreich getestet.

              ben steB 1 Antwort Letzte Antwort Antworten Zitieren 0
              • ben steB
                ben ste @davidschilling
                zuletzt editiert von

                Hallo @davidschilling ,

                nach etwas probieren bekomme ich es zumindest über CURL jetzt hin und glaube dir endlich das die API auch funktioniert 😉 Mal gucken ob man diese komische Absurdität mit den [] im Parameter auch in Python umsetzen kann.
                Interessant war noch das zuerst der Login via Token nicht funktioniert hatte.Gemäß deinem Beispiel konnte ich aber aus dem LocalStorage von Firefox zum testen meinen Cookie extrahieren ...

                curl -X POST https://elkw1610.krz.tools/api/files/song_arrangement/394 \
                  -H 'cookie: ChurchTools_ct_elkw1610=GEHEIM' \
                  -H 'content-type: multipart/form-data' \
                  -F 'files[]=@media/pinguin.png;type=image/png'
                

                Hatte dann sogar auch ohne CSRF das entsprechende Ergebnis gebracht.
                Nach 2 oder 3 weiteren Versuchen klappte es dann auch mit Authorization statt Cookie (wohl wissend, dass ich damit immer neue Logins im Log erzeuge ...)

                curl -X POST https://elkw1610.krz.tools/api/files/song_arrangement/394 \
                  -H 'Authorization: Login GEHEIM' \
                  -H 'content-type: multipart/form-data' \
                  -F 'files[]=@media/pinguin2.png;type=image/png'
                

                Über ein GET konnte ich übrigens undokumentiert über das selbe Schema an die URL der Dateien

                curl -X GET https://elkw1610.krz.tools/api/files/song_arrangement/394 \
                  -H 'Authorization: Login GEHEIM' \
                  -H 'content-type: multipart/form-data'
                

                da war dann u.a. der Link der dann die Datei enthält.

                Also Zusammengefasst ... Wenn ich SongArrangements Updaten will muss ich erst alle Dateien herunterladen, meine neue Datei im Download überschreiben / ergänzen und anschließend alle wieder hoch laden.

                Danke für die Hilfestellung - bin mal gespannt wann wann die API noch einmal erweitert wird. Jetzt ist ja der Finder endlich fertig ...

                ben steB 1 Antwort Letzte Antwort Antworten Zitieren 0
                • ben steB
                  ben ste @ben ste
                  zuletzt editiert von

                  Hallo zusammen, da sicher noch andere auf das Problem stoßen werden ...
                  Der komische "files[]" Parameter und die fehlende Angabe des entsprechend zu übergebenden Formats in der API führen sowohl in der API Demo als auch bei Verwendung des Python Requests Modul zu Problemen.

                  WICHTIG - was in der Doku fehlt ist, dass nicht das FileObjekt sondern ein Tuple aus Dateiname und Fileobjekt erwartet wird, ansonsten gibt der Fehler entweder Code 200 ohne etwas durchzuführen, oder Code 500 bei falschen Objekten zurück.
                  @davidschilling - Vielleicht könntet ihr das in der Doku ergänzen und Swagger so ausführen, dass auch das Beispiel funktioniert ... Ich glaube die Try Funktion geht genau deswegen nicht ...

                  Für alle die es mit Python nutzen wollen unten der getestete Code ... Wichtig - zuerst die Session über einen GET Aufruf auf /api/whoami mit entsprechenden Authorization Token initiieren.
                  @davidschilling - auch dafür wäre ein Beispiel in der Doku gut - das der Text Login vor dem Token stehen bleiben soll und es sich um einen normalen Header statt einer richtigen Auth Methode handelt war zumindest für mich nicht von Anfang an klar.

                  def upload_file(session,file_to_upload, domain_type='song_arrangement', domain_identifier=394):
                      """
                      Helper function to upload an attachment to any module of ChurchTools
                  
                      :param session: which is allready Authorized
                      :param file_to_upload: open file object - e.g. open('media/pinguin.png', 'rb')
                      :param domain_type:  The domain type. Currently supported are 'avatar', 'groupimage', 'logo', 'attatchments', 'html_template', 'service', 'song_arrangement', 'importtable', 'person', 'familyavatar', 'wiki_.?'.
                      :param domain_identifier: ID of the object in ChurchTools
                      :return:
                      """
                  
                      url = domain + '/api/files/{}/{}'.format(domain_type, domain_identifier)
                  
                      # add files as files form data with dict using 'files[]' as key and (tuple of filename and fileobject)
                      files = {'files[]': (file_to_upload.name, file_to_upload)}
                      response = session.post(url=url, files=files)
                  
                      """
                      # Issues with HEADERS in Request module when using non standard 'files[]' key in POST Request
                      # Workaround for ChurchTools - generate session with /api/whoami GET request and reuse it
                      # Requests module usually automatically completes required header Params e.g. Content-Type ...
                      # in case manual header e.g. for AUTH is used, headers don't auto complete
                      # and server rejects messsages or data is ommited 
                      # Error Code 500 is also missing in API documentation
                      
                      headers = {'Authorization': 'Login GEHEIM'}
                      response_test = requests.post(url=url, headers=headers, files=files)
                      #> this fails !
                      """
                  
                      if response.status_code == 200:
                          response_content = json.loads(response.content)
                          logging.info(response_content)
                      else:
                          logging.warning(response.content.decode())
                  
                  R 1 Antwort Letzte Antwort Antworten Zitieren 1
                  • DumbergerLD
                    DumbergerL
                    zuletzt editiert von DumbergerL

                    Ich hatte auch Probeme mit dem Endpunkt und einer Implementierung in PHP. Über die Bibliothek Guzzle habe ich es leider überhaupt nicht zum Laufen bekommen, weil Guzzle die Kombination aus dem Header "Content-type:multipart/form-data" und der Option "form_params" aussschließt.

                    Mit einem selbst zusammengebauten Curl-Request funktioniert es jetzt allerdings:

                    $ch = curl_init("https://intern.church.tools/api/files/avatar/21?login_token=" . $loginToken);
                    curl_setopt($ch, CURLOPT_HTTPHEADER, [
                        "content-type:multipart/form-data",
                        "csrf-token:" . $csrfToken
                    ]);
                    curl_setopt($ch, CURLOPT_POST, true);
                    curl_setopt($ch, CURLOPT_POSTFIELDS, ["files[]" => curl_file_create($filePath)]);
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                    
                    $resultString = (string)curl_exec($ch);
                    $curlInfo = curl_getinfo($ch);
                    

                    Ich habe das ganze auch in einen API-Wrapper verpackt. (https://github.com/5pm-HDH/churchtools-api)
                    Wer also auch via PHP Datein hochladen möchte kann auch die den Wrapper benutzen:

                    $newFile = (new FileRequestBuilder("avatar", 22))->upload(__DIR__ . "/avatar-1.png");
                    
                    1 Antwort Letzte Antwort Antworten Zitieren 0
                    • R
                      richard @ben ste
                      zuletzt editiert von richard

                      @davidschilling, @ben-ste: Ich habe exakt so wie ihr versucht Avatar-Bilder für unsere Mitglieder hochzuladen und komme nicht über folgende Meldung hinaus:

                      {'message': 'There are validation errors', 'messageKey': 'validation.error', 'translatedMessage': 'Die eingegebenen Daten waren nicht korrekt.', 'args': [], 'errors': [{'fieldId': 'files', 'message': 'Nur eine Datei darf für diesen Domain Typ hochgeladen werden.', 'messageKey': 'validation.domainfiles', 'args': {'input': None, 'multipleAllowed': True}}]}
                      

                      @ben-ste: Funktioniert dein Codebeispiel immer noch und gibt es vielleicht etwas, was du im Codeschnipsel nicht dokumentiert hast, was ich übersehen könnte?
                      Habe mittlerweile alle möglichen Kombinationen aus Header, Files und Data durch und bekomme es nicht hin Dateien hochzuladen.

                      ben steB 1 Antwort Letzte Antwort Antworten Zitieren 0
                      • ben steB
                        ben ste @richard
                        zuletzt editiert von

                        @richard , mein Code findet sich mittlerweile unter https://github.com/bensteUEM/ChurchToolsAPI/releases/tag/1.2.3.10
                        inkl automatischen Tests. Der Dateiupload für Song arrangenents geht auf jeden Fall, ich meine ein Testfall lädt auch ein Gruppensymbol, bin mir aber nicht sicher
                        Ich würde also davon ausgehen, dass es grundsätzlich geht, ggf haben sich aber in der Zwischenzeit weitere Prämissen aufgetan die dort im Code auch sauber dokumentiert sind (u.a. CSRF Token usw die dort mit Login Automatische abgehandelt werden)

                        Meine Empfehlung wäre daher wie auf der release Seite beschrieben das Paket via pip zu installieren und dann entsprechend der Doku zu verwenden. Solltest du dabei auf ungetestete oder reproduzierbar defekte Anwendungsfälle stoßen kann ich es gerne dort in die Wunschliste aufnehmen.

                        T 1 Antwort Letzte Antwort Antworten Zitieren 0
                        • C corth50 hat am auf dieses Thema verwiesen
                        • T
                          thommyb ChurchToolsMitarbeiter @ben ste
                          zuletzt editiert von

                          Mit der aktuellen Version 3.117 haben wir begonnen, die schon lange und wiederholt gewünschten Endpunkte für Songs und Arrangements zu implementieren. Das ist noch nicht ganz fertig und rund, aber diejenigen, die sich hier Tools und ähnliches geschrieben haben, um ihren Bestand an Liedern zu importieren, sind herzlich eingeladen, hier schon mal reinzuschauen und uns Feedback zu geben.

                          1 Antwort Letzte Antwort Antworten Zitieren 0
                          • Erster Beitrag
                            Letzter Beitrag