activesp 0.0.7 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/activesp/caching.rb +14 -0
- data/lib/activesp/connection.rb +26 -0
- data/lib/activesp/content_type.rb +10 -5
- data/lib/activesp/file.rb +15 -0
- data/lib/activesp/folder.rb +2 -2
- data/lib/activesp/ghost_field.rb +4 -4
- data/lib/activesp/group.rb +2 -2
- data/lib/activesp/item.rb +20 -5
- data/lib/activesp/list.rb +64 -53
- data/lib/activesp/site.rb +10 -10
- data/lib/activesp/user.rb +3 -3
- data/lib/activesp/util.rb +43 -12
- metadata +11 -8
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0-pre
|
data/lib/activesp/caching.rb
CHANGED
@@ -28,6 +28,20 @@ module ActiveSP
|
|
28
28
|
# @private
|
29
29
|
module Caching
|
30
30
|
|
31
|
+
module InstanceMethods
|
32
|
+
|
33
|
+
# @private
|
34
|
+
def clear_cache_for(name)
|
35
|
+
instance_variable_set("@#{name}", nil) # Make sure it is defined first... Dirty, right?
|
36
|
+
remove_instance_variable("@#{name}")
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.extended(o)
|
42
|
+
o.send(:include, ActiveSP::Caching::InstanceMethods)
|
43
|
+
end
|
44
|
+
|
31
45
|
private
|
32
46
|
|
33
47
|
def cache(name, options = {})
|
data/lib/activesp/connection.rb
CHANGED
@@ -132,6 +132,32 @@ module ActiveSP
|
|
132
132
|
end
|
133
133
|
end
|
134
134
|
|
135
|
+
def head(url)
|
136
|
+
# TODO: support HTTPS too
|
137
|
+
@open_params ||= begin
|
138
|
+
u = URL(@root_url)
|
139
|
+
[u.host, u.port]
|
140
|
+
end
|
141
|
+
Net::HTTP.start(*@open_params) do |http|
|
142
|
+
request = Net::HTTP::Head.new(URL(url).full_path.gsub(/ /, "%20"))
|
143
|
+
if @login
|
144
|
+
case auth_type
|
145
|
+
when :ntlm
|
146
|
+
request.ntlm_auth(@login, @password)
|
147
|
+
when :basic
|
148
|
+
request.basic_auth(@login, @password)
|
149
|
+
else
|
150
|
+
raise ArgumentError, "Unknown authentication type #{auth_type.inspect}"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
response = http.request(request)
|
154
|
+
# if Net::HTTPFound === response
|
155
|
+
# response = fetch(response["location"])
|
156
|
+
# end
|
157
|
+
# response
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
135
161
|
end
|
136
162
|
|
137
163
|
end
|
@@ -98,6 +98,11 @@ module ActiveSP
|
|
98
98
|
end
|
99
99
|
cache :fields, :dup => :always
|
100
100
|
|
101
|
+
def fields_by_name
|
102
|
+
fields.inject({}) { |h, f| h[decode_field_name(f.StaticName)] = f ; h }
|
103
|
+
end
|
104
|
+
cache :fields_by_name, :dup => :always
|
105
|
+
|
101
106
|
# See {Base#save}
|
102
107
|
# @return [void]
|
103
108
|
def save
|
@@ -130,12 +135,12 @@ module ActiveSP
|
|
130
135
|
|
131
136
|
def internal_attribute_types
|
132
137
|
@@internal_attribute_types ||= {
|
133
|
-
"Description" => GhostField.new("
|
134
|
-
"FeatureId" => GhostField.new("
|
135
|
-
"Group" => GhostField.new("
|
138
|
+
"Description" => GhostField.new("Description", "Text", false, true),
|
139
|
+
"FeatureId" => GhostField.new("FeatureId", "Text", false, true),
|
140
|
+
"Group" => GhostField.new("Group", "Text", false, true),
|
136
141
|
"Hidden" => GhostField.new("Hidden", "Bool", false, true),
|
137
|
-
"ID" => GhostField.new("
|
138
|
-
"Name" => GhostField.new("
|
142
|
+
"ID" => GhostField.new("ID", "Text", false, true),
|
143
|
+
"Name" => GhostField.new("Name", "Text", false, true),
|
139
144
|
"ReadOnly" => GhostField.new("ReadOnly", "Bool", false, true),
|
140
145
|
"Sealed" => GhostField.new("Sealed", "Bool", false, true),
|
141
146
|
"V2ListTemplateName" => GhostField.new("V2ListTemplateName", "Text", false, true),
|
data/lib/activesp/file.rb
CHANGED
@@ -44,10 +44,19 @@ module ActiveSP
|
|
44
44
|
@item.list.site.connection.fetch(@url).body
|
45
45
|
end
|
46
46
|
|
47
|
+
def content_type
|
48
|
+
head_data["content-type"]
|
49
|
+
end
|
50
|
+
|
51
|
+
def content_size
|
52
|
+
head_data["content-length"].to_i
|
53
|
+
end
|
54
|
+
|
47
55
|
def destroy
|
48
56
|
if @destroyable
|
49
57
|
result = call("Lists", "delete_attachment", "listName" => @item.list.id, "listItemID" => @item.ID, "url" => @url)
|
50
58
|
if delete_result = result.xpath("//sp:DeleteAttachmentResponse", NS).first
|
59
|
+
@item.clear_cache_for(:attachment_urls)
|
51
60
|
self
|
52
61
|
else
|
53
62
|
raise "file could not be deleted"
|
@@ -65,6 +74,12 @@ module ActiveSP
|
|
65
74
|
# @private
|
66
75
|
alias inspect to_s
|
67
76
|
|
77
|
+
private
|
78
|
+
|
79
|
+
def head_data
|
80
|
+
@head_data ||= @item.list.site.connection.head(@url)
|
81
|
+
end
|
82
|
+
|
68
83
|
end
|
69
84
|
|
70
85
|
end
|
data/lib/activesp/folder.rb
CHANGED
@@ -34,7 +34,7 @@ module ActiveSP
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def is_folder?
|
37
|
-
|
37
|
+
true
|
38
38
|
end
|
39
39
|
|
40
40
|
# Returns the list of items in this folder
|
@@ -68,7 +68,7 @@ module ActiveSP
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def create_document(parameters = {})
|
71
|
-
@list.create_document(parameters.merge(:folder => absolute_url))
|
71
|
+
@list.create_document(parameters.merge(:folder => absolute_url, :folder_object => self))
|
72
72
|
end
|
73
73
|
|
74
74
|
# Returns the item with the given name
|
data/lib/activesp/ghost_field.rb
CHANGED
@@ -35,11 +35,11 @@ module ActiveSP
|
|
35
35
|
include Util
|
36
36
|
|
37
37
|
# @private
|
38
|
-
attr_reader :Name, :internal_type, :Mult, :ReadOnly
|
38
|
+
attr_reader :Name, :internal_type, :Mult, :ReadOnly, :DisplayName, :Required
|
39
39
|
|
40
40
|
# @private
|
41
|
-
def initialize(name, type, mult, read_only)
|
42
|
-
@Name, @internal_type, @Mult, @ReadOnly = name, type, mult, read_only
|
41
|
+
def initialize(name, type, mult, read_only, display_name = name)
|
42
|
+
@Name, @DisplayName, @internal_type, @Mult, @ReadOnly = name, display_name, type, mult, read_only
|
43
43
|
end
|
44
44
|
|
45
45
|
# @private
|
@@ -86,7 +86,7 @@ module ActiveSP
|
|
86
86
|
def original_attributes
|
87
87
|
@original_attributes ||= {
|
88
88
|
"ColName" => @Name,
|
89
|
-
"DisplayName" => @
|
89
|
+
"DisplayName" => @DisplayName,
|
90
90
|
"Mult" => @Mult,
|
91
91
|
"Name" => @Name,
|
92
92
|
"ReadOnly" => @ReadOnly,
|
data/lib/activesp/group.rb
CHANGED
@@ -97,8 +97,8 @@ module ActiveSP
|
|
97
97
|
"Description" => GhostField.new("Description", "Text", false, true),
|
98
98
|
"ID" => GhostField.new("ID", "Text", false, true),
|
99
99
|
"Name" => GhostField.new("Name", "Text", false, true),
|
100
|
-
"OwnerID" => GhostField.new("
|
101
|
-
"OwnerIsUser" => GhostField.new("OwnerIsUser", "Bool", false, true)
|
100
|
+
"OwnerID" => GhostField.new("OwnerID", "Integer", false, true, "Owner ID"),
|
101
|
+
"OwnerIsUser" => GhostField.new("OwnerIsUser", "Bool", false, true, "Owner Is User?")
|
102
102
|
}
|
103
103
|
end
|
104
104
|
|
data/lib/activesp/item.rb
CHANGED
@@ -258,7 +258,9 @@ module ActiveSP
|
|
258
258
|
if error_code == 0
|
259
259
|
@ID = nil
|
260
260
|
else
|
261
|
-
|
261
|
+
message = create_result.xpath("./sp:ErrorText", NS).first
|
262
|
+
message &&= message.text
|
263
|
+
raise "cannot destroy item, error code = #{error_code}, error description = #{message}"
|
262
264
|
end
|
263
265
|
self
|
264
266
|
end
|
@@ -306,19 +308,30 @@ module ActiveSP
|
|
306
308
|
cache :original_attributes
|
307
309
|
|
308
310
|
def internal_attribute_types
|
309
|
-
list.fields_by_name
|
311
|
+
# list.fields_by_name
|
312
|
+
content_type.fields_by_name
|
310
313
|
end
|
314
|
+
cache :internal_attribute_types
|
311
315
|
|
312
316
|
def update_attributes_internal(attributes)
|
313
317
|
attributes = attributes.dup
|
314
318
|
if file_leaf_ref = attributes.delete("FileLeafRef")
|
315
319
|
base_name = ::File.basename(file_leaf_ref, ".*")
|
320
|
+
type = ::File.extname(file_leaf_ref).sub(/\A\./, "")
|
321
|
+
if type != original_attributes["File Type"].to_s
|
322
|
+
raise ArgumentError, "Cannot change file type of a document"
|
323
|
+
end
|
324
|
+
file_ref = URI.unescape(original_attributes["EncodedAbsUrl"])
|
316
325
|
end
|
317
|
-
updates = Builder::XmlMarkup.new.Batch("OnError" => "Continue", "ListVersion" =>
|
326
|
+
updates = Builder::XmlMarkup.new.Batch("OnError" => "Continue", "ListVersion" => @list.attribute("Version")) do |xml|
|
318
327
|
xml.Method("ID" => 1, "Cmd" => "Update") do
|
319
328
|
xml.Field(self.ID, "Name" => "ID")
|
320
329
|
construct_xml_for_update_list_items(xml, @list.fields_by_name, attributes)
|
321
|
-
|
330
|
+
if file_ref
|
331
|
+
xml.Field(base_name, "Name" => "BaseName")
|
332
|
+
xml.Field(file_ref, "Name" => "FileRef")
|
333
|
+
end
|
334
|
+
xml.Field("1", "Name" => "FSObjType") if is_folder?
|
322
335
|
end
|
323
336
|
end
|
324
337
|
result = call("Lists", "update_list_items", "listName" => @list.id, "updates" => updates)
|
@@ -329,7 +342,9 @@ module ActiveSP
|
|
329
342
|
@attributes_before_type_cast = clean_item_attributes(row.attributes)
|
330
343
|
reload
|
331
344
|
else
|
332
|
-
|
345
|
+
message = create_result.xpath("./sp:ErrorText", NS).first
|
346
|
+
message &&= message.text
|
347
|
+
raise "cannot update item, error code = #{error_code}, error description = #{message}"
|
333
348
|
end
|
334
349
|
end
|
335
350
|
|
data/lib/activesp/list.rb
CHANGED
@@ -94,7 +94,8 @@ module ActiveSP
|
|
94
94
|
folder = options.delete(:folder)
|
95
95
|
# Always include a query because for some reason SP is capable of not finding certain
|
96
96
|
# items otherwise.
|
97
|
-
query = { "query" => options.delete(:query) || "<Query><Where></Where></Query>" }
|
97
|
+
# query = { "query" => options.delete(:query) || "<Query><Where></Where></Query>" }
|
98
|
+
query = { "query" => options.delete(:query) || "" }
|
98
99
|
no_preload = options.delete(:no_preload)
|
99
100
|
options.empty? or raise ArgumentError, "unknown options #{options.keys.map { |k| k.inspect }.join(", ")}"
|
100
101
|
query_options = Builder::XmlMarkup.new.QueryOptions do |xml|
|
@@ -152,6 +153,10 @@ module ActiveSP
|
|
152
153
|
# Returns the item with the given name or nil if there is no item with the given name
|
153
154
|
# @return [Item]
|
154
155
|
def item(name)
|
156
|
+
__item(name)
|
157
|
+
end
|
158
|
+
|
159
|
+
def __item(name, options = {})
|
155
160
|
query = Builder::XmlMarkup.new.Query do |xml|
|
156
161
|
xml.Where do |xml|
|
157
162
|
xml.Eq do |xml|
|
@@ -160,7 +165,7 @@ module ActiveSP
|
|
160
165
|
end
|
161
166
|
end
|
162
167
|
end
|
163
|
-
items(:query => query).first
|
168
|
+
items(options.merge(:query => query)).first
|
164
169
|
end
|
165
170
|
|
166
171
|
alias / item
|
@@ -189,7 +194,11 @@ module ActiveSP
|
|
189
194
|
else
|
190
195
|
view_fields = Builder::XmlMarkup.new.ViewFields
|
191
196
|
end
|
192
|
-
|
197
|
+
if token
|
198
|
+
result = call("Lists", "get_list_item_changes_since_token", "listName" => @id, 'queryOptions' => '<queryOptions xmlns:s="http://schemas.microsoft.com/sharepoint/soap/" ><QueryOptions/></queryOptions>', 'changeToken' => token, 'viewFields' => view_fields)
|
199
|
+
else
|
200
|
+
result = call("Lists", "get_list_item_changes_since_token", "listName" => @id, 'queryOptions' => '<queryOptions xmlns:s="http://schemas.microsoft.com/sharepoint/soap/" ><QueryOptions/></queryOptions>', 'viewFields' => view_fields)
|
201
|
+
end
|
193
202
|
updates = []
|
194
203
|
result.xpath("//z:row", NS).each do |row|
|
195
204
|
attributes = clean_item_attributes(row.attributes)
|
@@ -361,66 +370,66 @@ module ActiveSP
|
|
361
370
|
|
362
371
|
def internal_attribute_types
|
363
372
|
@@internal_attribute_types ||= {
|
364
|
-
"AllowAnonymousAccess" => GhostField.new("AllowAnonymousAccess", "Bool", false, true),
|
365
|
-
"AllowDeletion" => GhostField.new("AllowDeletion", "Bool", false, true),
|
366
|
-
"AllowMultiResponses" => GhostField.new("AllowMultiResponses", "Bool", false, true),
|
367
|
-
"AnonymousPermMask" => GhostField.new("AnonymousPermMask", "Integer", false, true),
|
368
|
-
"AnonymousViewListItems" => GhostField.new("AnonymousViewListItems", "Bool", false, true),
|
373
|
+
"AllowAnonymousAccess" => GhostField.new("AllowAnonymousAccess", "Bool", false, true, "Allow Anonymous Access?"),
|
374
|
+
"AllowDeletion" => GhostField.new("AllowDeletion", "Bool", false, true, "Allow Deletion?"),
|
375
|
+
"AllowMultiResponses" => GhostField.new("AllowMultiResponses", "Bool", false, true, "Allow Multiple Responses?"),
|
376
|
+
"AnonymousPermMask" => GhostField.new("AnonymousPermMask", "Integer", false, true, "Anonymous Permission Mask"),
|
377
|
+
"AnonymousViewListItems" => GhostField.new("AnonymousViewListItems", "Bool", false, true, "Anonymous Can View List Items?"),
|
369
378
|
"Author" => GhostField.new("Author", "InternalUser", false, true),
|
370
|
-
"BaseTemplate" => GhostField.new("BaseTemplate", "Text", false, true),
|
371
|
-
"BaseType" => GhostField.new("BaseType", "Text", false, true),
|
372
|
-
"Created" => GhostField.new("Created", "StandardDateTime", false, true),
|
373
|
-
"DefaultViewUrl" => GhostField.new("DefaultViewUrl", "Text", false, true),
|
379
|
+
"BaseTemplate" => GhostField.new("BaseTemplate", "Text", false, true, "Base Template"),
|
380
|
+
"BaseType" => GhostField.new("BaseType", "Text", false, true, "Base Type"),
|
381
|
+
"Created" => GhostField.new("Created", "StandardDateTime", false, true, "Created"),
|
382
|
+
"DefaultViewUrl" => GhostField.new("DefaultViewUrl", "Text", false, true, "Default View Url"),
|
374
383
|
"Description" => GhostField.new("Description", "Text", false, false),
|
375
384
|
"Direction" => GhostField.new("Direction", "Text", false, true),
|
376
|
-
"DocTemplateUrl" => GhostField.new("DocTemplateUrl", "Text", false, true),
|
377
|
-
"EmailAlias" => GhostField.new("EmailAlias", "Text", false, true),
|
378
|
-
"EmailInsertsFolder" => GhostField.new("EmailInsertsFolder", "Text", false, true),
|
379
|
-
"EnableAssignedToEmail" => GhostField.new("EnableAssignedToEmail", "Bool", false, true),
|
380
|
-
"EnableAttachments" => GhostField.new("EnableAttachments", "Bool", false, true),
|
381
|
-
"EnableMinorVersion" => GhostField.new("EnableMinorVersion", "Bool", false, true),
|
382
|
-
"EnableModeration" => GhostField.new("EnableModeration", "Bool", false, true),
|
383
|
-
"EnableVersioning" => GhostField.new("EnableVersioning", "Bool", false, true),
|
384
|
-
"EventSinkAssembly" => GhostField.new("EventSinkAssembly", "Text", false, true),
|
385
|
-
"EventSinkClass" => GhostField.new("EventSinkClass", "Text", false, true),
|
386
|
-
"EventSinkData" => GhostField.new("EventSinkData", "Text", false, true),
|
387
|
-
"FeatureId" => GhostField.new("FeatureId", "Text", false, true),
|
385
|
+
"DocTemplateUrl" => GhostField.new("DocTemplateUrl", "Text", false, true, "Document Template URL"),
|
386
|
+
"EmailAlias" => GhostField.new("EmailAlias", "Text", false, true, "Email Alias"),
|
387
|
+
"EmailInsertsFolder" => GhostField.new("EmailInsertsFolder", "Text", false, true, "Email Inserts Folder"),
|
388
|
+
"EnableAssignedToEmail" => GhostField.new("EnableAssignedToEmail", "Bool", false, true, "Enable Assign to Email?"),
|
389
|
+
"EnableAttachments" => GhostField.new("EnableAttachments", "Bool", false, true, "Enable Attachments?"),
|
390
|
+
"EnableMinorVersion" => GhostField.new("EnableMinorVersion", "Bool", false, true, "Enable Minor Versions?"),
|
391
|
+
"EnableModeration" => GhostField.new("EnableModeration", "Bool", false, true, "Enable Moderation?"),
|
392
|
+
"EnableVersioning" => GhostField.new("EnableVersioning", "Bool", false, true, "Enable Versioning?"),
|
393
|
+
"EventSinkAssembly" => GhostField.new("EventSinkAssembly", "Text", false, true, "Event Sink Assembly"),
|
394
|
+
"EventSinkClass" => GhostField.new("EventSinkClass", "Text", false, true, "Event Sink Class"),
|
395
|
+
"EventSinkData" => GhostField.new("EventSinkData", "Text", false, true, "Event Sink Data"),
|
396
|
+
"FeatureId" => GhostField.new("FeatureId", "Text", false, true, "Feature ID"),
|
388
397
|
"Flags" => GhostField.new("Flags", "Integer", false, true),
|
389
|
-
"HasUniqueScopes" => GhostField.new("HasUniqueScopes", "Bool", false, true),
|
398
|
+
"HasUniqueScopes" => GhostField.new("HasUniqueScopes", "Bool", false, true, "Has Unique Scopes?"),
|
390
399
|
"Hidden" => GhostField.new("Hidden", "Bool", false, true),
|
391
400
|
"ID" => GhostField.new("ID", "Text", false, true),
|
392
|
-
"ImageUrl" => GhostField.new("ImageUrl", "Text", false, true),
|
393
|
-
"InheritedSecurity" => GhostField.new("InheritedSecurity", "Bool", false, true),
|
394
|
-
"InternalName" => GhostField.new("InternalName", "Text", false, true),
|
395
|
-
"ItemCount" => GhostField.new("ItemCount", "Integer", false, true),
|
396
|
-
"LastDeleted" => GhostField.new("LastDeleted", "StandardDateTime", false, true),
|
397
|
-
"LastModified" => GhostField.new("LastModified", "XMLDateTime", false, true),
|
398
|
-
"LastModifiedForceRecrawl" => GhostField.new("LastModifiedForceRecrawl", "XMLDateTime", false, true),
|
399
|
-
"MajorVersionLimit" => GhostField.new("MajorVersionLimit", "Integer", false, true),
|
400
|
-
"MajorWithMinorVersionsLimit" => GhostField.new("MajorWithMinorVersionsLimit", "Integer", false, true),
|
401
|
-
"MobileDefaultViewUrl" => GhostField.new("MobileDefaultViewUrl", "Text", false, true),
|
401
|
+
"ImageUrl" => GhostField.new("ImageUrl", "Text", false, true, "Image URL"),
|
402
|
+
"InheritedSecurity" => GhostField.new("InheritedSecurity", "Bool", false, true, "Has Inherited Security?"),
|
403
|
+
"InternalName" => GhostField.new("InternalName", "Text", false, true, "Internal Name"),
|
404
|
+
"ItemCount" => GhostField.new("ItemCount", "Integer", false, true, "Item Count"),
|
405
|
+
"LastDeleted" => GhostField.new("LastDeleted", "StandardDateTime", false, true, "Deleted"),
|
406
|
+
"LastModified" => GhostField.new("LastModified", "XMLDateTime", false, true, "Modified"),
|
407
|
+
"LastModifiedForceRecrawl" => GhostField.new("LastModifiedForceRecrawl", "XMLDateTime", false, true, "Last Modified Force Recrawl"),
|
408
|
+
"MajorVersionLimit" => GhostField.new("MajorVersionLimit", "Integer", false, true, "Major Version Limit"),
|
409
|
+
"MajorWithMinorVersionsLimit" => GhostField.new("MajorWithMinorVersionsLimit", "Integer", false, true, "Major With Minor Versions Limit"),
|
410
|
+
"MobileDefaultViewUrl" => GhostField.new("MobileDefaultViewUrl", "Text", false, true, "Mobile Default View URL"),
|
402
411
|
"Modified" => GhostField.new("Modified", "StandardDateTime", false, true),
|
403
|
-
"MultipleDataList" => GhostField.new("MultipleDataList", "Bool", false, true),
|
412
|
+
"MultipleDataList" => GhostField.new("MultipleDataList", "Bool", false, true, "Is Multiple Data List?"),
|
404
413
|
"Name" => GhostField.new("Name", "Text", false, true),
|
405
414
|
"Ordered" => GhostField.new("Ordered", "Bool", false, true),
|
406
415
|
"Permissions" => GhostField.new("Permissions", "Text", false, true),
|
407
|
-
"ReadSecurity" => GhostField.new("ReadSecurity", "Integer", false, true),
|
408
|
-
"RequireCheckout" => GhostField.new("RequireCheckout", "Bool", false, true),
|
409
|
-
"RootFolder" => GhostField.new("RootFolder", "Text", false, true),
|
410
|
-
"ScopeId" => GhostField.new("ScopeId", "Text", false, true),
|
411
|
-
"SendToLocation" => GhostField.new("SendToLocation", "Text", false, true),
|
412
|
-
"ServerTemplate" => GhostField.new("ServerTemplate", "Text", false, true),
|
413
|
-
"ShowUser" => GhostField.new("ShowUser", "Bool", false, true),
|
414
|
-
"ThumbnailSize" => GhostField.new("ThumbnailSize", "Integer", false, true),
|
416
|
+
"ReadSecurity" => GhostField.new("ReadSecurity", "Integer", false, true, "Read Security"),
|
417
|
+
"RequireCheckout" => GhostField.new("RequireCheckout", "Bool", false, true, "Requires Checkout?"),
|
418
|
+
"RootFolder" => GhostField.new("RootFolder", "Text", false, true, "Root Folder"),
|
419
|
+
"ScopeId" => GhostField.new("ScopeId", "Text", false, true, "Scope ID"),
|
420
|
+
"SendToLocation" => GhostField.new("SendToLocation", "Text", false, true, "Send To Location"),
|
421
|
+
"ServerTemplate" => GhostField.new("ServerTemplate", "Text", false, true, "Server Template"),
|
422
|
+
"ShowUser" => GhostField.new("ShowUser", "Bool", false, true, "Shows User?"),
|
423
|
+
"ThumbnailSize" => GhostField.new("ThumbnailSize", "Integer", false, true, "Thumbnail Size"),
|
415
424
|
"Title" => GhostField.new("Title", "Text", false, true),
|
416
|
-
"ValidSecurityInfo" => GhostField.new("ValidSecurityInfo", "Bool", false, true),
|
425
|
+
"ValidSecurityInfo" => GhostField.new("ValidSecurityInfo", "Bool", false, true, "Has Valid Security Info?"),
|
417
426
|
"Version" => GhostField.new("Version", "Integer", false, true),
|
418
|
-
"WebFullUrl" => GhostField.new("WebFullUrl", "Text", false, true),
|
419
|
-
"WebId" => GhostField.new("WebId", "Text", false, true),
|
420
|
-
"WebImageHeight" => GhostField.new("WebImageHeight", "Integer", false, true),
|
421
|
-
"WebImageWidth" => GhostField.new("WebImageWidth", "Integer", false, true),
|
422
|
-
"WorkFlowId" => GhostField.new("WorkFlowId", "Text", false, true),
|
423
|
-
"WriteSecurity" => GhostField.new("WriteSecurity", "Integer", false, true)
|
427
|
+
"WebFullUrl" => GhostField.new("WebFullUrl", "Text", false, true, "Full Web URL"),
|
428
|
+
"WebId" => GhostField.new("WebId", "Text", false, true, "Web ID"),
|
429
|
+
"WebImageHeight" => GhostField.new("WebImageHeight", "Integer", false, true, "Web Image Height"),
|
430
|
+
"WebImageWidth" => GhostField.new("WebImageWidth", "Integer", false, true, "Web Image Width"),
|
431
|
+
"WorkFlowId" => GhostField.new("WorkFlowId", "Text", false, true, "Work Flow ID"),
|
432
|
+
"WriteSecurity" => GhostField.new("WriteSecurity", "Integer", false, true, "Write Security")
|
424
433
|
}
|
425
434
|
end
|
426
435
|
|
@@ -456,9 +465,10 @@ module ActiveSP
|
|
456
465
|
parameters = parameters.dup
|
457
466
|
content = parameters.delete(:content) or raise ArgumentError, "Specify the content in the :content parameter"
|
458
467
|
folder = parameters.delete(:folder)
|
468
|
+
folder_object = parameters.delete(:folder_object)
|
459
469
|
overwrite = parameters.delete(:overwrite)
|
460
470
|
file_name = parameters.delete("FileLeafRef") or raise ArgumentError, "Specify the file name in the 'FileLeafRef' parameter"
|
461
|
-
raise ArgumentError, "document with file name #{file_name.inspect} already exists" if
|
471
|
+
raise ArgumentError, "document with file name #{file_name.inspect} already exists" if __item(file_name, :folder => folder_object) && !overwrite
|
462
472
|
destination_urls = Builder::XmlMarkup.new.wsdl(:string, URI.escape(::File.join(folder || url, file_name)))
|
463
473
|
parameters = type_check_attributes_for_creation(fields_by_name, parameters)
|
464
474
|
attributes = untype_cast_attributes(@site, self, fields_by_name, parameters)
|
@@ -470,13 +480,14 @@ module ActiveSP
|
|
470
480
|
if error_code != "Success"
|
471
481
|
raise "#{error_code} : #{copy_result["ErrorMessage"]}"
|
472
482
|
else
|
473
|
-
|
483
|
+
__item(file_name, :folder => folder_object)
|
474
484
|
end
|
475
485
|
end
|
476
486
|
|
477
487
|
def create_list_item(parameters)
|
478
488
|
parameters = parameters.dup
|
479
489
|
folder = parameters.delete(:folder)
|
490
|
+
folder_object = parameters.delete(:folder_object)
|
480
491
|
folder_name = parameters.delete(:folder_name)
|
481
492
|
parameters = type_check_attributes_for_creation(fields_by_name, parameters)
|
482
493
|
attributes = untype_cast_attributes(@site, self, fields_by_name, parameters)
|
data/lib/activesp/site.rb
CHANGED
@@ -246,21 +246,21 @@ module ActiveSP
|
|
246
246
|
|
247
247
|
def internal_attribute_types
|
248
248
|
@@internal_attribute_types ||= {
|
249
|
-
"AllowAnonymousAccess" => GhostField.new("AllowAnonymousAccess", "Bool", false, true),
|
250
|
-
"AnonymousViewListItems" => GhostField.new("AnonymousViewListItems", "Bool", false, true),
|
249
|
+
"AllowAnonymousAccess" => GhostField.new("AllowAnonymousAccess", "Bool", false, true, "Allow Anonymous Access?"),
|
250
|
+
"AnonymousViewListItems" => GhostField.new("AnonymousViewListItems", "Bool", false, true, "Anonymous Can View List Items?"),
|
251
251
|
"Author" => GhostField.new("Author", "InternalUser", false, true),
|
252
252
|
"Description" => GhostField.new("Description", "Text", false, true),
|
253
|
-
"ExternalSecurity" => GhostField.new("ExternalSecurity", "Bool", false, true),
|
254
|
-
"InheritedSecurity" => GhostField.new("InheritedSecurity", "Bool", false, true),
|
255
|
-
"IsBucketWeb" => GhostField.new("IsBucketWeb", "Bool", false, true),
|
253
|
+
"ExternalSecurity" => GhostField.new("ExternalSecurity", "Bool", false, true, "Has External Security?"),
|
254
|
+
"InheritedSecurity" => GhostField.new("InheritedSecurity", "Bool", false, true, "Has Inherited Security?"),
|
255
|
+
"IsBucketWeb" => GhostField.new("IsBucketWeb", "Bool", false, true, "Is Bucket Web?"),
|
256
256
|
"Language" => GhostField.new("Language", "Integer", false, true),
|
257
|
-
"LastModified" => GhostField.new("LastModified", "XMLDateTime", false, true),
|
258
|
-
"LastModifiedForceRecrawl" => GhostField.new("LastModifiedForceRecrawl", "XMLDateTime", false, true),
|
257
|
+
"LastModified" => GhostField.new("LastModified", "XMLDateTime", false, true, "Modified"),
|
258
|
+
"LastModifiedForceRecrawl" => GhostField.new("LastModifiedForceRecrawl", "XMLDateTime", false, true, "Last Modified Force Recrawl"),
|
259
259
|
"Permissions" => GhostField.new("Permissions", "Text", false, true),
|
260
260
|
"Title" => GhostField.new("Title", "Text", false, true),
|
261
|
-
"UsedInAutocat" => GhostField.new("UsedInAutocat", "Bool", false, true),
|
262
|
-
"ValidSecurityInfo" => GhostField.new("ValidSecurityInfo", "Bool", false, true),
|
263
|
-
"WebID" => GhostField.new("WebID", "Text", false, true)
|
261
|
+
"UsedInAutocat" => GhostField.new("UsedInAutocat", "Bool", false, true, "Used in Autocat?"),
|
262
|
+
"ValidSecurityInfo" => GhostField.new("ValidSecurityInfo", "Bool", false, true, "Has Valid Security Info?"),
|
263
|
+
"WebID" => GhostField.new("WebID", "Text", false, true, "Web ID")
|
264
264
|
}
|
265
265
|
end
|
266
266
|
|
data/lib/activesp/user.rb
CHANGED
@@ -83,9 +83,9 @@ module ActiveSP
|
|
83
83
|
@@internal_attribute_types ||= {
|
84
84
|
"Email" => GhostField.new("Email", "Text", false, true),
|
85
85
|
"ID" => GhostField.new("ID", "Text", false, true),
|
86
|
-
"IsDomainGroup" => GhostField.new("Email", "Bool", false, true),
|
87
|
-
"IsSiteAdmin" => GhostField.new("IsSiteAdmin", "Bool", false, true),
|
88
|
-
"LoginName" => GhostField.new("LoginName", "Text", false, true),
|
86
|
+
"IsDomainGroup" => GhostField.new("Email", "Bool", false, true, "Is Domain Group?"),
|
87
|
+
"IsSiteAdmin" => GhostField.new("IsSiteAdmin", "Bool", false, true, "Is Site Admin?"),
|
88
|
+
"LoginName" => GhostField.new("LoginName", "Text", false, true, "Login Name"),
|
89
89
|
"Name" => GhostField.new("Name", "Text", false, true),
|
90
90
|
"Notes" => GhostField.new("Notes", "Text", false, true),
|
91
91
|
"Sid" => GhostField.new("Sid", "Text", false, true)
|
data/lib/activesp/util.rb
CHANGED
@@ -53,7 +53,11 @@ module ActiveSP
|
|
53
53
|
when "DateTime"
|
54
54
|
v = Time.parse(v)
|
55
55
|
when "XMLDateTime"
|
56
|
-
|
56
|
+
if v == "0001-01-01T00:00:00"
|
57
|
+
v = nil
|
58
|
+
else
|
59
|
+
v = Time.xmlschema(v.sub(/ /, "T"))
|
60
|
+
end
|
57
61
|
when "Computed", "Text", "Guid", "ContentTypeId", "URL"
|
58
62
|
when "Integer", "Counter", "Attachments"
|
59
63
|
v = v && v != "" ? Integer(v) : nil
|
@@ -70,9 +74,9 @@ module ActiveSP
|
|
70
74
|
|
71
75
|
when "User"
|
72
76
|
d = split_multi(v)
|
73
|
-
v =
|
77
|
+
v = create_user_or_group_by_name(site, d[2])
|
74
78
|
when "InternalUser"
|
75
|
-
v =
|
79
|
+
v = create_user_or_group_by_name(site, v)
|
76
80
|
when "UserMulti"
|
77
81
|
d = split_multi(v)
|
78
82
|
v = (0...(d.length / 4)).map { |i| create_user_or_group(site, d[4 * i + 2]) }
|
@@ -118,23 +122,43 @@ module ActiveSP
|
|
118
122
|
end
|
119
123
|
|
120
124
|
def create_user_or_group(site, entry)
|
121
|
-
if entry
|
122
|
-
User.new(site.connection.root, "SHAREPOINT\\system")
|
123
|
-
elsif entry[/\\/]
|
125
|
+
if entry[/\\/]
|
124
126
|
User.new(site.connection.root, entry)
|
125
127
|
else
|
126
128
|
Group.new(site.connection.root, entry)
|
127
129
|
end
|
128
130
|
end
|
129
131
|
|
132
|
+
def create_user_or_group_by_name(site, name)
|
133
|
+
if /\A\d+\z/ === name
|
134
|
+
create_user_or_group_by_id(site, name)
|
135
|
+
else
|
136
|
+
if user = site.connection.users.find { |u| u.attribute("Name") === name }
|
137
|
+
User.new(site.connection.root, user.attribute("LoginName"))
|
138
|
+
elsif group = site.connection.groups.find { |g| g.attribute("Name") === name }
|
139
|
+
Group.new(site.connection.root, name)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def create_user_or_group_by_id(site, id)
|
145
|
+
if user = site.connection.users.find { |u| u.attribute("ID") === id }
|
146
|
+
User.new(site.connection.root, user.attribute("LoginName"))
|
147
|
+
elsif group = site.connection.groups.find { |g| g.attribute("ID") === id }
|
148
|
+
Group.new(site.connection.root, group.attribute("Name"))
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
130
152
|
def type_check_attribute(field, value)
|
131
153
|
case field.internal_type
|
132
|
-
when "Text", "File"
|
154
|
+
when "Text", "File", "Note", "URL", "Choice"
|
133
155
|
value.to_s
|
134
156
|
when "Bool", "Boolean"
|
135
157
|
!!value
|
136
158
|
when "Integer"
|
137
|
-
Integer(value)
|
159
|
+
Integer(value) if value
|
160
|
+
when "Number"
|
161
|
+
Float(value) if value
|
138
162
|
when "StandardDateTime", "XMLDateTime"
|
139
163
|
Time === value and value or raise ArgumentError, "wrong type for #{field.Name} attribute"
|
140
164
|
when "InternalUser"
|
@@ -173,6 +197,8 @@ module ActiveSP
|
|
173
197
|
if ::ActiveSP::User === value || field.attributes["UserSelectionMode"] == "PeopleAndGroups" && ::ActiveSP::Group === value
|
174
198
|
# TODO: check if the user is in the correct group in case a group is specified
|
175
199
|
value
|
200
|
+
elsif value == nil && !field.attributes["Required"]
|
201
|
+
nil
|
176
202
|
else
|
177
203
|
raise ArgumentError, "wrong type for #{field.Name} attribute"
|
178
204
|
end
|
@@ -190,6 +216,8 @@ module ActiveSP
|
|
190
216
|
raise ArgumentError, "wrong type for #{field.Name} attribute"
|
191
217
|
end
|
192
218
|
end
|
219
|
+
when "ContentTypeId"
|
220
|
+
value
|
193
221
|
else
|
194
222
|
raise "not yet #{field.Name}:#{field.internal_type}"
|
195
223
|
end
|
@@ -198,7 +226,7 @@ module ActiveSP
|
|
198
226
|
def type_check_attributes_for_creation(fields, attributes)
|
199
227
|
attributes.inject({}) do |h, (k, v)|
|
200
228
|
if field = fields[k]
|
201
|
-
if !field.ReadOnly
|
229
|
+
if !field.ReadOnly || field.Name == "ContentType"
|
202
230
|
h[k] = type_check_attribute(field, v)
|
203
231
|
h
|
204
232
|
else
|
@@ -214,23 +242,26 @@ module ActiveSP
|
|
214
242
|
attributes.inject({}) do |h, (k, v)|
|
215
243
|
if field = fields[k]
|
216
244
|
case field.internal_type
|
217
|
-
when "Text", "File"
|
245
|
+
when "Text", "File", "Note", "URL", "Choice"
|
218
246
|
when "Bool"
|
219
247
|
v = v ? "TRUE" : "FALSE"
|
220
248
|
when "Boolean"
|
221
249
|
v = v ? "1" : "0"
|
222
250
|
when "Integer"
|
223
251
|
v = v.to_s
|
252
|
+
when "Number"
|
253
|
+
v = v.to_s
|
224
254
|
when "DateTime"
|
225
255
|
v = v.strftime("%Y-%m-%d %H:%M:%S")
|
226
256
|
when "User"
|
227
|
-
v = v.ID
|
257
|
+
v = v.ID if v
|
228
258
|
when "UserMulti"
|
229
259
|
v = v.map { |ug| ug.ID }.join(";#;#")
|
230
260
|
when "Lookup"
|
231
|
-
v = v.ID
|
261
|
+
v = v.ID if v
|
232
262
|
when "LookupMulti"
|
233
263
|
v = v.map { |i| i.ID }.join(";#;#")
|
264
|
+
when "ContentTypeId"
|
234
265
|
else
|
235
266
|
raise "don't know type #{field.internal_type.inspect} for #{k}=#{v.inspect} on self"
|
236
267
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activesp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.7
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Peter Vanbroekhoven
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-05-19 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -24,12 +24,15 @@ dependencies:
|
|
24
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- - "
|
27
|
+
- - "="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
29
|
+
hash: 113
|
30
30
|
segments:
|
31
31
|
- 0
|
32
|
-
|
32
|
+
- 7
|
33
|
+
- 2
|
34
|
+
- 7
|
35
|
+
version: 0.7.2.7
|
33
36
|
type: :runtime
|
34
37
|
version_requirements: *id001
|
35
38
|
- !ruby/object:Gem::Dependency
|
@@ -81,7 +84,7 @@ files:
|
|
81
84
|
- lib/activesp/user.rb
|
82
85
|
- lib/activesp/util.rb
|
83
86
|
- lib/activesp.rb
|
84
|
-
has_rdoc:
|
87
|
+
has_rdoc: true
|
85
88
|
homepage: http://www.xaop.com/labs/activesp
|
86
89
|
licenses: []
|
87
90
|
|