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/LICENSE ADDED
@@ -0,0 +1,25 @@
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
+
10
+ Software is furnished to do so, subject to the following
11
+ conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
+
23
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,105 @@
1
+ = ActiveSP Release 0.0.3 "Under Pressure" (Aug 27th 2010)
2
+
3
+ == What?
4
+
5
+ ActiveSP is a library for talking to SharePoint through its web services in an
6
+ object-oriented way.
7
+
8
+ At the moment it only provides read-only access and write access to list items.
9
+ Full write access is on the way!
10
+
11
+ == Why?
12
+
13
+ Because Ruby is great and SharePoint's popularity is a fact of life.
14
+
15
+ == When?
16
+
17
+ This library is pure Ruby and does not need a Ruby VM running on .NET (such as IronRuby).
18
+ Use this library when using IronRuby is not an option, or when it needs to run on more
19
+ than IronRuby.
20
+
21
+ The web services are not fully functional and somewhat slow, so if you can use
22
+ the .NET platform then consider talking to the .NET API's directly instead.
23
+
24
+ == How?
25
+
26
+ Install the gem and its dependencies:
27
+
28
+ gem install activesp
29
+
30
+ Create a file <tt>test.rb</tt> like this:
31
+
32
+ require 'rubygems'
33
+ require 'activesp'
34
+
35
+ def browse(item, indentation = 0)
36
+ puts " " * indentation + "- " + item.class.to_s + " : " + item.url
37
+ case item
38
+ when ActiveSP::Site
39
+ puts " " * indentation + " Title = #{item.Title}, Description = #{item.Description}"
40
+ item.sites.each { |site| browse(site, indentation + 1) }
41
+ item.lists.each { |list| browse(list, indentation + 1) }
42
+ when ActiveSP::List
43
+ puts " " * indentation + " Description = #{item.Description}, Hidden = #{item.Hidden}"
44
+ item.items.each { |item| browse(item, indentation + 1) }
45
+ when ActiveSP::Folder
46
+ item.items.each { |item| browse(item, indentation + 1) }
47
+ when ActiveSP::Item
48
+ item.content_urls.each do |url|
49
+ puts " " * indentation + " Content URL = #{url}"
50
+ end
51
+ end
52
+ end
53
+
54
+ c = ActiveSP::Connection.new(:login => "your login", :password => "your password", :root => "URL of root site")
55
+
56
+ browse(c.root)
57
+
58
+ Run <tt>ruby test.rb</tt> and it will print the structure of your SharePoint site.
59
+
60
+ The examples directory contains this example plus a few others. We will add more along the way.
61
+
62
+ == Support
63
+
64
+ We support read access to sites (webs), lists, items, documents, folders, content type,
65
+ columns (fields), content, users, groups, roles.
66
+
67
+ We support write access to list items (including documents): create, update and delete list items.
68
+
69
+ We do not yet support life cycles, versions, full write support.
70
+
71
+ == Compatibility
72
+
73
+ We have tested ActiveSP with SharePoint 2007 and SharePoint 2010. ActiveSP has been tested
74
+ on Mac OS X with Ruby 1.8.6, but we do not see any reason why it would not work on Linux
75
+ or Windows, or with other Ruby implementations.
76
+
77
+ For release 0.0.3, we have not tested extensively on SharePoint 2007 so we can't guarantee
78
+ compatibility.
79
+
80
+ == Changelog
81
+
82
+ === ActiveSP Release 0.0.3 "Under Pressure" (Aug 27th 2010)
83
+
84
+ * Added write support for list items (including documents): create, update, delete
85
+ * Use association proxies for list items and item attachments
86
+ * Decode field names (e.g., File_x0020_Type becomes File Type)
87
+ * A few bug fixes
88
+ * Added method to ask for list changes since token
89
+
90
+ === ActiveSP Release 0.0.1 "Space Oddity" (Apr 9th 2010)
91
+
92
+ * Initial release
93
+
94
+ == License
95
+
96
+ ActiveSP is released under the MIT license. The usual disclaimers apply, including that we are
97
+ not responsible for inevitable Ruby addiction.
98
+
99
+ See the LICENSE file included in the distribution for further details.
100
+
101
+ == Who?
102
+
103
+ ActiveSP is copyright (c) 2010 XAOP bvba
104
+
105
+ Visit us at http://www.xaop.com.
data/Rakefile CHANGED
@@ -1,5 +1,31 @@
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
  require 'rubygems'
2
27
  require 'rake/gempackagetask'
28
+ require 'yard'
3
29
 
4
30
  ACTIVESP_VERSION = File.readlines("VERSION")[0][/[\d.]*/]
5
31
 
@@ -9,18 +35,17 @@ spec = Gem::Specification.new do |s|
9
35
  s.version = ACTIVESP_VERSION
10
36
  s.author = "Peter Vanbroekhoven"
11
37
  s.email = "peter@xaop.com"
12
- #s.homepage = "http://www.xaop.com/pages/dctmruby"
38
+ s.homepage = "http://www.xaop.com/labs/activesp"
13
39
  s.summary = "Interface to SharePoint"
14
- s.description = s.summary
15
- #s.rubyforge_project = s.name
16
- s.files += %w(VERSION Rakefile)
40
+ s.description = "An object-oriented interface to SharePoint that uses the web services provided by SharePoint to connect to it. Supports SharePoint 2007 and 2010."
41
+ s.files += %w(VERSION LICENSE README.rdoc Rakefile)
17
42
  s.files += Dir['lib/**/*.rb']
18
43
  # s.bindir = "bin"
19
- # s.executables.push(*(Dir['bin/*.rb'] - ["bin/encrypt-dmcl.rb"]).map { |f| File.basename(f) })
44
+ # s.executables.push(*(Dir['bin/*.rb']))
20
45
  s.add_dependency('savon-xaop')
21
46
  s.add_dependency('nokogiri')
22
47
  # s.rdoc_options << '--exclude' << 'ext' << '--main' << 'README'
23
- # s.extra_rdoc_files = ["README", "docs/README.html"]
48
+ # s.extra_rdoc_files = ["README"]
24
49
  s.has_rdoc = false
25
50
  s.require_paths << 'lib'
26
51
  # s.autorequire = 'mysql'
@@ -32,3 +57,7 @@ Rake::GemPackageTask.new(spec) do |pkg|
32
57
  pkg.need_zip = true
33
58
  pkg.need_tar = true
34
59
  end
60
+
61
+ YARD::Rake::YardocTask.new do |t|
62
+ t.options = ['--no-private', '--readme', 'README.rdoc']
63
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.4
data/lib/activesp.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
  require 'nokogiri'
2
27
  require 'time'
3
28
 
@@ -6,6 +31,7 @@ end
6
31
 
7
32
  require 'activesp/util'
8
33
  require 'activesp/caching'
34
+ require 'activesp/associations'
9
35
  require 'activesp/persistent_caching'
10
36
 
11
37
  require 'activesp/base'
@@ -24,3 +50,4 @@ require 'activesp/user'
24
50
  require 'activesp/group'
25
51
  require 'activesp/role'
26
52
  require 'activesp/permission_set'
53
+ require 'activesp/file'
@@ -0,0 +1,76 @@
1
+ # Copyright (c) 2010 XAOP bvba
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person
4
+ # obtaining a copy of this software and associated documentation
5
+ # files (the "Software"), to deal in the Software without
6
+ # restriction, including without limitation the rights to use,
7
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the
9
+ # Software is furnished to do so, subject to the following
10
+ # conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ #
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
+ # OTHER DEALINGS IN THE SOFTWARE.
25
+
26
+ module ActiveSP
27
+
28
+ # @private
29
+ module Associations
30
+
31
+ class AssociationProxy
32
+
33
+ include Enumerable
34
+
35
+ def initialize(object, &element_getter)
36
+ @object = object
37
+ @element_getter = element_getter
38
+ end
39
+
40
+ def each(&blk)
41
+ @element_getter.call(blk)
42
+ end
43
+
44
+ def first
45
+ each { |element| return element }
46
+ nil
47
+ end
48
+
49
+ def last
50
+ inject { |_, element| element }
51
+ end
52
+
53
+ def count
54
+ inject(0) { |cnt, _| cnt + 1 }
55
+ end
56
+
57
+ end
58
+
59
+ private
60
+
61
+ def association(name, each_method = ("each_" + name.to_s.sub(/s\z/, "")).to_sym, &blk)
62
+ proxy = Class.new(AssociationProxy) do
63
+ class_eval(&blk) if blk
64
+ define_method(:to_s) { "#{@object.to_s}.#{name}" }
65
+ define_method(:inspect) { "#{@object.inspect}.#{name}" }
66
+ end
67
+ define_method(name) do |*a|
68
+ proxy.new(self) do |blk|
69
+ send(each_method, *a, &blk)
70
+ end
71
+ end
72
+ end
73
+
74
+ end
75
+
76
+ end
data/lib/activesp/base.rb CHANGED
@@ -1,35 +1,99 @@
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
+ # The base class for all objects stored in SharePoint
3
29
  class Base
4
30
 
5
31
  extend Caching
32
+ extend Associations
6
33
 
34
+ # Returns a key that can be used to retrieve this object later on using {Connection#find_by_key}
35
+ # @return [String]
36
+ def key
37
+ raise "This is here for documentation purposes only"
38
+ end
39
+
40
+ # Returns the attributes of this object as a Hash
41
+ # @return [Hash{String => Integer, Float, String, Time, Boolean, Base}]
7
42
  def attributes
8
43
  current_attributes
9
44
  end
10
- cache :attributes, :dup => true
45
+ cache :attributes, :dup => :always
11
46
 
47
+ # Returns the types of the attributes of this object as a Hash
48
+ # @return [Hash{String => Field}]
12
49
  def attribute_types
13
50
  internal_attribute_types
14
51
  end
15
- cache :attribute_types, :dup => true
52
+ cache :attribute_types, :dup => :always
16
53
 
54
+ # Returns whether or not this object has an attribute with the given name
55
+ # @param [String] name The name of the attribute
56
+ # @return [Boolean]
17
57
  def has_attribute?(name)
18
- attributes.has_key?(name)
58
+ current_attributes.has_key?(name)
19
59
  end
20
60
 
61
+ # Returns whether or not this object has an attribute with the given name that can be assigned to
62
+ # @param [String] name The name of the attribute
63
+ # @return [Boolean]
21
64
  def has_writable_attribute?(name)
22
- has_attribute?(name) && !attribute_types[name].ReadOnly
65
+ has_attribute?(name) and attr = internal_attribute_types[name] and !attr.ReadOnly
23
66
  end
24
67
 
68
+ # Returns the value of the attribute of the given name, or nil if this object does not have an attribute by the given name
69
+ # @param [String] name The name of the attribute
70
+ # @return [Integer, Float, String, Time, Boolean, Base]
25
71
  def attribute(name)
26
- attributes[name]
72
+ current_attributes[name]
73
+ end
74
+
75
+ # Returns the type of the attribute by the given name, or nil if this object does not have an attribute by the given name
76
+ # @param [String] name The name of the attribute
77
+ # @return [Field]
78
+ def attribute_type(name)
79
+ internal_attribute_types[name]
27
80
  end
28
81
 
82
+ # Sets the attribute with the given name to the given value
83
+ # @param [String] name The name of the attribute
84
+ # @param [Integer, Float, String, Time, Boolean, Base] value The value to assign
85
+ # @return [Integer, Float, String, Time, Boolean, Base] The assigned value
86
+ # @raise [ArgumentError] Raised when this object does not have an attribute by the given name or if the attribute by the given name is read-only
29
87
  def set_attribute(name, value)
30
- current_attributes[name] = value
88
+ has_attribute?(name) and field = attribute_type(name) and internal_attribute_types[name] or raise ArgumentError, "#{self} has no field by the name #{name}"
89
+ !field.ReadOnly or raise ArgumentError, "field #{name} of #{self} is read-only"
90
+ current_attributes[name] = type_check_attribute(field, value)
31
91
  end
32
92
 
93
+ # Provides convenient getters and setters for attributes. Note that no name mangling
94
+ # is done, so an attribute such as Title is accessed as obj.Title. The main rationale
95
+ # behind this is that name mangling is usually not lossless (e.g., both <tt>Title</tt>
96
+ # and <tt>title</tt> could map to the more Rubyish <tt>title</tt>) and imperfect.
33
97
  def method_missing(m, *a, &b)
34
98
  ms = m.to_s
35
99
  if a.length == 0 && has_attribute?(ms)
@@ -41,13 +105,35 @@ module ActiveSP
41
105
  end
42
106
  end
43
107
 
108
+ # Reloads the object from the server
109
+ # @return [void]
110
+ def reload
111
+ end
112
+
113
+ # Saves the object to the server. Raises an exception when the save fails
114
+ # @return [void]
115
+ def save
116
+ end
117
+
44
118
  private
45
119
 
46
120
  def current_attributes
47
- original_attributes
121
+ original_attributes.inject({}) { |h, (k, v)| h[k] = ::Array === v ? v.dup.freeze : v ; h }
48
122
  end
49
123
  cache :current_attributes
50
124
 
125
+ def changed_attributes
126
+ before = original_attributes
127
+ after = current_attributes
128
+ changes = {}
129
+ after.each do |name, value|
130
+ if before[name] != value
131
+ changes[name] = value
132
+ end
133
+ end
134
+ changes
135
+ end
136
+
51
137
  end
52
138
 
53
139
  end