ass_launcher 0.1.1.alpha

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.
@@ -0,0 +1,188 @@
1
+ # encoding: utf-8
2
+
3
+ require 'ass_launcher/enterprise/ole/ole_binaries'
4
+
5
+ module AssLauncher
6
+ module Enterprise
7
+ # 1C:Enterprise ole objects layer
8
+ module Ole
9
+ # 1C Infobase External Connection
10
+ class IbConnection
11
+ attr_reader :__ole__
12
+ protected :__ole__
13
+
14
+ # (see OleBinaries::AbstractAssOleBinary#initialize)
15
+ def initialize(requirement)
16
+ @requirement = requirement.to_s
17
+ end
18
+
19
+ # Open connection in to infobase described in conn_str
20
+ # @param conn_str [Support::ConnectionString::Server,
21
+ # Support::ConnectionString::File, String]
22
+ def __open__(conn_str)
23
+ return true if __opened__?
24
+ __init_ole__(__ole_binary__.ole.connect(__cs__(conn_str)))
25
+ true
26
+ end
27
+
28
+ def __init_ole__(ole)
29
+ @__ole__ = ole
30
+ end
31
+ private :__init_ole__
32
+
33
+ # Try close connection.
34
+ # @note *It* *not* *guaranteed* *real* *closing* *connection!*
35
+ # Connection keep alive while have any alive WIN32OLE refs
36
+ # generated this connection. {WIN32OLE#\_\_ass_ole_free\_\_} try kill
37
+ # refs but it work not always
38
+ # @see WIN32OLE
39
+ def __close__
40
+ return true if __closed__?
41
+ __ole__.send :__ass_ole_free__
42
+ @__ole__ = nil
43
+ true
44
+ end
45
+
46
+ # True if connection closed
47
+ def __closed__?
48
+ __ole__.nil?
49
+ end
50
+
51
+ # True if connection opened
52
+ def __opened__?
53
+ !__closed__?
54
+ end
55
+
56
+ # Set 1C Ole server properties
57
+ def __configure_com_connector__(**opts)
58
+ opts.each do |k, v|
59
+ __ole_binary__.ole.setproperty(k, v)
60
+ end
61
+ end
62
+
63
+ def __cs__(conn_str)
64
+ return conn_str.to_ole_string if conn_str.respond_to? :to_ole_string
65
+ conn_str.to_s
66
+ end
67
+ protected :__cs__
68
+
69
+ def __ole_binary__
70
+ @__ole_binary__ ||= OleBinaries::COMConnector.new(@requirement)
71
+ end
72
+ protected :__ole_binary__
73
+
74
+ # Try call ole method
75
+ # @raise [RuntimeError] if object closed
76
+ def method_missing(method, *args)
77
+ fail "Attempt call method for closed object #{self.class.name}"\
78
+ if __closed__?
79
+ __ole__.send(method, *args)
80
+ end
81
+ protected :method_missing
82
+ end
83
+
84
+ # IWorkingProcessConnection
85
+ class WpConnection < IbConnection
86
+ # Connection with 1C Server working process described in uri
87
+ # @param uri [URI, String]
88
+ def __open__(uri)
89
+ return true if __opened__?
90
+ __init_ole__(__ole_binary__.ole.connectworkingprocess(uri.to_s))
91
+ true
92
+ end
93
+ end
94
+
95
+ # Wrapper for IServerAgentConnection
96
+ class AgentConnection < IbConnection
97
+ # Connection with 1C Server agent described in uri
98
+ # @param (see WpConnection#__open__)
99
+ def __open__(uri)
100
+ return true if __opened__?
101
+ __init_ole__(__ole_binary__.ole.connectagent(uri.to_s))
102
+ true
103
+ end
104
+ end
105
+
106
+ class ApplicationConnectError < StandardError; end
107
+
108
+ # Wrapper for V8xc.Application ole object
109
+ class ThinApplication < IbConnection
110
+ # Array of objects with opened connection for close all
111
+ def self.objects
112
+ @objects ||= []
113
+ end
114
+
115
+ # Close all opened connectons
116
+ def self.close_all
117
+ objects.each(&:__close__)
118
+ end
119
+
120
+ def initialize(requirement)
121
+ super
122
+ @opened = false
123
+ end
124
+
125
+ # (see IbConnection#__open__)
126
+ # @raise [ApplicationConnectError]
127
+ def __open__(conn_str)
128
+ return true if __opened__?
129
+ __try_open__(conn_str)
130
+ self.class.objects << self
131
+ __opened__?
132
+ end
133
+
134
+ def __try_open__(conn_str)
135
+ @opened = __ole_binary__.ole.connect(__cs__(conn_str))
136
+ fail ApplicationConnectError unless __opened__?
137
+ rescue StandardError => e
138
+ @opened = false
139
+ @__ole_binary__ = nil
140
+ raise e
141
+ end
142
+ protected :__try_open__
143
+
144
+ def __ole__
145
+ __ole_binary__.ole
146
+ end
147
+ protected :__ole__
148
+
149
+ def __opened__?
150
+ @opened
151
+ end
152
+
153
+ def __closed__?
154
+ !__opened__?
155
+ end
156
+
157
+ def __close__
158
+ return true if __closed__?
159
+ # rubocop:disable HandleExceptions
160
+ begin
161
+ __ole__.terminate
162
+ rescue
163
+ # NOP
164
+ ensure
165
+ @__ole_binary__ = nil
166
+ @opened = false
167
+ ThinApplication.objects.delete(self)
168
+ end
169
+ # rubocop:enable HandleExceptions
170
+ true
171
+ end
172
+
173
+ def __ole_binary__
174
+ @__ole_binary__ ||= OleBinaries::ThinApplication.new(@requirement)
175
+ end
176
+ protected :__ole_binary__
177
+ end
178
+
179
+ # Wrapper for V8x.Application ole object
180
+ class ThickApplication < ThinApplication
181
+ def __ole_binary__
182
+ @__ole_binary__ ||= OleBinaries::ThickApplication.new(@requirement)
183
+ end
184
+ protected :__ole_binary__
185
+ end
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+
3
+ module AssLauncher
4
+ module Enterprise
5
+ module WebClients
6
+ module DefinedArguments
7
+ def self.extented(base)
8
+ raise "FIXME #{base}"
9
+ end
10
+ end
11
+
12
+ # Return object for run 1C webclent in required internet browser
13
+ # @param name [Symbol] - name of required internet browser for
14
+ # run 1C webclent
15
+ # @return [WebClients::IE, WebClients::Firefox, WebClients::Chrome,
16
+ # WebClients::Safary]
17
+ def self.client(name)
18
+ fail ArgumentError, "Invalid client name `#{name}'"\
19
+ unless BROWSERS.include? name
20
+ BROWSERS[name]
21
+ end
22
+
23
+ # @abstract
24
+ class Client
25
+ def accepted_connstr
26
+ [:http]
27
+ end
28
+
29
+ def initialize(connection_string)
30
+ @connection_string = connection_string
31
+ validate_connection_string
32
+ extend DefinedArguments
33
+ end
34
+
35
+ def validate_connection_string
36
+ raise 'FIXME'
37
+ #fail ArgumentError, "Invalid connection_string \
38
+ #`#{@connection_string}'"\
39
+ #unless accepted_connstr.include?(@connection_string.is)
40
+ end
41
+
42
+ # @todo TODO: можно запускать как драйвер силениум
43
+ def run(args)
44
+ raise 'FIXME'
45
+ end
46
+ end # Client
47
+ class Firefox < Client; end
48
+ class IE < Client; end
49
+ class Chrome < Client; end
50
+ class Safary < Client; end
51
+
52
+ BROWSERS = { firefox: Firefox,
53
+ iexplore: IE,
54
+ chrome: Chrome,
55
+ safary: Safary
56
+ }.freeze
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,111 @@
1
+ # encoding: utf-8
2
+
3
+ module AssLauncher
4
+ #
5
+ class Configuration
6
+ # Path for search 1C binaries
7
+ attr_accessor :search_path
8
+ end
9
+ # 1C:Entrprise platform abstraction layer
10
+ module Enterprise
11
+ require 'ass_launcher/enterprise/binary_wrapper'
12
+ require 'ass_launcher/enterprise/web_clients'
13
+ require 'ass_launcher/enterprise/ole'
14
+
15
+ extend AssLauncher::Support::Platforms
16
+
17
+ WIN_BINARIES = { BinaryWrapper::ThinClient => '1cv8c.exe',
18
+ BinaryWrapper::ThickClient => '1cv8.exe'
19
+ }.freeze
20
+ LINUX_BINARIES = { BinaryWrapper::ThinClient => '1cv8c',
21
+ BinaryWrapper::ThickClient => '1cv8'
22
+ }.freeze
23
+ def self.windows_or_cygwin?
24
+ platform.cygwin? || platform.windows?
25
+ end
26
+ private_class_method :windows_or_cygwin?
27
+
28
+ def self.linux?
29
+ platform.linux?
30
+ end
31
+ private_class_method :linux?
32
+
33
+ # Return paths for searching instaled 1C platform
34
+ # @note
35
+ # - For Windows return value of 'Program Files' env.
36
+ # - For Linux return '/opt/1C'
37
+ # - In both cases you can set {AssLauncher::Configuration#search_path} and
38
+ # it will be added into array
39
+ # @return [Array<String>
40
+ def self.search_paths
41
+ sp = []
42
+ sp << AssLauncher.config.search_path
43
+ if windows_or_cygwin?
44
+ sp += platform.env[/\Aprogram\s*files.*/i].uniq.map { |pf| "#{pf}/1c*" }
45
+ elsif linux?
46
+ sp += %w(/opt/1C /opt/1c)
47
+ end
48
+ sp.compact.uniq
49
+ end
50
+
51
+ # @api private
52
+ def self.binaries(klass)
53
+ if windows_or_cygwin?
54
+ WIN_BINARIES[klass]
55
+ elsif linux?
56
+ LINUX_BINARIES[klass]
57
+ end
58
+ end
59
+
60
+ def self.find_clients(klass)
61
+ find_binaries(binaries(klass)).map do |binpath|
62
+ klass.new(binpath)
63
+ end
64
+ end
65
+ private_class_method :find_clients
66
+
67
+ def self.requiremet?(client, requiremet)
68
+ return true if requiremet.empty?
69
+ Gem::Requirement.new(requiremet).satisfied_by? client.version
70
+ end
71
+ private_class_method :requiremet?
72
+
73
+ # Return array of wrappers for 1C thin client executables
74
+ # found in {.search_paths}
75
+ # @param requiremet [String] - suitable for [Gem::Requirement] string.
76
+ # Define requiremet version of 1C:Platform.
77
+ # @return [Array<BinaryWrapper::ThinClient>]
78
+ def self.thin_clients(requiremet = '')
79
+ find_clients(BinaryWrapper::ThinClient).map do |c|
80
+ c if requiremet?(c, requiremet)
81
+ end.compact
82
+ end
83
+
84
+ # Return array of wrappers for 1C platform(thick client) executables
85
+ # found in {.search_paths}
86
+ # @param (see thin_clients)
87
+ # @return [Array<BinaryWrapper::ThickClient>]
88
+ def self.thick_clients(requiremet = '')
89
+ find_clients(BinaryWrapper::ThickClient).map do |c|
90
+ c if requiremet?(c, requiremet)
91
+ end.compact
92
+ end
93
+
94
+ # (see WebClients.client)
95
+ def self.web_client(name)
96
+ WebClients.client(name)
97
+ end
98
+
99
+ # Find and return all 1C:Entrprise binaries
100
+ # @return [Array<BinaryWrapper>]
101
+ def self.find_binaries(basename)
102
+ return [] if basename.to_s.empty?
103
+ r = []
104
+ search_paths.flatten.each do |sp|
105
+ r += platform.glob("#{sp}/**/#{basename}")
106
+ end
107
+ r
108
+ end
109
+ private_class_method :find_binaries
110
+ end
111
+ end