s41c 0.0.5 → 0.0.6
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.
- 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
|