Navigation

    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Song Import über die REST-Api

    ChurchTools Schnittstellen
    api import songs anlegen
    6
    14
    418
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • fschwarm24
      fschwarm24 last edited by

      Hallo zusammen,

      sehe ich das richtig, dass es keine Möglichkeit gibt, Songs über die REST-API zu importieren?

      Viele Grüße
      Florian

      M 1 Reply Last reply Reply Quote 1
      • M
        mnietsch @fschwarm24 last edited by

        Hallo,

        Tatsächlich habe ich mir jetzt gerade die gleiche Frage gestellt.
        Ich habe eine XML Datei mit unserem Lieder-Fundus, die ich gerne automatisch in CT importieren würde.

        In der alten API hab ich noch eine Funktion zum anlegen, löschen und editieren gefunden, aber die neue API sehe ich diese Funktionen noch ebenfalls nicht.

        Ist das zeitnah geplant anzubieten?
        Gruß Micha

        M 1 Reply Last reply Reply Quote 0
        • M
          mnietsch @mnietsch last edited by

          Könnt ihr bitte eine grobe Einschätzung geben, wann Song importieren / editieren von der API unterstützt werden wird?
          Das Thema wird bei mir doch recht zeitnah relevant werden, sodass ich da gerne eine Einschätzung hätte.

          Kann ich auf einen automatisierten Workflow hinarbeiten oder muss ich mir definitiv eine Alternative suchen, da das Thema in den kommenden Monaten noch nicht angefasst wird?

          Gruß Micha

          davidschilling 1 Reply Last reply Reply Quote 0
          • davidschilling
            davidschilling ChurchToolsMitarbeiter @mnietsch last edited by

            Alle Funktionen die es aktuell im CT Frontend gibt werden über Apis genutzt.
            Also gibt es auch eine Api für die Songs.

            Nur gibt es dafür noch keine neue Api dafür.

            Hier noch die Doku zur Api. Die alte Api ist die AJAX API.

            1 Reply Last reply Reply Quote 0
            • ben ste
              ben ste last edited by

              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.

              davidschilling 1 Reply Last reply Reply Quote 0
              • davidschilling
                davidschilling ChurchToolsMitarbeiter @ben ste last edited by 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 ste 2 Replies Last reply Reply Quote 0
                • ben ste
                  ben ste @davidschilling last edited by

                  @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 Reply Last reply Reply Quote 0
                  • ben ste
                    ben ste @davidschilling last edited by 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

                    davidschilling 1 Reply Last reply Reply Quote 0
                    • davidschilling
                      davidschilling ChurchToolsMitarbeiter @ben ste last edited by 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 ste 1 Reply Last reply Reply Quote 0
                      • ben ste
                        ben ste @davidschilling last edited by

                        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 ste 1 Reply Last reply Reply Quote 0
                        • ben ste
                          ben ste @ben ste last edited by

                          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 Reply Last reply Reply Quote 1
                          • DumbergerL
                            DumbergerL last edited by 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 Reply Last reply Reply Quote 0
                            • R
                              richard @ben ste last edited by 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 ste 1 Reply Last reply Reply Quote 0
                              • ben ste
                                ben ste @richard last edited by

                                @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.

                                1 Reply Last reply Reply Quote 0
                                • First post
                                  Last post