idnio 2.3.2b

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,345 @@
1
+ require 'fileutils'
2
+ #
3
+ # Markdown Writing Utility
4
+ #
5
+ module Markdown
6
+
7
+ @@buffer = ""
8
+ @@file = nil
9
+
10
+
11
+
12
+ # private_class_method :new
13
+
14
+ #def self.open( file )
15
+ # open( file )
16
+ #end
17
+
18
+ def self.open( file )
19
+ @@file = file
20
+ if File.exist?( @@file )
21
+ FileUtils.rm_f( @@file )
22
+ end
23
+
24
+ FileUtils.mkdir_p File.dirname( file )
25
+ end
26
+
27
+ def self.toc
28
+ text = "\n[TOC]\n"
29
+ @@buffer << text
30
+ return text
31
+ end
32
+
33
+ def self.strong( text )
34
+ text = "**#{text}**"
35
+ @@buffer << text
36
+ return text
37
+ end
38
+
39
+ def self.h1( text )
40
+ text = "\n# #{text}\n"
41
+ @@buffer << text
42
+ return text
43
+ end
44
+
45
+ def self.h2( text )
46
+ text = "\n## #{text}\n"
47
+ @@buffer << text
48
+ return text
49
+ end
50
+
51
+ def self.h3( text )
52
+ text = "\n### #{text}\n"
53
+ @@buffer << text
54
+ return text
55
+ end
56
+
57
+ def self.h4( text )
58
+ text = "\n#### #{text}\n"
59
+ @@buffer << text
60
+ return text
61
+ end
62
+
63
+ def self.h5( text )
64
+ text = "\n##### #{text}\n"
65
+ @@buffer << text
66
+ return text
67
+ end
68
+
69
+ def self.link( link, label )
70
+ text = "[#{label}](#{link})"
71
+ @@buffer << text
72
+ return text
73
+ end
74
+
75
+ def self.image( file, alt_text )
76
+ text = "\n![#{alt_text}](#{file})\n"
77
+ @@buffer << text
78
+ return text
79
+ end
80
+
81
+ def self.code( text )
82
+ text = "\n~~~\n#{text}\n~~~\n"
83
+ @@buffer << text
84
+ return text
85
+ end
86
+
87
+ def self.json( text )
88
+ text = "\n~~~json\n#{text}\n~~~\n"
89
+ @@buffer << text
90
+ return text
91
+ end
92
+
93
+ def self.xml( text )
94
+ text = "\n~~~xml\n#{text}\n~~~\n"
95
+ @@buffer << text
96
+ return text
97
+ end
98
+
99
+ def self.text( text )
100
+ text = "#{text}"
101
+ @@buffer << text
102
+ return text
103
+ end
104
+
105
+ def self.line( text )
106
+ text = "\n***\n"
107
+ @@buffer << text
108
+ return text
109
+ end
110
+
111
+ def self.ul( list )
112
+ text = ""
113
+ list.each do |item|
114
+ text << "- #{item}\n"
115
+ end
116
+ @@buffer << text
117
+ return text
118
+ end
119
+
120
+ def self.ul2( list )
121
+ text = ""
122
+ list.each do |item|
123
+ text << "\t- #{item}\n"
124
+ end
125
+ @@buffer << text
126
+ return text
127
+ end
128
+
129
+ def self.ol( list )
130
+ text = ""
131
+ list.each_with_index do |item, index|
132
+ output << "#{index + 1}. #{item}\n"
133
+ end
134
+ @@buffer << text
135
+ return text
136
+ end
137
+
138
+ # Generate a Markdown table.
139
+ # labels and data are one and two-dimensional arrays, respectively.
140
+ # All input must have a to_s method.
141
+ # Pass align: 'l' for left alignment or 'r' for right alignment. Anything
142
+ # else will result in cells being centered. Pass an array of align values
143
+ # to specify alignment per column.
144
+ # If is_rows is true, then each sub-array of data represents a row.
145
+ # Conversely, if is_rows is false, each sub-array of data represents a column.
146
+ # Empty cells can be given with nil or an empty string.
147
+ def self.make_table(labels, data, align: '', is_rows: false)
148
+ validate(labels, data, align, is_rows)
149
+
150
+ # Deep copy the arguments so we don't mutate the originals.
151
+ labels = Marshal.load(Marshal.dump(labels))
152
+ data = Marshal.load(Marshal.dump(data))
153
+
154
+ # Remove any breaking Markdown characters.
155
+ labels.map! {|label| sanitize(label)}
156
+ data.map! {|datum| datum.map {|cell| sanitize(cell)}}
157
+
158
+ # Convert align to something that other methods won't need to validate.
159
+ align.class == String && align = [align] * labels.length
160
+ align.map! {|a| a =~ /[lr]/i ? a.downcase : 'c'}
161
+
162
+ # Generate the column labels and alignment line.
163
+ header_line = labels.join('|')
164
+ alignment_line = parse_alignment(align, labels.length)
165
+
166
+ # Pad the data arrays so that it can be transposed if necessary.
167
+ max_len = data.map(&:length).max
168
+ data.map! {|datum| fill(datum, max_len)}
169
+
170
+ # Generate the table rows.
171
+ rows = (is_rows ? data : data.transpose).map {|row| row.join('|')}
172
+
173
+ text = [header_line, alignment_line, rows.join("\n")].join("\n")
174
+ @@buffer << text
175
+ return text
176
+ end
177
+
178
+ # Convert a Markdown table into human-readable form.
179
+ # def self.plain_text( md_table )
180
+ # md_table !~ // && raise('Invalid input')
181
+ #
182
+ # # Split the table into lines to get the labels, rows, and alignments.
183
+ # lines = md_table.split("\n")
184
+ # alignments = lines[1].split('|')
185
+ # # labels or rows might have some empty values but alignments
186
+ # # is guaranteed to be of the right width.
187
+ # table_width = alignments.length
188
+ # # '|||'.split('|') == [], so we need to manually add trailing empty cells.
189
+ # # Leading empty cells are taken care of automatically.
190
+ # labels = fill(lines[0].split('|'), table_width)
191
+ # rows = lines[2..-1].map {|line| fill(line.split('|'), table_width)}
192
+ #
193
+ # # Get the width for each column.
194
+ # cols = rows.transpose
195
+ # widths = cols.each_index.map {|i| column_width(cols[i].push(labels[i]))}
196
+ #
197
+ # # Align the labels and cells.
198
+ # labels = labels.each_index.map { |i|
199
+ # aligned_cell(unsanitize(labels[i]), widths[i], alignments[i])
200
+ # }
201
+ # rows.map! { |row|
202
+ # row.each_index.map { |i|
203
+ # aligned_cell(unsanitize(row[i]), widths[i], alignments[i])
204
+ # }
205
+ # }
206
+ #
207
+ # border = "\n|" + widths.map {|w| '=' * w}.join('|') + "|\n"
208
+ # return (
209
+ # border + [
210
+ # '|' + labels.join('|') + '|',
211
+ # rows.map {|row| '|' + row.join('|') + '|'}.join(border.tr('=', '-'))
212
+ # ].join(border) + border
213
+ # ).strip
214
+ #
215
+ # end
216
+
217
+ # Sanity checks for make_table.
218
+ private_class_method def self.validate(labels, data, align, is_rows)
219
+ if labels.class != Array
220
+ raise('labels must be an array')
221
+ end
222
+ if data.class != Array || data.any? {|datum| datum.class != Array}
223
+ raise('data must be a two-dimensional array')
224
+ end
225
+ if labels.empty?
226
+ raise('No column labels given')
227
+ end
228
+ if data.all? {|datum| datum.empty?}
229
+ raise('No cells given')
230
+ end
231
+ if labels.any? {|label| !label.respond_to?(:to_s)}
232
+ raise('One or more column labels cannot be made into a string')
233
+ end
234
+ if data.any? {|datum| datum.any? {|cell| !cell.respond_to?(:to_s)}}
235
+ raise('One or more cells cannot be made into a string')
236
+ end
237
+ if ![String, Array].include?(align.class)
238
+ raise('align must be a string or array')
239
+ end
240
+ if align.class == Array && align.any? {|val| val.class != String}
241
+ raise('One or more align values is not a string')
242
+ end
243
+ if !is_rows && data.length > labels.length
244
+ raise('Too many data columns given')
245
+ end
246
+ if is_rows && data.any? {|row| row.length > labels.length}
247
+ raise('One or more rows has too many cells')
248
+ end
249
+ end
250
+
251
+ # Convert some input to a string and replace any '|' characters with
252
+ # a non-breaking equivalent,
253
+ private_class_method def self.sanitize(input)
254
+ bar = '&#124;' # Non-breaking HTML vertical bar.
255
+ return input.to_s.gsub('|', bar)
256
+ end
257
+
258
+ # Replace non-breaking HTML characters with their plaintext counterparts.
259
+ private_class_method def self.unsanitize(input)
260
+ return input.gsub(/(&nbsp;)|(&#124;)/, '&nbsp;' => ' ', '&#124;' => '|')
261
+ end
262
+
263
+ # Generate the alignment line from a string or array.
264
+ # align must be a string or array of strings.
265
+ # n: number of labels in the table to be created.
266
+ private_class_method def self.parse_alignment(align, n)
267
+ align_map = {'l' => ':-', 'c' => ':-:', 'r' => '-:'}
268
+ alignments = align.map {|a| align_map[a]}
269
+ # If not enough values were given, center the remaining columns.
270
+ alignments.length < n && alignments += [':-:'] * (n - alignments.length)
271
+ return alignments.join('|')
272
+ end
273
+
274
+ # Align some text in a cell.
275
+ private_class_method def self.aligned_cell(text, width, align)
276
+ if align =~ /:-+:/ # Center alignment.
277
+ start = (width / 2) - (text.length / 2)
278
+ elsif align =~ /-+:/ # Right alignment.
279
+ start = width - text.length - 1
280
+ else # Left alignment.
281
+ start = 1
282
+ end
283
+ return ' ' * start + text + ' ' * (width - start - text.length)
284
+ end
285
+
286
+ # Get the width for a column.
287
+ private_class_method def self.column_width(col)
288
+ # Pad each cell on either side and maintain a minimum 3 width of characters.
289
+ return [(!col.empty? ? col.map(&:length).max : 0) + 2, 3].max
290
+ end
291
+
292
+ # Add any missing empty values to a row.
293
+ private_class_method def self.fill(row, n)
294
+ row.length > n && raise('Sanity checks failed for fill')
295
+ return row.length < n ? row + ([''] * (n - row.length)) : row
296
+ end
297
+
298
+ #
299
+ # Used to get the string buffer (if needed).
300
+ #
301
+ def self.get_buffer
302
+ return @@buffer
303
+ end
304
+
305
+ #
306
+ # Used to set the string buffer (if needed).
307
+ #
308
+ def self.set_buffer( new_buffer )
309
+ @@buffer = new_buffer
310
+ return @@buffer
311
+ end
312
+
313
+ #
314
+ # Replaces a string in the buffer.
315
+ #
316
+ def self.replace( lookups, replacement )
317
+
318
+ #
319
+ # Check to see if the lookups are an array;
320
+ # If yes, do all the replacements.
321
+ # If no, then only do the single replacement.
322
+ #
323
+ if lookups.kind_of?(Array)
324
+ lookups.each do |lookup|
325
+ @@buffer.gsub!( lookup, replacement )
326
+ end
327
+ else
328
+ @@buffer.gsub!( lookups, replacement )
329
+ end
330
+
331
+ #
332
+ # Return the string buffer
333
+ #
334
+ return @@buffer
335
+ end
336
+
337
+ #
338
+ # Write the string out to file; and clear the string buffer.
339
+ #
340
+ def self.write
341
+ File.open( @@file, 'a+') { |file| file.write( @@buffer ) }
342
+ @@buffer = ""
343
+ end
344
+
345
+ end
@@ -0,0 +1,153 @@
1
+ require 'idnio/timer'
2
+ require "json"
3
+ #
4
+ # Program Utility
5
+ #
6
+ module Program
7
+
8
+ def self.setConfig(config)
9
+
10
+ end
11
+
12
+ def self.line
13
+ $log.info "--------------------------------------------------------------"
14
+ end
15
+
16
+ #
17
+ # Utility method for printing messages.
18
+ #
19
+ def self.output( message )
20
+ Program.line
21
+ $log.info " #{message}"
22
+ Program.line
23
+ end
24
+
25
+ #
26
+ # Utility to start the program
27
+ #
28
+ def self.start( name, author, version, date )
29
+ Timer.start
30
+
31
+ $log.unknown "--------------------------------------------------------------"
32
+ $log.unknown " #{name}"
33
+ $log.unknown "--------------------------------------------------------------"
34
+ $log.unknown " Version: #{version}"
35
+ $log.unknown " Date: #{date}"
36
+ $log.unknown " Author: #{author}"
37
+ $log.unknown "--------------------------------------------------------------"
38
+
39
+ if $config.has_key?( 'tenant' )
40
+
41
+ $log.debug "Personal Access Token configuration detected. Using settings from 'tenant'."
42
+
43
+ $url = $config['tenant']['url']
44
+ $tenant = $config['tenant']['url'].clone.gsub!(/.api|https:\/\//,"")
45
+
46
+ $log.debug "Calling IdentityNow to get a JWT OAuth token..."
47
+
48
+ response = IDNAPI.post_unauth( "#{$url}/oauth/token?grant_type=client_credentials&client_id=#{$config['tenant']['client-id']}&client_secret=#{$config['tenant']['client-secret']}" )
49
+
50
+ case response
51
+ when Net::HTTPSuccess
52
+
53
+ session = JSON.parse( response.body )
54
+
55
+ if !session.nil? && session.has_key?( 'access_token' )
56
+ $token = session['access_token']
57
+ $log.debug "Session token: #{$token}"
58
+ else
59
+ $log.fatal "Error: Unable to parse session token from response. (#{response.code})"
60
+ abort
61
+ end
62
+
63
+ else
64
+ $log.fatal "Error: Unable to retreive session token. Please check 'tenant' configuration and try again. (#{response.code})"
65
+ abort
66
+ end
67
+
68
+ elsif $config.has_key?( 'session' )
69
+
70
+ $log.debug "Session configuration detected. Using settings from 'session'."
71
+
72
+ $tenant = $config['session']['baseUrl'].clone.gsub!(/.api|https:\/\//,"")
73
+ $url = $config['session']['baseUrl']
74
+ $token = $config['session']['accessToken']
75
+
76
+ $log.debug "Session token: #{$token}"
77
+
78
+ else
79
+
80
+ $log.fatal "Error: Configuration does not have details to retreive session. Please configure 'session' or 'tenant' settings."
81
+ abort
82
+
83
+ end
84
+
85
+ unless $tenant.nil?
86
+ $log.unknown " Tenant: #{$tenant}"
87
+ $log.unknown "--------------------------------------------------------------"
88
+ end
89
+
90
+ end
91
+
92
+ #
93
+ # Utility to end the program
94
+ #
95
+ def self.end( )
96
+ Timer.stop
97
+ output( "Process completed in #{Timer.elapsed}" )
98
+ end
99
+
100
+ #
101
+ # Utility method to write output files to a directory.
102
+ #
103
+ def self.write_file( directory, name, text )
104
+ name.gsub!(/[^0-9A-Za-z. -]/,"-")
105
+ FileUtils.mkdir_p directory
106
+ File.open( File.join( directory, name ), 'w+') { |file| file.write( text ) }
107
+ end
108
+
109
+ def self.get_filenames( directory )
110
+ output = Array.new
111
+ Dir.glob("#{directory}/*.json") do |file|
112
+ #tmp = file.slice! "#{directory}/"
113
+ output.push(file)
114
+ end
115
+ return output
116
+ end
117
+
118
+ def self.read_directory( directory )
119
+ output = Array.new
120
+ Dir.glob("#{directory}/*.json") do |file|
121
+ output.push(Program.read_file(file))
122
+ end
123
+ return output
124
+ end
125
+
126
+ #
127
+ # Utility method to read output files to a directory.
128
+ #
129
+ def self.read_file( directory, name )
130
+ return Program.read_file("#{directory}/#{name}")
131
+ end
132
+
133
+ def self.read_file( name )
134
+ output = ""
135
+ #name.gsub!(/[^0-9A-Za-z. -]/,"-")
136
+ f = File.open( name, 'r')
137
+ f.each_line do |line|
138
+ output += line
139
+ end
140
+ f.close
141
+ return output
142
+ end
143
+
144
+ def self.write_csv(directory, name, content)
145
+ if !File.file?("#{directory}/#{name}")
146
+ Program.write_file(directory, name, "")
147
+ end
148
+ CSV.open("#{directory}/#{name}", "ab") do |csv|
149
+ csv << content
150
+ end
151
+ end
152
+
153
+ end