pyu-activesp 0.0.4.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +25 -0
- data/README.rdoc +105 -0
- data/Rakefile +63 -0
- data/VERSION +1 -0
- data/lib/activesp/associations.rb +76 -0
- data/lib/activesp/base.rb +139 -0
- data/lib/activesp/caching.rb +60 -0
- data/lib/activesp/connection.rb +126 -0
- data/lib/activesp/content_type.rb +152 -0
- data/lib/activesp/field.rb +193 -0
- data/lib/activesp/file.rb +71 -0
- data/lib/activesp/folder.rb +103 -0
- data/lib/activesp/ghost_field.rb +100 -0
- data/lib/activesp/group.rb +107 -0
- data/lib/activesp/item.rb +338 -0
- data/lib/activesp/list.rb +509 -0
- data/lib/activesp/permission_set.rb +64 -0
- data/lib/activesp/persistent_caching.rb +112 -0
- data/lib/activesp/role.rb +116 -0
- data/lib/activesp/root.rb +128 -0
- data/lib/activesp/site.rb +305 -0
- data/lib/activesp/url.rb +146 -0
- data/lib/activesp/user.rb +97 -0
- data/lib/activesp/util.rb +326 -0
- data/lib/activesp.rb +53 -0
- metadata +118 -0
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
ADDED
@@ -0,0 +1,63 @@
|
|
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
|
+
require 'rubygems'
|
27
|
+
require 'rake/gempackagetask'
|
28
|
+
require 'yard'
|
29
|
+
|
30
|
+
ACTIVESP_VERSION = File.readlines("VERSION")[0][/[\d.]*/]
|
31
|
+
|
32
|
+
desc "Build the gem"
|
33
|
+
spec = Gem::Specification.new do |s|
|
34
|
+
s.name = "activesp"
|
35
|
+
s.version = ACTIVESP_VERSION
|
36
|
+
s.author = "Peter Vanbroekhoven"
|
37
|
+
s.email = "peter@xaop.com"
|
38
|
+
s.homepage = "http://www.xaop.com/labs/activesp"
|
39
|
+
s.summary = "Interface to SharePoint"
|
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)
|
42
|
+
s.files += Dir['lib/**/*.rb']
|
43
|
+
# s.bindir = "bin"
|
44
|
+
# s.executables.push(*(Dir['bin/*.rb']))
|
45
|
+
s.add_dependency('savon-xaop')
|
46
|
+
s.add_dependency('nokogiri')
|
47
|
+
# s.rdoc_options << '--exclude' << 'ext' << '--main' << 'README'
|
48
|
+
# s.extra_rdoc_files = ["README"]
|
49
|
+
s.has_rdoc = false
|
50
|
+
s.require_paths << 'lib'
|
51
|
+
# s.autorequire = 'mysql'
|
52
|
+
s.required_ruby_version = '>= 1.8.1'
|
53
|
+
s.platform = Gem::Platform::RUBY
|
54
|
+
end
|
55
|
+
|
56
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
57
|
+
pkg.need_zip = true
|
58
|
+
pkg.need_tar = true
|
59
|
+
end
|
60
|
+
|
61
|
+
YARD::Rake::YardocTask.new do |t|
|
62
|
+
t.options = ['--no-private', '--readme', 'README.rdoc']
|
63
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.4.1.2
|
@@ -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
|
@@ -0,0 +1,139 @@
|
|
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
|
+
# The base class for all objects stored in SharePoint
|
29
|
+
class Base
|
30
|
+
|
31
|
+
extend Caching
|
32
|
+
extend Associations
|
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}]
|
42
|
+
def attributes
|
43
|
+
current_attributes
|
44
|
+
end
|
45
|
+
cache :attributes, :dup => :always
|
46
|
+
|
47
|
+
# Returns the types of the attributes of this object as a Hash
|
48
|
+
# @return [Hash{String => Field}]
|
49
|
+
def attribute_types
|
50
|
+
internal_attribute_types
|
51
|
+
end
|
52
|
+
cache :attribute_types, :dup => :always
|
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]
|
57
|
+
def has_attribute?(name)
|
58
|
+
current_attributes.has_key?(name)
|
59
|
+
end
|
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]
|
64
|
+
def has_writable_attribute?(name)
|
65
|
+
has_attribute?(name) and attr = internal_attribute_types[name] and !attr.ReadOnly
|
66
|
+
end
|
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]
|
71
|
+
def attribute(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]
|
80
|
+
end
|
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
|
87
|
+
def set_attribute(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)
|
91
|
+
end
|
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.
|
97
|
+
def method_missing(m, *a, &b)
|
98
|
+
ms = m.to_s
|
99
|
+
if a.length == 0 && has_attribute?(ms)
|
100
|
+
attribute(ms)
|
101
|
+
elsif a.length == 1 && ms[-1] == ?= && has_writable_attribute?(ms[0..-2])
|
102
|
+
set_attribute(ms[0..-2], *a)
|
103
|
+
else
|
104
|
+
super
|
105
|
+
end
|
106
|
+
end
|
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
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def current_attributes
|
121
|
+
original_attributes.inject({}) { |h, (k, v)| h[k] = ::Array === v ? v.dup.freeze : v ; h }
|
122
|
+
end
|
123
|
+
cache :current_attributes
|
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
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
@@ -0,0 +1,60 @@
|
|
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 Caching
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def cache(name, options = {})
|
34
|
+
options = options.dup
|
35
|
+
duplicate = options.delete(:dup)
|
36
|
+
options.empty? or raise ArgumentError, "unsupported options #{options.keys.map { |k| k.inspect }.join(", ")}"
|
37
|
+
(@cached_methods ||= []) << name
|
38
|
+
alias_method("#{name}__uncached", name)
|
39
|
+
access = private_instance_methods.include?(name) ? "private" : protected_instance_methods.include?(name) ? "protected" : "public"
|
40
|
+
private("#{name}__uncached")
|
41
|
+
module_eval <<-RUBY
|
42
|
+
def #{name}(*a, &b)
|
43
|
+
if defined? @#{name}
|
44
|
+
@#{name}
|
45
|
+
else
|
46
|
+
@#{name} = #{name}__uncached(*a, &b)#{".dup" if duplicate == :once}
|
47
|
+
end#{".dup" if duplicate == :always}
|
48
|
+
end
|
49
|
+
#{access} :#{name}
|
50
|
+
remove_method(:reload) if instance_methods(false).include?("reload")
|
51
|
+
def reload
|
52
|
+
#{@cached_methods.map { |m| "remove_instance_variable(:@#{m}) if defined?(@#{m})" }.join(';')}
|
53
|
+
super if defined? super
|
54
|
+
end
|
55
|
+
RUBY
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,126 @@
|
|
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
|
+
require 'savon'
|
27
|
+
require 'net/ntlm_http'
|
28
|
+
|
29
|
+
Savon::Request.logger.level = Logger::ERROR
|
30
|
+
|
31
|
+
Savon::Response.error_handler do |soap_fault|
|
32
|
+
soap_fault[:detail][:errorstring]
|
33
|
+
end
|
34
|
+
|
35
|
+
module ActiveSP
|
36
|
+
|
37
|
+
# This class is uses to configure the connection to a SharePoint repository. This is
|
38
|
+
# the starting point for doing anything with SharePoint.
|
39
|
+
class Connection
|
40
|
+
|
41
|
+
include Util
|
42
|
+
include PersistentCachingConfig
|
43
|
+
|
44
|
+
# @private
|
45
|
+
# TODO: create profile
|
46
|
+
attr_reader :login, :password, :root_url, :trace
|
47
|
+
|
48
|
+
# @param [Hash] options The connection options
|
49
|
+
# @option options [String] :root The URL of the root site
|
50
|
+
# @option options [String] :login (nil) The login
|
51
|
+
# @option options [String] :password (nil) The password associated with the given login. Is mandatory if the login is specified. Also can't be "password" as that is inherently insafe. We don't explicitly check for this, but it can't be that.
|
52
|
+
def initialize(options = {})
|
53
|
+
options = options.dup
|
54
|
+
@root_url = options.delete(:root) or raise ArgumentError, "missing :root option"
|
55
|
+
@login = options.delete(:login)
|
56
|
+
@password = options.delete(:password)
|
57
|
+
@trace = options.delete(:trace)
|
58
|
+
options.empty? or raise ArgumentError, "unknown options #{options.keys.map { |k| k.inspect }.join(", ")}"
|
59
|
+
cache = nil
|
60
|
+
configure_persistent_cache { |c| cache ||= c }
|
61
|
+
end
|
62
|
+
|
63
|
+
# Finds the object with the given key
|
64
|
+
# @param [String] key The key of the object to find
|
65
|
+
# @return [Base, nil] The object with the given key, or nil if no object with the given key is found
|
66
|
+
def find_by_key(key)
|
67
|
+
type, trail = decode_key(key)
|
68
|
+
case type[0]
|
69
|
+
when ?S
|
70
|
+
ActiveSP::Site.new(self, trail[0] == "" ? @root_url : ::File.join(@root_url, trail[0]), trail[1].to_i)
|
71
|
+
when ?L
|
72
|
+
ActiveSP::List.new(find_by_key(trail[0]), trail[1])
|
73
|
+
when ?U
|
74
|
+
ActiveSP::User.new(root, trail[0])
|
75
|
+
when ?G
|
76
|
+
ActiveSP::Group.new(root, trail[0])
|
77
|
+
when ?R
|
78
|
+
ActiveSP::Role.new(root, trail[0])
|
79
|
+
when ?A
|
80
|
+
find_by_key(trail[0]).field(trail[1])
|
81
|
+
when ?P
|
82
|
+
ActiveSP::PermissionSet.new(find_by_key(trail[0]))
|
83
|
+
when ?F
|
84
|
+
list = find_by_key(trail[0])
|
85
|
+
ActiveSP::Folder.new(list, trail[1])
|
86
|
+
when ?I
|
87
|
+
list = find_by_key(trail[0])
|
88
|
+
ActiveSP::Item.new(list, trail[1])
|
89
|
+
when ?T
|
90
|
+
parent = find_by_key(trail[0])
|
91
|
+
if ActiveSP::List === parent
|
92
|
+
ActiveSP::ContentType.new(parent.site, parent, trail[1])
|
93
|
+
else
|
94
|
+
ActiveSP::ContentType.new(parent, nil, trail[1])
|
95
|
+
end
|
96
|
+
else
|
97
|
+
raise "not yet #{key.inspect}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Fetches the content at the given URL using the login and password with which this
|
102
|
+
# connection was constructed, if any. Always uses the GET method. Supports only
|
103
|
+
# HTTP as protocol at the time of writing. This is useful for fetching content files
|
104
|
+
# from the server.
|
105
|
+
# @param [String] url The URL to fetch
|
106
|
+
# @return [String] The content fetched from the URL
|
107
|
+
def fetch(url)
|
108
|
+
# TODO: support HTTPS too
|
109
|
+
@open_params ||= begin
|
110
|
+
u = URL(@root_url)
|
111
|
+
[u.host, u.port]
|
112
|
+
end
|
113
|
+
Net::HTTP.start(*@open_params) do |http|
|
114
|
+
request = Net::HTTP::Get.new(URL(url).full_path.gsub(/ /, "%20"))
|
115
|
+
request.ntlm_auth(@login, @password) if @login
|
116
|
+
response = http.request(request)
|
117
|
+
# if Net::HTTPFound === response
|
118
|
+
# response = fetch(response["location"])
|
119
|
+
# end
|
120
|
+
# response
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|