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 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