activesp 0.0.1 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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