Class: Viewpoint::SPWS::Websvc::Lists

Inherits:
Object
  • Object
show all
Includes:
WebServiceBase
Defined in:
lib/viewpoint/spws/websvc/lists.rb

Overview

This class represents the Sharepoint Lists Web Service.

Constant Summary

Constants included from WebServiceBase

WebServiceBase::NAMESPACES

Constants included from Viewpoint::SPWS

VERSION

Instance Attribute Summary

Attributes included from WebServiceBase

#spcon

Attributes included from Viewpoint::SPWS

#logger

Instance Method Summary collapse

Methods included from Viewpoint::SPWS

root_logger, set_log_level

Constructor Details

#initialize(spcon) ⇒ Lists

Returns a new instance of Lists.



24
25
26
27
28
# File 'lib/viewpoint/spws/websvc/lists.rb', line 24

def initialize(spcon)
  @default_ns  = 'http://schemas.microsoft.com/sharepoint/soap/'
  @ws_endpoint = '_vti_bin/Lists.asmx'
  super
end

Instance Method Details

#add_list(name, desc, templ_id) ⇒ Viewpoint::SPWS::List

Add a List to this site.

Parameters:

  • name (String)

    A name for the List

  • desc (String)

    A description of the List

  • templ_id (Integer)

    The template type for this List. See the Microsoft docs for additional information.

Returns:

  • (Viewpoint::SPWS::List)

    The new List object

See Also:



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/viewpoint/spws/websvc/lists.rb', line 37

def add_list(name, desc, templ_id)
  soapmsg = build_soap_envelope do |type, builder|
    if(type == :header)
    else
      builder.AddList {
        builder.parent.default_namespace = @default_ns
        builder.listName(name)
        builder.description(desc)
        builder.templateID(templ_id)
      }
    end
  end
  soaprsp = Nokogiri::XML(send_soap_request(soapmsg.doc.to_xml))
  return soaprsp
  ns = {"xmlns"=> @default_ns}
  new_list(soaprsp.xpath('//xmlns:AddListResult/xmlns:List', ns).first)
end

#add_list_from_feature(name, desc, feature_id, templ_id) ⇒ Viewpoint::SPWS::List

Add a List to this site from a feature ID.

Parameters:

  • name (String)

    A name for the List

  • desc (String)

    A description of the List

  • feature_id (String)

    The GUID of the feature ID.

  • templ_id (Integer)

    The template type for this List. See the Microsoft docs for additional information.

Returns:

  • (Viewpoint::SPWS::List)

    The new List object

See Also:



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/viewpoint/spws/websvc/lists.rb', line 63

def add_list_from_feature(name, desc, feature_id, templ_id)
  soapmsg = build_soap_envelope do |type, builder|
    if(type == :header)
    else
      builder.AddListFromFeature {
        builder.parent.default_namespace = @default_ns
        builder.listName(name)
        builder.description(desc)
        builder.featureID(feature_id)
        builder.templateID(templ_id)
      }
    end
  end
  soaprsp = Nokogiri::XML(send_soap_request(soapmsg.doc.to_xml))
  ns = {"xmlns"=> @default_ns}
  new_list(soaprsp.xpath('//xmlns:AddListResult/xmlns:List', ns).first)
end

#delete_list(name) ⇒ Object

TODO:

Work out the return value

Delete a list from this site.

Parameters:

  • name (String)

    Either the name or the GUID of the list



84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/viewpoint/spws/websvc/lists.rb', line 84

def delete_list(name)
  soapmsg = build_soap_envelope do |type, builder|
    if(type == :header)
    else
      builder.DeleteList {
        builder.parent.default_namespace = @default_ns
        builder.listName(name)
      }
    end
  end
  soaprsp = Nokogiri::XML(send_soap_request(soapmsg.doc.to_xml))
  #ns = {"xmlns"=> @default_ns}
end

#get_file(file_ref) ⇒ String

Retrieve a file from Sharepoint. This is not a standard Web Service method, buth rather a convenience method that is part of ViewpointSPWS.

Examples:

resp = listws.get_file(listitem.file_ref)
File.open(listitem.file_name,'w+') do |f|
  f.write(resp)
end

Parameters:

  • file_ref (String)

    The fileref property from a ListItem object

Returns:

  • (String)

    A String representing the bytestream of a file. You should be able to write it out to a file with something like this:



426
427
428
429
430
431
# File 'lib/viewpoint/spws/websvc/lists.rb', line 426

def get_file(file_ref)
  p1 = Pathname.new @spcon.site_base.request_uri
  p2 = Pathname.new "/#{file_ref}"
  target = p2.relative_path_from p1
  @spcon.get(target.to_s)
end

#get_list(list) ⇒ Viewpoint::SPWS::List

Retrieve a specific Sharepoint List

Parameters:

  • list (String)

    title or the GUID for the list

Returns:

  • (Viewpoint::SPWS::List)

See Also:



148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/viewpoint/spws/websvc/lists.rb', line 148

def get_list(list)
  soapmsg = build_soap_envelope do |type, builder|
    if(type == :header)
    else
      builder.GetList {
        builder.parent.default_namespace = @default_ns
        builder.listName(list)
      }
    end
  end
  soaprsp = Nokogiri::XML(send_soap_request(soapmsg.doc.to_xml))
  ns = {"xmlns"=> @default_ns}
  new_list(soaprsp.xpath('//xmlns:GetListResult/xmlns:List', ns).first)
end

#get_list_collection(show_hidden = false) ⇒ Object

Returns all the lists for a Sharepoint site.

Parameters:

  • show_hidden (Boolean) (defaults to: false)

    Whether or not to show hidden lists. Default = false

See Also:



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/viewpoint/spws/websvc/lists.rb', line 121

def get_list_collection(show_hidden = false)
  soapmsg = build_soap_envelope do |type, builder|
    if(type == :header)
    else
      builder.GetListCollection {
        builder.parent.default_namespace = @default_ns
      }
    end
  end
  soaprsp = Nokogiri::XML(send_soap_request(soapmsg.doc.to_xml))
  ns = {"xmlns"=> @default_ns}
  lists = []
  soaprsp.xpath('//xmlns:Lists/xmlns:List', ns).each do |l|
    lists << new_list(l)
  end
  if(!show_hidden)
    lists.reject! do |i|
      i.hidden?
    end
  end
  lists
end

#get_list_content_types(name, content_type_id = nil) ⇒ Object

TODO:

Work out the return value

Returns a collection of content type definition schemas

Parameters:

  • name (String)

    Either the name or the GUID of the list

  • content_type_id (String) (defaults to: nil)

    (nil) The content type ID. I’m still not clear on what specifying this value does. In my limitted testing it does not seem to have an effect on the output.

See Also:



104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/viewpoint/spws/websvc/lists.rb', line 104

def get_list_content_types(name, content_type_id = nil)
  soapmsg = build_soap_envelope do |type, builder|
    if(type == :header)
    else
      builder.GetListContentTypes {
        builder.parent.default_namespace = @default_ns
        builder.listName(name)
        builder.contentTypeId(content_type_id)
      }
    end
  end
  soaprsp = Nokogiri::XML(send_soap_request(soapmsg.doc.to_xml))
end

#get_list_item_changes_since_token(list, token = nil, opts = {}) {|builder| ... } ⇒ Hash

Get List Items changes from a given change token

Examples:

The following example shows how to prepare a CAML Query with a block. It filters for all objects of ObjectType ‘0’ = Files

items = listws.get_list_items('Shared Documents',:recursive => true) do |b|
  b.Query {
    b.Where {
      b.Eq {
        b.FieldRef(:Name => 'FSObjType')
        b.Value(0, :Type => 'Integer')
      }
    }
  }
end

Parameters:

  • list (String)

    title or the GUID for the list

  • token (String) (defaults to: nil)

    (nil) The change token or nil to get all

  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :view_name (String) — default: ''

    GUID for the view surrounded by curly braces If nothing is passed it used the default of the View

  • :row_limit (String) — default: ''

    A String representing the number of rows to return.

  • :recursive (Boolean) — default: true

    If true look in subfolders as well as root

  • :date_in_utc (Boolean) — default: true

    If true return dates in UTC

  • :folder (String) — default: ''

    Filter document library items for items in the specified folder

Yields:

  • (builder)

    Yields a Builder object that can be used to build a CAML Query. See the example on how to use it.

Yield Parameters:

  • builder (Nokogiro::XML::Builder)

    The builder object used to create the Query

Returns:

  • (Hash)

    returns a Hash with the keys :last_change_token, which contains a String that holds a change token that may be used in subsequent calls, and :items which holds an Array of ListItem objects.

See Also:



277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/viewpoint/spws/websvc/lists.rb', line 277

def get_list_item_changes_since_token(list, token=nil, opts = {})
  # Set Default values
  opts[:recursive] = true unless opts.has_key?(:recursive)
  opts[:view_name] = '' unless opts.has_key?(:view_name)
  opts[:row_limit] = '' unless opts.has_key?(:row_limit)
  opts[:date_in_utc] = true unless opts.has_key?(:date_in_utc)
  opts[:folder] = '' unless opts.has_key?(:folder)

  soapmsg = build_soap_envelope do |type, builder|
    if(type == :header)
    else
      builder.GetListItemChangesSinceToken {
        builder.parent.default_namespace = @default_ns
        builder.listName(list)
        builder.viewName(opts[:view_name])
        builder.rowLimit(opts[:row_limit])

        if block_given?
          builder.query {
            builder.parent.default_namespace = ''
            yield builder
          }
        end

        builder.queryOptions {
          builder.QueryOptions {
            builder.parent.default_namespace = ''
            builder.Folder(opts[:folder])
            builder.ViewAttributes(:Scope => 'Recursive') if opts[:recursive]
            builder.DateInUtc('True') if opts[:date_in_utc]
            builder.IncludeAttachmentUrls('True')
          }
        }

        builder.changeToken(token)
        # @todo Is this worth supporting???
        #builder.contains()
      }
    end
  end
  soaprsp = Nokogiri::XML(send_soap_request(soapmsg.doc.to_xml))
  ns = {'xmlns:z' => "#RowsetSchema",
       'xmlns:rs' => "urn:schemas-microsoft-com:rowset",
       'xmlns'    => @default_ns,
  }
  items = []
  soaprsp.xpath('//rs:data/z:row', ns).each do |li|
    items << Types::ListItem.new(self, list, li)
  end
  changes = soaprsp.xpath('//xmlns:GetListItemChangesSinceTokenResult/xmlns:listitems/xmlns:Changes',ns).first
  {:last_change_token => changes['LastChangeToken'], :items => items}
end

#get_list_items(list, opts = {}) {|builder| ... } ⇒ Object

Get List Items based on certain parameters

Examples:

The following example shows how to prepare a CAML Query with a block. It filters for all objects of ObjectType ‘0’ = Files

items = listws.get_list_items('Shared Documents',:recursive => true) do |b|
  b.Query {
    b.Where {
      b.Eq {
        b.FieldRef(:Name => 'FSObjType')
        b.Value(0, :Type => 'Integer')
      }
    }
  }
end

Parameters:

  • list (String)

    title or the GUID for the list

  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :view_name (String) — default: ''

    GUID for the view surrounded by curly braces If nothing is passed it used the default of the View

  • :row_limit (String) — default: ''

    A String representing the number of rows to return.

  • :recursive (Boolean) — default: true

    If true look in subfolders as well as root

  • :date_in_utc (Boolean) — default: true

    If true return dates in UTC

  • :folder (String) — default: ''

    Filter document library items for items in the specified folder

  • :view_fields (Array<String,Symbol>)

    and array of String or Symbols that represent which fields to return with the query.

Yields:

  • (builder)

    Yields a Builder object that can be used to build a CAML Query. See the example on how to use it.

Yield Parameters:

  • builder (Nokogiro::XML::Builder)

    The builder object used to create the Query

See Also:



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/viewpoint/spws/websvc/lists.rb', line 190

def get_list_items(list, opts = {})
  # Set Default values
  opts[:recursive] = true unless opts.has_key?(:recursive)
  opts[:view_name] = '' unless opts.has_key?(:view_name)
  opts[:row_limit] = '' unless opts.has_key?(:row_limit)
  opts[:date_in_utc] = true unless opts.has_key?(:date_in_utc)
  opts[:folder] = '' unless opts.has_key?(:folder)

  soapmsg = build_soap_envelope do |type, builder|
    if(type == :header)
    else
      builder.GetListItems {
        builder.parent.default_namespace = @default_ns
        builder.listName(list)
        builder.viewName(opts[:view_name])
        builder.rowLimit(opts[:row_limit])

        if block_given?
          builder.query {
            builder.parent.default_namespace = ''
            yield builder
          }
        end

        if(opts[:view_fields])
          builder.viewFields {
            builder.ViewFields {
              builder.parent.default_namespace = ''
              opts[:view_fields].each do |f|
                builder.FieldRef(:Name => f.to_s.camel_case)
              end
            }
          }
        end

        builder.queryOptions {
          builder.QueryOptions {
            builder.parent.default_namespace = ''
            builder.Folder(opts[:folder])
            builder.ViewAttributes(:Scope => 'Recursive') if opts[:recursive]
            builder.DateInUtc('True') if opts[:date_in_utc]
            builder.IncludeAttachmentUrls('True')
          }
        }
        # @todo Is this worth supporting???
        #builder.webID(parms[:web_id])
      }
    end
  end
  soaprsp = Nokogiri::XML(send_soap_request(soapmsg.doc.to_xml))
  ns = {'xmlns:z' => "#RowsetSchema"}
  items = []
  soaprsp.xpath('//z:row', ns).each do |li|
    items << Types::ListItem.new(self, list, li)
  end
  items
end

#update_list_items(list, updates = {}) {|builder| ... } ⇒ Object

Adds, deletes, or updates the specified items in a list

Examples:

The following example shows how to prepare a Batch request with a block. It updates a Task item to Status ‘Completed’.

item_id = 95
listws.update_list_items('Task List') do |b|
  b.Method(:ID => 1, :Cmd => 'Update') do
    b.Field(item_id,:Name => 'ID')
    b.Field("Completed", :Name => 'Status')
  end
end

How to Add and Delete via passed parameters

updates = [
  {:id => "New", :command => "New", :title => "Test Task"},
  {:id => 'New',:command => 'New', :title => 'Test Task 2'},
  {:id => 98,:command => 'Delete'},
]
resp = listws.update_list_items('Task List',:item_updates => updates)

Parameters:

  • list (String)

    title or the GUID for the list

  • updates (Hash) (defaults to: {})

Options Hash (updates):

  • :view_name (String) — default: ''

    GUID for the view without curly braces If nothing is passed it used the default of the View

  • :on_error (String) — default: 'Continue'

    What to do if an error ocurrs. It must be either ‘Return’ or ‘Contiue’

  • :list_version (String) — default: ''

    The version of the list we wish to modify

  • :version (String) — default: ''

    The version of Sharepoint we are acting on

  • :item_updates (Array<Hash>)

    An array of Hashes that specify what to update. Each hash needs an :id key to specify the item ID and a :command key that specifies “New”, “Update” or “Delete”. All other keys are field names in either CamelCase or ruby_case with values to set them to. =>

    [{:id => 95, :command => 'Update', :status => 'Completed',
    => 107, :command => 'Update', :title => "Test"]}
    

Yields:

Yield Parameters:

  • builder (Nokogiro::XML::Builder)

    The builder object used to create the Batch

See Also:



367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
# File 'lib/viewpoint/spws/websvc/lists.rb', line 367

def update_list_items(list, updates = {})
  # Set Default values
  updates[:view_name] = '' unless updates.has_key?(:view_name)
  updates[:on_error] = 'Continue' unless updates.has_key?(:on_error)
  updates[:list_version] = '' unless updates.has_key?(:list_version)
  updates[:version] = '' unless updates.has_key?(:version)

  soapmsg = build_soap_envelope do |type, builder|
    if(type == :header)
    else
      builder.UpdateListItems {
        builder.parent.default_namespace = @default_ns
        builder.listName(list)

        builder.updates {
          builder.Batch(:ViewName => updates[:view_name],
                        :OnError  => updates[:on_error],
                        :ListVersion  => updates[:list_version],
                        :Version  => updates[:version]) {
            builder.parent.default_namespace = ''

            # First format passed item_updates
            updates[:item_updates] && updates[:item_updates].each_with_index do |iu,idx|
              iu = iu.clone
              builder.Method(:ID => "VP_IDX#{idx}", :Cmd => iu.delete(:command)) do
                builder.Field(iu.delete(:id), :Name => 'ID')
                iu.each_pair do |k,v|
                  builder.Field(v, :Name => k.to_s.camel_case)
                end
              end
            end

            # Now include block-passed updates
            if block_given?
              yield builder
            end
          }
        }
      }
    end
  end

  soaprsp = Nokogiri::XML(send_soap_request(soapmsg.doc.to_xml))
  parse_update_list_items(list, soaprsp)
end