queri 0.0.2

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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +96 -0
  7. data/Rakefile +7 -0
  8. data/lib/queri/realtime/agents.rb +80 -0
  9. data/lib/queri/realtime/queues.rb +64 -0
  10. data/lib/queri/realtime.rb +14 -0
  11. data/lib/queri/stats/agents_and_sessions/agent_availability.rb +76 -0
  12. data/lib/queri/stats/agents_and_sessions.rb +11 -0
  13. data/lib/queri/stats/answered_calls/agents_on_queue.rb +73 -0
  14. data/lib/queri/stats/answered_calls/all_calls.rb +81 -0
  15. data/lib/queri/stats/answered_calls.rb +11 -0
  16. data/lib/queri/stats/unanswered_calls/all_calls.rb +80 -0
  17. data/lib/queri/stats/unanswered_calls.rb +11 -0
  18. data/lib/queri/stats.rb +9 -0
  19. data/lib/queri/version.rb +3 -0
  20. data/lib/queri.rb +113 -0
  21. data/queri.gemspec +25 -0
  22. data/spec/queri_spec.rb +268 -0
  23. data/spec/realtime/agents_spec.rb +18 -0
  24. data/spec/realtime/queues_spec.rb +18 -0
  25. data/spec/realtime/realtime_spec.rb +10 -0
  26. data/spec/spec_helper.rb +11 -0
  27. data/spec/stats/agents_and_sessions/agent_availability_spec.rb +18 -0
  28. data/spec/stats/agents_and_sessions/agents_and_sessions_spec.rb +7 -0
  29. data/spec/stats/answered_calls/agents_on_queue_spec.rb +18 -0
  30. data/spec/stats/answered_calls/all_calls_spec.rb +18 -0
  31. data/spec/stats/answered_calls/answered_calls_spec.rb +7 -0
  32. data/spec/stats/stats_spec.rb +7 -0
  33. data/spec/stats/unanswered_calls/all_calls_spec.rb +18 -0
  34. data/spec/stats/unanswered_calls/unanswered_calls_spec.rb +7 -0
  35. data/spec/support/constantize.rb +27 -0
  36. data/spec/support/shared/shared_examples_for_agent_level_report_instance.rb +37 -0
  37. data/spec/support/shared/shared_examples_for_aggregate_report_instance.rb +37 -0
  38. data/spec/support/shared/shared_examples_for_private_constant.rb +9 -0
  39. data/spec/support/shared/shared_examples_for_queuemetrics_report.rb +25 -0
  40. data/spec/support/shared/shared_examples_for_realtime_report.rb +32 -0
  41. data/spec/support/shared/shared_examples_for_realtime_report_instance.rb +26 -0
  42. data/spec/support/shared/shared_examples_for_report_class.rb +13 -0
  43. data/spec/support/shared/shared_examples_for_report_method.rb +13 -0
  44. data/spec/support/shared/shared_examples_for_stats_report.rb +44 -0
  45. data/spec/support/time_helper.rb +17 -0
  46. 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
@@ -0,0 +1,18 @@
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
+ spec/config.yml
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in queri.gemspec
4
+ gemspec
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,7 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new('spec')
6
+
7
+ task :default => :spec
@@ -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, "&nbsp;",
18
+ :empty_column, "&nbsp;",
19
+ :agent, "Agent &nbsp;",
20
+ :login_time, "Last logon &nbsp;",
21
+ :assigned_queues, "Queue(s):",
22
+ :extension, "Extension &nbsp;",
23
+ :pause, "On pause &nbsp;",
24
+ :server, "Srv",
25
+ :time_last_call_ended, "Last call",
26
+ :on_queue, "On queue",
27
+ :magic_wand, "&nbsp;"
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, "&nbsp;",
18
+ :queue, "Queue &nbsp;",
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,14 @@
1
+ module Queri
2
+ class Realtime
3
+ @@query_method = "QM.realtime"
4
+ @@xml_code = "RealtimeDO"
5
+
6
+ def self.query_method
7
+ @@query_method
8
+ end
9
+
10
+ def self.xml_code
11
+ @@xml_code
12
+ end
13
+ end
14
+ 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, "&nbsp;",
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,11 @@
1
+ module Queri
2
+ class Stats
3
+ class AgentsAndSessions
4
+ @@xml_code = "AgentsDo"
5
+
6
+ def self.xml_code
7
+ @@xml_code
8
+ end
9
+ end
10
+ end
11
+ 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, "&nbsp;",
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,11 @@
1
+ module Queri
2
+ class Stats
3
+ class AnsweredCalls
4
+ @@xml_code = "OkDO"
5
+
6
+ def self.xml_code
7
+ @@xml_code
8
+ end
9
+ end
10
+ end
11
+ 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
@@ -0,0 +1,11 @@
1
+ module Queri
2
+ class Stats
3
+ class UnansweredCalls
4
+ @@xml_code = "KoDO"
5
+
6
+ def self.xml_code
7
+ @@xml_code
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module Queri
2
+ class Stats
3
+ @@query_method = "QM.stats"
4
+
5
+ def self.query_method
6
+ @@query_method
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module Queri
2
+ VERSION = "0.0.2"
3
+ end