jsgoecke-echi_files 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.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2009 Jason Goecke
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,55 @@
1
+ h1. ECHI Files Ruby Library
2
+
3
+ h2. Description
4
+
5
+ A library that allows one to take an ASCII or Binary file from an <a href="http://www.google.com/url?sa=t&source=web&ct=res&cd=1&url=http%3A%2F%2Fsupport.avaya.com%2Fjapple%2Fcss%2Fjapple%3FPAGE%3DProduct%26temp.productID%3D107584&ei=h1tlSaXpDomQtQO9_8mVAw&usg=AFQjCNGdjBmfY-7VhcTninYr1c9byz0U3w&sig2=qV5YXM9h76TFe_xodJ7CHg">Avaya CMS</a> <a href="http://support.avaya.com/elmodocs2/cms/R14/ECHI.pdf">External Call History Interface (ECHI)</a> and convert it into a Ruby hash for further processing.
6
+
7
+ h2. Features
8
+
9
+ * Convert Binary file to Ruby hash
10
+ * Convert ASCII file to Ruby hash
11
+ * Support both standard and extended file formats
12
+ * Tested with both Ruby 1.8.6 and JRuby 1.1.5
13
+
14
+ h2. Example
15
+ <pre>
16
+ <code>
17
+ require 'echi_files'
18
+
19
+ #Provide a filename to process as an argument on the commandline
20
+ filename = File.expand_path(ARGV[0])
21
+
22
+ #Open the file
23
+ filehandle = open(filename, "rb")
24
+
25
+ #Instantiate an EchiFiles class to process your ASCII or BINARY files
26
+ echi_handler = EchiFiles.new
27
+
28
+ #Use this to process a binary file
29
+ file_type = 'BINARY'
30
+ format = 'EXTENDED'
31
+ #In some cases the extra_byte is needed
32
+ extra_byte = true
33
+ data = echi_handler.process_file(filehandle, file_type, format, extra_byte)
34
+
35
+ #Use this to process a binary file
36
+ file_type = 'ASCII'
37
+ format = 'EXTENDED'
38
+ extra_byte = true
39
+ #Use this to process an ASCII file
40
+ data = echi_handler.process_file(filehandle, file_type, format, extra_byte)
41
+
42
+ #If you need to strip in characters from the asaiuui field
43
+ #@data Is the Array of Hashes converted above
44
+ #@array_of_decimal_values Is an array of decimal ascii values to be stripped
45
+ data = echi_handler.strip_asaiuui(data, array_of_decimal_values)
46
+ </code>
47
+ </pre>
48
+
49
+ h2. Dependencies
50
+
51
+ * FasterCSV 1.4.0+
52
+
53
+ h2. Installation
54
+
55
+ sudo gem install jsgoecke-echi_files --source=http://gems.github.com/
@@ -0,0 +1,22 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "echi_files"
3
+ s.version = "0.1.0"
4
+ s.date = "2009-01-19"
5
+ s.summary = "Ruby Library for Processing Avaya ECHI Files"
6
+ s.description = "Ruby Library for processing External Call History (ECHI) files from the Avaya CMS"
7
+ s.authors = ["Jason Goecke"]
8
+ s.email = ["jason -at- goecke.net"]
9
+ s.has_rdoc = false
10
+ s.homepage = "http://jsgoecke.github.com/echi_files"
11
+ s.rubygems_version = "1.3.1"
12
+
13
+ s.files = ["lib/echi_files.rb",
14
+ "lib/extended-definition.yml",
15
+ "lib/standard-definition.yml",
16
+ "LICENSE",
17
+ "README.textile",
18
+ "echi_files.gemspec"]
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency("fastercsv", ">=", "1.4.0")
22
+ end
data/lib/echi_files.rb ADDED
@@ -0,0 +1,185 @@
1
+ require 'yaml'
2
+ require 'fastercsv'
3
+
4
+ class EchiFiles
5
+
6
+ def initialize
7
+ @extended = YAML::load_file(File.expand_path(File.dirname(__FILE__) + "/extended-definition.yml"))
8
+ @standard = YAML::load_file(File.expand_path(File.dirname(__FILE__) + "/standard-definition.yml"))
9
+ end
10
+
11
+ #Method for parsing the various datatypes from the ECH file
12
+ def dump_binary(filehandle, type, length)
13
+ case type
14
+ when 'int'
15
+ #Process integers, assigning appropriate profile based on length
16
+ #such as long int, short int and tiny int.
17
+ case length
18
+ when 4
19
+ value = filehandle.read(length).unpack("l").first.to_i
20
+ when 2
21
+ value = filehandle.read(length).unpack("s").first.to_i
22
+ when 1
23
+ value = filehandle.read(length).unpack("U").first.to_i
24
+ end
25
+ #Process appropriate intergers into datetime format in the database
26
+ when 'datetime'
27
+ case length
28
+ when 4
29
+ value = filehandle.read(length).unpack("l").first.to_i
30
+ puts value.inspect
31
+ value = Time.at(value)
32
+ end
33
+ #Process strings
34
+ when 'str'
35
+ value = filehandle.read(length).unpack("M").first.to_s.rstrip
36
+ #Process individual bits that are booleans
37
+ when 'bool'
38
+ value = filehandle.read(length).unpack("b8").last.to_s
39
+ #Process that one wierd boolean that is actually an int, instead of a bit
40
+ when 'boolint'
41
+ value = filehandle.read(length).unpack("U").first.to_i
42
+ #Change the values of the field to Y/N for the varchar(1) representation of BOOLEAN
43
+ if value == 1
44
+ value = 'Y'
45
+ else
46
+ value = 'N'
47
+ end
48
+ end
49
+ return value
50
+ end
51
+
52
+ #Mehtod that performs the conversions
53
+ def convert_binary_file(filehandle, schema, extra_byte)
54
+
55
+ #Read header information first
56
+ fileversion = dump_binary(filehandle, 'int', 4)
57
+ filenumber = dump_binary(filehandle, 'int', 4)
58
+
59
+ bool_cnt = 0
60
+ bytearray = nil
61
+ data = Array.new
62
+ while filehandle.eof == FALSE do
63
+ record = Hash.new
64
+ schema["echi_records"].each do | field |
65
+ #We handle the 'boolean' fields differently, as they are all encoded as bits in a single 8-bit byte
66
+ if field["type"] == 'bool'
67
+ if bool_cnt == 0
68
+ bytearray = dump_binary(filehandle, field["type"], field["length"])
69
+ end
70
+ #Ensure we parse the bytearray and set the appropriate flags
71
+ #We need to make sure the entire array is not nil, in order to do Y/N
72
+ #if Nil we then set all no
73
+ if bytearray != '00000000'
74
+ if bytearray.slice(bool_cnt,1) == '1'
75
+ value = 'Y'
76
+ else
77
+ value = 'N'
78
+ end
79
+ else
80
+ value = 'N'
81
+ end
82
+ record.merge!({ field["name"] => value })
83
+ bool_cnt += 1
84
+ if bool_cnt == 8
85
+ bool_cnt = 0
86
+ end
87
+ else
88
+ #Process 'standard' fields
89
+ value = dump_binary(filehandle, field["type"], field["length"])
90
+ record.merge!({ field["name"] => value })
91
+ end
92
+
93
+ end
94
+
95
+ #Scan past the end of line record if enabled in the configuration file
96
+ #Comment this out if you do not need to read the 'extra byte'
97
+ if extra_byte
98
+ filehandle.read(1)
99
+ end
100
+ data << record
101
+ end
102
+
103
+ return data
104
+ end
105
+
106
+ #Method to create a Ruby hash out of the Avaya ECHI files
107
+ #@filehandle The filehandle
108
+ #@type Whether this is ASCII or Binary data
109
+ #@schema Whether this is the ECHI EXTENDED or STANDARD file format
110
+ def convert_ascii_file(filehandle, schema)
111
+
112
+ data = Array.new
113
+ filehandle.each do |line|
114
+ record = Hash.new
115
+ FasterCSV.parse(line) do |row|
116
+ cnt = 0
117
+ row.each do |field|
118
+ if field != nil
119
+ if schema["echi_records"][cnt]["type"] == "bool" || schema["echi_records"][cnt]["type"] == "boolint"
120
+ case field
121
+ when "0"
122
+ record.merge!({ schema["echi_records"][cnt]["name"] => "N" })
123
+ when "1"
124
+ record.merge!({ schema["echi_records"][cnt]["name"] => "Y" })
125
+ when nil
126
+ record.merge!({ schema["echi_records"][cnt]["name"] => "N" })
127
+ else
128
+ record.merge!({ schema["echi_records"][cnt]["name"] => "Y" })
129
+ end
130
+ else
131
+ record.merge!({ schema["echi_records"][cnt]["name"] => field })
132
+ end
133
+ cnt += 1
134
+ end
135
+ end
136
+ end
137
+ data << record
138
+ end
139
+
140
+ return data
141
+ end
142
+
143
+ #Pass a filehandle of the file to process that includes
144
+ #@filehandle The filehandle
145
+ #@type Whether this is ASCII or Binary data
146
+ #@format Whether this is the ECHI EXTENDED or STANDARD file format
147
+ #@extra_byte Set to true if you want to read an extra byte at the end of each record
148
+ #This method will return an array of hashes of the resulting data processed
149
+ def process_file(filehandle, type, format, extra_byte)
150
+
151
+ #Set the appropriate schema format for standard or extended from the Avaya CMS
152
+ case format
153
+ when 'EXTENDED'
154
+ schema = @extended
155
+ when 'STANDARD'
156
+ schema = @standard
157
+ end
158
+
159
+ #Process based on the filetype passed
160
+ case type
161
+ when 'ASCII'
162
+ return convert_ascii_file(filehandle, schema)
163
+ when 'BINARY'
164
+ return convert_binary_file(filehandle, schema, extra_byte)
165
+ end
166
+
167
+ end
168
+
169
+ #Method used to strip special characters
170
+ #@data An Array of Hashes to be processed
171
+ #@characters An Array of charcters to be stripped
172
+ def strip_asaiuui(data, characters)
173
+
174
+ stripped_data = Array.new
175
+ data.each do |row|
176
+ characters.each do |char|
177
+ row["asaiuui"].gsub!(char.chr,"")
178
+ end
179
+ stripped_data << row
180
+ end
181
+
182
+ return stripped_data
183
+ end
184
+
185
+ end
@@ -0,0 +1,234 @@
1
+ #ECH File construct, order is important, as the application sequentially reads the file
2
+ #Version 12 through 15 - Extended Schema
3
+ echi_records:
4
+ - name: callid
5
+ type: int
6
+ length: 4
7
+ - name: acwtime
8
+ type: int
9
+ length: 4
10
+ - name: onholdtime
11
+ type: int
12
+ length: 4
13
+ - name: consulttime
14
+ type: int
15
+ length: 4
16
+ - name: disptime
17
+ type: int
18
+ length: 4
19
+ - name: duration
20
+ type: int
21
+ length: 4
22
+ - name: segstart
23
+ type: datetime
24
+ length: 4
25
+ - name: segstop
26
+ type: datetime
27
+ length: 4
28
+ - name: talktime
29
+ type: int
30
+ length: 4
31
+ - name: netintime
32
+ type: int
33
+ length: 4
34
+ - name: origholdtime
35
+ type: int
36
+ length: 4
37
+ - name: queuetime
38
+ type: int
39
+ length: 4
40
+ - name: ringtime
41
+ type: int
42
+ length: 4
43
+ - name: dispivector
44
+ type: int
45
+ length: 2
46
+ - name: dispsplit
47
+ type: int
48
+ length: 2
49
+ - name: firstivector
50
+ type: int
51
+ length: 2
52
+ - name: split1
53
+ type: int
54
+ length: 2
55
+ - name: split2
56
+ type: int
57
+ length: 2
58
+ - name: split3
59
+ type: int
60
+ length: 2
61
+ - name: trunkgroup
62
+ type: int
63
+ length: 2
64
+ - name: tklocid
65
+ type: int
66
+ length: 2
67
+ - name: origlocid
68
+ type: int
69
+ length: 2
70
+ - name: answerlocid
71
+ type: int
72
+ length: 2
73
+ - name: obslocid
74
+ type: int
75
+ length: 2
76
+ - name: uuilen
77
+ type: int
78
+ length: 2
79
+ - name: assist
80
+ type: bool
81
+ length: 1
82
+ - name: audiodifficulty
83
+ type: bool
84
+ length: 1
85
+ - name: conference
86
+ type: bool
87
+ length: 1
88
+ - name: daqueued
89
+ type: bool
90
+ length: 1
91
+ - name: holdabn
92
+ type: bool
93
+ length: 1
94
+ - name: malicious
95
+ type: bool
96
+ length: 1
97
+ - name: observingcall
98
+ type: bool
99
+ length: 1
100
+ - name: transferred
101
+ type: bool
102
+ length: 1
103
+ - name: agentreleased
104
+ type: boolint
105
+ length: 1
106
+ - name: acdnum
107
+ type: int
108
+ length: 1
109
+ - name: calldisp
110
+ type: int
111
+ length: 1
112
+ - name: disppriority
113
+ type: int
114
+ length: 1
115
+ - name: holds
116
+ type: int
117
+ length: 1
118
+ - name: segment
119
+ type: int
120
+ length: 1
121
+ - name: ansreason
122
+ type: int
123
+ length: 1
124
+ - name: origreason
125
+ type: int
126
+ length: 1
127
+ - name: dispsklevel
128
+ type: int
129
+ length: 1
130
+ - name: events0
131
+ type: int
132
+ length: 1
133
+ - name: events1
134
+ type: int
135
+ length: 1
136
+ - name: events2
137
+ type: int
138
+ length: 1
139
+ - name: events3
140
+ type: int
141
+ length: 1
142
+ - name: events4
143
+ type: int
144
+ length: 1
145
+ - name: events5
146
+ type: int
147
+ length: 1
148
+ - name: events6
149
+ type: int
150
+ length: 1
151
+ - name: events7
152
+ type: int
153
+ length: 1
154
+ - name: events8
155
+ type: int
156
+ length: 1
157
+ - name: ucid
158
+ type: str
159
+ length: 21
160
+ - name: dispvdn
161
+ type: str
162
+ length: 8
163
+ - name: eqloc
164
+ type: str
165
+ length: 10
166
+ - name: firstvdn
167
+ type: str
168
+ length: 8
169
+ - name: origlogid
170
+ type: str
171
+ length: 10
172
+ - name: anslogid
173
+ type: str
174
+ length: 10
175
+ - name: lastobserver
176
+ type: str
177
+ length: 10
178
+ - name: dialednumber
179
+ type: str
180
+ length: 25
181
+ - name: callingparty
182
+ type: str
183
+ length: 13
184
+ - name: collectdigits
185
+ type: str
186
+ length: 17
187
+ - name: cwcdigits
188
+ type: str
189
+ length: 17
190
+ - name: callingII
191
+ type: str
192
+ length: 3
193
+ - name: cwcs0
194
+ type: str
195
+ length: 17
196
+ - name: cwcs1
197
+ type: str
198
+ length: 17
199
+ - name: cwcs2
200
+ type: str
201
+ length: 17
202
+ - name: cwcs3
203
+ type: str
204
+ length: 17
205
+ - name: cwcs4
206
+ type: str
207
+ length: 17
208
+ - name: vdn2
209
+ type: str
210
+ length: 8
211
+ - name: vdn3
212
+ type: str
213
+ length: 8
214
+ - name: vdn4
215
+ type: str
216
+ length: 8
217
+ - name: vdn5
218
+ type: str
219
+ length: 8
220
+ - name: vdn6
221
+ type: str
222
+ length: 8
223
+ - name: vdn7
224
+ type: str
225
+ length: 8
226
+ - name: vdn8
227
+ type: str
228
+ length: 8
229
+ - name: vdn9
230
+ type: str
231
+ length: 8
232
+ - name: asaiuui
233
+ type: str
234
+ length: 96
@@ -0,0 +1,198 @@
1
+ #ECH File construct, order is important, as the application sequentially reads the file
2
+ #Version 14 - Standard Schema
3
+ echi_records:
4
+ - name: callid
5
+ type: int
6
+ length: 4
7
+ - name: acwtime
8
+ type: int
9
+ length: 4
10
+ - name: onholdtime
11
+ type: int
12
+ length: 4
13
+ - name: consulttime
14
+ type: int
15
+ length: 4
16
+ - name: disptime
17
+ type: int
18
+ length: 4
19
+ - name: duration
20
+ type: int
21
+ length: 4
22
+ - name: segstart
23
+ type: datetime
24
+ length: 4
25
+ - name: segstop
26
+ type: datetime
27
+ length: 4
28
+ - name: talktime
29
+ type: int
30
+ length: 4
31
+ - name: netintime
32
+ type: int
33
+ length: 4
34
+ - name: origholdtime
35
+ type: int
36
+ length: 4
37
+ - name: dispivector
38
+ type: int
39
+ length: 2
40
+ - name: dispsplit
41
+ type: int
42
+ length: 2
43
+ - name: firstivector
44
+ type: int
45
+ length: 2
46
+ - name: split1
47
+ type: int
48
+ length: 2
49
+ - name: split2
50
+ type: int
51
+ length: 2
52
+ - name: split3
53
+ type: int
54
+ length: 2
55
+ - name: trunkgroup
56
+ type: int
57
+ length: 2
58
+ - name: tklocid
59
+ type: int
60
+ length: 2
61
+ - name: origlocid
62
+ type: int
63
+ length: 2
64
+ - name: answerlocid
65
+ type: int
66
+ length: 2
67
+ - name: obslocid
68
+ type: int
69
+ length: 2
70
+ - name: assist
71
+ type: bool
72
+ length: 1
73
+ - name: audiodifficulty
74
+ type: bool
75
+ length: 1
76
+ - name: conference
77
+ type: bool
78
+ length: 1
79
+ - name: daqueued
80
+ type: bool
81
+ length: 1
82
+ - name: holdabn
83
+ type: bool
84
+ length: 1
85
+ - name: malicious
86
+ type: bool
87
+ length: 1
88
+ - name: observingcall
89
+ type: bool
90
+ length: 1
91
+ - name: transferred
92
+ type: bool
93
+ length: 1
94
+ - name: agentreleased
95
+ type: boolint
96
+ length: 1
97
+ - name: acdnum
98
+ type: int
99
+ length: 1
100
+ - name: calldisp
101
+ type: int
102
+ length: 1
103
+ - name: disppriority
104
+ type: int
105
+ length: 1
106
+ - name: holds
107
+ type: int
108
+ length: 1
109
+ - name: segment
110
+ type: int
111
+ length: 1
112
+ - name: ansreason
113
+ type: int
114
+ length: 1
115
+ - name: origreason
116
+ type: int
117
+ length: 1
118
+ - name: dispsklevel
119
+ type: int
120
+ length: 1
121
+ - name: events0
122
+ type: int
123
+ length: 1
124
+ - name: events1
125
+ type: int
126
+ length: 1
127
+ - name: events2
128
+ type: int
129
+ length: 1
130
+ - name: events3
131
+ type: int
132
+ length: 1
133
+ - name: events4
134
+ type: int
135
+ length: 1
136
+ - name: events5
137
+ type: int
138
+ length: 1
139
+ - name: events6
140
+ type: int
141
+ length: 1
142
+ - name: events7
143
+ type: int
144
+ length: 1
145
+ - name: events8
146
+ type: int
147
+ length: 1
148
+ - name: ucid
149
+ type: str
150
+ length: 21
151
+ - name: dispvdn
152
+ type: str
153
+ length: 8
154
+ - name: eqloc
155
+ type: str
156
+ length: 10
157
+ - name: firstvdn
158
+ type: str
159
+ length: 8
160
+ - name: origlogid
161
+ type: str
162
+ length: 10
163
+ - name: anslogid
164
+ type: str
165
+ length: 10
166
+ - name: lastobserver
167
+ type: str
168
+ length: 10
169
+ - name: dialednumber
170
+ type: str
171
+ length: 25
172
+ - name: callingparty
173
+ type: str
174
+ length: 13
175
+ - name: collectdigits
176
+ type: str
177
+ length: 17
178
+ - name: cwcdigits
179
+ type: str
180
+ length: 17
181
+ - name: callingII
182
+ type: str
183
+ length: 3
184
+ - name: cwcs0
185
+ type: str
186
+ length: 17
187
+ - name: cwcs1
188
+ type: str
189
+ length: 17
190
+ - name: cwcs2
191
+ type: str
192
+ length: 17
193
+ - name: cwcs3
194
+ type: str
195
+ length: 17
196
+ - name: cwcs4
197
+ type: str
198
+ length: 17
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jsgoecke-echi_files
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jason Goecke
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-19 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: fastercsv
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ - - "="
24
+ - !ruby/object:Gem::Version
25
+ version: 1.4.0
26
+ version:
27
+ description: Ruby Library for processing External Call History (ECHI) files from the Avaya CMS
28
+ email:
29
+ - jason -at- goecke.net
30
+ executables: []
31
+
32
+ extensions: []
33
+
34
+ extra_rdoc_files: []
35
+
36
+ files:
37
+ - lib/echi_files.rb
38
+ - lib/extended-definition.yml
39
+ - lib/standard-definition.yml
40
+ - LICENSE
41
+ - README.textile
42
+ - echi_files.gemspec
43
+ has_rdoc: false
44
+ homepage: http://jsgoecke.github.com/echi_files
45
+ post_install_message:
46
+ rdoc_options: []
47
+
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ requirements: []
63
+
64
+ rubyforge_project:
65
+ rubygems_version: 1.2.0
66
+ signing_key:
67
+ specification_version: 2
68
+ summary: Ruby Library for Processing Avaya ECHI Files
69
+ test_files: []
70
+