s41c 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/s41c/client.rb +42 -15
- data/lib/s41c/parser.rb +18 -12
- data/lib/s41c/sandbox.rb +10 -6
- data/lib/s41c/server.rb +39 -18
- data/lib/s41c/utils.rb +18 -3
- data/lib/s41c/version.rb +1 -1
- metadata +2 -3
- data/s41c-0.0.4.gem +0 -0
data/lib/s41c/client.rb
CHANGED
@@ -6,6 +6,10 @@ module S41C
|
|
6
6
|
|
7
7
|
include S41C::Utils
|
8
8
|
|
9
|
+
# Создать инстанс клиента
|
10
|
+
#
|
11
|
+
# @param [ String ] адрес сервера
|
12
|
+
# @param [ Integer ] порт сервера
|
9
13
|
def initialize(host='localhost', port=1421)
|
10
14
|
require 'net/telnet'
|
11
15
|
require 's41c/parser'
|
@@ -14,36 +18,59 @@ module S41C
|
|
14
18
|
@prompt = /^\+OK/n
|
15
19
|
@errors = []
|
16
20
|
|
17
|
-
end
|
21
|
+
end
|
18
22
|
|
23
|
+
# Задать данные для авторизации
|
24
|
+
#
|
25
|
+
# @param [ String ] логин
|
26
|
+
# @param [ String ] пароль
|
19
27
|
def login(username, password = nil)
|
20
28
|
@login = username.nil? || username.empty? ? nil : username
|
21
29
|
@password = password
|
22
30
|
|
23
31
|
self
|
24
|
-
end
|
32
|
+
end
|
25
33
|
|
34
|
+
# Возвращает массив ошибок
|
35
|
+
#
|
36
|
+
# @return [ Array ] массив ошибок
|
26
37
|
def errors
|
27
38
|
@errors
|
28
|
-
end
|
39
|
+
end
|
29
40
|
|
41
|
+
# Проверка соединения с сервером
|
30
42
|
def ping
|
31
43
|
cmd "ping"
|
32
|
-
end
|
44
|
+
end
|
33
45
|
|
46
|
+
# Отключиться от сервера
|
34
47
|
def disconnect
|
35
48
|
cmd "disconnect"
|
36
|
-
end
|
49
|
+
end
|
37
50
|
|
51
|
+
# Остановить сервер и отключиться от него
|
38
52
|
def shutdown
|
39
53
|
cmd "shutdown"
|
40
|
-
end
|
54
|
+
end
|
41
55
|
|
42
|
-
|
56
|
+
# Выполнить на сервере блок кода
|
57
|
+
#
|
58
|
+
# @param [ Hash ] переменные, которые будут доступны внутри блока
|
59
|
+
# @param [ Proc ] блок кода
|
60
|
+
#
|
61
|
+
# @return [ String ] результат выполнения блока
|
62
|
+
def request(vars = {}, &block)
|
43
63
|
code = S41C::Parser.new(block).parse
|
44
|
-
|
45
|
-
end # request
|
64
|
+
dump = Marshal.dump({vars: vars, code: code})
|
46
65
|
|
66
|
+
self.eval dump
|
67
|
+
end
|
68
|
+
|
69
|
+
# Выполнить на сервере строку
|
70
|
+
#
|
71
|
+
# @param [ String ] строка кода
|
72
|
+
#
|
73
|
+
# @return [ String ] результат выполнения
|
47
74
|
def eval(code)
|
48
75
|
cmd "eval\0\n#{code}\nend_of_code"
|
49
76
|
end
|
@@ -71,18 +98,18 @@ module S41C
|
|
71
98
|
@errors << e.message
|
72
99
|
return false
|
73
100
|
end
|
74
|
-
end
|
101
|
+
end
|
75
102
|
|
76
103
|
def cmd(str)
|
77
104
|
return @errors unless conn
|
78
|
-
parse @client.cmd(
|
79
|
-
end
|
105
|
+
parse @client.cmd(str)
|
106
|
+
end
|
80
107
|
|
81
108
|
def parse(response)
|
82
109
|
resp = to_utf8(response)
|
83
110
|
resp.lines.first.chomp
|
84
|
-
end
|
111
|
+
end
|
85
112
|
|
86
|
-
end
|
113
|
+
end
|
87
114
|
|
88
|
-
end
|
115
|
+
end
|
data/lib/s41c/parser.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
module S41C
|
3
|
+
module S41C #:nodoc
|
4
4
|
|
5
|
-
class Parser
|
5
|
+
class Parser #:nodoc
|
6
6
|
|
7
7
|
BLOCK_BEGINNERS = /module|class|def|begin|do|case|if|unless|{/
|
8
8
|
BLOCK_ENDERS = /end|}/
|
9
9
|
|
10
|
+
#:nodoc
|
10
11
|
def initialize(block)
|
11
12
|
sl = block.source_location
|
12
13
|
@file, @start_line = sl.first, (sl.last)
|
@@ -22,15 +23,22 @@ module S41C
|
|
22
23
|
|
23
24
|
end # new
|
24
25
|
|
26
|
+
#:nodoc
|
25
27
|
def parse
|
26
28
|
raw = @lines[@start_line..-1]
|
27
29
|
depth = 0
|
30
|
+
code = []
|
28
31
|
@finish_line = @start_line
|
29
32
|
|
30
33
|
raw.each_with_index do |line, index|
|
31
34
|
|
32
|
-
|
33
|
-
|
35
|
+
line.gsub!(/^\r\n/,'')
|
36
|
+
line.gsub!(/\r\n$/,'')
|
37
|
+
|
38
|
+
depth += line.scan(BLOCK_BEGINNERS).count
|
39
|
+
depth -= line.scan(BLOCK_ENDERS).count
|
40
|
+
|
41
|
+
code << line
|
34
42
|
|
35
43
|
if depth == 0
|
36
44
|
@finish_line = index
|
@@ -39,14 +47,12 @@ module S41C
|
|
39
47
|
|
40
48
|
end # each
|
41
49
|
|
42
|
-
|
43
|
-
|
44
|
-
block.first.sub!(/^.*#{BLOCK_BEGINNERS}/, '')
|
45
|
-
block.last.sub!(/#{BLOCK_ENDERS}.*$/, '')
|
50
|
+
code.first.sub!(/^.*#{BLOCK_BEGINNERS}/, '')
|
51
|
+
code.last.sub!(/#{BLOCK_ENDERS}.*$/, '')
|
46
52
|
|
47
|
-
|
48
|
-
end
|
53
|
+
code.delete_if{|el| el.empty?}.join(';')
|
54
|
+
end
|
49
55
|
|
50
|
-
end
|
56
|
+
end
|
51
57
|
|
52
|
-
end
|
58
|
+
end
|
data/lib/s41c/sandbox.rb
CHANGED
@@ -1,20 +1,24 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
module S41C
|
3
|
+
module S41C #:nodoc
|
4
4
|
|
5
|
-
class Sandbox
|
5
|
+
class Sandbox #:nodoc
|
6
6
|
|
7
7
|
include S41C::Utils
|
8
8
|
|
9
|
-
|
9
|
+
#:nodoc
|
10
|
+
def initialize(ole, dump)
|
10
11
|
@ole = ole
|
11
|
-
|
12
|
+
dump.untaint
|
13
|
+
hsh = Marshal.load(dump)
|
14
|
+
@vars = hsh[:vars]
|
12
15
|
@code = proc {
|
13
16
|
$SAFE = 3
|
14
|
-
instance_eval code, __FILE__, __LINE__
|
17
|
+
instance_eval hsh[:code], __FILE__, __LINE__
|
15
18
|
}
|
16
19
|
end
|
17
20
|
|
21
|
+
#:nodoc
|
18
22
|
def eval_code
|
19
23
|
begin
|
20
24
|
@code.call
|
@@ -29,4 +33,4 @@ module S41C
|
|
29
33
|
|
30
34
|
end
|
31
35
|
|
32
|
-
end
|
36
|
+
end
|
data/lib/s41c/server.rb
CHANGED
@@ -6,6 +6,11 @@ module S41C
|
|
6
6
|
|
7
7
|
include S41C::Utils
|
8
8
|
|
9
|
+
# Создать инстанс сервера
|
10
|
+
#
|
11
|
+
# @param [ String ] адрес, на котором будет запущен сервер
|
12
|
+
# @param [ Integer ] порт
|
13
|
+
# @param [ String ] лог-файл
|
9
14
|
def initialize(host='localhost', port=1421, log_file=nil)
|
10
15
|
require 'socket'
|
11
16
|
require 'win32ole'
|
@@ -14,37 +19,53 @@ module S41C
|
|
14
19
|
@logger = log_file ? ::STDOUT.reopen(log_file, 'a') : ::STDOUT
|
15
20
|
@ole_name = 'V77.Application'
|
16
21
|
|
17
|
-
end
|
22
|
+
end
|
18
23
|
|
24
|
+
# Задать данные для авторизации подключающихся клиентов
|
25
|
+
#
|
26
|
+
# @param [ String ] логин
|
27
|
+
# @param [ String ] пароль
|
19
28
|
def login(username, password)
|
20
29
|
@login = username
|
21
30
|
@password = password
|
22
31
|
|
23
32
|
self
|
24
|
-
end
|
33
|
+
end
|
25
34
|
|
35
|
+
# Параметры подключения к базе 1C
|
36
|
+
#
|
37
|
+
# @params [ String ] база
|
38
|
+
# @params [ String ] имя пользователя
|
39
|
+
# @params [ String ] пароль пользователя
|
26
40
|
def db(database, user=nil, password=nil)
|
27
41
|
@conn_options = "/d #{database}"
|
28
42
|
@conn_options << " /n #{user}" if user
|
29
43
|
@conn_options << " /p #{password}" if password
|
30
44
|
|
31
45
|
self
|
32
|
-
end
|
46
|
+
end
|
33
47
|
|
48
|
+
# Название ole-объекта, который будет использоваться для подключения к 1С
|
49
|
+
#
|
50
|
+
# @param [ String ] название ole-объекта
|
34
51
|
def ole_name=(name)
|
35
52
|
@ole_name = name
|
36
53
|
|
37
54
|
self
|
38
|
-
end
|
55
|
+
end
|
39
56
|
|
57
|
+
# Задать блок кода, который будет выполнен при выключении сервера
|
58
|
+
#
|
59
|
+
# @param [ Proc ] блок кода
|
40
60
|
def at_exit(&block)
|
41
61
|
::Kernel::at_exit do
|
42
62
|
yield
|
43
63
|
end
|
44
64
|
|
45
65
|
self
|
46
|
-
end
|
66
|
+
end
|
47
67
|
|
68
|
+
# Запустить сервер
|
48
69
|
def start
|
49
70
|
|
50
71
|
["INT", "TERM"].each do |signal|
|
@@ -68,18 +89,18 @@ module S41C
|
|
68
89
|
retry
|
69
90
|
end
|
70
91
|
|
71
|
-
end
|
92
|
+
end
|
72
93
|
|
73
94
|
private
|
74
95
|
|
75
96
|
def read_response(session)
|
76
|
-
|
77
|
-
end
|
97
|
+
(session.gets || '').chomp
|
98
|
+
end
|
78
99
|
|
79
100
|
def log(msg)
|
80
101
|
@logger.puts msg
|
81
102
|
@logger.flush
|
82
|
-
end
|
103
|
+
end
|
83
104
|
|
84
105
|
def connect_to_1c
|
85
106
|
begin
|
@@ -97,11 +118,11 @@ module S41C
|
|
97
118
|
end
|
98
119
|
end
|
99
120
|
|
100
|
-
def eval_code(
|
121
|
+
def eval_code(dump)
|
101
122
|
return "Error: not connected" unless @conn
|
102
123
|
|
103
|
-
S41C::Sandbox.new(@ole,
|
104
|
-
end
|
124
|
+
S41C::Sandbox.new(@ole, dump).eval_code
|
125
|
+
end
|
105
126
|
|
106
127
|
def main_loop(server)
|
107
128
|
loop do
|
@@ -137,11 +158,11 @@ module S41C
|
|
137
158
|
cmd = args.shift
|
138
159
|
case cmd
|
139
160
|
when "eval"
|
140
|
-
|
161
|
+
dump = ""
|
141
162
|
while !(part = session.gets)['end_of_code']
|
142
|
-
|
163
|
+
dump << part
|
143
164
|
end
|
144
|
-
session.puts to_bin(eval_code(
|
165
|
+
session.puts to_bin(eval_code(dump))
|
145
166
|
session.puts "+OK"
|
146
167
|
when "ping"
|
147
168
|
session.puts "pong"
|
@@ -161,8 +182,8 @@ module S41C
|
|
161
182
|
}
|
162
183
|
|
163
184
|
end
|
164
|
-
end
|
185
|
+
end
|
165
186
|
|
166
|
-
end
|
187
|
+
end
|
167
188
|
|
168
|
-
end
|
189
|
+
end
|
data/lib/s41c/utils.rb
CHANGED
@@ -4,10 +4,20 @@ module S41C
|
|
4
4
|
|
5
5
|
module Utils
|
6
6
|
|
7
|
+
# Переводит строку в бинарное представление
|
8
|
+
#
|
9
|
+
# @param [ String ] строка в utf-8
|
10
|
+
#
|
11
|
+
# @return [ String ] строка в бинарном представлении
|
7
12
|
def to_bin(str)
|
8
13
|
str.to_s.force_encoding("BINARY")
|
9
14
|
end
|
10
15
|
|
16
|
+
# Переводит строку в utf-8
|
17
|
+
#
|
18
|
+
# @param [ String ] бинарная строка или строка из 1С
|
19
|
+
#
|
20
|
+
# @return [ String ] строка в utf-8
|
11
21
|
def to_utf8(str)
|
12
22
|
return unless str.is_a?(String)
|
13
23
|
if str.encoding.to_s == "IBM866"
|
@@ -17,14 +27,19 @@ module S41C
|
|
17
27
|
end
|
18
28
|
end
|
19
29
|
|
30
|
+
# Обертка над 1С-функцией "ЗначениеВСтрокуВнутр"
|
31
|
+
#
|
32
|
+
# @param [ Object ] объект 1С
|
33
|
+
#
|
34
|
+
# @return [ String ] идентификатор объекта
|
20
35
|
def get_1c_id(obj)
|
21
36
|
return false unless @ole
|
22
37
|
|
23
38
|
str_id = @ole.invoke('ЗначениеВСтрокуВнутр', obj)
|
24
39
|
escaped_str_id = "\"#{str_id.gsub('"', '""')}\""
|
25
40
|
|
26
|
-
end
|
41
|
+
end
|
27
42
|
|
28
|
-
end
|
43
|
+
end
|
29
44
|
|
30
|
-
end
|
45
|
+
end
|
data/lib/s41c/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: s41c
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-08 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: TCP-socket сервер и клиент для платформы "1С:Предприятие"
|
15
15
|
email:
|
@@ -28,7 +28,6 @@ files:
|
|
28
28
|
- lib/s41c/server.rb
|
29
29
|
- lib/s41c/client.rb
|
30
30
|
- lib/s41c.rb
|
31
|
-
- s41c-0.0.4.gem
|
32
31
|
- Gemfile
|
33
32
|
- Rakefile
|
34
33
|
homepage: https://github.com/dancingbytes/s41c
|
data/s41c-0.0.4.gem
DELETED
Binary file
|