Skip to content

Instantly share code, notes, and snippets.

@JoeStanton
Created June 13, 2013 13:44
Show Gist options
  • Save JoeStanton/5773786 to your computer and use it in GitHub Desktop.
Save JoeStanton/5773786 to your computer and use it in GitHub Desktop.
Sharepoint.coffee
request = require 'request'
_ = require 'underscore'
url = require 'url'
log = require '../log'
async = require 'async'
config = require '../config'
Parser = new require('xml2js').Parser
requestQueue = async.queue _postQuery, 1
BASE_CAML_QUERY =
"<rowLimit>999999</rowLimit>
<queryOptions xmlns:SOAPSDK9=\"http://schemas.microsoft.com/sharepoint/soap/\" >
<QueryOptions>
<ViewAttributes Scope=\"Recursive\" />
</QueryOptions>
</queryOptions>"
postQuery = (cookie, service, method, siteUrl, query, callback) ->
requestQueue.push
cookie: cookie
service: service
method: method
siteUrl: siteUrl
query: query
callback: callback
_postQuery = (cookie, service, method, siteUrl, query, callback) ->
soapActionHeader = 'http://schemas.microsoft.com/sharepoint/soap/' + method
methodNameSpace = 'http://schemas.microsoft.com/sharepoint/soap/'
webServiceUrl = (url.resolve(siteUrl, "_vti_bin/#{service}.asmx"))
envelope = '<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><' + method + ' xmlns=\"' + methodNameSpace + '\">' + query + '</' + method + '></soap:Body></soap:Envelope>'
jar = request.jar()
jar.add request.cookie cookie[0]
log.verbose "requesting #{webServiceUrl}"
req =
uri: webServiceUrl
rejectUnauthorized: false
body: envelope
timeout: 10000
jar: jar
headers:
'Content-Type': 'text/xml'
'SOAPAction': soapActionHeader
request.post webServiceUrl,
rejectUnauthorized: false
body: envelope
timeout: 10000,
jar: jar
headers:
'Content-Type': 'text/xml'
'SOAPAction': soapActionHeader
, (error, response, body) ->
if error or not response
console.log "==========="
console.log "ERROR: #{error}"
console.log(JSON.stringify(req))
console.log "==========="
if error
log.error "Could not get content from #{siteUrl}. The service requested was #{service}."
log.error error
callback error
else if not response
callback new Error "No response from sharepoint has been returned. Check network connectivity and access to #{siteUrl}."
else if response.statusCode >= 400
callback new Error "Bad response code (#{response.statusCode}) from SharePoint when requesting content."
else
log.verbose "Successfully fetched from site #{siteUrl}."
parser = new Parser()
parser.parseString body
, (error, data) ->
if error
callback new Error 'Error occured when parsing returned xml from SharePoint.'
else
log.verbose 'Successfully parsed SharePoint data to JSON from XML.'
responseBody = data['soap:Envelope']["soap:Body"]
listItemResponse = responseBody[0].GetListItemsResponse
listResponse = responseBody[0].GetListCollectionResponse
webResponse = responseBody[0].GetWebCollectionResponse
attachmentResponse = responseBody[0].GetAttachmentsResponse
results = []
total = 0
if listItemResponse
total = parseInt listItemResponse[0].GetListItemsResult[0].listitems[0]['rs:data'][0]['$'].ItemCount
if total > 0
results = listItemResponse[0].GetListItemsResult[0].listitems[0]['rs:data'][0]['z:row']
else if listResponse
results = listResponse[0].GetListCollectionResult[0].Lists[0].List
total = results?.length
else if webResponse
results = webResponse[0].GetWebCollectionResult[0].Webs[0].Web
total = results?.length
else if attachmentResponse
results = attachmentResponse[0].vAttachments[0].string
callback null,
results: results
total: total
exports.getListItem = (siteUrl, cookie, listId, itemId, callback) ->
log.info "Attempting a fetch for item id #{itemId} from list id #{listId} from the site #{siteUrl}."
query =
"<listName>#{listId}</listName>
#{BASE_CAML_QUERY}
<query>
<Query>
<Where>
<Eq>
<FieldRef Name=\'ID\' />
<Value Type=\'Integer\'>#{itemId}</Value>
</Eq>
</Where>
</Query>
</query>"
postQuery cookie, 'Lists', 'GetListItems', siteUrl, query, (error, data) ->
if error
callback error
else
if data?.results.length
callback null, data.results[0]['$']
else
callback null, data?.results
exports.getPage = (siteUrl, cookie, listId, itemId, callback) ->
log.info "Attempting a fetch for page id #{itemId} from list id #{listId} from the site #{siteUrl}."
query =
"<listName>#{listId}</listName>
#{BASE_CAML_QUERY}
<query>
<Query>
<Where>
<Eq>
<FieldRef Name=\'ID\' />
<Value Type=\'Integer\'>#{itemId}</Value>
</Eq>
</Where>
</Query>
</query>
<viewFields>
<ViewFields>
<FieldRef Name='Title' />
<FieldRef Name='PublishingPageContent' />
</ViewFields>
</viewFields>"
postQuery cookie, 'Lists', 'GetListItems', siteUrl, query, (error, data) ->
if error
callback error
else
if data?.results.length
callback null, data.results[0]['$']
else
callback null, data?.results
exports.getListItems = (siteUrl, cookie, listId, callback) ->
query =
"<listName>#{listId}</listName>
#{BASE_CAML_QUERY}"
postQuery cookie, 'Lists', 'GetListItems', siteUrl, query, (error, data) ->
if error
callback error
else
callback null, data?.results
exports.getLists = (siteUrl, cookie, callback) ->
postQuery cookie, 'Lists', 'GetListCollection', siteUrl, '', (error, data) ->
if error
callback error
else
callback null, data?.results
exports.getSites = (siteUrl, cookie, callback) ->
postQuery cookie, 'Webs', 'GetWebCollection', siteUrl, '', (error, data) ->
if error
callback error
else
callback null, data?.results
exports.getAttachments = (siteUrl, cookie, listId, itemId, callback) ->
query = "<strListName>#{listId}</strListName><strItemId>#{itemId}</strItemId>"
postQuery cookie, 'SiteData', 'GetAttachments', siteUrl, query, (error, data) ->
if error
callback error
else
callback null, data?.results
exports.getTermSets = (siteUrl, cookie, language, termStoreId, termSetId, callback) ->
query =
"<sspId>#{termStoreId}</sspId>
<lcid>#{language}</lcid>
<termSetId>#{termSetId}</termSetId>"
postTaxonomyQuery cookie, 'TaxonomyClientService', 'GetChildTermsInTermSet', siteUrl, query, (error, rootTerms) ->
if error
callback error
else
exports.getChildTerms siteUrl, cookie, language, termStoreId, termSetId, rootTerms, (error, results) ->
if error
callback error
else
root = {}
for result in results
label = result.label.replace(/&/g,'&');
cleanseTaxonomy result
root[label] = result
callback null, root
exports.getChildTerms = (siteUrl, cookie, language, termStoreId, termSetId, terms, callback) ->
async.each terms, (term, termCallback) ->
if not term.hasChildren
return termCallback null
query =
"<sspId>#{termStoreId}</sspId>
<lcid>#{language}</lcid>
<termId>#{term.id}</termId>
<termSetId>#{termSetId}</termSetId>"
postTaxonomyQuery cookie, 'TaxonomyClientService', 'GetChildTermsInTerm', siteUrl, query, (error, childTerms) ->
if error
callback error
else
exports.getChildTerms siteUrl, cookie, language, termStoreId, termSetId, childTerms, (error, results) ->
if error
termCallback error
else
for result in results
label = result.label.replace(/&/g,'&');
cleanseTaxonomy result
term[label] = result
termCallback null, term
, (error) ->
if error
callback error
else
callback null, terms
cleanseTaxonomy = (node) ->
delete node.label
delete node.id
delete node.hasChildren
postTaxonomyQuery = (cookie, service, method, siteUrl, query, callback) ->
soapActionHeader = 'http://schemas.microsoft.com/sharepoint/taxonomy/soap/' + method
methodNameSpace = 'http://schemas.microsoft.com/sharepoint/taxonomy/soap/'
webServiceUrl = (url.resolve(siteUrl, "_vti_bin/#{service}.asmx"))
envelope = '<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><' + method + ' xmlns=\"' + methodNameSpace + '\">' + query + '</' + method + '></soap:Body></soap:Envelope>'
jar = request.jar()
jar.add request.cookie cookie[0]
log.warn "requesting #{webServiceUrl}"
request.post webServiceUrl,
rejectUnauthorized: false
body: envelope
jar: jar
headers:
'Content-Type': 'text/xml'
'SOAPAction': soapActionHeader
, (error, response, body) ->
if error
callback new Error 'Could not get taxonomies.'
else
parser = new Parser()
parser.parseString body
, (error, data) ->
if error
callback error
else
responseBody = data['soap:Envelope']["soap:Body"]
actualResponseBody = ''
if responseBody[0].GetChildTermsInTermSetResponse
actualResponseBody = responseBody[0].GetChildTermsInTermSetResponse[0].GetChildTermsInTermSetResult[0]
else if responseBody[0].GetChildTermsInTermResponse
actualResponseBody = responseBody[0].GetChildTermsInTermResponse[0].GetChildTermsInTermResult[0]
if actualResponseBody
parser = new Parser()
parser.parseString actualResponseBody
, (error, data) ->
if error
callback error
else
result = _.map data.TermStore.T, (term) ->
hasChildren = term['TMS'][0]['TM'][0]['$']['a69']
termId = term['$']['a9']
label = term['LS'][0]['TL'][0]['$']['a32']
return id: termId, label: label, hasChildren: hasChildren
callback null, result
else
callback
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment