cmis-ruby 0.3.1 → 0.3.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.
- checksums.yaml +4 -4
- data/lib/cmis-ruby.rb +4 -0
- data/lib/cmis/connection.rb +147 -89
- data/lib/cmis/core_ext/array.rb +14 -0
- data/lib/cmis/core_ext/hash.rb +5 -0
- data/lib/cmis/helpers.rb +17 -4
- data/lib/cmis/object.rb +2 -7
- data/lib/cmis/relationship.rb +4 -0
- data/lib/cmis/relationships.rb +101 -0
- data/lib/cmis/repository.rb +1 -10
- data/lib/cmis/version.rb +1 -1
- data/spec/helper.rb +0 -1
- data/spec/object_spec.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c5f9d4df93396fe4735ee09d4d97db95c48df45
|
4
|
+
data.tar.gz: 8938574723b4af67c631415610fcf4f71c4a1987
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db9eec57e4879bcd1ef91cac2f717754e3ac376995cc11fe4f4c3af91dba94b3f777af086447e785eeb4d3887e3ae0247daea4be8f0fbd44e45737b3f42db71a
|
7
|
+
data.tar.gz: d8e06feb0c924488abe759cf1b7525f7d3e1ee33dde2e77e5bee374164d4542bda06b057705dcc974eb806a3f39998db52e0a640a071bdbf3d4ca59ce19f8f2f
|
data/lib/cmis-ruby.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'cmis/core_ext/array'
|
2
|
+
require 'cmis/core_ext/hash'
|
3
|
+
|
1
4
|
require 'cmis/connection'
|
2
5
|
require 'cmis/exceptions'
|
3
6
|
require 'cmis/server'
|
@@ -6,6 +9,7 @@ require 'cmis/object_factory'
|
|
6
9
|
require 'cmis/query_result'
|
7
10
|
require 'cmis/query'
|
8
11
|
require 'cmis/children'
|
12
|
+
require 'cmis/relationships'
|
9
13
|
require 'cmis/repository'
|
10
14
|
require 'cmis/object'
|
11
15
|
require 'cmis/document'
|
data/lib/cmis/connection.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'active_support'
|
2
|
+
require 'json'
|
2
3
|
require 'typhoeus'
|
3
4
|
require 'net/http/post/multipart'
|
4
5
|
|
5
6
|
module CMIS
|
6
7
|
class Connection
|
7
|
-
|
8
8
|
def initialize(service_url, username, password, headers)
|
9
9
|
@service_url = service_url
|
10
10
|
@username = username
|
@@ -15,123 +15,181 @@ module CMIS
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def execute!(params = {}, options = {})
|
18
|
-
options
|
19
|
-
|
20
|
-
|
18
|
+
query, headers = parse_options(options)
|
19
|
+
|
20
|
+
Request.new(service_url: @service_url,
|
21
|
+
url_cache: @url_cache,
|
22
|
+
params: params,
|
23
|
+
query: query,
|
24
|
+
headers: headers,
|
25
|
+
username: @username,
|
26
|
+
password: @password).run
|
27
|
+
end
|
21
28
|
|
22
|
-
|
29
|
+
private
|
23
30
|
|
24
|
-
|
31
|
+
def parse_options(options)
|
32
|
+
options.symbolize_keys!
|
33
|
+
query = options[:query] || {}
|
34
|
+
headers = @headers
|
35
|
+
headers.merge!(options[:headers]) if options[:headers]
|
36
|
+
[ query, headers ]
|
37
|
+
end
|
25
38
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
query
|
39
|
+
class Request
|
40
|
+
def initialize(options)
|
41
|
+
@service_url = options[:service_url]
|
42
|
+
@url_cache = options[:url_cache]
|
43
|
+
@params = massage(options[:params])
|
44
|
+
@repository_id = @params.delete(:repositoryId)
|
45
|
+
@query = options[:query]
|
46
|
+
@headers = options[:headers]
|
47
|
+
@username = options[:username]
|
48
|
+
@password = options[:password]
|
33
49
|
end
|
34
50
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
51
|
+
def run
|
52
|
+
case method
|
53
|
+
when 'get'
|
54
|
+
typhoeus_request
|
55
|
+
when 'post'
|
56
|
+
typhoeus_request
|
57
|
+
when 'multipart_post'
|
58
|
+
multipart_post
|
59
|
+
end
|
42
60
|
end
|
43
61
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
62
|
+
private
|
63
|
+
|
64
|
+
def typhoeus_request
|
65
|
+
options = {
|
66
|
+
method: method,
|
67
|
+
body: body,
|
68
|
+
params: query,
|
69
|
+
headers: @headers,
|
70
|
+
followlocation: true
|
71
|
+
}
|
72
|
+
options[:userpwd] = "#{@username}:#{@password}" if @username
|
73
|
+
response = Typhoeus::Request.new(url, options).run
|
74
|
+
Response.new(response.headers['Content-Type'], response.body).parse!
|
75
|
+
end
|
54
76
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
77
|
+
def multipart_post
|
78
|
+
uri = URI.parse(url)
|
79
|
+
req = Net::HTTP::Post::Multipart.new(uri.path, body)
|
80
|
+
@headers.each { |key, value| req[key] = value }
|
81
|
+
req.basic_auth @username, @password if @username
|
82
|
+
opts = if uri.scheme == 'https'
|
83
|
+
{ use_ssl: true , verify_mode: OpenSSL::SSL::VERIFY_NONE }
|
84
|
+
else
|
85
|
+
{}
|
86
|
+
end
|
87
|
+
Net::HTTP.start(uri.host, uri.port, opts) do |http|
|
88
|
+
response = http.request(req)
|
89
|
+
Response.new(response['Content-Type'], response.body).parse!
|
60
90
|
end
|
61
91
|
end
|
62
|
-
end
|
63
92
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
else
|
68
|
-
urls = repository_urls(repository_id)
|
69
|
-
if cmis_object_id
|
70
|
-
urls[:root_folder_url]
|
93
|
+
def url
|
94
|
+
if @repository_id.nil?
|
95
|
+
@service_url
|
71
96
|
else
|
72
|
-
urls
|
97
|
+
urls = repository_urls(@repository_id)
|
98
|
+
if @params[:objectId]
|
99
|
+
urls[:root_folder_url]
|
100
|
+
else
|
101
|
+
urls[:repository_url]
|
102
|
+
end
|
73
103
|
end
|
74
104
|
end
|
75
|
-
end
|
76
105
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
106
|
+
def method
|
107
|
+
if @params[:cmisaction]
|
108
|
+
if @params[:content]
|
109
|
+
'multipart_post'
|
110
|
+
else
|
111
|
+
'post'
|
112
|
+
end
|
113
|
+
else
|
114
|
+
'get'
|
115
|
+
end
|
84
116
|
end
|
85
|
-
@url_cache[repository_id]
|
86
|
-
end
|
87
117
|
|
88
|
-
|
89
|
-
|
118
|
+
def body
|
119
|
+
@params if @params[:cmisaction]
|
120
|
+
end
|
90
121
|
|
91
|
-
|
92
|
-
|
122
|
+
def query
|
123
|
+
if @params[:cmisaction]
|
124
|
+
@query
|
125
|
+
else
|
126
|
+
@params.merge(@query)
|
127
|
+
end
|
93
128
|
end
|
94
129
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
130
|
+
# TODO: Extract functionality
|
131
|
+
def massage(hash)
|
132
|
+
hash.compact
|
133
|
+
|
134
|
+
if content_hash = hash[:content]
|
135
|
+
hash[:content] = UploadIO.new(content_hash[:stream],
|
136
|
+
content_hash[:mime_type],
|
137
|
+
content_hash[:filename])
|
138
|
+
end
|
139
|
+
|
140
|
+
if props = hash.delete(:properties)
|
141
|
+
props.each_with_index do |(id, value), index|
|
142
|
+
value = value.to_time if value.is_a?(Date) or value.is_a?(DateTime)
|
143
|
+
value = (value.to_f * 1000).to_i if value.is_a?(Time)
|
144
|
+
if value.is_a?(Array)
|
145
|
+
hash.merge!("propertyId[#{index}]" => id)
|
146
|
+
value.each_with_index do |v, idx|
|
147
|
+
hash.merge!("propertyValue[#{index}][#{idx}]" => value[idx])
|
148
|
+
end
|
149
|
+
else
|
150
|
+
hash.merge!("propertyId[#{index}]" => id,
|
151
|
+
"propertyValue[#{index}]" => value)
|
103
152
|
end
|
104
|
-
else
|
105
|
-
hash.merge!("propertyId[#{index}]" => id,
|
106
|
-
"propertyValue[#{index}]" => value)
|
107
153
|
end
|
108
154
|
end
|
155
|
+
hash
|
109
156
|
end
|
110
|
-
hash
|
111
|
-
end
|
112
157
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
158
|
+
def repository_urls(repository_id)
|
159
|
+
if @url_cache[repository_id].nil?
|
160
|
+
|
161
|
+
options = { method: 'get' }
|
162
|
+
options[:userpwd] = "#{@username}:#{@password}" if @username
|
163
|
+
response = Typhoeus::Request.new(@service_url, options).run
|
164
|
+
repository_infos = JSON.parse(response.body)
|
165
|
+
|
166
|
+
unless repository_infos.has_key?(repository_id)
|
167
|
+
raise Exceptions::ObjectNotFound, "repositoryId: #{repository_id}"
|
168
|
+
end
|
169
|
+
|
170
|
+
repository_info = repository_infos[repository_id]
|
171
|
+
@url_cache[repository_id] = { repository_url: repository_info['repositoryUrl'],
|
172
|
+
root_folder_url: repository_info['rootFolderUrl'] }
|
173
|
+
end
|
174
|
+
@url_cache[repository_id]
|
118
175
|
end
|
119
176
|
end
|
120
177
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
178
|
+
class Response
|
179
|
+
def initialize(content_type, body)
|
180
|
+
@content_type = content_type
|
181
|
+
@body = body
|
182
|
+
end
|
183
|
+
|
184
|
+
def parse!
|
185
|
+
return @body unless @content_type =~ /application\/json/
|
127
186
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
Net::HTTP.start(url.host, url.port, opts) { |http| http.request(req) }
|
187
|
+
result = JSON.parse(@body)
|
188
|
+
if result.is_a?(Hash) && ex = result['exception']
|
189
|
+
raise "CMIS::Exceptions::#{ex.camelize}".constantize, result['message']
|
190
|
+
end
|
191
|
+
result.with_indifferent_access
|
192
|
+
end
|
135
193
|
end
|
136
194
|
end
|
137
195
|
end
|
data/lib/cmis/helpers.rb
CHANGED
@@ -41,10 +41,7 @@ module CMIS
|
|
41
41
|
result = raw['succinctProperties']
|
42
42
|
elsif raw['properties']
|
43
43
|
result = raw['properties'].reduce({}) do |h, (k, v)|
|
44
|
-
|
45
|
-
val = v['value'].first if v['value'].is_a?(Array) and v['cardinality'] == 'single'
|
46
|
-
val = Time.at(val / 1000) if val and v['type'] == 'datetime'
|
47
|
-
h.merge(k => val)
|
44
|
+
h.merge(k => sanitize(v))
|
48
45
|
end
|
49
46
|
else
|
50
47
|
result = {}
|
@@ -52,5 +49,21 @@ module CMIS
|
|
52
49
|
|
53
50
|
result.with_indifferent_access
|
54
51
|
end
|
52
|
+
|
53
|
+
def sanitize(prop)
|
54
|
+
value = prop['value']
|
55
|
+
|
56
|
+
# Sometimes (when?) single values come in an array
|
57
|
+
if value.is_a?(Array) && prop['cardinality'] == 'single'
|
58
|
+
value = value.first
|
59
|
+
end
|
60
|
+
|
61
|
+
if !!value && prop['type'] == 'datetime'
|
62
|
+
# CMIS sends millis since epoch
|
63
|
+
value = Time.at(value / 1000.0)
|
64
|
+
end
|
65
|
+
|
66
|
+
value
|
67
|
+
end
|
55
68
|
end
|
56
69
|
end
|
data/lib/cmis/object.rb
CHANGED
@@ -50,13 +50,8 @@ module CMIS
|
|
50
50
|
objectId: cmis_object_id }, opts)
|
51
51
|
end
|
52
52
|
|
53
|
-
def relationships(
|
54
|
-
|
55
|
-
repositoryId: repository.id,
|
56
|
-
objectId: cmis_object_id,
|
57
|
-
relationshipDirection: direction }, opts)
|
58
|
-
|
59
|
-
result['objects'].map { |r| Relationship.new(r, repository) }
|
53
|
+
def relationships(opts = {})
|
54
|
+
Relationships.new(self, opts)
|
60
55
|
end
|
61
56
|
|
62
57
|
def policies(opts = {})
|
data/lib/cmis/relationship.rb
CHANGED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'active_support/core_ext/hash/slice'
|
2
|
+
|
3
|
+
module CMIS
|
4
|
+
class Relationships
|
5
|
+
# Options: from, page_size
|
6
|
+
def initialize(object, options = {})
|
7
|
+
@object = object
|
8
|
+
@options = options.stringify_keys!
|
9
|
+
|
10
|
+
init_options
|
11
|
+
end
|
12
|
+
|
13
|
+
# Options: limit
|
14
|
+
def each_relationship(options = {}, &block)
|
15
|
+
return enum_for(:each_relationship, options) unless block_given?
|
16
|
+
|
17
|
+
init_options
|
18
|
+
limit = parse_limit(options)
|
19
|
+
counter = 0
|
20
|
+
|
21
|
+
while has_next?
|
22
|
+
results.each do |object|
|
23
|
+
break unless counter < limit
|
24
|
+
yield object
|
25
|
+
counter = counter.next
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Options: limit
|
31
|
+
def each_page(options = {}, &block)
|
32
|
+
return enum_for(:each_page, options) unless block_given?
|
33
|
+
|
34
|
+
init_options
|
35
|
+
limit = parse_limit(options)
|
36
|
+
counter = 0
|
37
|
+
|
38
|
+
while has_next?
|
39
|
+
break unless counter < limit
|
40
|
+
yield r = results
|
41
|
+
counter += r.size
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def results
|
46
|
+
result = do_get_relationships
|
47
|
+
|
48
|
+
@skip_count += result.results.size
|
49
|
+
@has_next = result.has_more_items
|
50
|
+
@total = result.num_items
|
51
|
+
|
52
|
+
result.results
|
53
|
+
end
|
54
|
+
|
55
|
+
def has_next?
|
56
|
+
@has_next
|
57
|
+
end
|
58
|
+
|
59
|
+
def total
|
60
|
+
@total ||= do_get_relationships.num_items
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def init_options
|
66
|
+
@max_items = @options['page_size'] || 10
|
67
|
+
@skip_count = @options['from'] || 0
|
68
|
+
@direction = @options['direction'] || :either
|
69
|
+
@include_subtypes = @options['include_subtypes']
|
70
|
+
@type_id = @options['type_id']
|
71
|
+
@has_next = true
|
72
|
+
|
73
|
+
@opts = @options.slice('query', 'headers')
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse_limit(options)
|
77
|
+
options.stringify_keys!
|
78
|
+
limit = options['limit'] || 10
|
79
|
+
limit = BigDecimal::INFINITY if limit == :all
|
80
|
+
raise 'Not a valid limit' unless limit.is_a? Numeric
|
81
|
+
limit
|
82
|
+
end
|
83
|
+
|
84
|
+
def do_get_relationships
|
85
|
+
result = @object.connection.execute!({ cmisselector: 'relationships',
|
86
|
+
repositoryId: @object.repository.id,
|
87
|
+
objectId: @object.cmis_object_id,
|
88
|
+
maxItems: @max_items,
|
89
|
+
skipCount: @skip_count,
|
90
|
+
relationshipDirection: @direction,
|
91
|
+
includeSubRelationshipTypes: @include_subtypes,
|
92
|
+
typeId: @type_id }, @opts)
|
93
|
+
|
94
|
+
results = result['objects'].map do |r|
|
95
|
+
ObjectFactory.create(r, @object.repository)
|
96
|
+
end
|
97
|
+
|
98
|
+
QueryResult.new(results, result['numItems'], result['hasMoreItems'])
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/cmis/repository.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support'
|
2
|
-
|
3
1
|
module CMIS
|
4
2
|
class Repository
|
5
3
|
attr_reader :connection
|
@@ -118,14 +116,7 @@ module CMIS
|
|
118
116
|
QUOTE = "\'"
|
119
117
|
|
120
118
|
def normalize(value)
|
121
|
-
|
122
|
-
when DateTime
|
123
|
-
value = value.strftime('%Y-%m-%dT%H:%M:%S.%L')
|
124
|
-
"TIMESTAMP '#{value}'"
|
125
|
-
when Time
|
126
|
-
value = value.strftime('%Y-%m-%dT%H:%M:%S.%L')
|
127
|
-
"TIMESTAMP '#{value}'"
|
128
|
-
when Date
|
119
|
+
if value.respond_to?(:strftime)
|
129
120
|
value = value.strftime('%Y-%m-%dT%H:%M:%S.%L')
|
130
121
|
"TIMESTAMP '#{value}'"
|
131
122
|
else
|
data/lib/cmis/version.rb
CHANGED
data/spec/helper.rb
CHANGED
data/spec/object_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cmis-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenneth Geerts
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-03-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: typhoeus
|
@@ -69,6 +69,8 @@ files:
|
|
69
69
|
- lib/cmis-ruby.rb
|
70
70
|
- lib/cmis/children.rb
|
71
71
|
- lib/cmis/connection.rb
|
72
|
+
- lib/cmis/core_ext/array.rb
|
73
|
+
- lib/cmis/core_ext/hash.rb
|
72
74
|
- lib/cmis/document.rb
|
73
75
|
- lib/cmis/exceptions.rb
|
74
76
|
- lib/cmis/folder.rb
|
@@ -81,6 +83,7 @@ files:
|
|
81
83
|
- lib/cmis/query.rb
|
82
84
|
- lib/cmis/query_result.rb
|
83
85
|
- lib/cmis/relationship.rb
|
86
|
+
- lib/cmis/relationships.rb
|
84
87
|
- lib/cmis/repository.rb
|
85
88
|
- lib/cmis/server.rb
|
86
89
|
- lib/cmis/type.rb
|