activesp 0.0.1 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,37 @@
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 Caching
4
30
 
31
+ private
32
+
5
33
  def cache(name, options = {})
34
+ options = options.dup
6
35
  duplicate = options.delete(:dup)
7
36
  options.empty? or raise ArgumentError, "unsupported options #{options.keys.map { |k| k.inspect }.join(", ")}"
8
37
  (@cached_methods ||= []) << name
@@ -14,11 +43,11 @@ module ActiveSP
14
43
  if defined? @#{name}
15
44
  @#{name}
16
45
  else
17
- @#{name} = #{name}__uncached(*a, &b)
18
- end#{".dup" if duplicate}
46
+ @#{name} = #{name}__uncached(*a, &b)#{".dup" if duplicate == :once}
47
+ end#{".dup" if duplicate == :always}
19
48
  end
20
49
  #{access} :#{name}
21
- undef reload if instance_methods.include?("reload")
50
+ remove_method(:reload) if instance_methods(false).include?("reload")
22
51
  def reload
23
52
  #{@cached_methods.map { |m| "remove_instance_variable(:@#{m}) if defined?(@#{m})" }.join(';')}
24
53
  super if defined? super
@@ -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 'savon'
2
27
  require 'net/ntlm_http'
3
28
 
@@ -9,29 +34,40 @@ end
9
34
 
10
35
  module ActiveSP
11
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.
12
39
  class Connection
13
40
 
14
41
  include Util
15
42
  include PersistentCachingConfig
16
43
 
44
+ # @private
17
45
  # TODO: create profile
18
46
  attr_reader :login, :password, :root_url, :trace
19
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.
20
52
  def initialize(options = {})
53
+ options = options.dup
21
54
  @root_url = options.delete(:root) or raise ArgumentError, "missing :root option"
22
55
  @login = options.delete(:login)
23
56
  @password = options.delete(:password)
24
57
  @trace = options.delete(:trace)
25
58
  options.empty? or raise ArgumentError, "unknown options #{options.keys.map { |k| k.inspect }.join(", ")}"
26
59
  cache = nil
27
- configure_persistent_cache { |c| cache = c }
60
+ configure_persistent_cache { |c| cache ||= c }
28
61
  end
29
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
30
66
  def find_by_key(key)
31
67
  type, trail = decode_key(key)
32
68
  case type[0]
33
69
  when ?S
34
- ActiveSP::Site.new(self, trail[0] == "" ? @root_url : File.join(@root_url, trail[0]), trail[1].to_i)
70
+ ActiveSP::Site.new(self, trail[0] == "" ? @root_url : ::File.join(@root_url, trail[0]), trail[1].to_i)
35
71
  when ?L
36
72
  ActiveSP::List.new(find_by_key(trail[0]), trail[1])
37
73
  when ?U
@@ -45,19 +81,11 @@ module ActiveSP
45
81
  when ?P
46
82
  ActiveSP::PermissionSet.new(find_by_key(trail[0]))
47
83
  when ?F
48
- parent = find_by_key(trail[0])
49
- if ActiveSP::Folder === parent
50
- ActiveSP::Folder.new(parent.list, trail[1], parent)
51
- else
52
- ActiveSP::Folder.new(parent, trail[1], nil)
53
- end
84
+ list = find_by_key(trail[0])
85
+ ActiveSP::Folder.new(list, trail[1])
54
86
  when ?I
55
- parent = find_by_key(trail[0])
56
- if ActiveSP::Folder === parent
57
- ActiveSP::Item.new(parent.list, trail[1], parent)
58
- else
59
- ActiveSP::Item.new(parent, trail[1], nil)
60
- end
87
+ list = find_by_key(trail[0])
88
+ ActiveSP::Item.new(list, trail[1])
61
89
  when ?T
62
90
  parent = find_by_key(trail[0])
63
91
  if ActiveSP::List === parent
@@ -70,6 +98,12 @@ module ActiveSP
70
98
  end
71
99
  end
72
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
73
107
  def fetch(url)
74
108
  # TODO: support HTTPS too
75
109
  @open_params ||= begin
@@ -78,9 +112,12 @@ module ActiveSP
78
112
  end
79
113
  Net::HTTP.start(*@open_params) do |http|
80
114
  request = Net::HTTP::Get.new(URL(url).full_path.gsub(/ /, "%20"))
81
- request.ntlm_auth(@login, @password)
115
+ request.ntlm_auth(@login, @password) if @login
82
116
  response = http.request(request)
83
- response
117
+ # if Net::HTTPFound === response
118
+ # response = fetch(response["location"])
119
+ # end
120
+ # response
84
121
  end
85
122
  end
86
123
 
@@ -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 ContentType < Base
@@ -7,9 +32,11 @@ module ActiveSP
7
32
  extend PersistentCaching
8
33
  include Util
9
34
 
35
+ # @private
10
36
  attr_reader :id
11
37
 
12
38
  persistent { |site, list, id, *a| [site.connection, [:content_type, id]] }
39
+ # @private
13
40
  def initialize(site, list, id, name = nil, description = nil, version = nil, group = nil)
14
41
  @site, @list, @id = site, list, id
15
42
  @Name = name if name
@@ -18,49 +45,71 @@ module ActiveSP
18
45
  @Group = group if group
19
46
  end
20
47
 
48
+ # Returns the scope of the content type. This can be either a site or a list
49
+ # @return [Site, List]
21
50
  def scope
22
51
  @list || @site
23
52
  end
24
53
 
54
+ # Returns the supertype of this content type. This is the content type as defined on the containing
55
+ # site in case this content type has a list as scope. returns nil for a content type that has a site
56
+ # as scope
57
+ # @return [ContentType, nil]
25
58
  def supertype
26
59
  superkey = split_id[0..-2].join("")
27
60
  (@list ? @list.content_type(superkey) : nil) || @site.content_type(superkey)
28
61
  end
29
62
  cache :supertype
30
63
 
64
+ # See {Base#key}
65
+ # @return [String]
31
66
  def key
32
67
  encode_key("T", [scope.key, @id])
33
68
  end
34
69
 
70
+ # @private
35
71
  def Name
36
72
  data["Name"].to_s
37
73
  end
38
74
  cache :Name
39
75
 
76
+ # @private
40
77
  def Description
41
78
  data["Description"].to_s
42
79
  end
43
80
  cache :Description
44
81
 
82
+ # @private
45
83
  def Version
46
84
  data["Version"].to_s
47
85
  end
48
86
  cache :Version
49
87
 
88
+ # @private
50
89
  def Group
51
90
  data["Group"].to_s
52
91
  end
53
92
  cache :Group
54
93
 
94
+ # Returns the list of fields defined for this content type
95
+ # @return [Array<Field>]
55
96
  def fields
56
97
  data.xpath("//sp:Field", NS).map { |field| scope.field(field["ID"]) }.compact
57
98
  end
58
- cache :fields, :dup => true
99
+ cache :fields, :dup => :always
59
100
 
101
+ # See {Base#save}
102
+ # @return [void]
103
+ def save
104
+ p untype_cast_attributes(@site, nil, internal_attribute_types, changed_attributes)
105
+ end
106
+
107
+ # @private
60
108
  def to_s
61
109
  "#<ActiveSP::ContentType Name=#{self.Name}>"
62
110
  end
63
111
 
112
+ # @private
64
113
  alias inspect to_s
65
114
 
66
115
  private
@@ -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 Field < Base
@@ -6,41 +31,62 @@ module ActiveSP
6
31
  extend Caching
7
32
  include Util
8
33
 
9
- attr_reader :scope, :ID, :Name, :internal_type, :parent
34
+ # @private
35
+ attr_reader :ID, :Name, :internal_type
36
+ # Returns the scope of the field. This can be a site or a list
37
+ # @return [Site, List]
38
+ attr_reader :scope
39
+ # Returns the parent field. This is the field defined on the containing site in case the field has a list as scope
40
+ # @return [Field]
41
+ attr_reader :parent
10
42
 
11
43
  # There is no call to get to the field info directly, so these should always
12
44
  # be accessed through the site or list they belong to. Hence, we do not use
13
45
  # caching here as it is useless.
46
+ # @private
14
47
  def initialize(scope, id, name, type, parent, attributes_before_type_cast)
15
48
  @scope, @ID, @Name, @internal_type, @parent, @attributes_before_type_cast = scope, id, name, type, parent, attributes_before_type_cast
16
49
  @site = Site === @scope ? @scope : @scope.site
17
50
  end
18
51
 
52
+ # See {Base#key}
53
+ # @return [String]
19
54
  def key
20
55
  encode_key("A", [@scope.key, @ID])
21
56
  end
22
57
 
58
+ # @private
23
59
  def List
24
60
  list_for_lookup
25
61
  end
26
62
 
63
+ # @private
27
64
  def Type
28
65
  translate_internal_type(self)
29
66
  end
30
67
 
31
- # This is only defined when it is true; joy to the world!
68
+ # @private
32
69
  def Mult
33
70
  !!attributes["Mult"]
34
71
  end
35
72
 
73
+ # @private
36
74
  def ReadOnly
37
75
  !!attributes["ReadOnly"]
38
76
  end
39
77
 
78
+ # See {Base#save}
79
+ # @return [void]
80
+ def save
81
+ p untype_cast_attributes(@site, nil, internal_attribute_types, changed_attributes)
82
+ end
83
+
84
+ # @private
40
85
  def to_s
41
86
  "#<ActiveSP::Field name=#{self.Name}>"
42
87
  end
43
88
 
89
+ # @private
44
90
  alias inspect to_s
45
91
 
46
92
  private
@@ -0,0 +1,71 @@
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
+ class File
29
+
30
+ include InSite
31
+
32
+ attr_reader :url
33
+
34
+ def initialize(item, url, destroyable)
35
+ @item, @url, @destroyable = item, url, destroyable
36
+ @site = @item.list.site
37
+ end
38
+
39
+ def file_name
40
+ ::File.basename(@url)
41
+ end
42
+
43
+ def data
44
+ @item.list.site.connection.fetch(@url).body
45
+ end
46
+
47
+ def destroy
48
+ if @destroyable
49
+ result = call("Lists", "delete_attachment", "listName" => @item.list.id, "listItemID" => @item.ID, "url" => @url)
50
+ if delete_result = result.xpath("//sp:DeleteAttachmentResponse", NS).first
51
+ self
52
+ else
53
+ raise "file could not be deleted"
54
+ end
55
+ else
56
+ raise TypeError, "this file cannot be destroyed"
57
+ end
58
+ end
59
+
60
+ # @private
61
+ def to_s
62
+ "#<ActiveSP::File url=#{@url}>"
63
+ end
64
+
65
+ # @private
66
+ alias inspect to_s
67
+
68
+ end
69
+
70
+ end
71
+