pyu-activesp 0.0.4.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,107 @@
1
+ # Copyright (c) 2010 XAOP bvba
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person
4
+ # obtaining a copy of this software and associated documentation
5
+ # files (the "Software"), to deal in the Software without
6
+ # restriction, including without limitation the rights to use,
7
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the
9
+ # Software is furnished to do so, subject to the following
10
+ # conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ #
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
+ # OTHER DEALINGS IN THE SOFTWARE.
25
+
26
+ module ActiveSP
27
+
28
+ class Group < Base
29
+
30
+ extend Caching
31
+ extend PersistentCaching
32
+ include Util
33
+ include InSite
34
+
35
+ persistent { |site, name, *a| [site.connection, [:group, name]] }
36
+ # @private
37
+ def initialize(site, name)
38
+ @site, @name = site, name
39
+ end
40
+
41
+ # See {Base#key}
42
+ # @return [String]
43
+ def key
44
+ encode_key("G", [@name])
45
+ end
46
+
47
+ # Returns the list of users in this group
48
+ # @return [User]
49
+ def users
50
+ call("UserGroup", "get_user_collection_from_group", "groupName" => @name).xpath("//spdir:User", NS).map do |row|
51
+ attributes = clean_attributes(row.attributes)
52
+ User.new(@site, attributes["LoginName"])
53
+ end
54
+ end
55
+ cache :users, :dup => :always
56
+
57
+ # Returns false. The same method is present on {Role} where it returns true. Roles and groups can generally be
58
+ # duck-typed, and this method is there for the rare case where you do need to make the distinction
59
+ # @return [Boolean]
60
+ def is_role?
61
+ false
62
+ end
63
+
64
+ # See {Base#save}
65
+ # @return [void]
66
+ def save
67
+ p untype_cast_attributes(@site, nil, internal_attribute_types, changed_attributes)
68
+ end
69
+
70
+ # @private
71
+ def to_s
72
+ "#<ActiveSP::Group name=#{@name}>"
73
+ end
74
+
75
+ # @private
76
+ alias inspect to_s
77
+
78
+ private
79
+
80
+ def data
81
+ call("UserGroup", "get_group_info", "groupName" => @name).xpath("//spdir:Group", NS).first
82
+ end
83
+ cache :data
84
+
85
+ def attributes_before_type_cast
86
+ clean_attributes(data.attributes)
87
+ end
88
+ cache :attributes_before_type_cast
89
+
90
+ def original_attributes
91
+ type_cast_attributes(@site, nil, internal_attribute_types, attributes_before_type_cast)
92
+ end
93
+ cache :original_attributes
94
+
95
+ def internal_attribute_types
96
+ @@internal_attribute_types ||= {
97
+ "Description" => GhostField.new("Description", "Text", false, true),
98
+ "ID" => GhostField.new("ID", "Text", false, true),
99
+ "Name" => GhostField.new("Name", "Text", false, true),
100
+ "OwnerID" => GhostField.new("OsnerID", "Integer", false, true),
101
+ "OwnerIsUser" => GhostField.new("OwnerIsUser", "Bool", false, true)
102
+ }
103
+ end
104
+
105
+ end
106
+
107
+ end
@@ -0,0 +1,338 @@
1
+ # Copyright (c) 2010 XAOP bvba
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person
4
+ # obtaining a copy of this software and associated documentation
5
+ # files (the "Software"), to deal in the Software without
6
+ # restriction, including without limitation the rights to use,
7
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the
9
+ # Software is furnished to do so, subject to the following
10
+ # conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ #
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
+ # OTHER DEALINGS IN THE SOFTWARE.
25
+
26
+ module ActiveSP
27
+
28
+ class Item < Base
29
+
30
+ include InSite
31
+ extend Caching
32
+ include Util
33
+
34
+ # Returns the list in which the item is located
35
+ # @return [List]
36
+ attr_reader :list
37
+
38
+ # @private
39
+ def initialize(list, id, folder = :unset, uid = nil, url = nil, attributes_before_type_cast = nil)
40
+ @list, @id = list, id
41
+ @folder = folder if folder != :unset # We have to allow for nil
42
+ @uid = uid if uid
43
+ @site = list.site
44
+ @url = url if url
45
+ @attributes_before_type_cast = attributes_before_type_cast if attributes_before_type_cast
46
+ end
47
+
48
+ def ID
49
+ @id
50
+ end
51
+
52
+ def is_folder?
53
+ false
54
+ end
55
+
56
+ # Returns the folder, if any, that this item is located in.
57
+ # @return [Folder, nil]
58
+ def folder
59
+ query = Builder::XmlMarkup.new.Query do |xml|
60
+ xml.Where do |xml|
61
+ xml.Eq do |xml|
62
+ xml.FieldRef(:Name => "FileRef")
63
+ xml.Value(::File.dirname(url).sub(/\A\//, ""), :Type => "Text")
64
+ end
65
+ xml.Eq do |xml|
66
+ xml.FieldRef(:Name => "FSObjType")
67
+ xml.Value(1, :Type => "Text")
68
+ end
69
+ end
70
+ end
71
+ @list.items(:folder => :all, :query => query).first
72
+ end
73
+ cache :folder
74
+
75
+ # Returns the parent of this item.
76
+ # @return [Folder, List]
77
+ def parent
78
+ folder || @list
79
+ end
80
+
81
+ # @private
82
+ def id
83
+ uid
84
+ end
85
+
86
+ # @private
87
+ def uid
88
+ attributes["UniqueID"]
89
+ end
90
+ cache :uid
91
+
92
+ # The URL of this item
93
+ # @return [String]
94
+ def url
95
+ # URL(@list.url).join(attributes["ServerUrl"]).to_s
96
+ attributes["ServerUrl"]
97
+ end
98
+ cache :url
99
+
100
+ def absolute_url
101
+ URL(@list.url).join(attributes["ServerUrl"]).to_s
102
+ end
103
+ cache :absolute_url
104
+
105
+ # See {Base#key}
106
+ # @return [String]
107
+ def key
108
+ encode_key("I", [@list.key, @id])
109
+ end
110
+
111
+ # Returns a list of the URLs of the attachments of this item. Note that for items in a document
112
+ # library, this returns an empty list
113
+ # @return [Array<String>]
114
+ def attachment_urls
115
+ @list.when_list do
116
+ result = call("Lists", "get_attachment_collection", "listName" => @list.id, "listItemID" => @id)
117
+ return result.xpath("//sp:Attachment", NS).map { |att| att.text }
118
+ end
119
+ @list.when_document_library { raise TypeError, "a document library does not support attachments" }
120
+ @list.raise_on_unknown_type
121
+ end
122
+ cache :attachment_urls, :dup => :always
123
+
124
+ # Yields each attachment as a ActiveSP::File object.
125
+ #
126
+ def each_attachment
127
+ attachment_urls.each { |url| yield ActiveSP::File.new(self, url, true) }
128
+ end
129
+
130
+ def add_attachment(parameters = {})
131
+ @list.when_list do
132
+ parameters = parameters.dup
133
+ content = parameters.delete(:content) or raise ArgumentError, "Specify the content in the :content parameter"
134
+ file_name = parameters.delete(:file_name) or raise ArgumentError, "Specify the file name in the :file_name parameter"
135
+ result = call("Lists", "add_attachment", "listName" => @list.ID, "listItemID" => self.ID, "fileName" => file_name, "attachment" => Base64.encode64(content.to_s))
136
+ add_result = result.xpath("//sp:AddAttachmentResult", NS).first
137
+ if add_result
138
+ clear_cache_for(:attachment_urls)
139
+ return ActiveSP::File.new(self, add_result.text, true)
140
+ else
141
+ raise "cannot add attachment"
142
+ end
143
+ end
144
+ @list.when_document_library { raise TypeError, "a document library does not support attachments" }
145
+ @list.raise_on_unknown_type
146
+ end
147
+
148
+ association :attachments do
149
+ def create(parameters = {})
150
+ @object.add_attachment(parameters)
151
+ end
152
+ end
153
+
154
+ def content
155
+ @list.when_list { raise TypeError, "a list has attachments" }
156
+ @list.when_document_library { return ActiveSP::File.new(self, url, false) }
157
+ @list.raise_on_unknown_type
158
+ end
159
+
160
+ def content=(data)
161
+ @list.when_list { raise TypeError, "a list has attachments" }
162
+ @list.when_document_library { @list.create_document(:overwrite => true, :content => data, "FileLeafRef" => original_attributes["FileLeafRef"]) }
163
+ @list.raise_on_unknown_type
164
+ end
165
+
166
+ # Returns a list of the content URLs for this item. For items in document libraries, this
167
+ # returns the url, for other items this returns the attachments. These URLs can be used
168
+ # to download all contents. See {Connection#fetch}
169
+ # @return [Array<String>]
170
+ def content_urls
171
+ @list.when_list { return attachment_urls }
172
+ @list.when_document_library { return is_folder? ? [] : [url] }
173
+ @list.raise_on_unknown_type
174
+ end
175
+ cache :content_urls, :dup => :always
176
+
177
+ # Returns the content type of this item
178
+ # @return [ContentType]
179
+ def content_type
180
+ ContentType.new(@site, @list, attributes["ContentTypeId"])
181
+ end
182
+ cache :content_type
183
+
184
+ # def versions
185
+ # call("Versions", "get_versions", "fileName" => attributes["ServerUrl"])
186
+ # end
187
+
188
+ # See {Base#save}
189
+ # @return [self]
190
+ def save
191
+ update_attributes_internal(untype_cast_attributes(@site, nil, internal_attribute_types, changed_attributes))
192
+ self
193
+ end
194
+
195
+ def check_out
196
+ @list.when_list { raise TypeError, "cannot check out list items; they would disappear" }
197
+ @list.raise_on_unknown_type
198
+ result = call("Lists", "check_out_file", "pageUrl" => absolute_url, "checkoutToLocal" => false)
199
+ checkout_result = result.xpath("//sp:CheckOutFileResult", NS).first.text
200
+ if checkout_result == "true"
201
+ self
202
+ else
203
+ raise "cannot check out this item"
204
+ end
205
+ end
206
+
207
+ def check_in(options = {})
208
+ options = options.dup
209
+ type = options.delete(:type) or raise ArgumentError, ":type parameter not specified"
210
+ comment = options.delete(:comment)
211
+ options.empty? or raise ArgumentError, "unsupported options #{options.keys.map { |k| k.inspect }.join(", ")}"
212
+ @list.when_list { raise TypeError, "cannot check in list items because you can't check them out" }
213
+ @list.raise_on_unknown_type
214
+ if checkin_type = { :minor => 0, :major => 1, :overwrite => 2 }[type]
215
+ if type == :minor && !@list.attribute("EnableMinorVersion")
216
+ raise TypeError, "this list does not support minor versions"
217
+ end
218
+ result = call("Lists", "check_in_file", "pageUrl" => absolute_url, "comment" => comment, "CheckinType" => checkin_type)
219
+ checkin_result = result.xpath("//sp:CheckInFileResult", NS).first.text
220
+ if checkin_result == "true"
221
+ self
222
+ else
223
+ raise "cannot check in this item"
224
+ end
225
+ else
226
+ raise ArgumentError, "invalid checkin type #{type.inspect}, valid values are :minor, :major and :overwrite"
227
+ end
228
+ end
229
+
230
+ def cancel_checkout
231
+ @list.when_list { raise TypeError, "cannot undo check-out for list items because you can't check them out" }
232
+ @list.raise_on_unknown_type
233
+ result = call("Lists", "undo_check_out", "pageUrl" => absolute_url)
234
+ cancel_result = result.xpath("//sp:UndoCheckOutResult", NS).first.text
235
+ if cancel_result == "true"
236
+ self
237
+ else
238
+ raise "cannot cancel check-out for this item"
239
+ end
240
+ end
241
+
242
+ def update_attributes(attributes)
243
+ attributes.each do |k, v|
244
+ set_attribute(k, v)
245
+ end
246
+ save
247
+ end
248
+
249
+ def destroy
250
+ updates = Builder::XmlMarkup.new.Batch("OnError" => "Continue", "ListVersion" => 1) do |xml|
251
+ xml.Method("ID" => 1, "Cmd" => "Delete") do
252
+ xml.Field(self.ID, "Name" => "ID")
253
+ end
254
+ end
255
+ result = call("Lists", "update_list_items", "listName" => @list.id, "updates" => updates)
256
+ create_result = result.xpath("//sp:Result", NS).first
257
+ error_code = create_result.xpath("./sp:ErrorCode", NS).first.text.to_i(0)
258
+ if error_code == 0
259
+ @ID = nil
260
+ else
261
+ raise "cannot create item, error code = #{error_code}"
262
+ end
263
+ self
264
+ end
265
+
266
+ # @private
267
+ def to_s
268
+ "#<ActiveSP::Item url=#{url}>"
269
+ end
270
+
271
+ # @private
272
+ alias inspect to_s
273
+
274
+ def ==(object)
275
+ ::ActiveSP::List === object && self.ID == object.ID
276
+ end
277
+
278
+ private
279
+
280
+ def raw_attributes
281
+ query_options = Builder::XmlMarkup.new.QueryOptions do |xml|
282
+ xml.Folder
283
+ end
284
+ query = Builder::XmlMarkup.new.Query do |xml|
285
+ xml.Where do |xml|
286
+ xml.Eq do |xml|
287
+ xml.FieldRef(:Name => "ID")
288
+ xml.Value(@id, :Type => "Counter")
289
+ end
290
+ end
291
+ end
292
+ @list.__each_item(query_options, "query" => query) do |attributes|
293
+ return attributes
294
+ end
295
+ end
296
+ cache :raw_attributes
297
+
298
+ def attributes_before_type_cast
299
+ clean_item_attributes(raw_attributes)
300
+ end
301
+ cache :attributes_before_type_cast
302
+
303
+ def original_attributes
304
+ type_cast_attributes(@site, @list, @list.fields_by_name, attributes_before_type_cast)
305
+ end
306
+ cache :original_attributes
307
+
308
+ def internal_attribute_types
309
+ list.fields_by_name
310
+ end
311
+
312
+ def update_attributes_internal(attributes)
313
+ attributes = attributes.dup
314
+ if file_leaf_ref = attributes.delete("FileLeafRef")
315
+ base_name = ::File.basename(file_leaf_ref, ".*")
316
+ end
317
+ updates = Builder::XmlMarkup.new.Batch("OnError" => "Continue", "ListVersion" => 1) do |xml|
318
+ xml.Method("ID" => 1, "Cmd" => "Update") do
319
+ xml.Field(self.ID, "Name" => "ID")
320
+ construct_xml_for_update_list_items(xml, @list.fields_by_name, attributes)
321
+ xml.Field(base_name, "Name" => "BaseName") if base_name
322
+ end
323
+ end
324
+ result = call("Lists", "update_list_items", "listName" => @list.id, "updates" => updates)
325
+ create_result = result.xpath("//sp:Result", NS).first
326
+ error_code = create_result.xpath("./sp:ErrorCode", NS).first.text.to_i(0)
327
+ if error_code == 0
328
+ row = result.xpath("//z:row", NS).first
329
+ @attributes_before_type_cast = clean_item_attributes(row.attributes)
330
+ reload
331
+ else
332
+ raise "cannot create item, error code = #{error_code}"
333
+ end
334
+ end
335
+
336
+ end
337
+
338
+ end