tehportal 0.1.0
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 +7 -0
- data/.gitignore +23 -0
- data/Gemfile +4 -0
- data/README.md +128 -0
- data/Rakefile +2 -0
- data/app/controllers/remedy_controller.rb +59 -0
- data/config/config.yml +0 -0
- data/config/locales/ru.yml +2 -0
- data/config/routes.rb +8 -0
- data/lib/nori_patch.rb +30 -0
- data/lib/tehportal/attachment.rb +62 -0
- data/lib/tehportal/configuration.rb +5 -0
- data/lib/tehportal/engine.rb +9 -0
- data/lib/tehportal/model.rb +14 -0
- data/lib/tehportal/operation.rb +30 -0
- data/lib/tehportal/remedy_client.rb +111 -0
- data/lib/tehportal/version.rb +3 -0
- data/lib/tehportal.rb +39 -0
- data/tehportal.gemspec +23 -0
- metadata +103 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8c5a8fa924393d1efda5585ea6666232b67310de
|
4
|
+
data.tar.gz: 5f6601b8bd473d1b691c56258bbe1a8814140a86
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1392c6f43ed7369ccbc8b5ce71d26e34a0ade9363d5dd718df3a3d45e511bc19e0334aecc4bad58d81bcc8c907b1a2cda3d4828358b76150022cc6a11197849b
|
7
|
+
data.tar.gz: 2b70144a02c70d0a8fc3229a496751c94426fbcfc47f8115ace6182e7eab7c9e7184ce8fb4546311cff2e0da71680230e1ca85d7ef74febc18193f9c803ee2cf
|
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
.idea
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
# Tehportal
|
2
|
+
|
3
|
+
## Описание
|
4
|
+
Данный gem это ядро для работы с remedy и возможно с другими системами.
|
5
|
+
|
6
|
+
## Модели
|
7
|
+
Все сервиси группируем - инциденты, изменения, проблемы, задачи и тд. Для каждой группы делаем модель с базовым классом - **Tehportal::Model**.
|
8
|
+
В модели делаем описание всех сервисов в виде хэша:
|
9
|
+
|
10
|
+
@@services = {
|
11
|
+
show: 'ATC:HPD:AKEOS-Portal-Get-Incident-WorkInfo',
|
12
|
+
list: 'ATC:INC:AKEOS-List',
|
13
|
+
create: 'ATC:INC:AKEOS-Create',
|
14
|
+
update: 'ATC:INC:AKEOS-Modify'
|
15
|
+
}
|
16
|
+
|
17
|
+
Где ключ данного хэша будет соответствовать action-методу в соответствующем контроллере.
|
18
|
+
Также в базовом классе моделе реализован запрос к серверу(сейчас через method_missing, после рефакторинга с помощью class_eval).
|
19
|
+
Модели называем во множественном числе(например: Tehportal::Incidents), чтобы соответствовало названию контроллера.
|
20
|
+
|
21
|
+
**ВАЖНО:** Т.к. в remedy важен порядок передаваемых ему полей в моделе реализован механизм, который расставляем параметры в нжном порядке. Нужно просто передать параметры.
|
22
|
+
|
23
|
+
### 1.Инциденты
|
24
|
+
Модель: **Tehportal::Incidents**
|
25
|
+
### 2.Изменения
|
26
|
+
### 3.Проблемы
|
27
|
+
Модель: **Tehportal::Problems**
|
28
|
+
### 4.Релизы
|
29
|
+
|
30
|
+
## Контроллеры/API
|
31
|
+
Все контроллеры для работы с remedy наследуются от **RemedyBaseController**. Перед запуском любого action-метода срабатывает хук который отпределяет
|
32
|
+
с какой моделью работать данному контроллеру.
|
33
|
+
|
34
|
+
Для каждого сервиса реализуется action-метод, в который в качестве параметра передается название операции и другие параметры.
|
35
|
+
|
36
|
+
Базовый url: _/tp/remedy_
|
37
|
+
|
38
|
+
Параметры который пойдут на вход Remedy передаются в массиве data (пример: data[ID]=23&data[Description]=New_Message)
|
39
|
+
Для action может быть несколько операций, они передаются параметром operation(пример: operation=INCGetList-InWork)
|
40
|
+
|
41
|
+
### 1.Инциденты
|
42
|
+
#### Список инцидентов
|
43
|
+
|
44
|
+
*URL:* GET /incidents/
|
45
|
+
|
46
|
+
|Операция|Описание|Параметры|
|
47
|
+
|--------|--------|---------|
|
48
|
+
| _INCGetList-InWork_ | Назначенные на меня со статусом "открытые" |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Login - логин пользователя|
|
49
|
+
| _INCGetList-SLABreached-My_ | Назначенные на меня со статусом "нарушенные" |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Login - логин пользователя|
|
50
|
+
| _INCGetList-Pending-My_ | Назначенные на меня со статусом "в ожидании" |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Login - логин пользователя|
|
51
|
+
| _INC_Created_By_Me_InWork_ | Созданные мной |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Login - логин пользователя|
|
52
|
+
| _INCGetList-SLABreached-OnMyGroup_ | Назначенные на группу со статусом "просроченные"|startRecord - offset для списка<br /> maxLimit - limit для списка<br />Group - Название группы|
|
53
|
+
| _INCGetList-InWork-OnMyGroup_ | Назначенные на группу со статусом "открытые"|startRecord - offset для списка<br /> maxLimit - limit для списка<br />Group - Название группы|
|
54
|
+
| _NCGetList-Pending-OnMyGroup_ | Назначенные на группу со статусом "в ожидании" |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Group - Название группы|
|
55
|
+
|
56
|
+
##### *URL:* GET /incidents/:id - Просмотр инцидента
|
57
|
+
##### *URL:* GET /incidents/:id/associations - Просмотр инцидента: свзяи
|
58
|
+
##### *URL:* GET /incidents/:id/tasks - Просмотр инцидента: задачи
|
59
|
+
##### *URL:* GET /incidents/:id/times - Просмотр инцидента: затраченное время
|
60
|
+
|
61
|
+
### 2.Задачи
|
62
|
+
#### Список задач
|
63
|
+
|
64
|
+
*URL:* GET /tasks/
|
65
|
+
|
66
|
+
|Операция|Описание|Параметры|
|
67
|
+
|--------|--------|---------|
|
68
|
+
| _TSK_My_InWork_ | Назначенные на меня со статусом "открытые" |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Login - логин пользователя|
|
69
|
+
| _TSK_Created_By_Me_InWork_ | Созданные мной |startRecord - offset для списка<br /> maxLimit - limit для списка<br />Login - логин пользователя|
|
70
|
+
| _TSK_OnMyGroup_InWork_ | Назначенные на группу со статусом "открытые"|startRecord - offset для списка<br /> maxLimit - limit для списка<br />Group - Название группы|
|
71
|
+
|
72
|
+
##### *URL:* GET /incidents/:id - Просмотр задачи
|
73
|
+
##### *URL:* GET /tasks/:id/comments - Просмотр задачи: комментарии
|
74
|
+
##### *URL:* GET /tasks/:id/times - Просмотр задачи: затраченное время
|
75
|
+
|
76
|
+
|
77
|
+
### 3.Изменения
|
78
|
+
### 4.Проблемы
|
79
|
+
Контроллер: **ProblemsController**
|
80
|
+
Методы:
|
81
|
+
|
82
|
+
* list
|
83
|
+
|
84
|
+
команда:
|
85
|
+
`GET /tp/remedy/problems?operation=[операция]`
|
86
|
+
|
87
|
+
операции:
|
88
|
+
|
89
|
+
- InWorkMy
|
90
|
+
- InWorkGroup
|
91
|
+
- InWorkAllGroups
|
92
|
+
|
93
|
+
* show
|
94
|
+
команда:
|
95
|
+
`GET /tp/remedy/problems/[id]`
|
96
|
+
|
97
|
+
* create
|
98
|
+
команда:
|
99
|
+
`POST /tp/remedy/problems`
|
100
|
+
|
101
|
+
### 5.Релизы
|
102
|
+
|
103
|
+
# Установка
|
104
|
+
|
105
|
+
1. Добавить следующую строчку в Gemfile:
|
106
|
+
|
107
|
+
`gem 'tehportal', git: 'git@gitlab.at-consulting:dfp/tehportal'`
|
108
|
+
|
109
|
+
1. В приложении необходимо создать инициализатор gem'а:
|
110
|
+
|
111
|
+
`Tehportal.configure do |config|
|
112
|
+
config.url = 'http://example.com'
|
113
|
+
config.server = 'example-server'
|
114
|
+
config.endpoint = 'http://example.com/services/ARService'
|
115
|
+
end`
|
116
|
+
|
117
|
+
1. Роутинг:
|
118
|
+
|
119
|
+
`mount Tehportal::Engine => '/'`
|
120
|
+
|
121
|
+
1. Авторизация: перед выполением каких либо действий нужно настроить пользователя от чьего имени будут выполняться запросы, если используется devise, то код будет следующего вида:
|
122
|
+
|
123
|
+
`Tehportal.setup_client(current_user.login, current_user.decrypt_password) if current_user`
|
124
|
+
|
125
|
+
|
126
|
+
# Использование
|
127
|
+
|
128
|
+
TODO: Write usage instructions here
|
data/Rakefile
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
#++
|
2
|
+
# Базовый контроллер для всех remedy-запросов.
|
3
|
+
#
|
4
|
+
# Базовый action-методы описываются тут, если в конкретном подклассе необходимо,
|
5
|
+
# то всегда базовый метод можно переопределить.
|
6
|
+
#--
|
7
|
+
class RemedyController < Tehportal.config.parent_controller.constantize
|
8
|
+
# before_filter :specify_params, only: %i(index search)
|
9
|
+
# respond_with_params only: %i(index search)
|
10
|
+
|
11
|
+
def send_request
|
12
|
+
model = "Tehportal::#{params[:model].capitalize}".constantize
|
13
|
+
render_remedy_json model.send(params[:method], params[:data])
|
14
|
+
end
|
15
|
+
|
16
|
+
# ВСЕВОЗМОЖНЫЕ СПИСКИ
|
17
|
+
def index
|
18
|
+
result = model.list(params[:operation], list_params)
|
19
|
+
result['getListValues'] = Array.wrap(result['getListValues'])
|
20
|
+
|
21
|
+
render_remedy_json result
|
22
|
+
end
|
23
|
+
|
24
|
+
# СВЯЗИ
|
25
|
+
def associations
|
26
|
+
render_remedy_json model.associations('GetList_Association', association_params)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# Получение класса модели, через которую будут делаться запросы
|
32
|
+
def model
|
33
|
+
@model ||= "Tehportal::#{params[:controller].split('/').last.capitalize}".constantize
|
34
|
+
end
|
35
|
+
|
36
|
+
def model_class(name)
|
37
|
+
"Tehportal::#{name.capitalize}".constantize
|
38
|
+
end
|
39
|
+
|
40
|
+
# Запрос на получение связей, имя ID объекта у всех разный
|
41
|
+
def association_params
|
42
|
+
data = {}
|
43
|
+
model_name = params[:controller].split('/').last.downcase.to_sym
|
44
|
+
params_map = {incidents: 'IncidentNumber', problems: 'ProblemInvestigationID', changes: 'Infrastructure_Change_ID'}
|
45
|
+
|
46
|
+
data[params_map[model_name]] = params[:id]
|
47
|
+
data
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def render_remedy_json(data)
|
53
|
+
prepared = data.except('@xmlns:ns0', '@xmlns:xsd', '@xmlns:xsi')
|
54
|
+
render json: (prepared.blank? && data.length != 3) ? nil : prepared
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
|
data/config/config.yml
ADDED
File without changes
|
data/config/routes.rb
ADDED
data/lib/nori_patch.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'nori/parser/nokogiri'
|
2
|
+
|
3
|
+
# В текущей реализации парсер пропускает пробелы между
|
4
|
+
# представленными в виде xml character entities non-ASCII словами,
|
5
|
+
# считая их мусором:
|
6
|
+
# <ns0:ASSIGNEDGROUP>Дежурная смена ЛП1.5</ns0:ASSIGNEDGROUP>
|
7
|
+
# Ожидается: "ns0:ASSIGNEDGROUP"=>"Дежурная смена ЛП1.5"
|
8
|
+
# Имеется в nori-2.4.0: "ns0:ASSIGNEDGROUP"=>"ДежурнаясменаЛП1.5"
|
9
|
+
class Nori::Parser::Nokogiri::Document
|
10
|
+
|
11
|
+
def characters(string)
|
12
|
+
last = stack.last
|
13
|
+
if last and last.children.last.is_a?(String) or string.strip.size > 0
|
14
|
+
last.add_node(string)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
alias cdata_block characters
|
18
|
+
|
19
|
+
def end_element(name)
|
20
|
+
if stack.size > 1
|
21
|
+
last = stack.pop
|
22
|
+
maybe_string = last.children.last
|
23
|
+
if maybe_string.is_a?(String) and maybe_string.strip.empty?
|
24
|
+
last.children.pop
|
25
|
+
end
|
26
|
+
stack.last.add_node last
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Tehportal
|
2
|
+
module Attachment
|
3
|
+
module_function
|
4
|
+
|
5
|
+
def file_list(path)
|
6
|
+
file_list = []
|
7
|
+
if path.present? and File.directory?(path)
|
8
|
+
file_list = Dir(path).content.select {|f| File.file?(f)}.map {|f| File.basename(f)}
|
9
|
+
end
|
10
|
+
file_list
|
11
|
+
end
|
12
|
+
|
13
|
+
def path_for(request_params, user)
|
14
|
+
if request_params[:commentable]
|
15
|
+
subject, id = request_params[:commentable]/'/'
|
16
|
+
else
|
17
|
+
subject = request_params[:controller]
|
18
|
+
if request_params[:action] == 'create'
|
19
|
+
id = 'NEW'
|
20
|
+
else
|
21
|
+
id = request_params[:id]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
if subject
|
25
|
+
"#{Rails.root}/tmp/#{subject}/#{id}/#{user.login}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def file_list_for(request_params, user)
|
30
|
+
path = path_for(request_params, user)
|
31
|
+
Attachment.file_list path
|
32
|
+
end
|
33
|
+
|
34
|
+
def collect_files_at(path)
|
35
|
+
files = {dir: path}
|
36
|
+
|
37
|
+
if File.directory?(path)
|
38
|
+
file_list = Attachment.file_list(path)
|
39
|
+
file_list[0..2].each_with_index do |file_name, index|
|
40
|
+
i = index+1
|
41
|
+
if content = read("#{path}/#{file_name}")
|
42
|
+
files.merge! :"name_#{i}" => file_name,
|
43
|
+
:"data_#{i}" => Base64.encode64(content),
|
44
|
+
:"size_#{i}" => content.size
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
files
|
50
|
+
end
|
51
|
+
|
52
|
+
def collect_files_for(request_params, user)
|
53
|
+
collect_files_at path_for(request_params, user)
|
54
|
+
end
|
55
|
+
|
56
|
+
def clear(params, user)
|
57
|
+
path_tmp = path_for(params, user)
|
58
|
+
FileUtils.rm_rf(path_tmp) if File.directory?(path_tmp)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Орерации(действия)
|
2
|
+
module Operation
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
# Метод описания операции
|
9
|
+
# @ name : Название операции
|
10
|
+
# @ url : url = название_сервиса + / + название_операции
|
11
|
+
# @ options : Параметры для операции
|
12
|
+
# - defaults : Значения по умолчанию для Body
|
13
|
+
def operation(name, url, options = {})
|
14
|
+
options[:defaults] ||= {}
|
15
|
+
service, operation = url.split('/')
|
16
|
+
model_name = self.name.split('::').last.downcase
|
17
|
+
|
18
|
+
Tehportal::Model.operations[model_name] ||= {}
|
19
|
+
Tehportal::Model.operations[model_name][name] = {service: service, operation: operation}
|
20
|
+
|
21
|
+
# Добавляем синглтон метод к классу модели
|
22
|
+
define_singleton_method(name) do |*args|
|
23
|
+
client = args[0].delete(:client) || Tehportal.client
|
24
|
+
message = options[:defaults].merge(args[0])
|
25
|
+
|
26
|
+
client.request(service, operation, message)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Tehportal
|
2
|
+
class RemedyClient
|
3
|
+
delegate :config, to: :Tehportal
|
4
|
+
|
5
|
+
def initialize(login = nil, password = nil)
|
6
|
+
@login, @password = login, password
|
7
|
+
@definitions = Rails.cache.read('tp.remedy.definitions') || {}
|
8
|
+
end
|
9
|
+
|
10
|
+
# Выполнение запроса к сервису
|
11
|
+
#
|
12
|
+
# @ service : Веб-сервис
|
13
|
+
# @ method : операция веб-сервиса
|
14
|
+
# @ body : хеш данных для запроса к веб-сервису
|
15
|
+
# e.g.: {"Status" => "Pending"}
|
16
|
+
def request(service, method, body = {})
|
17
|
+
message = {}
|
18
|
+
operation_map = operation_map(service, method)
|
19
|
+
|
20
|
+
operation_map[:input].each do |key|
|
21
|
+
message[key] = body[key] if body.has_key?(key) && body[key].to_s.downcase != 'null'
|
22
|
+
end unless operation_map.nil?
|
23
|
+
|
24
|
+
client = Savon.client(endpoint: "#{config.endpoint}?server=#{config.server}&webService=#{service}",
|
25
|
+
namespace: service,
|
26
|
+
soap_header: {'AuthenticationInfo' => {userName: @login, password: @password}},
|
27
|
+
ssl_verify_mode: :none,
|
28
|
+
raise_errors: false,
|
29
|
+
convert_response_tags_to: nil,
|
30
|
+
open_timeout: 300,
|
31
|
+
read_timeout: 300,
|
32
|
+
log: true,
|
33
|
+
logger: Rails.logger,
|
34
|
+
log_level: :debug,
|
35
|
+
filters: [:password])
|
36
|
+
|
37
|
+
response = client.call(method, message: message, soap_action: "urn:#{service}/#{method}", advanced_typecasting: false)
|
38
|
+
|
39
|
+
hash = response.to_hash
|
40
|
+
hash.has_key?('Fault') ? {errorMessage: hash['Fault']['faultstring']} : hash["#{method.gsub(/-/, '_')}Response"]
|
41
|
+
end
|
42
|
+
|
43
|
+
def wsdl_url(service)
|
44
|
+
[config.url, config.server, service].join('/')
|
45
|
+
end
|
46
|
+
|
47
|
+
# Получить Nori-made хеш на основе xml-документа <wsdl:definitions>
|
48
|
+
# e.g.: http://188.254.6.21/arsys/WSDL/public/skuf-app/ATC:INC:AKEOS-List
|
49
|
+
#
|
50
|
+
# @ service : имя сервиса
|
51
|
+
# e.g.: ATC:INC:AKEOS-List
|
52
|
+
def definitions(service)
|
53
|
+
unless @definitions[service]
|
54
|
+
@definitions[service] ||= begin
|
55
|
+
client = Savon.client({wsdl: wsdl_url(service),
|
56
|
+
ssl_verify_mode: :none,
|
57
|
+
raise_errors: false,
|
58
|
+
convert_request_keys_to: :none,
|
59
|
+
convert_response_tags_to: :none})
|
60
|
+
client.operations
|
61
|
+
xml = client.instance_variable_get(:@wsdl).xml
|
62
|
+
Nori.new(strip_namespaces: true, delete_namespace_attributes: true).parse(xml)['definitions']
|
63
|
+
end
|
64
|
+
|
65
|
+
Rails.cache.write('tp.remedy.definitions', @definitions, expires_in: 1.day)
|
66
|
+
end
|
67
|
+
|
68
|
+
@definitions[service]
|
69
|
+
end
|
70
|
+
|
71
|
+
# Определение доступных операций и их характеристик
|
72
|
+
# в соответствии с wsdl:definition по указанному сервису
|
73
|
+
#
|
74
|
+
# @ service : путь к значению в конфиге
|
75
|
+
# e.g.: ATC:INC:AKEOS-List
|
76
|
+
def operations_map(service)
|
77
|
+
defs = definitions(service)
|
78
|
+
schema = defs['types']['schema']
|
79
|
+
messages = Array.wrap(defs['message'])
|
80
|
+
elements = Array.wrap(schema['element'])
|
81
|
+
types = Array.wrap(schema['complexType'])
|
82
|
+
operations = Array.wrap(defs['portType']['operation'])
|
83
|
+
|
84
|
+
res = operations.map do |op|
|
85
|
+
op_name = op['@name']
|
86
|
+
|
87
|
+
message_name = op['output']['@message'].sub(/^[^:]+:/, '')
|
88
|
+
message = messages.find {|m| m['@name'] == message_name}
|
89
|
+
element_name = message['part']['@element'].sub(/^[^:]+:/, '')
|
90
|
+
# undasherize для удобства обхода (совместимо с текущим кодом)
|
91
|
+
element_name.tr! '-', '_'
|
92
|
+
|
93
|
+
type_name = elements.find {|e| e['@name'] == op_name}['@type'].sub(/^[^:]+:/, '')
|
94
|
+
type_input = types.find {|t| t['@name'] == type_name}['sequence']
|
95
|
+
if type_input
|
96
|
+
fields = Array.wrap(type_input['element'])
|
97
|
+
field_names = fields.map {|f| f['@name']}
|
98
|
+
end
|
99
|
+
|
100
|
+
[op_name, {output: element_name, input: Array.wrap(field_names)}]
|
101
|
+
end
|
102
|
+
|
103
|
+
Hash[res]
|
104
|
+
end
|
105
|
+
|
106
|
+
def operation_map(service, operation)
|
107
|
+
all_operations = operations_map(service)
|
108
|
+
all_operations[operation]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/lib/tehportal.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rails/all'
|
2
|
+
require 'savon'
|
3
|
+
|
4
|
+
require 'nori_patch'
|
5
|
+
require 'tehportal/engine'
|
6
|
+
|
7
|
+
# --
|
8
|
+
# Обертка для запросов к бекенду Техпортала (Ремеди)
|
9
|
+
# ++
|
10
|
+
module Tehportal
|
11
|
+
extend ActiveSupport::Autoload
|
12
|
+
|
13
|
+
autoload :Attachment
|
14
|
+
autoload :Configuration
|
15
|
+
autoload :Model
|
16
|
+
autoload :RemedyClient
|
17
|
+
|
18
|
+
class << self
|
19
|
+
attr_writer :config
|
20
|
+
attr_reader :client
|
21
|
+
|
22
|
+
delegate :request, to: :client
|
23
|
+
|
24
|
+
def configure
|
25
|
+
yield(config)
|
26
|
+
end
|
27
|
+
|
28
|
+
def config
|
29
|
+
@config ||= Configuration.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def setup_client(login, password)
|
33
|
+
@client = RemedyClient.new(login, password)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
require 'tehportal/version'
|
39
|
+
|
data/tehportal.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'tehportal/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'tehportal'
|
8
|
+
spec.version = Tehportal::VERSION
|
9
|
+
spec.authors = ['AT Consulting']
|
10
|
+
spec.email = ['info@at-consulting.ru']
|
11
|
+
spec.summary = %q{Прослойка для работы с Remedy.}
|
12
|
+
spec.description = %q{Прослойка для работы с Remedy.}
|
13
|
+
spec.homepage = 'https://at-consulting.ru'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ['lib']
|
19
|
+
|
20
|
+
spec.add_dependency 'savon', '~> 2.0'
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
22
|
+
spec.add_development_dependency 'rake'
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tehportal
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- AT Consulting
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: savon
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.6'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: "Прослойка для работы с Remedy."
|
56
|
+
email:
|
57
|
+
- info@at-consulting.ru
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- Gemfile
|
64
|
+
- README.md
|
65
|
+
- Rakefile
|
66
|
+
- app/controllers/remedy_controller.rb
|
67
|
+
- config/config.yml
|
68
|
+
- config/locales/ru.yml
|
69
|
+
- config/routes.rb
|
70
|
+
- lib/nori_patch.rb
|
71
|
+
- lib/tehportal.rb
|
72
|
+
- lib/tehportal/attachment.rb
|
73
|
+
- lib/tehportal/configuration.rb
|
74
|
+
- lib/tehportal/engine.rb
|
75
|
+
- lib/tehportal/model.rb
|
76
|
+
- lib/tehportal/operation.rb
|
77
|
+
- lib/tehportal/remedy_client.rb
|
78
|
+
- lib/tehportal/version.rb
|
79
|
+
- tehportal.gemspec
|
80
|
+
homepage: https://at-consulting.ru
|
81
|
+
licenses: []
|
82
|
+
metadata: {}
|
83
|
+
post_install_message:
|
84
|
+
rdoc_options: []
|
85
|
+
require_paths:
|
86
|
+
- lib
|
87
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
requirements: []
|
98
|
+
rubyforge_project:
|
99
|
+
rubygems_version: 2.2.2
|
100
|
+
signing_key:
|
101
|
+
specification_version: 4
|
102
|
+
summary: "Прослойка для работы с Remedy."
|
103
|
+
test_files: []
|