queri 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +96 -0
- data/Rakefile +7 -0
- data/lib/queri/realtime/agents.rb +80 -0
- data/lib/queri/realtime/queues.rb +64 -0
- data/lib/queri/realtime.rb +14 -0
- data/lib/queri/stats/agents_and_sessions/agent_availability.rb +76 -0
- data/lib/queri/stats/agents_and_sessions.rb +11 -0
- data/lib/queri/stats/answered_calls/agents_on_queue.rb +73 -0
- data/lib/queri/stats/answered_calls/all_calls.rb +81 -0
- data/lib/queri/stats/answered_calls.rb +11 -0
- data/lib/queri/stats/unanswered_calls/all_calls.rb +80 -0
- data/lib/queri/stats/unanswered_calls.rb +11 -0
- data/lib/queri/stats.rb +9 -0
- data/lib/queri/version.rb +3 -0
- data/lib/queri.rb +113 -0
- data/queri.gemspec +25 -0
- data/spec/queri_spec.rb +268 -0
- data/spec/realtime/agents_spec.rb +18 -0
- data/spec/realtime/queues_spec.rb +18 -0
- data/spec/realtime/realtime_spec.rb +10 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/stats/agents_and_sessions/agent_availability_spec.rb +18 -0
- data/spec/stats/agents_and_sessions/agents_and_sessions_spec.rb +7 -0
- data/spec/stats/answered_calls/agents_on_queue_spec.rb +18 -0
- data/spec/stats/answered_calls/all_calls_spec.rb +18 -0
- data/spec/stats/answered_calls/answered_calls_spec.rb +7 -0
- data/spec/stats/stats_spec.rb +7 -0
- data/spec/stats/unanswered_calls/all_calls_spec.rb +18 -0
- data/spec/stats/unanswered_calls/unanswered_calls_spec.rb +7 -0
- data/spec/support/constantize.rb +27 -0
- data/spec/support/shared/shared_examples_for_agent_level_report_instance.rb +37 -0
- data/spec/support/shared/shared_examples_for_aggregate_report_instance.rb +37 -0
- data/spec/support/shared/shared_examples_for_private_constant.rb +9 -0
- data/spec/support/shared/shared_examples_for_queuemetrics_report.rb +25 -0
- data/spec/support/shared/shared_examples_for_realtime_report.rb +32 -0
- data/spec/support/shared/shared_examples_for_realtime_report_instance.rb +26 -0
- data/spec/support/shared/shared_examples_for_report_class.rb +13 -0
- data/spec/support/shared/shared_examples_for_report_method.rb +13 -0
- data/spec/support/shared/shared_examples_for_stats_report.rb +44 -0
- data/spec/support/time_helper.rb +17 -0
- metadata +154 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c8ff886a7b69a9fdfe36380d9203f402fb8ed330
|
4
|
+
data.tar.gz: 8ee9d637892fe1cf67970193e4ddaf8e9389f9a3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d7d5dd17f5d435eaf4aa22c97273af719770e3b44bf67b955ef7300010951c14444021a362618313802aef9b5acf478ac8a9785d6a3c06a238a8ad9f80a06799
|
7
|
+
data.tar.gz: 031a8cfe9662fdb113fdada643bbdd209b6a2b603a4c9df3aac027150d97ea4f48099e5d4bdfcd126788bc870440dba790c30088f0c2b06eb4aee014df258c2a
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Brad Rice
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# Queri
|
2
|
+
|
3
|
+
Queri, or Queuemetrics Reporting Interface, sends requests to XMLRPC Client to return stats from Queuemetrics' reporting API platform given a valid set of client configurations.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'queri'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install queri
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
### Configuring
|
22
|
+
|
23
|
+
Configurations for connecting to a Queuemetrics XMLRPC client are needed to send requests for analyses. They can be viewed with:
|
24
|
+
|
25
|
+
Queri::config
|
26
|
+
|
27
|
+
You can set these configurations with the following:
|
28
|
+
|
29
|
+
Queri::configure({username: "new\_user", password: "new\_password"})
|
30
|
+
|
31
|
+
or with a local YAML file:
|
32
|
+
|
33
|
+
Queri::configure_with("/path/to/a/config.yml")
|
34
|
+
|
35
|
+
### Basic Usage
|
36
|
+
|
37
|
+
queues = ["1234"]
|
38
|
+
period_start = Time.now - 3600
|
39
|
+
period_end = Time.now
|
40
|
+
Queri::Stats::AgentsAndSessions::AgentAvailability.new( queues, period_start, period_end )
|
41
|
+
#=> report\_object
|
42
|
+
|
43
|
+
These report objects respond to the method #response, which returns either an Array or a Hash, depending on whether the report is an agent-level or aggregate analysis.
|
44
|
+
Keys for this response can be found by calling ::keys on the object class. ::key\_translations for the object class returns a hash associating these keys with the raw data keys returned from the XMLRPC client.
|
45
|
+
|
46
|
+
### Available Analyses
|
47
|
+
|
48
|
+
Currently returns analyses from two methods: QM.stats and QM.realtime.
|
49
|
+
* Stats
|
50
|
+
* AgentsAndSessions
|
51
|
+
* AgentAvailability
|
52
|
+
* AnsweredCalls
|
53
|
+
* AgentsOnQueue
|
54
|
+
* AllCalls
|
55
|
+
* UnansweredCalls
|
56
|
+
* AllCalls
|
57
|
+
* Realtime
|
58
|
+
* Agents
|
59
|
+
* Queues
|
60
|
+
|
61
|
+
### Required Arguments
|
62
|
+
|
63
|
+
Required arguments differ for the report classes.
|
64
|
+
|
65
|
+
Any subclass of Queri::Stats requires timestamps for period start and end, and will correct cases in which beginning times are greater than ending times.
|
66
|
+
|
67
|
+
Any subclass of Queri::Realtime will accept timestamps for period, but they will be ignored in the returned response, as the QM.realtime method does not accept a period restriction.
|
68
|
+
|
69
|
+
### Returned Values
|
70
|
+
|
71
|
+
Returned values vary between agent-level and aggregate reports.
|
72
|
+
Agent-level reports return an Array of Hashes, each Hash corresponding to an agent's metrics for the requested analysis.
|
73
|
+
Aggregate reports return a single Hash; the composite metrics for the requested analysis.
|
74
|
+
* Agent-level reports
|
75
|
+
* Stats
|
76
|
+
* AgentsAndSessions
|
77
|
+
* AgentAvailability
|
78
|
+
* AnsweredCalls
|
79
|
+
* AgentsOnQueue
|
80
|
+
* Realtime
|
81
|
+
* Agents
|
82
|
+
* Queues
|
83
|
+
* Aggregate reports
|
84
|
+
* Stats
|
85
|
+
* AnsweredCalls
|
86
|
+
* AllCalls
|
87
|
+
* UnansweredCalls
|
88
|
+
* AllCalls
|
89
|
+
|
90
|
+
## Contributing
|
91
|
+
|
92
|
+
1. Fork it
|
93
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
94
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
95
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
96
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
module Queri
|
2
|
+
class Realtime
|
3
|
+
class Agents
|
4
|
+
attr_reader :response
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def xml_code
|
8
|
+
Realtime.xml_code + ".RTAgentsLoggedIn"
|
9
|
+
end
|
10
|
+
|
11
|
+
def query_method
|
12
|
+
Realtime.query_method
|
13
|
+
end
|
14
|
+
|
15
|
+
def key_translations
|
16
|
+
Hash[
|
17
|
+
:ready_state, " ",
|
18
|
+
:empty_column, " ",
|
19
|
+
:agent, "Agent ",
|
20
|
+
:login_time, "Last logon ",
|
21
|
+
:assigned_queues, "Queue(s):",
|
22
|
+
:extension, "Extension ",
|
23
|
+
:pause, "On pause ",
|
24
|
+
:server, "Srv",
|
25
|
+
:time_last_call_ended, "Last call",
|
26
|
+
:on_queue, "On queue",
|
27
|
+
:magic_wand, " "
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
def keys
|
32
|
+
# This response is a conversion of a table view, and contains non-unique
|
33
|
+
# key values, so this method must be statically recorded, as to maintain
|
34
|
+
# order of keys.
|
35
|
+
[
|
36
|
+
:ready_state,
|
37
|
+
:empty_column,
|
38
|
+
:agent,
|
39
|
+
:login_time,
|
40
|
+
:assigned_queues,
|
41
|
+
:extension,
|
42
|
+
:pause,
|
43
|
+
:server,
|
44
|
+
:time_last_call_ended,
|
45
|
+
:on_queue,
|
46
|
+
:magic_wand
|
47
|
+
]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def initialize *args
|
52
|
+
raise ArgumentError, "expected argument: queues(Array)" unless valid_args?(args)
|
53
|
+
@queues = args.first
|
54
|
+
@response = parse_response
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def valid_args? args
|
60
|
+
valid = true
|
61
|
+
valid = false if args[0].class != Array
|
62
|
+
if valid and args[0].empty?
|
63
|
+
raise ArgumentError, "queues array cannot be empty"
|
64
|
+
end
|
65
|
+
return valid
|
66
|
+
end
|
67
|
+
|
68
|
+
def parse_response
|
69
|
+
r = Queri.send_request(@queues, self)
|
70
|
+
agent_metrics = []
|
71
|
+
r.each_with_index do |agent,i|
|
72
|
+
if i > 0
|
73
|
+
agent_metrics << Hash[self.class.keys.zip(agent)]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
return agent_metrics
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Queri
|
2
|
+
class Realtime
|
3
|
+
class Queues
|
4
|
+
attr_reader :response
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def xml_code
|
8
|
+
Realtime.xml_code + ".RTRiassunto"
|
9
|
+
end
|
10
|
+
|
11
|
+
def query_method
|
12
|
+
Realtime.query_method
|
13
|
+
end
|
14
|
+
|
15
|
+
def key_translations
|
16
|
+
Hash[
|
17
|
+
:empty_column, " ",
|
18
|
+
:queue, "Queue ",
|
19
|
+
:agents_logged_on, "N. agents",
|
20
|
+
:ready_agents, "Ready agents",
|
21
|
+
:paused_agents, "On pause",
|
22
|
+
:nonmembers_on_calls, "Unk",
|
23
|
+
:members_on_call_in_another_queue, "Bsy",
|
24
|
+
:calls_waiting, "N. Calls waiting",
|
25
|
+
:agents_handling_inbound_calls, "On phone inbound",
|
26
|
+
:agents_handling_outbound_calls, "On phone outbound"
|
27
|
+
]
|
28
|
+
end
|
29
|
+
|
30
|
+
def keys
|
31
|
+
key_translations.keys
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize *args
|
36
|
+
raise ArgumentError, "expected argument: queues(Array)" unless valid_args?(args)
|
37
|
+
@queues = args.first
|
38
|
+
@response = parse_response
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def valid_args? args
|
44
|
+
valid = true
|
45
|
+
valid = false if args[0].class != Array
|
46
|
+
if valid and args[0].empty?
|
47
|
+
raise ArgumentError, "queues array cannot be empty"
|
48
|
+
end
|
49
|
+
return valid
|
50
|
+
end
|
51
|
+
|
52
|
+
def parse_response
|
53
|
+
r = Queri.send_request(@queues, self)
|
54
|
+
xml_keys_to_human_readable_keys = self.class.key_translations.invert
|
55
|
+
new_keys = r.shift.map {|k| xml_keys_to_human_readable_keys[k]}
|
56
|
+
agent_metrics = []
|
57
|
+
r.each do |agent|
|
58
|
+
agent_metrics << Hash[new_keys.zip(agent)]
|
59
|
+
end
|
60
|
+
return agent_metrics
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Queri
|
2
|
+
class Stats
|
3
|
+
class AgentsAndSessions
|
4
|
+
class AgentAvailability
|
5
|
+
attr_reader :response
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def xml_code
|
9
|
+
AgentsAndSessions.xml_code + ".AgentAvail"
|
10
|
+
end
|
11
|
+
|
12
|
+
def query_method
|
13
|
+
Stats.query_method
|
14
|
+
end
|
15
|
+
|
16
|
+
def key_translations
|
17
|
+
Hash[
|
18
|
+
:level, "Level",
|
19
|
+
:agent, "Agent",
|
20
|
+
:time, "Time",
|
21
|
+
:total_pause_time, "On pause",
|
22
|
+
:billable_pause_time, "Billable",
|
23
|
+
:non_billable_pause_time, "Non bill.",
|
24
|
+
:billable_non_billable_overlap_time, "Overlapping",
|
25
|
+
:pause_percentage_of_total_time, " ",
|
26
|
+
:placeholder_for_bar_graph, "..."
|
27
|
+
]
|
28
|
+
end
|
29
|
+
|
30
|
+
def keys
|
31
|
+
key_translations.keys
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize *args
|
36
|
+
raise ArgumentError, "expected arguments: queues(Array), period_start(Time), period_end(Time)" unless valid_args?(args)
|
37
|
+
@queues, @period_start, @period_end = normalize_times(*args)
|
38
|
+
@response = parse_response
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def valid_args? args
|
44
|
+
valid = true
|
45
|
+
valid = false if args[0].class != Array
|
46
|
+
valid = false if args[1].class != Time
|
47
|
+
valid = false if args[2].class != Time
|
48
|
+
if valid and args[0].empty?
|
49
|
+
raise ArgumentError, "queues array cannot be empty"
|
50
|
+
end
|
51
|
+
return valid
|
52
|
+
end
|
53
|
+
|
54
|
+
def normalize_times queues, period_start, period_end
|
55
|
+
if period_start > period_end
|
56
|
+
tmp = period_start
|
57
|
+
period_start = period_end
|
58
|
+
period_end = tmp
|
59
|
+
end
|
60
|
+
return [queues, period_start, period_end]
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_response
|
64
|
+
r = Queri.send_request(@queues, self, @period_start, @period_end)
|
65
|
+
xml_keys_to_human_readable_keys = self.class.key_translations.invert
|
66
|
+
new_keys = r.shift.map {|k| xml_keys_to_human_readable_keys[k]}
|
67
|
+
agent_metrics = []
|
68
|
+
r.each do |agent|
|
69
|
+
agent_metrics << Hash[new_keys.zip(agent)]
|
70
|
+
end
|
71
|
+
return agent_metrics
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Queri
|
2
|
+
class Stats
|
3
|
+
class AnsweredCalls
|
4
|
+
class AgentsOnQueue
|
5
|
+
attr_reader :response
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def xml_code
|
9
|
+
AnsweredCalls.xml_code + ".AgentsOnQueue"
|
10
|
+
end
|
11
|
+
|
12
|
+
def query_method
|
13
|
+
Stats.query_method
|
14
|
+
end
|
15
|
+
|
16
|
+
def key_translations
|
17
|
+
Hash[
|
18
|
+
:agent, "Agent",
|
19
|
+
:number_of_calls, "N. Calls",
|
20
|
+
:percentage_of_all_calls_handled, " ",
|
21
|
+
:placeholder_for_bar_graph, "...",
|
22
|
+
:total_call_time, "Total call time",
|
23
|
+
:average_call_time, "Average call time"
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
27
|
+
def keys
|
28
|
+
key_translations.keys
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize *args
|
33
|
+
raise ArgumentError, "expected arguments: queues(Array), period_start(Time), period_end(Time)" unless valid_args?(args)
|
34
|
+
@queues, @period_start, @period_end = normalize_times(*args)
|
35
|
+
@response = parse_response
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def valid_args? args
|
41
|
+
valid = true
|
42
|
+
valid = false if args[0].class != Array
|
43
|
+
valid = false if args[1].class != Time
|
44
|
+
valid = false if args[2].class != Time
|
45
|
+
if valid and args[0].empty?
|
46
|
+
raise ArgumentError, "queues array cannot be empty"
|
47
|
+
end
|
48
|
+
return valid
|
49
|
+
end
|
50
|
+
|
51
|
+
def normalize_times queues, period_start, period_end
|
52
|
+
if period_start > period_end
|
53
|
+
tmp = period_start
|
54
|
+
period_start = period_end
|
55
|
+
period_end = tmp
|
56
|
+
end
|
57
|
+
return [queues, period_start, period_end]
|
58
|
+
end
|
59
|
+
|
60
|
+
def parse_response
|
61
|
+
r = Queri.send_request(@queues, self, @period_start, @period_end)
|
62
|
+
xml_keys_to_human_readable_keys = self.class.key_translations.invert
|
63
|
+
new_keys = r.shift.map {|k| xml_keys_to_human_readable_keys[k]}
|
64
|
+
agent_metrics = []
|
65
|
+
r.each do |agent|
|
66
|
+
agent_metrics << Hash[new_keys.zip(agent)]
|
67
|
+
end
|
68
|
+
return agent_metrics
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Queri
|
2
|
+
class Stats
|
3
|
+
class AnsweredCalls
|
4
|
+
class AllCalls
|
5
|
+
attr_reader :response
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def xml_code
|
9
|
+
AnsweredCalls.xml_code + ".RiassAllCalls"
|
10
|
+
end
|
11
|
+
|
12
|
+
def query_method
|
13
|
+
Stats.query_method
|
14
|
+
end
|
15
|
+
|
16
|
+
def key_translations
|
17
|
+
Hash[
|
18
|
+
:calls_answered, "N. calls answered by operators:",
|
19
|
+
:average_call_length, "Average call length:",
|
20
|
+
:minimum_call_length, "Min call length:",
|
21
|
+
:maximum_call_length, "Max call length:",
|
22
|
+
:total_call_length, "Total call length:",
|
23
|
+
:average_wait_time, "Average call waiting time:",
|
24
|
+
:minimum_wait_time, "Min waiting time:",
|
25
|
+
:maximum_wait_time, "Max waiting time:",
|
26
|
+
:total_wait_time, "Total waiting time:",
|
27
|
+
:average_initial_queue_position, "Average initial position",
|
28
|
+
:minimum_initial_queue_position, "Min initial position",
|
29
|
+
:maximum_initial_queue_position, "Max initial position",
|
30
|
+
:queue_position_coverage, "Coverage"
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
def keys
|
35
|
+
key_translations.keys
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize *args
|
40
|
+
raise ArgumentError, "expected arguments: queues(Array), period_start(Time), period_end(Time)" unless valid_args?(args)
|
41
|
+
@queues, @period_start, @period_end = normalize_times(*args)
|
42
|
+
@response = parse_response
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def valid_args? args
|
48
|
+
valid = true
|
49
|
+
valid = false if args[0].class != Array
|
50
|
+
valid = false if args[1].class != Time
|
51
|
+
valid = false if args[2].class != Time
|
52
|
+
if valid and args[0].empty?
|
53
|
+
raise ArgumentError, "queues array cannot be empty"
|
54
|
+
end
|
55
|
+
return valid
|
56
|
+
end
|
57
|
+
|
58
|
+
def normalize_times queues, period_start, period_end
|
59
|
+
if period_start > period_end
|
60
|
+
tmp = period_start
|
61
|
+
period_start = period_end
|
62
|
+
period_end = tmp
|
63
|
+
end
|
64
|
+
return [queues, period_start, period_end]
|
65
|
+
end
|
66
|
+
|
67
|
+
def parse_response
|
68
|
+
r = Queri.send_request(@queues, self, @period_start, @period_end)
|
69
|
+
xml_keys_to_human_readable_keys = self.class.key_translations.invert
|
70
|
+
r.each_with_index do |metric,i|
|
71
|
+
if i > 0
|
72
|
+
metric[0] = xml_keys_to_human_readable_keys[ metric[0] ]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
r.shift
|
76
|
+
Hash[*r.flatten]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Queri
|
2
|
+
class Stats
|
3
|
+
class UnansweredCalls
|
4
|
+
class AllCalls
|
5
|
+
attr_reader :response
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def xml_code
|
9
|
+
UnansweredCalls.xml_code + ".ReportKoAll"
|
10
|
+
end
|
11
|
+
|
12
|
+
def query_method
|
13
|
+
Stats.query_method
|
14
|
+
end
|
15
|
+
|
16
|
+
def key_translations
|
17
|
+
Hash[
|
18
|
+
:calls_unanswered, "N.of unanswered calls:",
|
19
|
+
:average_wait_before_disconnect, "Average wait time before disconnection:",
|
20
|
+
:minimum_wait_before_disconnect, "Min wait time before disconnection:",
|
21
|
+
:maximum_wait_before_disconnect, "Max wait time before disconnection:",
|
22
|
+
:total_wait_before_disconnect, "Total wait time before disconnection:",
|
23
|
+
:average_initial_queue_position, "Average initial position",
|
24
|
+
:minimum_initial_queue_position, "Min initial position",
|
25
|
+
:maximum_initial_queue_position, "Max initial position",
|
26
|
+
:queue_position_coverage, "Coverage",
|
27
|
+
:average_queue_position_at_disconnect, "Average queue position at disconnection:",
|
28
|
+
:minimum_queue_position_at_disconnect, "Min queue position at disconnection:",
|
29
|
+
:maximum_queue_position_at_disconnect, "Max queue position at disconnection:"
|
30
|
+
]
|
31
|
+
end
|
32
|
+
|
33
|
+
def keys
|
34
|
+
key_translations.keys
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize *args
|
39
|
+
raise ArgumentError, "expected arguments: queues(Array), period_start(Time), period_end(Time)" unless valid_args?(args)
|
40
|
+
@queues, @period_start, @period_end = normalize_times(*args)
|
41
|
+
@response = parse_response
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def valid_args? args
|
47
|
+
valid = true
|
48
|
+
valid = false if args[0].class != Array
|
49
|
+
valid = false if args[1].class != Time
|
50
|
+
valid = false if args[2].class != Time
|
51
|
+
if valid and args[0].empty?
|
52
|
+
raise ArgumentError, "queues array cannot be empty"
|
53
|
+
end
|
54
|
+
return valid
|
55
|
+
end
|
56
|
+
|
57
|
+
def normalize_times queues, period_start, period_end
|
58
|
+
if period_start > period_end
|
59
|
+
tmp = period_start
|
60
|
+
period_start = period_end
|
61
|
+
period_end = tmp
|
62
|
+
end
|
63
|
+
return [queues, period_start, period_end]
|
64
|
+
end
|
65
|
+
|
66
|
+
def parse_response
|
67
|
+
r = Queri.send_request(@queues, self, @period_start, @period_end)
|
68
|
+
xml_keys_to_human_readable_keys = self.class.key_translations.invert
|
69
|
+
r.each_with_index do |metric,i|
|
70
|
+
if i > 0
|
71
|
+
metric[0] = xml_keys_to_human_readable_keys[ metric[0] ]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
r.shift
|
75
|
+
Hash[*r.flatten]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/queri/stats.rb
ADDED