First version of Share CFC Released

At MAX Adobe talked about Share, their new document storage/sharing service. It's relatively simple to use. You upload a file - set permissions - and then get some nifty little widgets. For example - you can upload a PDF and then get a Flash Paper preview you can embed in a web page. (I've done one below.) Images should also allow for embedding as well, but I believe there is a bug with the thumbnail. Anyway - this was cool in itself - but when I heard there was an API during the keynote, I immediately opened my browser to the docs. (API is about the only word that gets my attention more than wishlist.)

I was surprised to find that their API didn't just allow for simple listings but also allowed you to upload and download your documents. What does this mean? It means you can leverage the complete Share service completely from within your own application. (Although check the licensing - I didn't really read it well and I'm sure you have to credit Adobe somewhere.)

I worked on the API and had some difficulty. I got some help from the Share team (thank you Patrick Rodriguez and Fang Chang!) and I'm releasing my first version of the wrapper.

Before using this wrapper, you must ensure you have a valid Adobe ID. Then you must get your API key and shared secret from here.

Once you have this information you can then initiate a connection to Share:

<cfif not isDefined("application.share") or isDefined("url.reinit")>
   <cfset application.share = createObject("component", "share").init("ray@camdenfamily.com","parishiltonrules",appkey,sharedsecret)>
</cfif>

You must persist the CFC so that the authentication/session information sticks. Otherwise the CFC will be pretty slow. That first hit to get set up takes about 2-3 seconds. Here is what you can do with my API:

List

This returns a query of information about the files and folders in your Share account. What I find cool is that folders, as far as I can tell, don't even show up on the Adobe site. Maybe I'm using the Flex app wrong, but I could only work with folders via the API. So the API actually lets you organize things even better than the public site! Example:

<cfdump var="#share.list()#">

And this example lists files under a folder:

<cfdump var="#share.list('e0755f34-73b7-11dc-b75f-151d3f6d9313')#" label="List of stuff under my new folder">

Create New Folder

Does what it says. It can make a new folder at root or below another folder.

<cfset r = share.newFolder("new folder one2")>

Right now the result is a string. It will either be an error (if the folder already exists) or an XML packet for the node. I'm thinking of making it CFTHROW in case of a real error and for success doing nothing - or returning a structure representing the node. Comments?

Delete

This deletes folders or files. Like above - I need to tweak the return logic a bit.

<cfset r = share.delete("9f801c1f-73b5-11dc-b75f-151d3f6d9313")>

Upload

Uploads a file. Example:

<cfset myfile = expandPath("./test.pdf")>
<cfset r = share.upload(myfile,"Test upload")>

Download

Downloads a file. Duh. Example:

<cfset destpath = expandPath(".") & "/" & replace(createUUID(), "-","_","all") & ".pdf">
<cfset share.download("dd5b6c48-7464-11dc-b75f-151d3f6d9313", destpath)>

To Do:

  • Rename is in there - but currently broken. Move is essentially the same and once I get rename done, I'll work on move.
  • Permissions/Shares: I've done nothing in this area yet.
  • Working with "file renditions" - which is a just a fancy way of making it easier for you to display stuff on your site. I'm thinking of something simple like this: <cfoutput>#share.renderPreview("nodeidhere")#<cfoutput>

You can download the zip below. It isn't explicitly stated in the file, but this code follows the same OS license I use for the rest of my code. Once I get the above finished, I'll be moving it to RIAForge.

And lastly - here is a sample embed of a PDF:

Edit: Removed preview as it was throwing errors.

Comments

Getting an actionscript error when viewing the flash paper

[RPC Fault faultString="HTTP request error" faultCode="Server.Error.Request" faultDetail="Error: [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2032: Stream Error. URL: https://share.adobe.com/adc/flash?nodeId=dd5b6c48-...;]. URL: https://share.adobe.com/adc/flash?nodeId=dd5b6c48-...;]
   at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::faultH...()
   at mx.rpc::Responder/fault()
   at mx.rpc::AsyncRequest/fault()
   at ::DirectHTTPMessageResponder/errorHandler()
   at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
   at flash.events::EventDispatcher/dispatchEvent()
   at flash.net::URLLoader/flash.net:URLLoader::redirectEvent()
# Posted By Gareth | 10/6/07 8:50 PM
Ray:

IE 7, FlashPlayer 9:

The app throws this ActionScript error from your page here:

[RPC Fault faultString="HTTP request error" faultCode="Server.Error.Request" faultDetail="Error: [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2032: Stream Error. URL: https://share.adobe.com/adc/flash?nodeId=dd5b6c48-...;]. URL: https://share.adobe.com/adc/flash?nodeId=dd5b6c48-...;]
   at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::faultH...()
   at mx.rpc::Responder/fault()
   at mx.rpc::AsyncRequest/fault()
   at ::DirectHTTPMessageResponder/errorHandler()
   at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
   at flash.events::EventDispatcher/dispatchEvent()
   at flash.net::URLLoader/flash.net:URLLoader::redirectEvent()
# Posted By Sid Wing | 10/6/07 8:52 PM
Not sure why this is throwing a flex exception, that's bad. But it does appear this file was shared with limited access, which is why the preview won't show up.
# Posted By Andrew Shebanow | 10/6/07 10:07 PM
Darn it, Ray! You beat me to it...
# Posted By Sean Corfield | 10/6/07 10:37 PM
I removed the preview. Remember that Share is still in beta so I guess it is to be expected - or maybe I did do the permissions wrong!
# Posted By Raymond Camden | 10/6/07 10:46 PM
Hey, Sean, you can still be the first to post a cool app that integrates with SHARE!
# Posted By Andrew Shebanow | 10/7/07 10:45 AM
Hey . . . you need to close a PRE tag somewhere in this post - everything after a certain point is appearing in monospace font. Kinda makes it a bit hard to read (trying to catch up on what you've been doing lately). ;-)
# Posted By Lola LB | 10/7/07 12:45 PM
Oops. Sorry.
# Posted By Raymond Camden | 10/7/07 1:19 PM
Speaking of sample apps - I'm thinking it would be cool if Share had RSS feeds - of course just for public items. I think I may write up a quick demo showing share.cfc feeding into the cffeed tag.
# Posted By Raymond Camden | 10/7/07 2:33 PM
Just an FYI - I'm working on an update. I've found a bug in the back end of the API (Adobe's side) and have sent some sample code to their engineers. The rest of the functions will be done once I hear back from them.
# Posted By Raymond Camden | 10/10/07 9:13 AM
I've run into a problem. Can someone here confirm that the code posted to this entry no longer works?
# Posted By Raymond Camden | 10/15/07 11:05 AM
Please ignore. There is a bit of issue with the server and the problems I saw were just temporary.
# Posted By Raymond Camden | 10/15/07 1:15 PM
Hey Ray, what's the status of the this project. I was just looking into doing something with the Share API for my local User Group Site and pretty quickly found your CFC. I see the last comments were back in October, so I figured I would see if you had made any more progress.

Wait, I just searched RiaForge and see you added it in November. I will download it from there and see what I can do with it.

Thanks for your work, man.

~Brad
# Posted By Brad Wood | 12/21/07 5:19 PM
Let me know what you think of it.
# Posted By Raymond Camden | 12/21/07 8:03 PM