ooor 1.9.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +23 -71
- data/Rakefile +5 -0
- data/bin/ooor +1 -0
- data/lib/ooor.rb +87 -129
- data/lib/ooor/associations.rb +64 -0
- data/lib/ooor/base.rb +218 -0
- data/lib/{app/models → ooor}/base64.rb +0 -0
- data/lib/ooor/connection.rb +37 -0
- data/lib/ooor/errors.rb +120 -0
- data/lib/ooor/field_methods.rb +153 -0
- data/lib/{app → ooor}/helpers/core_helpers.rb +2 -2
- data/lib/ooor/locale.rb +13 -0
- data/lib/ooor/mini_active_resource.rb +94 -0
- data/lib/ooor/model_registry.rb +19 -0
- data/lib/ooor/naming.rb +73 -0
- data/lib/ooor/rack.rb +114 -0
- data/lib/ooor/railtie.rb +41 -0
- data/lib/ooor/reflection.rb +537 -0
- data/lib/ooor/reflection_ooor.rb +92 -0
- data/lib/{app/models → ooor}/relation.rb +61 -22
- data/lib/ooor/relation/finder_methods.rb +113 -0
- data/lib/ooor/report.rb +53 -0
- data/lib/{app/models → ooor}/serialization.rb +18 -6
- data/lib/ooor/services.rb +133 -0
- data/lib/ooor/session.rb +120 -0
- data/lib/ooor/session_handler.rb +63 -0
- data/lib/ooor/transport.rb +34 -0
- data/lib/ooor/transport/json_client.rb +53 -0
- data/lib/ooor/transport/xml_rpc_client.rb +15 -0
- data/lib/ooor/type_casting.rb +193 -0
- data/lib/ooor/version.rb +8 -0
- data/spec/helpers/test_helper.rb +11 -0
- data/spec/install_nightly.sh +17 -0
- data/spec/ooor_spec.rb +197 -79
- data/spec/requirements.txt +19 -0
- metadata +58 -20
- data/lib/app/models/client_xmlrpc.rb +0 -34
- data/lib/app/models/open_object_resource.rb +0 -486
- data/lib/app/models/services.rb +0 -47
- data/lib/app/models/type_casting.rb +0 -134
- data/lib/app/models/uml.rb +0 -210
- data/lib/app/ui/action_window.rb +0 -96
- data/lib/app/ui/client_base.rb +0 -36
- data/lib/app/ui/form_model.rb +0 -88
- data/ooor.yml +0 -27
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'active_support/core_ext/class/attribute'
|
2
|
+
require 'active_support/core_ext/object/inclusion'
|
3
|
+
|
4
|
+
module Ooor
|
5
|
+
# = Ooor Reflection
|
6
|
+
module ReflectionOoor # :nodoc:
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def set_columns_hash(view_fields={})
|
11
|
+
reload_fields_definition()
|
12
|
+
@t.columns_hash ||= {}
|
13
|
+
@t.fields.each do |k, field|
|
14
|
+
unless @t.associations_keys.index(k)
|
15
|
+
@t.columns_hash[k] = field.merge({type: to_rails_type(view_fields[k] && view_fields[k]['type'] || field['type'])})
|
16
|
+
end
|
17
|
+
end
|
18
|
+
@t.columns_hash
|
19
|
+
end
|
20
|
+
|
21
|
+
def column_for_attribute(name)
|
22
|
+
columns_hash[name.to_s]
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_reflection(name)
|
26
|
+
options = {}
|
27
|
+
if many2one_associations.keys.include?(name)
|
28
|
+
macro = :belongs_to
|
29
|
+
relation = many2one_associations[name]['relation'] #TODO prefix?
|
30
|
+
const_get(relation)
|
31
|
+
options[:class_name] = relation #TODO or pass it camelized already?
|
32
|
+
elsif many2many_associations.keys.include?(name)
|
33
|
+
macro = :has_and_belongs_to_many
|
34
|
+
elsif one2many_associations.keys.include?(name)
|
35
|
+
macro = :has_many
|
36
|
+
end
|
37
|
+
reflection = Reflection::AssociationReflection.new(macro, name, options, nil)#active_record) #TODO active_record?
|
38
|
+
# case macro
|
39
|
+
# when :has_many, :belongs_to, :has_one, :has_and_belongs_to_many
|
40
|
+
# klass = options[:through] ? ThroughReflection : AssociationReflection
|
41
|
+
# reflection = klass.new(macro, name, options, active_record)
|
42
|
+
# when :composed_of
|
43
|
+
# reflection = AggregateReflection.new(macro, name, options, active_record)
|
44
|
+
# end
|
45
|
+
|
46
|
+
self.reflections = self.reflections.merge(name => reflection)
|
47
|
+
reflection
|
48
|
+
end
|
49
|
+
|
50
|
+
def reflect_on_association(association)
|
51
|
+
reflections[association] ||= create_reflection(association.to_s).tap do |reflection|
|
52
|
+
reflection.connection = connection
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
module Ooor
|
62
|
+
# = Active Record Reflection
|
63
|
+
module Reflection # :nodoc:
|
64
|
+
|
65
|
+
class MacroReflection
|
66
|
+
attr_accessor :connection
|
67
|
+
end
|
68
|
+
|
69
|
+
# Holds all the meta-data about an association as it was specified in the
|
70
|
+
# Active Record class.
|
71
|
+
class AssociationReflection < MacroReflection #:nodoc:
|
72
|
+
# Returns the target association's class.
|
73
|
+
#
|
74
|
+
# class Author < ActiveRecord::Base
|
75
|
+
# has_many :books
|
76
|
+
# end
|
77
|
+
#
|
78
|
+
# Author.reflect_on_association(:books).klass
|
79
|
+
# # => Book
|
80
|
+
#
|
81
|
+
# <b>Note:</b> Do not call +klass.new+ or +klass.create+ to instantiate
|
82
|
+
# a new association object. Use +build_association+ or +create_association+
|
83
|
+
# instead. This allows plugins to hook into association object creation.
|
84
|
+
def klass
|
85
|
+
# @klass ||= active_record.send(:compute_type, class_name)
|
86
|
+
@klass ||= connection.class_name_from_model_key(class_name).constantize
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# OOOR: OpenObject On Ruby
|
2
|
-
# Copyright (C) 2009-
|
2
|
+
# Copyright (C) 2009-TODAY Akretion LTDA (<http://www.akretion.com>).
|
3
3
|
# Author: Raphaël Valyi
|
4
4
|
# Licensed under the MIT license, see MIT-LICENSE file
|
5
5
|
|
@@ -9,16 +9,15 @@
|
|
9
9
|
module Ooor
|
10
10
|
# = Similar to Active Record Relation
|
11
11
|
class Relation
|
12
|
-
|
13
12
|
attr_reader :klass, :loaded
|
14
|
-
attr_accessor :
|
13
|
+
attr_accessor :options, :count_field, :includes_values, :eager_load_values, :preload_values,
|
15
14
|
:select_values, :group_values, :order_values, :reorder_flag, :joins_values, :where_values, :having_values,
|
16
|
-
:limit_value, :offset_value, :lock_value, :readonly_value, :create_with_value, :from_value
|
15
|
+
:limit_value, :offset_value, :lock_value, :readonly_value, :create_with_value, :from_value, :page_value, :per_value
|
17
16
|
alias :loaded? :loaded
|
18
|
-
|
19
|
-
def build_where(opts, other = [])
|
17
|
+
|
18
|
+
def build_where(opts, other = [])#TODO OpenERP domain is more than just the intersection of restrictions
|
20
19
|
case opts
|
21
|
-
when Array
|
20
|
+
when Array || '|' || '&'
|
22
21
|
[opts]
|
23
22
|
when Hash
|
24
23
|
opts.keys.map {|key|["#{key}", "=", opts[key]]}
|
@@ -27,7 +26,11 @@ module Ooor
|
|
27
26
|
|
28
27
|
def where(opts, *rest)
|
29
28
|
relation = clone
|
30
|
-
|
29
|
+
if opts.is_a?(Array) && opts.any? {|e| e.is_a? Array}
|
30
|
+
relation.where_values = opts
|
31
|
+
else
|
32
|
+
relation.where_values += build_where(opts, rest) unless opts.blank?
|
33
|
+
end
|
31
34
|
relation
|
32
35
|
end
|
33
36
|
|
@@ -60,14 +63,13 @@ module Ooor
|
|
60
63
|
calculate(:count, column_name, options)
|
61
64
|
end
|
62
65
|
|
63
|
-
def initialize(klass)
|
66
|
+
def initialize(klass, options={})
|
64
67
|
@klass = klass
|
65
68
|
@where_values = []
|
66
69
|
@loaded = false
|
67
|
-
@
|
70
|
+
@options = options
|
68
71
|
@count_field = false
|
69
|
-
@
|
70
|
-
@offset_value = false
|
72
|
+
@offset_value = 0
|
71
73
|
@order_values = []
|
72
74
|
end
|
73
75
|
|
@@ -93,24 +95,61 @@ module Ooor
|
|
93
95
|
self
|
94
96
|
end
|
95
97
|
|
98
|
+
def apply_finder_options(options)
|
99
|
+
relation = clone
|
100
|
+
relation.options = options #TODO this may be too simplified for chainability, merge smartly instead?
|
101
|
+
relation
|
102
|
+
end
|
103
|
+
|
104
|
+
def where_values
|
105
|
+
if @options && @options[:domain]
|
106
|
+
@options[:domain]
|
107
|
+
else
|
108
|
+
@where_values
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
96
112
|
# A convenience wrapper for <tt>find(:all, *args)</tt>. You can pass in all the
|
97
113
|
# same arguments to this method as you can to <tt>find(:all)</tt>.
|
98
114
|
def all(*args)
|
99
|
-
|
100
|
-
to_a
|
115
|
+
args.any? ? apply_finder_options(args.first).to_a : to_a
|
101
116
|
end
|
102
117
|
|
103
118
|
def to_a
|
104
|
-
|
105
|
-
|
106
|
-
search_order = false
|
119
|
+
if loaded?
|
120
|
+
@records
|
107
121
|
else
|
108
|
-
|
122
|
+
if @order_values.empty?
|
123
|
+
search_order = false
|
124
|
+
else
|
125
|
+
search_order = @order_values.join(", ")
|
126
|
+
end
|
127
|
+
|
128
|
+
if @options && @options[:name_search]
|
129
|
+
name_search = @klass.name_search(@options[:name_search], where_values, 'ilike', @options[:context], @limit_value)
|
130
|
+
@records = name_search.map do |tuple|
|
131
|
+
r = @klass.new({name: tuple[1]}, [])
|
132
|
+
r.id = tuple[0]
|
133
|
+
r #TODO load the fields optionally
|
134
|
+
end
|
135
|
+
else
|
136
|
+
if @per_value && @page_value
|
137
|
+
offset = @per_value * @page_value
|
138
|
+
limit = @per_value
|
139
|
+
else
|
140
|
+
offset = @offset_value
|
141
|
+
limit = @limit_value || false
|
142
|
+
end
|
143
|
+
@loaded = true
|
144
|
+
opts = @options.merge({
|
145
|
+
domain: where_values,
|
146
|
+
offset: offset,
|
147
|
+
limit: limit,
|
148
|
+
order: search_order,
|
149
|
+
})
|
150
|
+
@records = @klass.find(:all, opts)
|
151
|
+
end
|
109
152
|
end
|
110
|
-
ids = @klass.rpc_execute('search', @where_values, @offset_value, @limit_value, search_order, @context, @count_field)
|
111
|
-
@records = @klass.find(ids)
|
112
|
-
@loaded = true
|
113
|
-
@records
|
114
153
|
end
|
115
154
|
|
116
155
|
def eager_loading?
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Ooor
|
4
|
+
module FinderMethods
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def find(*arguments)
|
9
|
+
if arguments.size == 1 &&
|
10
|
+
arguments[0].is_a?(Hash) ||
|
11
|
+
(arguments[0].is_a?(Array) && !([arguments[0][1]] & Ooor::TypeCasting::OPERATORS).empty?)
|
12
|
+
find_single(nil, {domain: arguments[0]})
|
13
|
+
else
|
14
|
+
find_dispatch(*arguments)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
def find_dispatch(*arguments)
|
20
|
+
scope = arguments.slice!(0)
|
21
|
+
options = arguments.slice!(0) || {}
|
22
|
+
if (!scope.is_a?(Array) && !options.is_a?(Hash))
|
23
|
+
scope = [scope] + [options] + arguments
|
24
|
+
options = {}
|
25
|
+
end
|
26
|
+
case scope
|
27
|
+
when :all then find_single(nil, options)
|
28
|
+
when :first then find_first_or_last(options)
|
29
|
+
when :last then find_first_or_last(options, "DESC")
|
30
|
+
when :one then find_one(options)
|
31
|
+
else find_single(scope, options)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def find_first_or_last(options, ordering = "ASC")
|
36
|
+
options[:order] ||= "id #{ordering}"
|
37
|
+
options[:limit] = 1
|
38
|
+
find_single(nil, options)[0]
|
39
|
+
end
|
40
|
+
|
41
|
+
#actually finds many resources specified with scope = ids_array
|
42
|
+
def find_single(scope, options)
|
43
|
+
context = options[:context] || {}
|
44
|
+
reload_fields_definition(false, context)
|
45
|
+
fields = options[:fields] || options[:only] || fast_fields(options)
|
46
|
+
fields += options[:include] if options[:include]
|
47
|
+
|
48
|
+
if scope
|
49
|
+
is_collection, records = read_scope(context, fields, scope)
|
50
|
+
else
|
51
|
+
is_collection, records = read_domain(context, fields, options)
|
52
|
+
end
|
53
|
+
active_resources = []
|
54
|
+
records.each { |record| active_resources << new(record, [], context, true)}
|
55
|
+
if is_collection
|
56
|
+
active_resources
|
57
|
+
else
|
58
|
+
active_resources[0]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def read_scope(context, fields, scope)
|
63
|
+
if scope.is_a? Array
|
64
|
+
is_collection = true
|
65
|
+
else
|
66
|
+
scope = [scope]
|
67
|
+
is_collection = false
|
68
|
+
end
|
69
|
+
scope.map! { |item| item_to_id(item, context) }.reject! {|item| !item}
|
70
|
+
records = rpc_execute('read', scope, fields, context.dup)
|
71
|
+
records.sort_by! {|r| scope.index(r["id"])} if @connection.config[:force_xml_rpc]
|
72
|
+
return is_collection, records
|
73
|
+
end
|
74
|
+
|
75
|
+
def read_domain(context, fields, options)
|
76
|
+
if @connection.config[:force_xml_rpc]
|
77
|
+
domain = to_openerp_domain(options[:domain] || options[:conditions] || [])
|
78
|
+
ids = rpc_execute('search', domain, options[:offset] || 0, options[:limit] || false, options[:order] || false, context.dup)
|
79
|
+
records = rpc_execute('read', ids, fields, context.dup)
|
80
|
+
else
|
81
|
+
domain = to_openerp_domain(options[:domain] || options[:conditions] || [])
|
82
|
+
response = object_service(:search_read, openerp_model, 'search_read', {
|
83
|
+
fields: fields,
|
84
|
+
offset: options[:offset] || 0,
|
85
|
+
limit: options[:limit] || false,
|
86
|
+
domain: domain,
|
87
|
+
sort: options[:order] || false,
|
88
|
+
context: context
|
89
|
+
})
|
90
|
+
records = response["records"]
|
91
|
+
end
|
92
|
+
return true, records
|
93
|
+
end
|
94
|
+
|
95
|
+
def item_to_id(item, context)
|
96
|
+
if item.is_a?(String)
|
97
|
+
if item.to_i == 0#triggers ir_model_data absolute reference lookup
|
98
|
+
tab = item.split(".")
|
99
|
+
domain = [['name', '=', tab[-1]]]
|
100
|
+
domain << ['module', '=', tab[-2]] if tab[-2]
|
101
|
+
ir_model_data = const_get('ir.model.data').find(:first, domain: domain, context: context)
|
102
|
+
ir_model_data && ir_model_data.res_id && search([['id', '=', ir_model_data.res_id]], 0, false, false, context)[0]
|
103
|
+
else
|
104
|
+
item.to_i
|
105
|
+
end
|
106
|
+
else
|
107
|
+
item
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
data/lib/ooor/report.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module Ooor
|
4
|
+
module Report
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
#Added methods to obtain report data for a model
|
9
|
+
def report(report_name, ids, report_type='pdf', context={}) #TODO move to ReportService
|
10
|
+
context = connection.object.inject_session_context(:report, false, context)[0]
|
11
|
+
uid = @connection.config[:user_id]
|
12
|
+
pass = @connection.config[:password]
|
13
|
+
db = @connection.config[:database]
|
14
|
+
params = {model: openerp_model, id: ids[0], report_type: report_type}
|
15
|
+
connection.report.report(db, uid, pass, report_name, ids, params, context)
|
16
|
+
end
|
17
|
+
|
18
|
+
def report_get(report_id)
|
19
|
+
uid = @connection.config[:user_id]
|
20
|
+
pass = @connection.config[:password]
|
21
|
+
db = @connection.config[:database]
|
22
|
+
connection.report.report_get(db, uid, pass, report_id)
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_report_data(report_name, ids, report_type='pdf', context={})
|
26
|
+
report_id = report(report_name, ids, report_type, context)
|
27
|
+
if report_id
|
28
|
+
state = false
|
29
|
+
attempt = 0
|
30
|
+
while not state
|
31
|
+
report = self.report_get(report_id)
|
32
|
+
state = report["state"]
|
33
|
+
attempt = 1
|
34
|
+
if not state
|
35
|
+
sleep(0.1)
|
36
|
+
attempt += 1
|
37
|
+
else
|
38
|
+
return [report["result"],report["format"]]
|
39
|
+
end
|
40
|
+
if attempt > 100
|
41
|
+
logger.debug "OOOR RPC: 'Printing Aborted!'"
|
42
|
+
break
|
43
|
+
end
|
44
|
+
end
|
45
|
+
else
|
46
|
+
logger.debug "OOOR RPC: 'report not found'"
|
47
|
+
end
|
48
|
+
return nil
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -1,25 +1,41 @@
|
|
1
1
|
# OOOR: OpenObject On Ruby
|
2
|
-
# Copyright (C) 2009-
|
2
|
+
# Copyright (C) 2009-TODAY Akretion LTDA (<http://www.akretion.com>).
|
3
3
|
# Author: Raphaël Valyi
|
4
4
|
# Licensed under the MIT license, see MIT-LICENSE file
|
5
5
|
|
6
6
|
module Ooor
|
7
7
|
module Serialization
|
8
8
|
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
self.include_root_in_json = false
|
13
|
+
end
|
14
|
+
|
9
15
|
def serializable_hash(options = nil)
|
10
16
|
options ||= {}
|
11
17
|
hash = super(options)
|
12
18
|
|
13
19
|
attribute_names = attributes.keys.sort
|
14
20
|
included_associations = {}
|
21
|
+
serialize_many2one(included_associations)
|
22
|
+
serialize_x_to_many(included_associations)
|
23
|
+
|
24
|
+
method_names = Array.wrap(options[:methods]).map { |n| n if respond_to?(n.to_s) }.compact
|
25
|
+
Hash[(attribute_names + method_names).map { |n| [n, send(n)] }].merge(included_associations)
|
26
|
+
end
|
27
|
+
|
28
|
+
def serialize_many2one(included_associations)
|
15
29
|
self.class.many2one_associations.keys.each do |k|
|
16
|
-
if loaded_associations[k].is_a?
|
30
|
+
if loaded_associations[k].is_a? Base
|
17
31
|
included_associations[k] = loaded_associations[k].as_json[loaded_associations[k].class.openerp_model.gsub('.', '_')]
|
18
32
|
elsif associations[k].is_a? Array
|
19
33
|
included_associations[k] = {"id" => associations[k][0], "name" => associations[k][1]}
|
20
34
|
end
|
21
35
|
end
|
36
|
+
end
|
22
37
|
|
38
|
+
def serialize_x_to_many(included_associations)
|
23
39
|
(self.class.one2many_associations.keys + self.class.many2many_associations.keys).each do |k|
|
24
40
|
if loaded_associations[k].is_a? Array
|
25
41
|
included_associations[k] = loaded_associations[k].map {|item| item.as_json[item.class.openerp_model.gsub('.', '_')]}
|
@@ -27,11 +43,7 @@ module Ooor
|
|
27
43
|
included_associations[k] = associations[k].map {|id| {"id" => id}} if associations[k]
|
28
44
|
end
|
29
45
|
end
|
30
|
-
|
31
|
-
method_names = Array.wrap(options[:methods]).map { |n| n if respond_to?(n.to_s) }.compact
|
32
|
-
Hash[(attribute_names + method_names).map { |n| [n, send(n)] }].merge(included_associations)
|
33
46
|
end
|
34
47
|
|
35
48
|
end
|
36
49
|
end
|
37
|
-
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# OOOR: OpenObject On Ruby
|
2
|
+
# Copyright (C) 2009-2013 Akretion LTDA (<http://www.akretion.com>).
|
3
|
+
# Author: Raphaël Valyi
|
4
|
+
# Licensed under the MIT license, see MIT-LICENSE file
|
5
|
+
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
module Ooor
|
9
|
+
autoload :InvalidSessionError, 'ooor/errors'
|
10
|
+
|
11
|
+
class Service
|
12
|
+
def initialize(session)
|
13
|
+
@session = session
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.define_service(service, methods)
|
17
|
+
methods.each do |meth|
|
18
|
+
self.instance_eval do
|
19
|
+
define_method meth do |*args|
|
20
|
+
endpoint = @session.get_client(:xml, "#{@session.base_url}/#{service.to_s.gsub('ooor_alias_', '')}") #TODO make that transport agnostic
|
21
|
+
endpoint.call(meth.gsub('ooor_alias_', ''), *args)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
class CommonService < Service
|
30
|
+
define_service(:common, %w[ir_get ir_set ir_del about ooor_alias_login logout timezone_get get_available_updates get_migration_scripts get_server_environment login_message check_connectivity about get_stats list_http_services version authenticate get_available_updates set_loglevel get_os_time get_sqlcount])
|
31
|
+
|
32
|
+
def login(db, username, password)
|
33
|
+
@session.logger.debug "OOOR login - db: #{db}, username: #{username}"
|
34
|
+
|
35
|
+
if @session.config[:force_xml_rpc]
|
36
|
+
send("ooor_alias_login", db, username, password)
|
37
|
+
else
|
38
|
+
conn = @session.get_client(:json, "#{@session.base_jsonrpc2_url}")
|
39
|
+
response = conn.post do |req|
|
40
|
+
req.url '/web/session/authenticate'
|
41
|
+
req.headers['Content-Type'] = 'application/json'
|
42
|
+
req.body = {method: 'call', params: { db: db, login: username, password: password}}.to_json
|
43
|
+
end
|
44
|
+
@session.web_session[:cookie] = response.headers["set-cookie"]
|
45
|
+
if response.status == 200
|
46
|
+
sid_part1 = @session.web_session[:cookie].split("sid=")[1]
|
47
|
+
if sid_part1
|
48
|
+
@session.web_session[:sid] = @session.web_session[:cookie].split("sid=")[1].split(";")[0] # NOTE side is required on v7 but not on v8, this enables to sniff if we are on v7
|
49
|
+
end
|
50
|
+
json_response = JSON.parse(response.body)
|
51
|
+
@session.web_session[:session_id] = json_response['result']['session_id']
|
52
|
+
user_id = json_response['result']['uid']
|
53
|
+
@session.config[:user_id] = user_id
|
54
|
+
Ooor.session_handler.register_session(@session)
|
55
|
+
user_id
|
56
|
+
else
|
57
|
+
raise Faraday::Error::ClientError.new(response.status, response)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
class DbService < Service
|
65
|
+
define_service(:db, %w[get_progress drop dump restore rename db_exist list change_admin_password list_lang server_version migrate_databases create_database duplicate_database])
|
66
|
+
|
67
|
+
def create(password=@session.config[:db_password], db_name='ooor_test', demo=true, lang='en_US', user_password=@session.config[:password] || 'admin')
|
68
|
+
@session.logger.info "creating database #{db_name} this may take a while..."
|
69
|
+
process_id = @session.get_client(:xml, @session.base_url + "/db").call("create", password, db_name, demo, lang, user_password)
|
70
|
+
sleep(2)
|
71
|
+
while get_progress(password, process_id)[0] != 1
|
72
|
+
@session.logger.info "..."
|
73
|
+
sleep(0.5)
|
74
|
+
end
|
75
|
+
@session.global_login(username: 'admin', password: user_password, database: db_name)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
class ObjectService < Service
|
81
|
+
define_service(:object, %w[execute exec_workflow])
|
82
|
+
|
83
|
+
def object_service(service, obj, method, *args)
|
84
|
+
unless @session.config[:user_id]
|
85
|
+
@session.common.login(@session.config[:database], @session.config[:username], @session.config[:password])
|
86
|
+
end
|
87
|
+
args = inject_session_context(service, method, *args)
|
88
|
+
uid = @session.config[:user_id]
|
89
|
+
db = @session.config[:database]
|
90
|
+
@session.logger.debug "OOOR object service: rpc_method: #{service}, db: #{db}, uid: #{uid}, pass: #, obj: #{obj}, method: #{method}, *args: #{args.inspect}"
|
91
|
+
if @session.config[:force_xml_rpc]
|
92
|
+
pass = @session.config[:password]
|
93
|
+
send(service, db, uid, pass, obj, method, *args)
|
94
|
+
else
|
95
|
+
unless @session.web_session[:session_id]
|
96
|
+
@session.common.login(@session.config[:database], @session.config[:username], @session.config[:password])
|
97
|
+
end
|
98
|
+
json_conn = @session.get_client(:json, "#{@session.base_jsonrpc2_url}")
|
99
|
+
json_conn.oe_service(@session.web_session, service, obj, method, *args)
|
100
|
+
end
|
101
|
+
rescue InvalidSessionError
|
102
|
+
@session.config[:force_xml_rpc] = true #TODO set v6 version too
|
103
|
+
retry
|
104
|
+
rescue SessionExpiredError
|
105
|
+
@session.logger.debug "session for uid: #{uid} has expired, trying to login again"
|
106
|
+
@session.common.login(@session.config[:database], @session.config[:username], @session.config[:password])
|
107
|
+
retry
|
108
|
+
end
|
109
|
+
|
110
|
+
def inject_session_context(service, method, *args)
|
111
|
+
if service == :object && (i = Ooor.irregular_context_position(method)) && args.size >= i
|
112
|
+
c = HashWithIndifferentAccess.new(args[i])
|
113
|
+
args[i] = @session.session_context(c)
|
114
|
+
elsif args[-1].is_a? Hash #context
|
115
|
+
if args[-1][:context]
|
116
|
+
c = HashWithIndifferentAccess.new(args[-1][:context])
|
117
|
+
args[-1][:context] = @session.session_context(c)
|
118
|
+
else
|
119
|
+
c = HashWithIndifferentAccess.new(args[-1])
|
120
|
+
args[-1] = @session.session_context(c)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
args
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
class ReportService < Service
|
130
|
+
define_service(:report, %w[report report_get render_report]) #TODO make use json rpc transport too
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|