tehportal 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|