activesp 0.0.7 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|