obeya 0.1.0 → 0.2.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 +4 -4
- data/.gitignore +4 -0
- data/CHANGELOG.md +7 -0
- data/lib/obeya.rb +5 -5
- data/lib/obeya/client.rb +89 -12
- data/lib/obeya/ticket.rb +105 -16
- data/lib/obeya/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7adf220c51ab91d183c62813d1f3216403d01617
|
4
|
+
data.tar.gz: 9c0be6e00be9d76b5bda6b58f598485f06430d3b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 02e81e3735dc745d00a23751994c457be0fbe5f45598b624c1e6db03a91ce8b8d959a1e40eedcb699133f108ee425072da6dc4fc63cdf8dbdb6df7fd8da8e182
|
7
|
+
data.tar.gz: c25e312da1575753610a282f46ca1f6eb0ddae3617ecbc0c8d41949f6baa2619dd9c82d9935ccb3d60310e2433247fd3bada0ac13d1e4379217cd2b900984942
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -3,3 +3,10 @@
|
|
3
3
|
## 0.1.0 (not yet released)
|
4
4
|
|
5
5
|
* initial copy from the `investapp`
|
6
|
+
|
7
|
+
## 0.2.0
|
8
|
+
|
9
|
+
* Support the ability to retrieve all tickets for a bin, and to run a matcher through this
|
10
|
+
* Support custom fields on ticket
|
11
|
+
* Add an integration test (site configured)
|
12
|
+
|
data/lib/obeya.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
require_relative "obeya/version"
|
2
|
+
require_relative "obeya/bin"
|
3
|
+
require_relative "obeya/ticket_type"
|
4
|
+
require_relative "obeya/ticket"
|
5
|
+
require_relative "obeya/client"
|
6
6
|
|
7
7
|
module Obeya
|
8
8
|
# Your code goes here...
|
data/lib/obeya/client.rb
CHANGED
@@ -1,37 +1,58 @@
|
|
1
1
|
require 'faraday'
|
2
2
|
require 'faraday_middleware'
|
3
|
+
require 'date'
|
3
4
|
|
4
5
|
module Obeya
|
5
6
|
class Client
|
6
7
|
|
7
8
|
OBEYA_ROOT_URL = "https://beta.getobeya.com"
|
9
|
+
CUSTOM_FIELD_TYPES = [::NilClass, ::String, ::Float, ::Integer, ::Array, ::Date]
|
8
10
|
|
9
|
-
def initialize(company_id, username, password)
|
11
|
+
def initialize(company_id, username, password, logger=nil)
|
10
12
|
@company_id = company_id
|
11
13
|
@username = username
|
12
14
|
@password = password
|
15
|
+
@logger = logger
|
16
|
+
|
17
|
+
@bin_tickets = {}
|
13
18
|
end
|
14
19
|
|
15
|
-
def create_ticket(title, description, format: 'text', ticket_type_name: '
|
16
|
-
ticket = Ticket.new(
|
17
|
-
title,
|
18
|
-
description,
|
19
|
-
format,
|
20
|
-
ticket_type(ticket_type_name),
|
21
|
-
bin(bin_name)
|
20
|
+
def create_ticket(title, description, format: 'text', ticket_type_name: 'bug', bin_name: /please panic/i, **others)
|
21
|
+
ticket = Ticket.new({
|
22
|
+
title: title,
|
23
|
+
description: description,
|
24
|
+
format: format,
|
25
|
+
ticket_type: ticket_type(ticket_type_name),
|
26
|
+
bin: bin(bin_name) }.
|
27
|
+
merge(others)
|
22
28
|
)
|
23
29
|
|
24
|
-
|
30
|
+
ticket_to_json = ticket.to_json(custom_field_name_map)
|
31
|
+
response = post("/tickets/#{next_ticket_id}", ticket_to_json)
|
25
32
|
case response.status
|
26
33
|
when 200..299
|
27
34
|
true
|
28
35
|
else
|
29
|
-
|
30
|
-
|
36
|
+
log_warn "status: #{response.status}"
|
37
|
+
log_warn " #{response.inspect}"
|
31
38
|
false
|
32
39
|
end
|
33
40
|
end
|
34
41
|
|
42
|
+
def update_ticket(id, other_fields)
|
43
|
+
ticket = Ticket.new(other_fields)
|
44
|
+
|
45
|
+
response = put("/tickets/#{id}", ticket.to_json(custom_field_name_map, true))
|
46
|
+
case response.status
|
47
|
+
when 200..299
|
48
|
+
true
|
49
|
+
else
|
50
|
+
log_warn "status: #{response.status}"
|
51
|
+
log_warn " #{response.inspect}"
|
52
|
+
false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
35
56
|
def bin(name_or_regex)
|
36
57
|
case name_or_regex
|
37
58
|
when String
|
@@ -66,8 +87,54 @@ module Obeya
|
|
66
87
|
end
|
67
88
|
end
|
68
89
|
|
90
|
+
def tickets_in_named_bin(bin_name)
|
91
|
+
named_bin = bin(bin_name)
|
92
|
+
raise "Bin #{bin_name} not found" unless named_bin
|
93
|
+
tickets_in_bin(named_bin.id)
|
94
|
+
end
|
95
|
+
|
96
|
+
def tickets_in_bin(bin_id)
|
97
|
+
ticket_type_map = Hash[ticket_types.map { |t| [t.id, t] }]
|
98
|
+
bin_map = Hash[bins.map { |b| [b.id, b] }]
|
99
|
+
|
100
|
+
@bin_tickets[bin_id] ||= begin
|
101
|
+
get("/tickets?bin_id=#{bin_id}").map do |ticket_data|
|
102
|
+
Ticket.from_obeya(ticket_data, ticket_type_map, bin_map, custom_fields)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def matching_tickets_in_named_bin(bin_name, title_matcher)
|
108
|
+
named_bin = bin(bin_name)
|
109
|
+
raise "Bin #{bin_name} not found" unless named_bin
|
110
|
+
matching_tickets_in_bin(named_bin.id, title_matcher)
|
111
|
+
end
|
112
|
+
|
113
|
+
def matching_tickets_in_bin(bin_id, title_matcher)
|
114
|
+
tickets = tickets_in_bin(bin_id)
|
115
|
+
case title_matcher
|
116
|
+
when String
|
117
|
+
tickets.select { |t| t.title == title_matcher }
|
118
|
+
when Regexp
|
119
|
+
tickets.select { |t| t.title =~ title_matcher }
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Get custom fields as a hash of id => {id, name, type}
|
124
|
+
def custom_fields
|
125
|
+
@custom_fields ||= begin
|
126
|
+
Hash[get('/custom-fields').map do |cf|
|
127
|
+
[cf['_id'], { id: cf['_id'], name: cf['name'], type: CUSTOM_FIELD_TYPES[cf['type'].to_i] }]
|
128
|
+
end]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
69
132
|
private
|
70
133
|
|
134
|
+
def custom_field_name_map
|
135
|
+
@custom_field_name_map ||= Hash[custom_fields.values.map {|v| [v[:name], v] }]
|
136
|
+
end
|
137
|
+
|
71
138
|
def next_ticket_id
|
72
139
|
get('/ids?amount=1')[0]
|
73
140
|
end
|
@@ -77,7 +144,7 @@ module Obeya
|
|
77
144
|
request.headers.update({ accept: 'application/json', content_type: 'application/json' })
|
78
145
|
end
|
79
146
|
unless response.success?
|
80
|
-
raise("Obeya #{api_path} call
|
147
|
+
raise("Obeya #{api_path} call failed")
|
81
148
|
end
|
82
149
|
JSON.parse(response.body)
|
83
150
|
end
|
@@ -88,6 +155,12 @@ module Obeya
|
|
88
155
|
end
|
89
156
|
end
|
90
157
|
|
158
|
+
def put(api_path, json)
|
159
|
+
faraday.put("/rest/1/#{@company_id}#{api_path}", json) do |request|
|
160
|
+
request.headers.update({ accept: 'application/json', content_type: 'application/json' })
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
91
164
|
def faraday
|
92
165
|
@faraday ||= Faraday.new(OBEYA_ROOT_URL).tap do |connection|
|
93
166
|
connection.basic_auth(@username, @password)
|
@@ -95,5 +168,9 @@ module Obeya
|
|
95
168
|
end
|
96
169
|
end
|
97
170
|
|
171
|
+
def log_warn(s)
|
172
|
+
@logger.warn(s) if @logger
|
173
|
+
end
|
174
|
+
|
98
175
|
end
|
99
176
|
end
|
data/lib/obeya/ticket.rb
CHANGED
@@ -1,22 +1,111 @@
|
|
1
1
|
module Obeya
|
2
2
|
class Ticket
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
4
|
+
# title, description, format, ticket_type, bin, id=nil
|
5
|
+
def initialize(*params)
|
6
|
+
if params.first.is_a?(Hash)
|
7
|
+
@ticket_fields = params.first
|
8
|
+
else
|
9
|
+
@ticket_fields = {}
|
10
|
+
[:title, :description, :format, :ticket_type, :bin, :id].each_with_index do |param_key, idx|
|
11
|
+
break if idx>=params.size
|
12
|
+
@ticket_fields[param_key] = params[idx]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.from_obeya(src_hash, ticket_types, bins, custom_fields)
|
18
|
+
ticket_fields = Hash[
|
19
|
+
src_hash.map do |obeya_name, field_value|
|
20
|
+
case(obeya_name)
|
21
|
+
when 'rtformat'
|
22
|
+
[:format, field_value]
|
23
|
+
when 'name'
|
24
|
+
[:title, field_value]
|
25
|
+
when 'ticketType_id'
|
26
|
+
[:ticket_type, ticket_types[field_value.to_i]]
|
27
|
+
when 'bin_id'
|
28
|
+
[:bin, bins[field_value.to_i]]
|
29
|
+
when 'customFields'
|
30
|
+
nil
|
31
|
+
else
|
32
|
+
[obeya_name.to_sym, field_value]
|
33
|
+
end
|
34
|
+
end.compact
|
35
|
+
]
|
36
|
+
|
37
|
+
(src_hash['customFields'] || []).each do |custom_field_id, value|
|
38
|
+
ticket_fields[custom_fields[custom_field_id][:name]] = value
|
39
|
+
end
|
40
|
+
|
41
|
+
Obeya::Ticket::new(ticket_fields)
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_obeya(custom_field_name_map, for_update=false)
|
45
|
+
obeya_fields = Hash[@ticket_fields.map do |field_name, field_value|
|
46
|
+
case(field_name)
|
47
|
+
when :format
|
48
|
+
['rtformat', field_value]
|
49
|
+
when :title
|
50
|
+
['name', field_value]
|
51
|
+
when :description
|
52
|
+
['description', normalise(field_value)]
|
53
|
+
when :ticket_type
|
54
|
+
['ticketType_id', field_value.id]
|
55
|
+
when :bin
|
56
|
+
['bin_id', field_value.id]
|
57
|
+
else
|
58
|
+
if for_update
|
59
|
+
fdef = custom_field_name_map[field_name.to_s]
|
60
|
+
["customFields.#{fdef[:id]}", cast_to_obeya(field_value, fdef[:type])]
|
61
|
+
else
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end.compact
|
66
|
+
]
|
67
|
+
|
68
|
+
unless for_update
|
69
|
+
custom_fields = @ticket_fields.select {|fn, _v| ![:format, :title, :description, :ticket_type, :bin].include?(fn) }
|
70
|
+
if custom_fields && !custom_fields.empty?
|
71
|
+
obeya_fields['customFields'] =
|
72
|
+
Hash[custom_fields.map do |field_name, field_value|
|
73
|
+
fdef = custom_field_name_map[field_name.to_s]
|
74
|
+
[fdef[:id], cast_to_obeya(field_value, fdef[:type])]
|
75
|
+
end]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
obeya_fields
|
80
|
+
end
|
81
|
+
|
82
|
+
def cast_to_obeya(value, type)
|
83
|
+
case type.to_s
|
84
|
+
when 'String'
|
85
|
+
value.to_s
|
86
|
+
when 'Float'
|
87
|
+
value.to_f
|
88
|
+
when 'Integer'
|
89
|
+
value.to_i
|
90
|
+
when 'Array'
|
91
|
+
value
|
92
|
+
when 'Date'
|
93
|
+
Date.parse(value.to_s).strftime('%Y-%m-%dT%H:%M:%S.%LZ')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_json(custom_field_name_map, for_update=false)
|
98
|
+
to_obeya(custom_field_name_map, for_update).to_json
|
99
|
+
end
|
100
|
+
|
101
|
+
def [](name)
|
102
|
+
@ticket_fields[name]
|
103
|
+
end
|
104
|
+
|
105
|
+
def method_missing(name)
|
106
|
+
return @ticket_fields[name] if @ticket_fields.key?(name)
|
107
|
+
|
108
|
+
super
|
20
109
|
end
|
21
110
|
|
22
111
|
private
|
data/lib/obeya/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: obeya
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thorsten Boettger
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|