20 Replies Latest reply on Apr 29, 2016 11:22 AM by edmiidz

    Is there any REST/JS API for moving content?

    mansari3

      Is there any REST/JS API for moving content (bulk/individual) ? if not any thoughts on exposing them as well.

        • Re: Is there any REST/JS API for moving content?
          pawans

          Hi,

          As far as I know, there is no api for bulk move content.

          But we have developed a custom plugin for this.

          In this a system admin can select any group/space on jive and select all/some content items in it.

          And then they can be moved in bulk to another group/space.

          • Re: Is there any REST/JS API for moving content?
            gdinning

            I believe this can be done (at least for an individual object).  They say that anything in the UI can be done through the RESTful APIs now.  I'm not sure what version you're on but I notice that a lot of v6 still makes use of the v2 APIs.

             

            Here's a trick for figuring out how to replicate UI actions via REST.  Using a developer tool like Firebug, open the network traffic tab.  Perform the action in the UI and watch what kinds of requests are made.  You get all kinds of goodies from this like the URL, HTTP method, headers, and JSON body.

            1 person found this helpful
            • Re: Is there any REST/JS API for moving content?
              jezmartin

              I am currently having an App that does this for Discussions and Documents, it will be in the Marketplace soon.

              As is our norm, the code will be made available in our Github repository.

               

              In the interim, these were the basic steps:

              1. Acquire the content item via osapi.jive.corev3.contents.get()
              2. change the Parent value for the returned object
              3. Update the Content object - document.update()

               

              This works for a single item, but if you wanted to do this on multiple items, then you should use batch requests - osapi.newBatch()

              Details of the batch object can be found here

               

              I hope this helps

              • Re: Is there any REST/JS API for moving content?
                jameswright

                I do this sort of thing with XQuery 3.0 and the REST APIs:

                 

                     move-content.xq

                import module namespace jive = 'http://seu.jive.com';

                 

                let $communityURI := 'localhost:8080'

                let $request := jive:request-template('login', 'password')

                let $contentQuery := $communityURI || '/api/core/v3/contents?filter=tag(sometag)'

                let $newSpaceURI := '/api/core/v3/places/23232' return

                for $content in jive:get-all-items($request, $contentQuery ) return

                  copy $copy := $content

                  modify (replace value of node $copy/parent with $newSpaceURI)

                  return $copy

                       jive:update-item($request, $copy)

                 

                Here is a blow by blow of the above query which you can then use to replicate in any language you want... JS, Java, .net, whatever:

                 

                1) Setup the connection:

                let $communityURI := 'localhost:8080'

                let $request := jive:request-template('login', 'password')

                 

                2) define the objects involved using the jive v3 api:

                let $contentQuery := $communityURI || '/api/core/v3/contents?filter=tag(sometag)'

                 

                3) define the destination:

                let $newSpaceURI := '/api/core/v3/places/23232' return

                 

                4) For each object found from the 'contentQuery' change the parent property and then update the item by 'PUT'ing it back to Jive. (XQuery objects are not mutable, hence the need for the 'copy,modify,return' or what is called a transformation. $copy is a 'new' item which is exactly the same as the item returned, but with the parent property changed.

                 

                for $content in jive:get-all-items($request, $contentQuery ) return

                  copy $copy := $content

                  modify (replace value of node $copy/parent with $newSpaceURI)

                  return $copy

                       jive:update-item($request, $copy)

                 

                This could easily be accomplished via an html widget and some javascript as well....

                 

                My examples rely on a simple XQuery module with the namespace 'http://seu.jive.com' that I wrote which deals with the jive API calls and idiosyncrasies.  Its pretty short and simple. Below is a subset of the module methods you would need to utilize the above xquery expression: (Note the first line which is the namespace declaration). The http namespace (HTTP Client Module) has been defined by the EXPath group and is implemented in most XQuery engines to some degree. I use BaseX.

                 

                module namespace jive = 'http://seu.jive.com';

                 

                 

                 

                declare function jive:request-template($username as xs:string, $password as xs:string) as node() {

                  <http:request username="{$username}" password="{$password}" send-authorization="true" override-media-type="text/plain" method="get" />

                };

                 

                 

                 

                declare function jive:modify-request-template($request-template as node(), $method as xs:string, $body as node()) as node() {

                   if($request-template/@method != $method) then (

                       copy $request-template-copy := $request-template

                       modify (replace value of node $request-template-copy/@method with $method,

                       insert node $body into $request-template-copy)

                       return $request-template-copy

                   )   else ($request-template)

                };

                 

                 

                 

                declare function jive:modify-request-template($request-template as node(), $method as xs:string) as node() {

                  jive:modify-request-template($request-template, $method, <http:body media-type="text/plain"></http:body>)

                };

                 

                 

                 

                declare function jive:process-response($responseBody as xs:string) as node() {

                  json:parse(fn:replace($responseBody, "throw.*;\s*", ""))

                };

                 

                 

                 

                declare function jive:update-item($request-template as node(), $item as node()) as node() {

                  jive:process-response(

                    http:send-request(

                      jive:modify-request-template($request-template, 'PUT',

                        <http:body media-type="application/json">{json:serialize($item)}</http:body>),

                        $item/resources/self/ref)[2])

                };

                 

                 

                 

                declare function jive:get-all-items($request-template as node(), $baseURI as xs:string) {

                  let $response :=

                    jive:process-response(

                      http:send-request(

                        jive:modify-request-template($request-template, 'GET'), $baseURI)[2])

                  return ($response/list/value, if($response/links/next) then (jive:get-all-items($request-template, $response/links/next)) else ())

                };

                 

                declare function jive:get-item($request-template as node(), $uri as xs:string) as node() {

                  jive:process-response(

                     http:send-request(

                       jive:modify-request-template($request-template, 'GET'), $uri)[2])

                };

                 

                declare function jive:invite-to-group($request-template as node(), $emailsIn as xs:string*, $groupIn as node()) as node() {

                  let $invite :=

                    <json objects="json" arrays="invitees">

                      <body>Please come join the group</body>

                      <invitees>

                        {for $email in $emailsIn return <value>{$email}</value>}

                      </invitees>

                    </json>

                  return jive:create-item($request-template, $groupIn/resources/invites/ref,  <http:body media-type="application/json">{json:serialize($invite)}</http:body>)

                };

                 

                With the above module/Jive v3 api in tote, here are a few more examples of the possibilities:

                 

                 

                Here is a query which invites one user to all the groups with the 'client_group' tag on them.

                 

                import module namespace jive = 'http://seu.jive.com';

                 

                let $baseURI := 'localhost:8080'

                let $request := jive:request-template('login', 'password')

                let $concierge := jive:get-item($request, $baseURI || '/api/core/v3/people/email/' || 'fuse.support@somedomain.com')

                let $groups := jive:get-all-items($request, $baseURI || '/api/core/v3/places?filter=tag(client_group)&amp;count=100')

                return

                  for $group in $groups return

                    let $response := jive:invite-to-group($request, data($concierge/emails/value[1]/value), $group)/list/value[1] return

                    <invite-sent>{($response//invitee/displayName, $response//place/displayName), $response/resources/self/ref}</invite-sent>

                 

                Lastly, here is one, which makes a user an admin of all the groups they are apart of.

                import module namespace jive = 'http://seu.jive.com';

                 

                 

                let $baseURI := 'localhost:8080'

                let $request := jive:request-template('login', 'password')

                let $concierge := jive:get-item($request, $baseURI || '/api/core/v3/people/email/' || 'fuse.support@somedomain.com')

                return

                   for $membership in jive:get-all-items($request, $concierge/resources/members/ref)

                   return

                     copy $membership-copy := $membership

                     modify (replace value of node $membership-copy/state with 'owner',

                             insert nodes $membership/ancestor::json/@* into $membership-copy,

                             rename node $membership-copy as 'json')

                     return jive:update-item($request, $membership-copy)

                 

                 

                These are just some examples of the raw power you get with XQuery coupled with Jive's REST API. Obviously, this could be accomplished with any language.


                ENJOY! Hopefully this helps/ gives you some ideas. .

                - James

                  • Re: Is there any REST/JS API for moving content?
                    thomaslambert

                    Hello James,

                     

                    I currently doing the same thing in google apps script.

                    I find your result very effective. I tend to do very clean stuff also, even though it might seem a bit to go to far just for launching a few API REST calls, but I don't like to repeat myself.

                    So nice job, and thank you for the inspiration.

                     

                    I currently have a problem though with cloud hosting.

                      return ($response/list/value, if($response/links/next) then (jive:get-all-items($request-template, $response/links/next)) else ())

                    This would not work on cloud hosting : the API is returning an empty last page. Meaning the number of results will always be multiple of 25. If I have 60 followers of a group, a get request on this will return me 50 and the last page will be empty.

                    This is really bumming me out, as I worked a lot to get this to function correctly and with this bug I'm guaranteed not have all results on all my request.

                    I have a case open, they tell me it's a priority high. That means that maybe it will be solved in 3 months.

                    That voids all the purpose of the API, I don't understand how a bug like this could still be on production.

                     

                    But sorry for my rant, nice job to you James. I like seeing other people using the API for administration purpose

                     

                    Thomas.

                  • Re: Is there any REST/JS API for moving content?
                    pawans

                    Sorry to jump back to the thread after a long time.

                    We had a plugin for movecontent for jive 6.

                    Since we upgraded to jive 7, we i created a similar add-on for bulk content move based purely on jive's javascript apis instead of REST.

                    This app does not change date of moved content and no notifications after its moved to new group.

                     

                    I was planning to write a blog on JC since last week, but got delayed. Will do it tomorrow with the code.

                     

                    Just to give you a glimpse of a pre release version of how my move content app looks, check the attachment which is an older screenshot of add-on (not plugin).

                    This is one version of the app. The other is where it shows contents of the existing group instead of place picker for "from group".

                    I also managed to add pagination. But it had some problem after I added all content types.

                    Will share the code tomorrow. sorry for the delay.

                     

                    Group  Coffee   Jive.png