viewpoint-spws 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,107 @@
1
+ =begin
2
+ This file is part of ViewpointSPWS; the Ruby library for Microsoft Sharepoint Web Services.
3
+
4
+ Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ # This class is the glue between the Models and the Web Service.
20
+ class Viewpoint::SPWSClient
21
+ include Viewpoint::SPWS
22
+
23
+ # Initialize the SPWSClient instance.
24
+ # @param [String] endpoint The SPWS endpoint we will be connecting to
25
+ # @param [String] user The user to authenticate as. If you are using
26
+ # NTLM or Negotiate authentication you do not need to pass this parameter.
27
+ # @param [String] pass The user password. If you are using NTLM or
28
+ # Negotiate authentication you do not need to pass this parameter.
29
+ def initialize(endpoint, user = nil, pass = nil)
30
+ @con = Connection.new(endpoint)
31
+ @con.set_auth(user,pass) if(user && pass)
32
+ end
33
+
34
+ def copy_ws
35
+ @copyws ||= Websvc::Copy.new(@con)
36
+ end
37
+
38
+ def lists_ws
39
+ @listsws ||= Websvc::Lists.new(@con)
40
+ end
41
+
42
+ def usergroup_ws
43
+ @usergroupws ||= Websvc::UserGroup.new(@con)
44
+ end
45
+
46
+
47
+ # ========= List Accessor Proxy Methods =========
48
+
49
+ # Available list types that can be used for #add_list
50
+ LIST_TYPES = {
51
+ :custom_list => 100,
52
+ :document_library => 101,
53
+ :survey => 102,
54
+ :links => 103,
55
+ :announcements => 104,
56
+ :contacts => 105,
57
+ :events => 106,
58
+ :tasks => 107,
59
+ :discussion_board => 108,
60
+ :picture_library => 109,
61
+ :datasources => 110,
62
+ :form_library => 115,
63
+ :issues => 1100,
64
+ :custom_list_for_datasheet => 120,
65
+ }
66
+
67
+ # Retrieve all of the viewable lists for this site.
68
+ def get_lists
69
+ lists_ws.get_list_collection
70
+ end
71
+
72
+ # Retrieve a List object
73
+ # @param [String] list title or the GUID for the list
74
+ def get_list(list)
75
+ lists_ws.get_list(list)
76
+ end
77
+
78
+ # Add a List to this site
79
+ # @param [String] name A name for the List
80
+ # @param [String] desc A description of the List
81
+ # @param [Integer] list_type The list template id. Use the LIST_TYPES Hash.
82
+ def add_list(name, desc, list_type)
83
+ lists_ws.add_list(name, desc, list_type)
84
+ end
85
+
86
+ # Delete a list from this site.
87
+ # @param [String] list title or the GUID for the list
88
+ def delete_list(list)
89
+ lists_ws.delete_list(list)
90
+ end
91
+
92
+ # ========= UserGroup Accessor Proxy Methods =========
93
+
94
+ # Retrieve a user by e-mail
95
+ # @param [String] user either in e-mail form or DOMAIN\login form. If you
96
+ # specify an e-mail there is an additional web service call that needs
97
+ # to be made so if you're worried about performance use the DOMAIN\login
98
+ # form.
99
+ # @return [Viewpoint::SPWS::Types::User]
100
+ def get_user(user)
101
+ if user =~ /@/
102
+ ulh = usergroup_ws.get_user_login_from_email [user]
103
+ user = ulh[user]
104
+ end
105
+ usergroup_ws.get_user_info user
106
+ end
107
+ end
@@ -0,0 +1,27 @@
1
+ =begin
2
+ This file is part of ViewpointSPWS; the Ruby library for Microsoft Sharepoint Web Services.
3
+
4
+ Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ module Viewpoint::SPWS
20
+ module Types
21
+ PRIORITY = {:high => '(1) High', :normal => '(2) Normal', :low => '(3) Low'}.freeze
22
+
23
+ STATUS = {:not_started => 'Not Started', :in_progress => 'In Progress',
24
+ :completed => 'Completed', :deferred => 'Deferred',
25
+ :waiting => 'Waiting on someone else'}.freeze
26
+ end
27
+ end
@@ -0,0 +1,41 @@
1
+ =begin
2
+ This file is part of ViewpointSPWS; the Ruby library for Microsoft Sharepoint Web Services.
3
+
4
+ Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ # This class represents a Sharepoint List returned from the Lists Web Service with a
20
+ # ServerTemplate id of 101 (DocumentLibrary).
21
+ # @see http://msdn.microsoft.com/en-us/library/ms774810(v=office.12).aspx
22
+ class Viewpoint::SPWS::Types::DocumentLibrary < Viewpoint::SPWS::Types::List
23
+ include Viewpoint::SPWS::Types
24
+
25
+ # @param [Viewpoint::SPWS::Websvc::List] ws The webservice instance this List spawned from
26
+ # @param [Nokogiri::XML::Element] xml the List element we are building from
27
+ def initialize(ws, xml)
28
+ @copy_ws = Viewpoint::SPWS::Websvc::Copy.new(ws.spcon)
29
+ super
30
+ end
31
+
32
+ # Add a Document to this List
33
+ # @param [Hash] opts parameters for this Document
34
+ # @option opts [String] :file Path to the file to upload
35
+ # @return [Viewpoint::SPWS::Types::ListItem] The newly added Task
36
+ def add_file!(opts)
37
+ raise "Valid file argument required" unless(opts[:file] && File.exists?(opts[:file]))
38
+ fqpath = "#{self.path}/#{File.basename(opts[:file])}"
39
+ @copy_ws.copy_into_items(opts[:file], [fqpath])
40
+ end
41
+ end
@@ -0,0 +1,107 @@
1
+ =begin
2
+ This file is part of ViewpointSPWS; the Ruby library for Microsoft Sharepoint Web Services.
3
+
4
+ Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ # This class represents a Sharepoint List returned from the Lists Web Service
20
+ # @see http://msdn.microsoft.com/en-us/library/ms774810(v=office.12).aspx
21
+ class Viewpoint::SPWS::Types::List
22
+ include Viewpoint::SPWS::Types
23
+
24
+ attr_reader :guid, :title, :description, :created, :modified, :server_template,
25
+ :feature_id, :root_folder
26
+
27
+ # @param [Viewpoint::SPWS::Websvc::List] ws The webservice instance this List spawned from
28
+ # @param [Nokogiri::XML::Element] xml the List element we are building from
29
+ def initialize(ws, xml)
30
+ @ws = ws
31
+ @guid = xml['ID']
32
+ @title = xml['Title']
33
+ @description = xml['Description']
34
+ @hidden = (xml['Hidden'] == 'True')
35
+ @created = DateTime.parse(xml['Created'])
36
+ @modified = DateTime.parse(xml['Modified'])
37
+ @last_deleted = DateTime.parse(xml['LastDeleted'])
38
+ @item_count = xml['ItemCount']
39
+ @server_template= xml['ServerTemplate'].to_i
40
+ @feature_id = xml['FeatureId']
41
+ @root_folder = xml['RootFolder']
42
+ #@xmldoc = xml
43
+ @list_path = nil
44
+ end
45
+
46
+ # Return the full-qualified path of this List
47
+ def path
48
+ return @list_path if @list_path
49
+ site = @ws.spcon.site_base
50
+ @list_path = "#{site.scheme}://#{site.host}"
51
+ @list_path << ":#{site.port}" unless(site.port == 80 || site.port == 443)
52
+ @list_path << @root_folder
53
+ end
54
+
55
+ # Add a ListItem
56
+ # @param [Hash] opts options for List creation.
57
+ def add_item!(opts)
58
+ op = { :command => 'New', :id => 'New' }
59
+ opts.keys.each do |k|
60
+ case k
61
+ when :priority
62
+ op[k] = PRIORITY[opts[:priority]]
63
+ when :status
64
+ op[k] = STATUS[opts[:status]]
65
+ when :percent_complete
66
+ op[k] = opts[k] * 0.01
67
+ else
68
+ op[k] = opts[k]
69
+ end
70
+ end
71
+
72
+ resp = @ws.update_list_items(@guid, :item_updates => [op])
73
+ resp[:new].first
74
+ end
75
+
76
+ # Delete this List
77
+ def delete!
78
+ @ws.delete_list(@guid)
79
+ end
80
+
81
+ # Return the items in this List
82
+ def items
83
+ @ws.get_list_items(@guid)
84
+ end
85
+
86
+ # @param [String] item_id The item id for the item you want to retrieve
87
+ def get_item(item_id)
88
+ addl_fields = %w{LinkTitle Body AssignedTo Status Priority DueDate PercentComplete}
89
+
90
+ i = @ws.get_list_items(@guid, :recursive => true, :view_fields => addl_fields) do |b|
91
+ b.Query {
92
+ b.Where {
93
+ b.Eq {
94
+ b.FieldRef(:Name => 'ID')
95
+ b.Value(item_id, :Type => 'Counter')
96
+ }
97
+ }
98
+ }
99
+ end
100
+ raise "Returned more than one item for #get_item" if(i.length > 1)
101
+ i.first
102
+ end
103
+
104
+ def hidden?
105
+ @hidden
106
+ end
107
+ end
@@ -0,0 +1,248 @@
1
+ =begin
2
+ This file is part of ViewpointSPWS; the Ruby library for Microsoft Sharepoint Web Services.
3
+
4
+ Copyright © 2011 Dan Wanek <dan.wanek@gmail.com>
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ # This class represents a Sharepoint ListItem returned from the Lists Web Service
20
+ # @see
21
+ class Viewpoint::SPWS::Types::ListItem
22
+ include Viewpoint::SPWS::Types
23
+
24
+ attr_reader :id, :body, :file_name, :file_ref, :editor, :guid, :object_type
25
+ attr_reader :created_date, :modified_date, :due_date
26
+ attr_reader :title, :link_title, :status, :priority, :percent_complete
27
+
28
+ # @param [Viewpoint::SPWS::Websvc::List] ws The webservice instance this ListItem spawned from
29
+ # @param [String] list_id The list id that this item belongs to
30
+ # @param [Nokogiri::XML::Element] xml the List element we are building from
31
+ def initialize(ws, list_id, xml)
32
+ @ws = ws
33
+ @list_id = list_id
34
+ @pending_updates = [] # a place to store updates before #save! is called
35
+ @update_keys = {} # the variables to update after #save!
36
+ parse_xml_fields(xml)
37
+ end
38
+
39
+ # Save any pending changes
40
+ def save!
41
+ return true if @pending_updates.empty?
42
+ resp = @ws.update_list_items(@list_id, :item_updates => @pending_updates)
43
+ # @todo check for success before emptying Arry
44
+ update_local_vars resp[:update][0]
45
+ @pending_updates.clear
46
+ true
47
+ resp
48
+ end
49
+
50
+ # Pass a block of updates that will be committed in one transaction
51
+ # @example
52
+ # li.update! do |l|
53
+ # l.rename 'New Name'
54
+ # l.set_priority :low
55
+ # l.set_status :waiting
56
+ # end
57
+ def update!
58
+ yield self if block_given?
59
+ save!
60
+ end
61
+
62
+ # Delete this ListItem
63
+ def delete!
64
+ del = [{ :id => @id, :command => 'Delete',
65
+ :file_ref => full_file_ref }]
66
+ @ws.update_list_items(@list_id, :item_updates => del)
67
+ end
68
+
69
+
70
+ # Set a new title for this Item
71
+ # @param [String] title The new title
72
+ def rename(title)
73
+ raise "There is already a pending rename" if @update_keys[:@title]
74
+ upd = { :id => @id, :command => 'Update',
75
+ :title => title,
76
+ }
77
+ @pending_updates << upd
78
+ @update_keys[:@title] = 'ows_Title'
79
+ @update_keys[:@link_title] = 'ows_LinkTitle'
80
+ title
81
+ end
82
+
83
+ # Set a new title for this Item
84
+ # @see #rename
85
+ def rename!(title)
86
+ rename(title)
87
+ save!
88
+ end
89
+
90
+ # Set the priority of this Item
91
+ # @param [Symbol] priority The new priority. It must be one of these values:
92
+ # :high, :normal, :low
93
+ def set_priority(priority)
94
+ raise "Invalid priority it must be one of: #{PRIORITY.keys.join(', ')}" unless PRIORITY[priority]
95
+ raise "There is already a pending priority change" if @update_keys[:@priority]
96
+ upd = { :id => @id, :command => 'Update',
97
+ :priority => PRIORITY[priority],
98
+ }
99
+ @pending_updates << upd
100
+ @update_keys[:@priority] = 'ows_Priority'
101
+ priority
102
+ end
103
+
104
+ # Set the priority of this Item
105
+ # @see #set_priority
106
+ def set_priority!(priority)
107
+ set_priority priority
108
+ save!
109
+ end
110
+
111
+ # Set the status of this Item
112
+ # @param [Symbol] status The new status. It must be one of these values:
113
+ # :not_started, :in_progress, :completed, :deferred, :waiting
114
+ def set_status(status)
115
+ raise "Invalid status it must be one of: #{STATUS.keys.join(', ')}" unless STATUS[status]
116
+ raise "There is already a pending status change" if @update_keys[:@status]
117
+ upd = { :id => @id, :command => 'Update',
118
+ :status => STATUS[status],
119
+ }
120
+ @pending_updates << upd
121
+ @update_keys[:@status] = 'ows_Status'
122
+ status
123
+ end
124
+
125
+ # Set the status of this Item
126
+ # @see #set_status
127
+ def set_status!(status)
128
+ set_status(status)
129
+ save!
130
+ end
131
+
132
+ # Set the percentage complete of this item.
133
+ # @param [Fixnum] pct the percent complete of this item
134
+ def set_percent_complete(pct)
135
+ if(!(0..100).include?(pct))
136
+ raise "Invalid :percent_complete #{topts[:percent_complete]}"
137
+ end
138
+ raise "There is already a pending percent complete change" if @update_keys[:@percent_complete]
139
+
140
+ upd = { :id => @id, :command => 'Update',
141
+ :percent_complete => pct,
142
+ }
143
+ @pending_updates << upd
144
+ @update_keys[:@percent_complete] = 'ows_PercentComplete'
145
+ pct
146
+ end
147
+
148
+ # Set the percentage complete of this item.
149
+ # @see #set_percent_complete
150
+ def set_percent_complete!(pct)
151
+ set_percent_complete pct
152
+ save!
153
+ end
154
+
155
+ # Assign this item to a user
156
+ # @param [Viewpoint::SPWS::Types::User] user The user to assign this ListItem
157
+ # @todo should I return the String representation of the user or the Types::User?
158
+ def assign(user)
159
+ raise "There is already a pending assignment" if @update_keys[:@assigned_to]
160
+ upd = { :id => @id, :command => 'Update',
161
+ :AssignedTo => "#{user.id};##{user.login_name}",
162
+ }
163
+ @pending_updates << upd
164
+ @update_keys[:@assigned_to] = 'ows_AssignedTo'
165
+ user
166
+ end
167
+
168
+ # Assign this item to a user
169
+ # @see #assign
170
+ def assign!(user)
171
+ assign(user)
172
+ save!
173
+ end
174
+
175
+ private
176
+
177
+ # Return the full FileRef with the site URL attatched
178
+ def full_file_ref
179
+ uri = @ws.spcon.site_base
180
+ url = "#{uri.scheme}://#{uri.host}"
181
+ url << ":#{uri.port}" unless (uri.port == 80 || uri.port == 443)
182
+ url << "/#{@file_ref}"
183
+ end
184
+
185
+ # update the local variables after a #save!.
186
+ # Changed variables are tracked in @update_keys
187
+ # @param [Hash] resp The response Hash from a #save!
188
+ def update_local_vars(resp)
189
+ @update_keys.each_pair do |k,v|
190
+ set_field k, v, resp
191
+ end
192
+ @update_keys.clear
193
+ end
194
+
195
+ # Parse the fields out of the passed XML document.
196
+ # @param[Nokogiri::XML::Element] xml
197
+ def parse_xml_fields(xml)
198
+ @xmldoc = xml
199
+ set_field :@id, 'ows_ID'
200
+ set_field :@file_name, 'ows_LinkFilename'
201
+ set_field :@meta_info, 'ows_MetaInfo'
202
+ set_field :@link_title, 'ows_LinkTitle'
203
+ set_field :@body, 'ows_Body'
204
+ set_field :@title, 'ows_Title'
205
+ set_field :@status, 'ows_Status'
206
+ set_field :@priority, 'ows_Priority'
207
+ set_field :@percent_complete, 'ows_PercentComplete'
208
+ set_field :@due_date, 'ows_DueDate'
209
+ set_field :@assigned_to, 'ows_AssignedTo'
210
+ set_field :@file_ref, 'ows_FileRef'
211
+ set_field :@editor, 'ows_Editor'
212
+ set_field :@guid, 'ows_UniqueId'
213
+ set_field :@object_type, 'ows_FSObjType'
214
+ set_field :@created_date, 'ows_Created'
215
+ set_field :@modified_date, 'ows_Modified'
216
+ set_field :@created_date, 'ows_Created_x0020_Date' unless @created_date
217
+ set_field :@modified_date, 'ows_Last_x0020_Modified' unless @modified_date
218
+ @xmldoc = nil
219
+ end
220
+
221
+ # Parse a Sharepoint field or managed field
222
+ # @param [Symbol] vname The instance variable we will set the value to if it exists
223
+ # @param [String] fname The field name to check for
224
+ # @param [#[]] mapsrc A dictionary or Hash like item that contains variable data.
225
+ def set_field(vname, fname, mapsrc = @xmldoc)
226
+ newvar = nil
227
+ field = mapsrc[fname]
228
+ if field
229
+ if(field =~ /;#/)
230
+ newvar = mapsrc[fname].split(';#').last
231
+ else
232
+ newvar = field
233
+ end
234
+ newvar = transform(newvar)
235
+ end
236
+ instance_variable_set vname, newvar
237
+ end
238
+
239
+ # Run misc transforms on data
240
+ def transform(newvar)
241
+ case newvar
242
+ when /[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}/ # Transform DateTime
243
+ return DateTime.parse(newvar)
244
+ else
245
+ return newvar
246
+ end
247
+ end
248
+ end