bcl 0.7.0 → 0.8.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.
@@ -1,21 +1,7 @@
1
- ######################################################################
2
- # Copyright (c) 2008-2021, Alliance for Sustainable Energy.
3
- # All rights reserved.
4
- #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation; either
8
- # version 2.1 of the License, or (at your option) any later version.
9
- #
10
- # This library is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- # Lesser General Public License for more details.
14
- #
15
- # You should have received a copy of the GNU Lesser General Public
16
- # License along with this library; if not, write to the Free Software
17
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
- ######################################################################
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://openstudio.net/license
4
+ # *******************************************************************************
19
5
 
20
6
  module BCL
21
7
  class ComponentMethods
@@ -28,121 +14,32 @@ module BCL
28
14
  def initialize
29
15
  @parsed_measures_path = './measures/parsed'
30
16
  @config = nil
31
- @session = nil
32
- @access_token = nil
33
17
  @http = nil
34
- @api_version = 2.0
35
- @group_id = nil
36
- @logged_in = false
18
+ @api_version = nil
37
19
 
20
+ # load configs from file or default
38
21
  load_config
39
- end
40
22
 
41
- def login(username = nil, password = nil, url = nil, group_id = nil)
42
- # figure out what url to use
43
- if url.nil?
44
- url = @config[:server][:url]
45
- end
23
+ # configure connection
24
+ url = @config[:server][:url]
46
25
  # look for http vs. https
47
26
  if url.include? 'https'
48
27
  port = 443
49
28
  else
50
29
  port = 80
51
30
  end
31
+
52
32
  # strip out http(s)
53
33
  url = url.gsub('http://', '')
54
34
  url = url.gsub('https://', '')
55
35
 
56
- if username.nil? || password.nil?
57
- # log in via cached credentials
58
- username = @config[:server][:user][:username]
59
- password = @config[:server][:user][:password]
60
- @group_id = group_id || @config[:server][:user][:group]
61
- puts "logging in using credentials in .bcl/config.yml: Connecting to #{url} on port #{port} as #{username} with group #{@group_id}"
62
- else
63
- @group_id = group_id || @config[:server][:user][:group]
64
- puts "logging in using credentials in function arguments: Connecting to #{url} on port #{port} as #{username} with group #{@group_id}"
65
- end
66
-
67
- if @group_id.nil?
68
- puts '[WARNING] You did not set a group ID in your config.yml file or pass in a group ID. You can retrieve your group ID from the node number of your group page (e.g., https://bcl.nrel.gov/node/32). Will continue, but you will not be able to upload content.'
69
- end
70
-
71
36
  @http = Net::HTTP.new(url, port)
72
37
  @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
73
38
  if port == 443
74
39
  @http.use_ssl = true
75
40
  end
76
41
 
77
- data = %({"username":"#{username}","password":"#{password}"})
78
-
79
- login_path = '/api/user/login.json'
80
- headers = { 'Content-Type' => 'application/json' }
81
-
82
- res = @http.post(login_path, data, headers)
83
-
84
- # for debugging:
85
- # res.each do |key, value|
86
- # puts "#{key}: #{value}"
87
- # end
88
-
89
- if res.code == '200'
90
- puts 'Login Successful'
91
-
92
- bnes = ''
93
- bni = ''
94
- junkout = res['set-cookie'].split(';')
95
- junkout.each do |line|
96
- if line.match?(/BNES_SESS/)
97
- bnes = line.match(/(BNES_SESS.*)/)[0]
98
- end
99
- end
100
-
101
- junkout.each do |line|
102
- if line.match?(/BNI/)
103
- bni = line.match(/(BNI.*)/)[0]
104
- end
105
- end
106
-
107
- # puts "DATA: #{data}"
108
- session_name = ''
109
- sessid = ''
110
- json = JSON.parse(res.body)
111
- json.each do |key, val|
112
- if key == 'session_name'
113
- session_name = val
114
- elsif key == 'sessid'
115
- sessid = val
116
- end
117
- end
118
-
119
- @session = session_name + '=' + sessid + ';' + bni + ';' + bnes
120
-
121
- # get access token
122
- token_path = '/services/session/token'
123
- token_headers = { 'Content-Type' => 'application/json', 'Cookie' => @session }
124
- # puts "token_headers = #{token_headers.inspect}"
125
- access_token = @http.post(token_path, '', token_headers)
126
- if access_token.code == '200'
127
- @access_token = access_token.body
128
- else
129
- puts 'Unable to get access token; uploads will not work'
130
- puts "error code: #{access_token.code}"
131
- puts "error info: #{access_token.body}"
132
- end
133
-
134
- # puts "access_token = *#{@access_token}*"
135
- # puts "cookie = #{@session}"
136
-
137
- res
138
- else
139
-
140
- puts "error code: #{res.code}"
141
- puts "error info: #{res.body}"
142
- puts 'continuing as unauthenticated sessions (you can still search and download)'
143
-
144
- res
145
- end
42
+ puts "Connecting to BCL at URL: #{@config[:server][:url]}"
146
43
  end
147
44
 
148
45
  # retrieve measures for parsing metadata.
@@ -153,10 +50,18 @@ module BCL
153
50
  # raise "Please login before performing this action" if @session.nil?
154
51
 
155
52
  # make sure filter_term includes bundle
156
- if filter_term.nil?
157
- filter_term = 'fq[]=bundle%3Anrel_measure'
158
- elsif !filter_term.include? 'bundle'
159
- filter_term += '&fq[]=bundle%3Anrel_measure'
53
+ if @api_version == 2.0
54
+ if filter_term.nil?
55
+ filter_term = 'fq[]=bundle%3Anrel_measure'
56
+ elsif !filter_term.include? 'bundle'
57
+ filter_term += '&fq[]=bundle%3Anrel_measure'
58
+ end
59
+ else
60
+ if filter_term.nil?
61
+ filter_term = 'fq=bundle%3Ameasure'
62
+ elsif !filter_term.include? 'bundle'
63
+ filter_term += '&fq=bundle%3Ameasure'
64
+ end
160
65
  end
161
66
 
162
67
  # use provided search term or nil.
@@ -170,183 +75,6 @@ module BCL
170
75
  end
171
76
  end
172
77
 
173
- # evaluate the response from the API in a consistent manner
174
- def evaluate_api_response(api_response)
175
- valid = false
176
- result = { error: 'could not get json from http post response' }
177
- case api_response.code
178
- when '200'
179
- puts " Response Code: #{api_response.code}"
180
- if api_response.body.empty?
181
- puts ' 200 BUT ERROR: Returned body was empty. Possible causes:'
182
- puts ' - BSD tar on Mac OSX vs gnutar'
183
- result = { error: 'returned 200, but returned body was empty' }
184
- valid = false
185
- else
186
- puts ' 200 - Successful Upload'
187
- result = JSON.parse api_response.body
188
- valid = true
189
- end
190
- when '404'
191
- puts " Error Code: #{api_response.code} - #{api_response.body}"
192
- puts ' - check these common causes first:'
193
- puts " - you are trying to update content that doesn't exist"
194
- puts " - you are not an 'administrator member' of the group you're trying to upload to"
195
- result = JSON.parse api_response.body
196
- valid = false
197
- when '406'
198
- puts " Error Code: #{api_response.code}"
199
- # try to parse the response a bit
200
- error = JSON.parse api_response.body
201
- puts "temp error: #{error}"
202
- if error.key?('form_errors')
203
- if error['form_errors'].key?('field_tar_file')
204
- result = { error: error['form_errors']['field_tar_file'] }
205
- elsif error['form_errors'].key?('og_group_ref][und][0][default')
206
- result = { error: error['form_errors']['og_group_ref][und][0][default'] }
207
- end
208
- else
209
- result = error
210
- end
211
- valid = false
212
- when '500'
213
- puts " Error Code: #{api_response.code}"
214
- result = { error: api_response.message }
215
- # fail 'server exception'
216
- valid = false
217
- else
218
- puts " Response: #{api_response.code} - #{api_response.body}"
219
- valid = false
220
- end
221
-
222
- [valid, result]
223
- end
224
-
225
- # Construct the post parameter for the API content.json end point.
226
- # param(@update) is a boolean that triggers whether to use content_type or uuid
227
- def construct_post_data(filepath, update, content_type_or_uuid)
228
- # TODO: remove special characters in the filename; they create firewall errors
229
- # filename = filename.gsub(/\W/,'_').gsub(/___/,'_').gsub(/__/,'_').chomp('_').strip
230
-
231
- file_b64 = Base64.encode64(File.binread(filepath))
232
-
233
- data = {}
234
- data['file'] = {
235
- 'file' => file_b64,
236
- 'filesize' => File.size(filepath).to_s,
237
- 'filename' => File.basename(filepath)
238
- }
239
-
240
- data['node'] = {}
241
-
242
- # Only include the content type if this is an update
243
- if update
244
- data['node']['uuid'] = content_type_or_uuid
245
- else
246
- data['node']['type'] = content_type_or_uuid
247
- end
248
-
249
- # TODO: remove this field_component_tags once BCL is fixed
250
- data['node']['field_component_tags'] = { 'und' => '1289' }
251
- data['node']['og_group_ref'] = { 'und' => ['target_id' => @group_id] }
252
-
253
- # NOTE THIS ONLY WORKS IF YOU ARE A BCL SITE ADMIN
254
- data['node']['publish'] = '1'
255
-
256
- data
257
- end
258
-
259
- # pushes component to the bcl and publishes them (if logged-in as BCL Website Admin user).
260
- # username, password, and group_id are set in the ~/.bcl/config.yml file
261
- def push_content(filename_and_path, write_receipt_file, content_type)
262
- raise 'Please login before pushing components' if @session.nil?
263
- raise 'Do not have a valid access token; try again' if @access_token.nil?
264
-
265
- data = construct_post_data(filename_and_path, false, content_type)
266
-
267
- path = '/api/content.json'
268
- headers = { 'Content-Type' => 'application/json', 'X-CSRF-Token' => @access_token, 'Cookie' => @session }
269
-
270
- res = @http.post(path, JSON.dump(data), headers)
271
-
272
- valid, json = evaluate_api_response(res)
273
-
274
- if valid
275
- # write out a receipt file into the same directory of the component with the same file name as
276
- # the component
277
- if write_receipt_file
278
- File.open("#{File.dirname(filename_and_path)}/#{File.basename(filename_and_path, '.tar.gz')}.receipt", 'w') do |file|
279
- file << Time.now.to_s
280
- end
281
- end
282
- end
283
-
284
- [valid, json]
285
- end
286
-
287
- # pushes updated content to the bcl and publishes it (if logged-in as BCL Website Admin user).
288
- # username and password set in ~/.bcl/config.yml file
289
- def update_content(filename_and_path, write_receipt_file, uuid = nil)
290
- raise 'Please login before pushing components' unless @session
291
-
292
- # get the UUID if zip or xml file
293
- version_id = nil
294
- if uuid.nil?
295
- puts File.extname(filename_and_path).downcase
296
- if filename_and_path.match?(/^.*.tar.gz$/i)
297
- uuid, version_id = uuid_vid_from_tarball(filename_and_path)
298
- puts "Parsed uuid out of tar.gz file with value #{uuid}"
299
- end
300
- else
301
- # verify the uuid via regex
302
- unless uuid.match?(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/)
303
- raise "uuid of #{uuid} is invalid"
304
- end
305
- end
306
- raise 'Please pass in a tar.gz file or pass in the uuid' unless uuid
307
-
308
- data = construct_post_data(filename_and_path, true, uuid)
309
-
310
- path = '/api/content.json'
311
- headers = { 'Content-Type' => 'application/json', 'X-CSRF-Token' => @access_token, 'Cookie' => @session }
312
-
313
- res = @http.post(path, JSON.dump(data), headers)
314
-
315
- valid, json = evaluate_api_response(res)
316
-
317
- if valid
318
- # write out a receipt file into the same directory of the component with the same file name as
319
- # the component
320
- if write_receipt_file
321
- File.open("#{File.dirname(filename_and_path)}/#{File.basename(filename_and_path, '.tar.gz')}.receipt", 'w') do |file|
322
- file << Time.now.to_s
323
- end
324
- end
325
- end
326
-
327
- [valid, json]
328
- end
329
-
330
- def push_contents(array_of_components, skip_files_with_receipts, content_type)
331
- logs = []
332
- array_of_components.each do |comp|
333
- receipt_file = File.dirname(comp) + '/' + File.basename(comp, '.tar.gz') + '.receipt'
334
- log_message = ''
335
- if skip_files_with_receipts && File.exist?(receipt_file)
336
- log_message = "skipping because found receipt #{comp}"
337
- puts log_message
338
- else
339
- log_message = "pushing content #{File.basename(comp, '.tar.gz')}"
340
- puts log_message
341
- valid, res = push_content(comp, true, content_type)
342
- log_message += " #{valid} #{res.inspect.chomp}"
343
- end
344
- logs << log_message
345
- end
346
-
347
- logs
348
- end
349
-
350
78
  # Unpack the tarball in memory and extract the XML file to read the UUID and Version ID
351
79
  def uuid_vid_from_tarball(path_to_tarball)
352
80
  uuid = nil
@@ -406,43 +134,18 @@ module BCL
406
134
  [uuid, vid]
407
135
  end
408
136
 
409
- def update_contents(array_of_tarball_components, skip_files_with_receipts)
410
- logs = []
411
- array_of_tarball_components.each do |comp|
412
- receipt_file = File.dirname(comp) + '/' + File.basename(comp, '.tar.gz') + '.receipt'
413
- log_message = ''
414
- if skip_files_with_receipts && File.exist?(receipt_file)
415
- log_message = "skipping update because found receipt #{File.basename(comp)}"
416
- puts log_message
417
- else
418
- uuid, vid = uuid_vid_from_tarball(comp)
419
- if uuid.nil?
420
- log_message = "ERROR: uuid not found for #{File.basename(comp)}"
421
- puts log_message
422
- else
423
- log_message = "pushing updated content #{File.basename(comp)}"
424
- puts log_message
425
- valid, res = update_content(comp, true, uuid)
426
- log_message += " #{valid} #{res.inspect.chomp}"
427
- end
428
- end
429
- logs << log_message
430
- end
431
- logs
432
- end
433
-
434
137
  def search_by_uuid(uuid, vid = nil)
435
138
  full_url = '/api/search.json'
436
- action = nil
437
139
 
438
140
  # add api_version
439
- if @api_version < 2.0
440
- puts "WARNING: attempting to use search with api_version #{@api_version}. Use API v2.0 for this functionality."
141
+ if @api_version == 2.0
142
+ # uuid
143
+ full_url += "?api_version=#{@api_version}"
144
+ full_url += "&fq[]=ss_uuid:#{uuid}"
145
+ else
146
+ # uuid
147
+ full_url += "&fq=uuid:#{uuid}"
441
148
  end
442
- full_url += "?api_version=#{@api_version}"
443
-
444
- # uuid
445
- full_url += "&fq[]=ss_uuid:#{uuid}"
446
149
 
447
150
  res = @http.get(full_url)
448
151
  res = JSON.parse res.body
@@ -458,20 +161,9 @@ module BCL
458
161
  else
459
162
  content = content['component']
460
163
  end
461
-
462
- # TODO: check version_modified date if it exists?
463
- if !vid.nil? && content['vuuid'] == vid
464
- # no update needed
465
- action = 'noop'
466
- else
467
- # vid doesn't match: update existing
468
- action = 'update'
469
- end
470
- else
471
- # no uuid found: push new
472
- action = 'push'
473
164
  end
474
- action
165
+
166
+ content
475
167
  end
476
168
 
477
169
  # Simple method to search bcl and return the result as hash with symbols
@@ -492,22 +184,30 @@ module BCL
492
184
  full_url += '*.json'
493
185
  end
494
186
 
495
- # add api_version
496
- if @api_version < 2.0
497
- puts "WARNING: attempting to use search with api_version #{@api_version}. Use API v2.0 for this functionality."
187
+ # add api_version (legacy NREL is 2.0, otherwise use new syntax and ignore version)
188
+ if @api_version.nil?
189
+ # see if we can extract it from filter_str:
190
+ tmp = filter_str.match(/api_version=\d{1,}.\d{1,}/)
191
+ if tmp
192
+ @api_version = tmp.to_s.gsub(/api_version=/, '').to_f
193
+ puts "@api_version from filter_str: #{@api_version}"
194
+ end
498
195
  end
499
- full_url += "?api_version=#{@api_version}"
196
+
197
+ if @api_version == 2.0
198
+ full_url += "?api_version=#{@api_version}"
199
+ end
200
+ puts "@api_version: #{@api_version}"
500
201
 
501
202
  # add filters
502
- unless filter_str.nil?
503
- # strip out api_version from filters, if included
504
- if filter_str.include? 'api_version='
505
- filter_str = filter_str.gsub(/api_version=\d{1,}/, '')
506
- filter_str = filter_str.gsub(/&api_version=\d{1,}/, '')
203
+ if !filter_str.nil?
204
+ # strip out api_version from filters, if included & @api_version is defined
205
+ if (filter_str.include? 'api_version=')
206
+ filter_str = filter_str.gsub(/&api_version=\d{1,}.\d{1,}/, '')
207
+ filter_str = filter_str.gsub(/api_version=\d{1,}.\d{1,}/, '')
507
208
  end
508
209
  full_url = full_url + '&' + filter_str
509
210
  end
510
-
511
211
  # simple search vs. all results
512
212
  if !all
513
213
  puts "search url: #{full_url}"
@@ -556,14 +256,16 @@ module BCL
556
256
  receipt_file = File.dirname(comp) + '/' + File.basename(comp, '.tar.gz') + '.receipt'
557
257
  if File.exist?(receipt_file)
558
258
  FileUtils.remove_file(receipt_file)
559
-
560
259
  end
561
260
  end
562
261
  end
563
262
 
564
263
  def list_all_measures
565
- json = search(nil, 'fq[]=bundle%3Anrel_measure&show_rows=100')
566
-
264
+ if @api_version == 2.0
265
+ json = search(nil, 'fq[]=bundle%3Anrel_measure&show_rows=100')
266
+ else
267
+ json = search(nil, 'fq=bundle%3Ameasure&show_rows=100')
268
+ end
567
269
  json
568
270
  end
569
271
 
@@ -591,93 +293,27 @@ module BCL
591
293
  config_filename = File.expand_path('~/.bcl/config.yml')
592
294
 
593
295
  if File.exist?(config_filename)
594
- puts "loading config settings from #{config_filename}"
296
+ puts "loading URL config from #{config_filename}"
595
297
  @config = YAML.load_file(config_filename)
596
298
  else
597
- # location of template file
598
- FileUtils.mkdir_p(File.dirname(config_filename))
599
- File.open(config_filename, 'w') { |f| f << default_yaml.to_yaml }
600
- File.chmod(0o600, config_filename)
601
- puts "******** Please fill in user credentials in #{config_filename} file if you need to upload data **********"
602
- # fill in the @config data with the temporary data for now.
603
- @config = YAML.load_file(config_filename)
299
+ # use default URL
300
+ @config = {
301
+ server: {
302
+ url: 'https://bcl.nrel.gov'
303
+ }
304
+ }
604
305
  end
605
306
  end
606
307
 
308
+ # unused
607
309
  def default_yaml
608
310
  settings = {
609
311
  server: {
610
- url: 'https://bcl.nrel.gov',
611
- user: {
612
- username: 'ENTER_BCL_USERNAME',
613
- password: 'ENTER_BCL_PASSWORD',
614
- group: 'ENTER_GROUP_ID'
615
- }
312
+ url: 'https://bcl.nrel.gov'
616
313
  }
617
314
  }
618
315
 
619
316
  settings
620
317
  end
621
318
  end
622
-
623
- # TODO: make this extend the component_xml class (or create a super class around components)
624
-
625
- def self.gather_components(component_dir, chunk_size = 0, delete_previousgather = false, destination = nil)
626
- if destination.nil?
627
- @dest_filename = 'components'
628
- else
629
- @dest_filename = destination
630
- end
631
- @dest_file_ext = 'tar.gz'
632
-
633
- # store the starting directory
634
- current_dir = Dir.pwd
635
-
636
- # an array to hold reporting info about the batches
637
- gather_components_report = []
638
-
639
- # go to the directory containing the components
640
- Dir.chdir(component_dir)
641
-
642
- # delete any old versions of the component chunks
643
- FileUtils.rm_rf('./gather') if delete_previousgather
644
-
645
- # gather all the components into array
646
- targzs = Pathname.glob('./**/*.tar.gz')
647
- tar_cnt = 0
648
- chunk_cnt = 0
649
- targzs.each do |targz|
650
- if chunk_size != 0 && (tar_cnt % chunk_size) == 0
651
- chunk_cnt += 1
652
- end
653
- tar_cnt += 1
654
-
655
- destination_path = "./gather/#{chunk_cnt}"
656
- FileUtils.mkdir_p(destination_path)
657
- destination_file = "#{destination_path}/#{File.basename(targz.to_s)}"
658
- # puts "copying #{targz.to_s} to #{destination_file}"
659
- FileUtils.cp(targz.to_s, destination_file)
660
- end
661
-
662
- # gather all the .tar.gz files into a single tar.gz
663
- (1..chunk_cnt).each do |cnt|
664
- currentdir = Dir.pwd
665
-
666
- paths = []
667
- Pathname.glob("./gather/#{cnt}/*.tar.gz").each do |pt|
668
- paths << File.basename(pt.to_s)
669
- end
670
-
671
- Dir.chdir("./gather/#{cnt}")
672
- destination = "#{@dest_filename}_#{cnt}.#{@dest_file_ext}"
673
- puts "tarring batch #{cnt} of #{chunk_cnt} to #{@dest_filename}_#{cnt}.#{@dest_file_ext}"
674
- BCL.tarball(destination, paths)
675
- Dir.chdir(currentdir)
676
-
677
- # move the tarball back a directory
678
- FileUtils.move("./gather/#{cnt}/#{destination}", "./gather/#{destination}")
679
- end
680
-
681
- Dir.chdir(current_dir)
682
- end
683
319
  end
data/lib/bcl/core_ext.rb CHANGED
@@ -1,21 +1,7 @@
1
- ######################################################################
2
- # Copyright (c) 2008-2021, Alliance for Sustainable Energy.
3
- # All rights reserved.
4
- #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation; either
8
- # version 2.1 of the License, or (at your option) any later version.
9
- #
10
- # This library is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- # Lesser General Public License for more details.
14
- #
15
- # You should have received a copy of the GNU Lesser General Public
16
- # License along with this library; if not, write to the Free Software
17
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
- ######################################################################
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://openstudio.net/license
4
+ # *******************************************************************************
19
5
 
20
6
  class String
21
7
  def to_underscore
data/lib/bcl/tar_ball.rb CHANGED
@@ -1,65 +1,17 @@
1
- ######################################################################
2
- # Copyright (c) 2008-2021, Alliance for Sustainable Energy.
3
- # All rights reserved.
4
- #
5
- # This library is free software; you can redistribute it and/or
6
- # modify it under the terms of the GNU Lesser General Public
7
- # License as published by the Free Software Foundation; either
8
- # version 2.1 of the License, or (at your option) any later version.
9
- #
10
- # This library is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- # Lesser General Public License for more details.
14
- #
15
- # You should have received a copy of the GNU Lesser General Public
16
- # License along with this library; if not, write to the Free Software
17
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
- ######################################################################
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://openstudio.net/license
4
+ # *******************************************************************************
19
5
 
20
6
  module BCL
21
7
  module_function
22
8
 
23
- # tarball multiple paths recursively to destination
24
- def tarball(destination, paths)
25
- # check for filepath length limit
26
- full_destination = File.expand_path(destination)
27
- if full_destination.length > 259 # 256 chars max; "C:\" doesn't count
28
- puts "[TarBall] ERROR cannot generate #{destination} because path exceeds 256 char limit. shorten component name by at least by #{full_destination.length - 259} chars"
29
- return
30
- end
31
-
32
- Zlib::GzipWriter.open(destination) do |gzip|
33
- out = Archive::Tar::Minitar::Output.new(gzip)
34
-
35
- paths.each do |fi|
36
- if File.exist?(fi)
37
- Archive::Tar::Minitar.pack_file(fi, out)
38
- else
39
- puts "[TarBall] ERROR Could not file file: #{fi}"
40
- end
41
- end
42
- out.close
43
- end
44
- end
45
-
46
9
  def extract_tarball(filename, destination)
47
10
  Zlib::GzipReader.open(filename) do |gz|
48
11
  Archive::Tar::Minitar.unpack(gz, destination)
49
12
  end
50
13
  end
51
14
 
52
- def create_zip(_destination, paths)
53
- Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
54
- paths.each do |fi|
55
- # Two arguments:
56
- # - The name of the file as it will appear in the archive
57
- # - The original file, including the path to find it
58
- zipfile.add(fi.basename, fi)
59
- end
60
- end
61
- end
62
-
63
15
  def extract_zip(filename, destination, delete_zip = false)
64
16
  Zip::File.open(filename) do |zip_file|
65
17
  zip_file.each do |f|