Posted By

reboltutorial on 12/11/10


Tagged


Versions (?)

Upload Google Doc


 / Published in: R
 

URL: http://rebol.wik.is/Googledocs

  1. rebol [
  2. file: googledocs.r
  3. author: "Graham Chiu"
  4. rights: 'BSD
  5. date: 15-Aug-2009
  6. notes: { authenticates using clientauth against googledocs, and upload an acceptable document. Returns an XML object with accessor functions }
  7. comment: {
  8. 16-Aug-2009 - get list of folders and resourceids
  9. }
  10. ]
  11.  
  12. do %/c/rebol-sdk-276/source/prot-http.r ; enhanced http protocol
  13. do http://www.ross-gill.com/r/altxml.r ; Chris' XML parser - see http://www.ross-gill.com/page/XML+and+REBOL
  14.  
  15. googledocs: make object! [
  16. auth: none ; the authentication token - can store in db and restore it.
  17. folders: copy [] ; holds the list of folders
  18. set-auth: func [ token [string!] ][ self/auth: token ]
  19. authenticate: func [ email [email!] password [string!] client [string!] service [string!]
  20. /insecure { use http and not https }
  21. /local token page
  22. ][
  23. page: read/custom join either insecure [ http:// ][https://] "www.google.com/accounts/ClientLogin" compose
  24. [ POST
  25. (rejoin [ "Email=" email "&Passwd=" password "&source=" client "&service=" service] ) ]
  26. either parse page [ to "Auth=" copy token to end ][
  27. set-auth trim/tail token
  28. true
  29. ][ false ]
  30. ]
  31.  
  32. create-doc+metadata: func [ docname [string!]
  33. /local template
  34. ][
  35. rejoin [ {<?xml version='1.0' encoding='UTF-8'?>
  36. <atom:entry xmlns:atom="http://www.w3.org/2005/Atom">
  37. <atom:category scheme="http://schemas.google.com/g/2005#kind"
  38. term="http://schemas.google.com/docs/2007#document" label="document"/>
  39. <atom:title>} docname {</atom:title>
  40. </atom:entry>}]
  41. ]
  42.  
  43. upload-document: func [ docname [string!] source [file! string!] content-type [string!]
  44. /raw
  45. /local boundary filedata result payload
  46. ][
  47. if none? self/auth [ return false ] ; or throw an error
  48. boundary: rejoin ["__REBOL__" system/version "__" checksum form now/precise "__"]
  49. filedata: either file? source [ read/binary source ][ source ]
  50. payload: to-string rejoin [ #{} "--" boundary newline "Content-Type: application/atom+xml" newline newline create-doc+metadata docname newline newline "--" boundary newline "Content-Type: " content-type newline newline
  51. filedata newline newline "--" boundary "--" newline newline]
  52. result: read/custom http://docs.google.com/feeds/documents/private/full compose/deep [
  53. POST (payload)
  54. [ content-type: (rejoin [ "multipart/related; boundary=" boundary ]) Authorization: (join "GoogleLogin " self/auth) ]
  55. ]
  56. either raw [ result ][
  57. load-xml/dom result
  58. ]
  59. ]
  60.  
  61. read-resource: func [ resource [string!] /local url][
  62. url: switch/default resource [
  63. "folders" [ http://docs.google.com/feeds/documents/private/full/-/folder?showfolders=true ]
  64.  
  65. ][ none ]
  66. either url [
  67. read/custom url compose/deep [ GET "" [ content-type: "application/atom+xml" Authorization: (join "GoogleLogin " self/auth) ] ]
  68. ][
  69. false
  70. ]
  71. ]
  72.  
  73. get-list-of-folders: func [ /raw /local page xmlobject result title resourceb][
  74. result: copy []
  75. page: read-resource "folders"
  76. either all [ not raw page ] [
  77. ; process page to retrieve resourceids and folder names and return as a block of [ name resourceids pairs ]
  78. xmlobject: load-xml/dom page
  79. ; gets a block of entries
  80. ; entries: xmlobject/get-by-tag <entry>
  81. foreach entry xmlobject/get-by-tag <entry> [
  82. ; get the title first
  83. title: entry/get-by-tag <title>
  84. ; title is a block! but there should be only one member
  85. ; if the folder name is not present, add it
  86. if not find result name: select title/1/value /text [
  87. repend result [ name copy [] ]
  88. ]
  89. ; now get the resourceid with this folder
  90. resourceb: entry/get-by-tag <resourceid>
  91. ; append the resourceid value to the block associated with this foldername - if we have duplicate folder names, we get a block of resourceids
  92. append select result name resourceb/1/value
  93. ]
  94. self/folders: copy/deep result
  95. result
  96. ][
  97. page
  98. ]
  99. ]
  100.  
  101. get-folder-resourceids: func [ foldername /local folders][
  102. if empty? self/folders [
  103. folders: get-list-of-folders
  104. ]
  105. select self/folders foldername
  106. ]
  107. ]
  108.  
  109. halt
  110. ; create an instance of the googledocs object
  111. gdoc: make googledocs []
  112.  
  113. ; authenticate against the documents service named "writely"
  114. goggledocs/authenticate [email protected] q@$$w0rb "rebolapp" "writely"
  115.  
  116. ; upload a text document to root folder and return an xmlobject with accessor functions
  117. xmlobject: googledocs/upload-document "my document" %test.rtf "application/msword"
  118.  
  119. ; upload a text document to root folder and return the raw XML
  120. xml: gdoc/upload-document/raw "my document" %test.rtf "application/msword"
  121.  
  122. ; upload a binary document to root folder, and call it "my document"
  123. xml: googledocs/upload-document/raw "my document" %test.rtf "application/msword"
  124.  
  125. ; get the resourceid for a folder
  126. id: gdoc/get-folder-resourceids "my folder"
  127. >>[{folder:0B6ELdnC15jkoOWRhNDJlMTgtYjhkOS00YTli............}]

Report this snippet  

Comments

RSS Icon Subscribe to comments
Posted By: reboltutorial on December 11, 2010

POST /feeds/documents/private/full HTTP/1.0 Accept: / Connection: close User-Agent: REBOL View 2.7.6.3.1 Host: docs.google.com Referer: http://docs.google.com/feeds/documents/private/full Content-Type: multipart/related; boundary=REBOL2.7.6.3.15821639 Content-Length: 5844 Authorization: GoogleLogin auth=

--REBOL2.7.6.3.15821639 Content-Type: application/atom+xml

test

--REBOL2.7.6.3.15821639 Content-Type: application/msword

{\rtf1\ansi\ansicpg1252\uc0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deff0\adeff0{\fonttbl{\f0\fnil\fcharset0 Times New Roman;}}{\colortbl;}{\stylesheet{\s0\snext0\styrsid8412110\sqformat\spriority0\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 Normal;}{*\cs10\additive\ssemihidden\spriority0 Default Paragraph Font;}}{*\generator Aspose.Words for Java 3.0.0.0;}{\info{\title 12 Shirley Street}\version0\edmins0\nofpages0\nofwords0\nofchars0\nofcharsws0}\deflang1033\deflangfe2052\adeflang1025\jexpand\showxmlerrors1\viewscale100\fet0\widowctrl\nospaceforul\nolnht adjtbl\alntblind\lyttblrtgr\nogrowautofit\dntblnsbdb\noxlattoyen\wrppunct\nobrkwrptbl\expshrtn\snaptogridincell\asianbrkrule\htmautsp\noultrlspc\useltbaln\splytwnine\ftnlytwnine\lytcalctblwd\allowfieldendsel\newtblstyruls\lnbrkrule\formshade\nojkernpunct\dghspace180\dgvspace180\dghorigin1800\dgvorigin1440\dghshow1\dgvshow1\dgmargin\pgbrdrhead\pgbrdrfoot\sectd\ltrsect\sectdefaultcl\pard\plain\itap0\s0\ltrpar\li0\lin0\ri0\rin0\ql\faau to\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 12 Shirley Street }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 Karori }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 Wellington 6012 }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 \line }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrc h\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 $date }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 \line }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\ lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 Dear $provider }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 \line }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 Re: SANDRA JURY 14-Dec-1963 }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 \line }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faau to\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 Here with is my template. }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 \line }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\p ar}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 Yours sincerely }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 \line }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 \line }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 SANDRA JURY }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}\pard\plain\itap0\s0\sa280\saauto 1\ltrpar\li0\lin0\ri0\rin0\ql\faauto\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 \line }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049 \line }{\rtlch\alang1025\afs24\ltrch\fs24\lang1049\langnp1049\par}{*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept}}}

--REBOL2.7.6.3.15821639--

HTTP/1.1 201 Created Content-Type: application/atom+xml; charset=UTF-8 Expires: Fri, 25 Sep 2009 20:18:00 GMT Date: Fri, 25 Sep 2009 20:18:00 GMT Vary: Accept, X-GData-Authorization, GData-Version GData-Version: 1.0 Location: http://docs.google.com/feeds/documents/private/full/document%3A0AaELdnC15jkoZGduejVrYnNfMjcxY3g1dDdjZGc/g01dkf4x Content-Location: http://docs.google.com/feeds/documents/private/full/document%3A0AaELdnC15jkoZGduejVrYnNfMjcxY3g1dDdjZGc/g01dkf4x X-Content-Type-Options: nosniff X-XSS-Protection: 0 Server: GFE/2.0 Via: 1.1 bc6 Cache-Control: private, max-age=0, must-revalidate, no-transform, proxy-revalidate Connection: close

http://docs.google.com/feeds/documents/private/full/document%3A0AaELdnC15jkoZGduejVrYnNfMjcxY3g1dDdjZGc2009-09 -25T20:17:59.385Z2009-09-25T20:17:[email protected]:[email protected]l.com2009-09-25T20:17:59.451Z0

You need to login to post a comment.