activesp 0.0.1 → 0.0.4

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/lib/activesp/url.rb CHANGED
@@ -1,3 +1,29 @@
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
+ # @private
1
27
  def URL(*args)
2
28
  case args.length
3
29
  when 1
@@ -14,6 +40,7 @@ def URL(*args)
14
40
  end
15
41
  end
16
42
 
43
+ # @private
17
44
  class URL < Struct.new(:protocol, :host, :port, :path, :query, :fragment)
18
45
 
19
46
  def self.parse(url)
data/lib/activesp/user.rb CHANGED
@@ -1,3 +1,28 @@
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
+
1
26
  module ActiveSP
2
27
 
3
28
  class User < Base
@@ -7,21 +32,34 @@ module ActiveSP
7
32
  include Util
8
33
  include InSite
9
34
 
35
+ # @private
10
36
  attr_reader :login_name
11
37
 
12
38
  persistent { |site, login_name, *a| [site.connection, [:user, login_name]] }
13
- def initialize(site, login_name)
39
+ # @private
40
+ def initialize(site, login_name, attributes_before_type_cast = nil)
14
41
  @site, @login_name = site, login_name
42
+ @attributes_before_type_cast = attributes_before_type_cast if attributes_before_type_cast
15
43
  end
16
44
 
45
+ # See {Base#key}
46
+ # @return [String]
17
47
  def key
18
48
  encode_key("U", [@login_name])
19
49
  end
20
50
 
51
+ # See {Base#save}
52
+ # @return [void]
53
+ def save
54
+ p untype_cast_attributes(@site, nil, internal_attribute_types, changed_attributes)
55
+ end
56
+
57
+ # @private
21
58
  def to_s
22
59
  "#<ActiveSP::User login_name=#{login_name}>"
23
60
  end
24
61
 
62
+ # @private
25
63
  alias inspect to_s
26
64
 
27
65
  private
data/lib/activesp/util.rb CHANGED
@@ -1,9 +1,39 @@
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
+
1
26
  module ActiveSP
2
27
 
28
+ # @private
3
29
  module Util
4
30
 
5
31
  private
6
32
 
33
+ def decode_field_name(name)
34
+ name.gsub(/_x([0-9af]{4})_/i) { [$1.to_i(16)].pack("U") }
35
+ end
36
+
7
37
  def clean_attributes(attributes)
8
38
  attributes.inject({}) { |h, (k, v)| h[k] = v.to_s ; h }
9
39
  end
@@ -13,7 +43,8 @@ module ActiveSP
13
43
  end
14
44
 
15
45
  def type_cast_attributes(site, list, fields, attributes)
16
- attributes.inject({}) do |h, (k, v)|
46
+ result = attributes.inject({}) do |h, (k, v)|
47
+ k = decode_field_name(k)
17
48
  if field = fields[k]
18
49
  case field.internal_type
19
50
  when "ListReference"
@@ -34,17 +65,17 @@ module ActiveSP
34
65
  when "Bool"
35
66
  v = !!v[/true/i]
36
67
  when "File"
37
- # v = v.sub(/\A.*?;#/, "")
68
+ v = v.sub(/\A\d+;#/, "")
38
69
  when "Note"
39
70
 
40
71
  when "User"
41
72
  d = split_multi(v)
42
- v = User.new(site.connection.root, d[2][/\\/] ? d[2] : "SHAREPOINT\\system")
73
+ v = create_user_or_group(site, d[2])
43
74
  when "InternalUser"
44
- v = User.new(site.connection.root, v[/\\/] ? v : "SHAREPOINT\\system")
75
+ v = create_user_or_group(site, v)
45
76
  when "UserMulti"
46
77
  d = split_multi(v)
47
- v = (0...(d.length / 4)).map { |i| User.new(site.connection.root, d[4 * i + 2][/\\/] ? d[4 * i + 2] : "SHAREPOINT\\system") }
78
+ v = (0...(d.length / 4)).map { |i| create_user_or_group(site, d[4 * i + 2]) }
48
79
 
49
80
  when "Choice"
50
81
  # For some reason there is no encoding here
@@ -55,31 +86,183 @@ module ActiveSP
55
86
  when "Lookup"
56
87
  d = split_multi(v)
57
88
  if field.List
58
- v = create_item_from_id(field.List, d[0])
89
+ v = construct_item_from_id(field.List, d[0])
59
90
  else
60
91
  v = d[2]
61
92
  end
62
93
  when "LookupMulti"
63
94
  d = split_multi(v)
64
95
  if field.List
65
- v = (0...(d.length / 4)).map { |i| create_item_from_id(field.List, d[4 * i]) }
96
+ v = (0...(d.length / 4)).map { |i| construct_item_from_id(field.List, d[4 * i]) }
66
97
  else
67
98
  v = (0...(d.length / 4)).map { |i| d[4 * i + 2] }
68
99
  end
69
100
 
70
101
  else
71
102
  # raise NotImplementedError, "don't know type #{field.type.inspect} for #{k}=#{v.inspect}"
72
- warn "don't know type #{field.internal_type.inspect} for #{k}=#{v.inspect} on self"
103
+ # Note: can't print self if it needs the attributes to be loaded, so just display the class
104
+ # warn "don't know type #{field.internal_type.inspect} for #{k}=#{v.inspect} on #{self.class}"
73
105
  end
74
106
  else
75
107
  # raise ArgumentError, "can't find field #{k.inspect}"
76
- warn "can't find field #{k.inspect} on #{self}"
108
+ # Note: can't print self if it needs the attributes to be loaded, so just display the class
109
+ # warn "can't find field #{k.inspect} on #{self.class}"
110
+ end
111
+ h[k] = v
112
+ h
113
+ end
114
+ fields.each_key do |k|
115
+ result[k] = nil unless result.has_key?(k)
116
+ end
117
+ result
118
+ end
119
+
120
+ def create_user_or_group(site, entry)
121
+ if entry == "System Account"
122
+ User.new(site.connection.root, "SHAREPOINT\\system")
123
+ elsif entry[/\\/]
124
+ User.new(site.connection.root, entry)
125
+ else
126
+ Group.new(site.connection.root, entry)
127
+ end
128
+ end
129
+
130
+ def type_check_attribute(field, value)
131
+ case field.internal_type
132
+ when "Text", "File"
133
+ value.to_s
134
+ when "Bool", "Boolean"
135
+ !!value
136
+ when "Integer"
137
+ Integer(value)
138
+ when "StandardDateTime", "XMLDateTime"
139
+ Time === value and value or raise ArgumentError, "wrong type for #{field.Name} attribute"
140
+ when "InternalUser"
141
+ value = value.to_s
142
+ @site.rootsite.user(value) and value or raise ArgumentError, "user with login #{value} does not exist for #{field.Name} attribute"
143
+ when "Lookup"
144
+ if field.List
145
+ if ::ActiveSP::Item === value && value.list == field.List
146
+ value
147
+ else
148
+ raise ArgumentError, "wrong type for #{field.Name} attribute"
149
+ end
150
+ else
151
+ value.to_s
152
+ end
153
+ when "LookupMulti"
154
+ if field.List
155
+ begin
156
+ value = Array(value)
157
+ rescue Exception
158
+ raise ArgumentError, "wrong type for #{field.Name} attribute"
159
+ end
160
+ value.map do |val|
161
+ if ::ActiveSP::Item === val && val.list == field.List
162
+ val
163
+ else
164
+ raise ArgumentError, "wrong type for #{field.Name} attribute"
165
+ end
166
+ end
167
+ else
168
+ raise ArgumentError, "wrong type for #{field.Name} attribute"
169
+ end
170
+ when "DateTime"
171
+ Time === value and value or raise ArgumentError, "wrong type for #{field.Name} attribute"
172
+ when "User"
173
+ if ::ActiveSP::User === value || field.attributes["UserSelectionMode"] == "PeopleAndGroups" && ::ActiveSP::Group === value
174
+ # TODO: check if the user is in the correct group in case a group is specified
175
+ value
176
+ else
177
+ raise ArgumentError, "wrong type for #{field.Name} attribute"
178
+ end
179
+ when "UserMulti"
180
+ begin
181
+ value = Array(value)
182
+ rescue Exception
183
+ raise ArgumentError, "wrong type for #{field.Name} attribute"
184
+ end
185
+ value.map do |val|
186
+ if ::ActiveSP::User === val || field.attributes["UserSelectionMode"] == "PeopleAndGroups" && ::ActiveSP::Group === val
187
+ # TODO: check if the user is in the correct group in case a group is specified
188
+ val
189
+ else
190
+ raise ArgumentError, "wrong type for #{field.Name} attribute"
191
+ end
192
+ end
193
+ else
194
+ raise "not yet #{field.Name}:#{field.internal_type}"
195
+ end
196
+ end
197
+
198
+ def type_check_attributes_for_creation(fields, attributes)
199
+ attributes.inject({}) do |h, (k, v)|
200
+ if field = fields[k]
201
+ if !field.ReadOnly
202
+ h[k] = type_check_attribute(field, v)
203
+ h
204
+ else
205
+ raise ArgumentError, "field #{field.Name} is read-only"
206
+ end
207
+ else
208
+ raise "can't find field #{k.inspect}"
209
+ end
210
+ end
211
+ end
212
+
213
+ def untype_cast_attributes(site, list, fields, attributes)
214
+ attributes.inject({}) do |h, (k, v)|
215
+ if field = fields[k]
216
+ case field.internal_type
217
+ when "Text", "File"
218
+ when "Bool"
219
+ v = v ? "TRUE" : "FALSE"
220
+ when "Boolean"
221
+ v = v ? "1" : "0"
222
+ when "Integer"
223
+ v = v.to_s
224
+ when "DateTime"
225
+ v = v.strftime("%Y-%m-%d %H:%M:%S")
226
+ when "User"
227
+ v = v.ID
228
+ when "UserMulti"
229
+ v = v.map { |ug| ug.ID }.join(";#;#")
230
+ when "Lookup"
231
+ v = v.ID
232
+ when "LookupMulti"
233
+ v = v.map { |i| i.ID }.join(";#;#")
234
+ else
235
+ raise "don't know type #{field.internal_type.inspect} for #{k}=#{v.inspect} on self"
236
+ end
237
+ else
238
+ raise "can't find field #{k.inspect} on #{self}"
77
239
  end
78
240
  h[k] = v
79
241
  h
80
242
  end
81
243
  end
82
244
 
245
+ def construct_xml_for_copy_into_items(fields, attributes)
246
+ attributes.map do |k, v|
247
+ field = fields[k]
248
+ Builder::XmlMarkup.new.wsdl(
249
+ :FieldInformation,
250
+ "Type" => field.internal_type,
251
+ "Id" => field.ID,
252
+ "Value" => v,
253
+ "InternalName" => field.StaticName,
254
+ "DisplayName" => field.DisplayName
255
+ )
256
+ end.join("")
257
+ end
258
+
259
+ def construct_xml_for_update_list_items(xml, fields, attributes)
260
+ attributes.map do |k, v|
261
+ field = fields[k]
262
+ xml.Field(v, "Name" => field.StaticName)
263
+ end
264
+ end
265
+
83
266
  def encode_key(type, trail)
84
267
  "#{type}::#{trail.map { |t| t.to_s.gsub(/:/, ":-") }.join("::")}"
85
268
  end
@@ -94,7 +277,7 @@ module ActiveSP
94
277
  s.scan(/((?:[^;]|;;#|;[^#;]|;;(?!#))+)(;#)?/).flatten
95
278
  end
96
279
 
97
- def create_item_from_id(list, id)
280
+ def construct_item_from_id(list, id)
98
281
  query = Builder::XmlMarkup.new.Query do |xml|
99
282
  xml.Where do |xml|
100
283
  xml.Eq do |xml|
@@ -133,36 +316,11 @@ module ActiveSP
133
316
  end
134
317
  end
135
318
 
319
+ # Somewhat dirty
320
+ def escape_xml(xml)
321
+ Builder::XmlMarkup.new.s(xml).scan(/\A<s>(.*)<\/s>\z/)
322
+ end
323
+
136
324
  end
137
325
 
138
326
  end
139
-
140
-
141
- __END__
142
-
143
- escaping in field names:
144
-
145
- _x[4-digit code]_
146
-
147
- [space] 20
148
- < 3C
149
- > 3E
150
- # 23
151
- % 25
152
- { 7B
153
- } 7D
154
- | 7C
155
- \ 5C
156
- ^ 5E
157
- ~ 7E
158
- [ 5B
159
- ] 5D
160
- ` 60
161
- ; 3B
162
- / 2F
163
- ? 3F
164
- : 3A
165
- @ 40
166
- = 3D
167
- & 26
168
- $ 24
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activesp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 4
10
+ version: 0.0.4
5
11
  platform: ruby
6
12
  authors:
7
13
  - Peter Vanbroekhoven
@@ -9,30 +15,38 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2010-04-02 00:00:00 +02:00
18
+ date: 2010-09-29 00:00:00 +02:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: savon-xaop
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
23
32
  version: "0"
24
- version:
33
+ type: :runtime
34
+ version_requirements: *id001
25
35
  - !ruby/object:Gem::Dependency
26
36
  name: nokogiri
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
30
40
  requirements:
31
41
  - - ">="
32
42
  - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
33
46
  version: "0"
34
- version:
35
- description: Interface to SharePoint
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ description: An object-oriented interface to SharePoint that uses the web services provided by SharePoint to connect to it. Supports SharePoint 2007 and 2010.
36
50
  email: peter@xaop.com
37
51
  executables: []
38
52
 
@@ -42,12 +56,16 @@ extra_rdoc_files: []
42
56
 
43
57
  files:
44
58
  - VERSION
59
+ - LICENSE
60
+ - README.rdoc
45
61
  - Rakefile
62
+ - lib/activesp/associations.rb
46
63
  - lib/activesp/base.rb
47
64
  - lib/activesp/caching.rb
48
65
  - lib/activesp/connection.rb
49
66
  - lib/activesp/content_type.rb
50
67
  - lib/activesp/field.rb
68
+ - lib/activesp/file.rb
51
69
  - lib/activesp/folder.rb
52
70
  - lib/activesp/ghost_field.rb
53
71
  - lib/activesp/group.rb
@@ -62,8 +80,8 @@ files:
62
80
  - lib/activesp/user.rb
63
81
  - lib/activesp/util.rb
64
82
  - lib/activesp.rb
65
- has_rdoc: true
66
- homepage:
83
+ has_rdoc: false
84
+ homepage: http://www.xaop.com/labs/activesp
67
85
  licenses: []
68
86
 
69
87
  post_install_message:
@@ -73,21 +91,29 @@ require_paths:
73
91
  - lib
74
92
  - lib
75
93
  required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
76
95
  requirements:
77
96
  - - ">="
78
97
  - !ruby/object:Gem::Version
98
+ hash: 53
99
+ segments:
100
+ - 1
101
+ - 8
102
+ - 1
79
103
  version: 1.8.1
80
- version:
81
104
  required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
82
106
  requirements:
83
107
  - - ">="
84
108
  - !ruby/object:Gem::Version
109
+ hash: 3
110
+ segments:
111
+ - 0
85
112
  version: "0"
86
- version:
87
113
  requirements: []
88
114
 
89
115
  rubyforge_project:
90
- rubygems_version: 1.3.5
116
+ rubygems_version: 1.3.7
91
117
  signing_key:
92
118
  specification_version: 3
93
119
  summary: Interface to SharePoint