blackstack-core 1.2.28 → 1.2.29

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/functions.rb +194 -163
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cf281a3482c533e39b0f6d9a97372b826f18c08ed4ba391c78905bb49ed627ac
4
- data.tar.gz: 83f6252605460480b216ecfe80a9b314ee33a943f163f10bf4efa6797595464f
3
+ metadata.gz: 61e89c40560e966edd297c6fbce7e0099a94bce4dd88c0653f7e20feceb8234e
4
+ data.tar.gz: 28543d06207cc6399371e857b0982ec7432801e5344372304165a0aaa4053660
5
5
  SHA512:
6
- metadata.gz: f1338a61f396612dcd83e5d88446c6818051e4231a22b2d10f14d39fedba49386d21ceba4b1779bd728f0c09376ec6b3e73a0e3db8e6c03740348d5922befbe6
7
- data.tar.gz: 28e3bed3a23f02fba73e91cb0fdd6aa607b43e340027c4e649010e06066e66fdfa50f3e50e9e2404b4be014d4f10f7bb6dbc70c21e48f341fb32a42c565b4f59
6
+ metadata.gz: 8545ef59846393d06cb272b8e503847b3c11e9837933ac770c546acf724265a6e560407dea7bcbe67bccf49ec505b89463b4aab52bb83094fdeb792b517f7479
7
+ data.tar.gz: 3eaac8af64b460a4cf941d3756faa219da65a75300cbe47fe1574ae4bb9426e3a5d6a2c028dcb81e940646bc4566f433ed48493cbf4665c5eee58d76b341823f
data/lib/functions.rb CHANGED
@@ -20,7 +20,7 @@ module BlackStack
20
20
 
21
21
  def self.api_url
22
22
  @@api_url
23
- end
23
+ end
24
24
 
25
25
  def self.api_port
26
26
  @@api_port
@@ -37,7 +37,7 @@ module BlackStack
37
37
  def self.classes
38
38
  @@classes
39
39
  end # def self.classes
40
-
40
+
41
41
  def self.set_client(
42
42
  api_key: ,
43
43
  api_url: ,
@@ -60,7 +60,7 @@ module BlackStack
60
60
  end # def self.set_server
61
61
 
62
62
  def self.post(
63
- endpoint: ,
63
+ endpoint: ,
64
64
  params: {}
65
65
  )
66
66
  begin
@@ -84,7 +84,7 @@ module BlackStack
84
84
 
85
85
  # Base class.
86
86
  # List of methods you have to overload if you develop a profile type.
87
- #
87
+ #
88
88
  class Base
89
89
  # object json descriptor
90
90
  attr_accessor :desc
@@ -120,10 +120,10 @@ module BlackStack
120
120
 
121
121
 
122
122
  # Get array of hash descriptor of profile.
123
- #
124
- # Parameters:
123
+ #
124
+ # Parameters:
125
125
  # - id_account: guid. Id of the account to bring the profiles. Sysowner must provide the id_account for getting an account value. For non sysowner it is assigned to his account.
126
- # - promiscuous: boolean. It works only for Sysowner. If true, it will bring all non-deleted rows. If false, it will bring only rows matching id_profile. Default: false.
126
+ # - promiscuous: boolean. It works only for Sysowner. If true, it will bring all non-deleted rows, including the ones that are not owned by Sysowner. If false, it will bring only rows matching id_profile. Default: false.
127
127
  # - page: integer. Page number.
128
128
  # - limit: integer. Number of profiles per page.
129
129
  # - params: hash. Additional filter parameters used by the specific child class.
@@ -147,8 +147,8 @@ module BlackStack
147
147
  end # def self.base
148
148
 
149
149
  # Get array of hash descriptors of profiles.
150
- #
151
- # Parameters:
150
+ #
151
+ # Parameters:
152
152
  # - id: guid. Id of the profile to bring.
153
153
  #
154
154
  def self.count
@@ -163,8 +163,8 @@ module BlackStack
163
163
  end # def self.count
164
164
 
165
165
  # Get array of hash descriptors of profiles.
166
- #
167
- # Parameters:
166
+ #
167
+ # Parameters:
168
168
  # - id: guid. Id of the profile to bring.
169
169
  #
170
170
  def self.get(id)
@@ -179,6 +179,23 @@ module BlackStack
179
179
  return self.new(ret['result']).child_class_instance
180
180
  end # def self.get
181
181
 
182
+ # Delete object.
183
+ #
184
+ # Parameters:
185
+ # - id: guid. Id of the profile to bring.
186
+ #
187
+ def self.delete(id)
188
+ params = {}
189
+ params['id'] = id
190
+ params['backtrace'] = BlackStack::API.backtrace
191
+ ret = BlackStack::API.post(
192
+ endpoint: "#{self.object_name}/delete",
193
+ params: params
194
+ )
195
+ raise "Error calling get endpoint: #{ret['status']}" if ret['status'] != 'success'
196
+ return self.new(ret['result']).child_class_instance
197
+ end # def self.get
198
+
182
199
  # Submit a hash descriptor to the server for an update
183
200
  #
184
201
  def self.update(desc)
@@ -248,6 +265,20 @@ module BlackStack
248
265
  return ret['result'] == {} ? nil : self.new(ret['result']).child_class_instance
249
266
  end # def self.upsert
250
267
 
268
+ # Submit a hash descriptor to the server for an upsert
269
+ #
270
+ def self.upsert2(desc)
271
+ params = {}
272
+ params['desc'] = desc
273
+ params['backtrace'] = BlackStack::API.backtrace
274
+ ret = BlackStack::API.post(
275
+ endpoint: "#{self.object_name}/upsert2",
276
+ params: params
277
+ )
278
+ raise "Error calling upsert endpoint: #{ret['status']}" if ret['status'] != 'success'
279
+ return ret['result'] == {} ? nil : self.new(ret['result']).child_class_instance
280
+ end # def self.upsert
281
+
251
282
  # Submit a hash descriptor to the server for an upsert
252
283
  #
253
284
  def upsert
@@ -266,7 +297,7 @@ module BlackStack
266
297
  ret = nil
267
298
  # getting the HTML
268
299
  zyte = ZyteClient.new(key: api_key)
269
- html = zyte.extract(url: url, options: options, data_filename: data_filename)
300
+ html = zyte.extract(url: url, options: options, data_filename: data_filename)
270
301
  # return the URL of the file in the cloud
271
302
  return html
272
303
  end # def zyte_html
@@ -284,7 +315,7 @@ module BlackStack
284
315
  def zyte_snapshot(url, api_key:, options:, data_filename:, dropbox_folder:nil, retry_times: 3)
285
316
  # "The garbage character must be due to the 520 error code which was caused on the second request."
286
317
  garbage = "\x9E\xE9e"
287
-
318
+
288
319
  ret = nil
289
320
  raise "Either dropbox_folder parameter or self.desc['id_account'] are required." if dropbox_folder.nil? && self.desc['id_account'].nil?
290
321
  dropbox_folder = self.desc['id_account'] if dropbox_folder.nil?
@@ -302,7 +333,7 @@ module BlackStack
302
333
  try = 0
303
334
  html = garbage
304
335
  while try < retry_times && html == garbage
305
- html = zyte.extract(url: url, options: options, data_filename: data_filename)
336
+ html = zyte.extract(url: url, options: options, data_filename: data_filename)
306
337
  try += 1
307
338
  end
308
339
  # save the HTML in the local file in /tmp
@@ -318,9 +349,9 @@ module BlackStack
318
349
 
319
350
  end # class Base
320
351
 
321
- # -----------------------------------------------------------------------------------------
352
+ # -----------------------------------------------------------------------------------------
322
353
  # PRY Supporting Functions
323
- # -----------------------------------------------------------------------------------------
354
+ # -----------------------------------------------------------------------------------------
324
355
  module Debugging
325
356
  @@allow_breakpoints = false
326
357
  @@verbose = false
@@ -341,7 +372,7 @@ module BlackStack
341
372
  print "Breakpoint are not allowed" if @@verbose
342
373
  end
343
374
 
344
- Binding.class_eval do
375
+ Binding.class_eval do
345
376
  alias_method :old_pry, :pry
346
377
  define_method :pry, new_pry
347
378
  end
@@ -349,21 +380,21 @@ module BlackStack
349
380
  end
350
381
  end
351
382
 
352
- # -----------------------------------------------------------------------------------------
383
+ # -----------------------------------------------------------------------------------------
353
384
  # OCRA Supporting Functions
354
- # -----------------------------------------------------------------------------------------
385
+ # -----------------------------------------------------------------------------------------
355
386
  module OCRA
356
387
  # OCRA files run into a temp folder, where the script is unpacked.
357
- #
388
+ #
358
389
  # This function is useful to require a configuration file when the
359
390
  # script is running inside an OCRA temp folder, since the local folder
360
391
  # of the running command is not the filder where the exe file is hosted.
361
- #
362
- # More information:
392
+ #
393
+ # More information:
363
394
  # * https://stackoverflow.com/questions/1937743/how-to-get-the-current-working-directorys-absolute-path-from-irb
364
395
  # * https://stackoverflow.com/questions/8577223/ruby-get-the-file-being-executed
365
396
  # * https://stackoverflow.com/questions/7399882/ruby-getting-path-from-pathfilename/7400057
366
- #
397
+ #
367
398
  def self.require_in_working_path(filename, path, show_path_info=false)
368
399
  puts '' if show_path_info
369
400
  path = File.expand_path File.dirname(path)
@@ -375,13 +406,13 @@ module BlackStack
375
406
  end
376
407
  end # module OCRA
377
408
 
378
- # -----------------------------------------------------------------------------------------
409
+ # -----------------------------------------------------------------------------------------
379
410
  # DateTime Functions
380
- # -----------------------------------------------------------------------------------------
381
- module DateTime
382
- # -----------------------------------------------------------------------------------------
411
+ # -----------------------------------------------------------------------------------------
412
+ module DateTime
413
+ # -----------------------------------------------------------------------------------------
383
414
  # Encoding
384
- # -----------------------------------------------------------------------------------------
415
+ # -----------------------------------------------------------------------------------------
385
416
  module Encoding
386
417
  # Convierte un objeto date-time a un string con formato sql-datetime (yyyy-mm-dd hh:mm:ss).
387
418
  def self.datetime_to_sql(o)
@@ -389,50 +420,50 @@ module BlackStack
389
420
  end
390
421
  end # module Encode
391
422
 
392
- # -----------------------------------------------------------------------------------------
423
+ # -----------------------------------------------------------------------------------------
393
424
  # Miscelaneous
394
- # -----------------------------------------------------------------------------------------
425
+ # -----------------------------------------------------------------------------------------
395
426
  module Misc
396
427
  def self.datetime_values_check(year,month,day,hour,minute,second)
397
428
  if (year.to_i<1900 || year.to_i>=2100)
398
429
  return false
399
430
  end
400
-
431
+
401
432
  if (month.to_i<1 || month.to_i>12)
402
433
  return false
403
434
  end
404
-
435
+
405
436
  # TODO: Considerar la cantidad de dias de cada mes, y los anios biciestos. Buscar alguna funcion existente.
406
437
  if (day.to_i<1 || day.to_i>31)
407
438
  return false
408
439
  end
409
-
440
+
410
441
  if (hour.to_i<0 || hour.to_i>23)
411
442
  return false
412
443
  end
413
-
444
+
414
445
  if (minute.to_i<0 || minute.to_i>59)
415
446
  return false
416
447
  end
417
-
448
+
418
449
  if (second.to_i<0 || second.to_i>59)
419
450
  return false
420
451
  end
421
-
452
+
422
453
  return true
423
454
  end # datetime_values_check
424
455
  end # module Misc
425
456
  end # module DateTime
426
457
 
427
- # -----------------------------------------------------------------------------------------
458
+ # -----------------------------------------------------------------------------------------
428
459
  # Numeric Functions
429
- # -----------------------------------------------------------------------------------------
460
+ # -----------------------------------------------------------------------------------------
430
461
  module Number
431
- # -----------------------------------------------------------------------------------------
462
+ # -----------------------------------------------------------------------------------------
432
463
  # Encoding
433
- # -----------------------------------------------------------------------------------------
464
+ # -----------------------------------------------------------------------------------------
434
465
  module Encoding
435
- # Converts number to a string with a format like xx,xxx,xxx.xxxx
466
+ # Converts number to a string with a format like xx,xxx,xxx.xxxx
436
467
  # number: it may be int or float
437
468
  def self.format_with_separator(number)
438
469
  whole_part, decimal_part = number.to_s.split('.')
@@ -444,7 +475,7 @@ module BlackStack
444
475
  # Ejemplo: "4 hours, 30 minutes"
445
476
  # Ejemplo: "3 days, 4 hour"
446
477
  def self.encode_minutes(n)
447
- # TODO: validar que n sea un entero mayor a 0
478
+ # TODO: validar que n sea un entero mayor a 0
448
479
  if (n<0)
449
480
  return "?"
450
481
  end
@@ -459,13 +490,13 @@ module BlackStack
459
490
  end # module Encode
460
491
  end # module Number
461
492
 
462
- # -----------------------------------------------------------------------------------------
493
+ # -----------------------------------------------------------------------------------------
463
494
  # String Functions
464
- # -----------------------------------------------------------------------------------------
495
+ # -----------------------------------------------------------------------------------------
465
496
  module Strings
466
497
 
467
498
  GUID_SIZE = 36
468
- MATCH_PASSWORD = /(?=.*[a-zA-Z])(?=.*[0-9]).{6,}/
499
+ MATCH_PASSWORD = /(?=.*[a-zA-Z])(?=.*[0-9]).{6,}/
469
500
  MATCH_GUID = /{?[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]\-[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]}?/
470
501
  MATCH_FILENAME = /[\w\-\_\.]+/
471
502
  MATCH_EMAIL = /[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{1,25}/
@@ -474,7 +505,7 @@ module BlackStack
474
505
  MATCH_PHONE = /(?:\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}/
475
506
 
476
507
  # Note: MATCH_URL gets the URL up to '?', but it doesn't retrieves the parameters.
477
- # Exmaple:
508
+ # Exmaple:
478
509
  # https://foo.com/bar?param1=value1&param2=value2 --> https://foo.com/bar?
479
510
  # https://foo.com/bar/?param1=value1&param2=value2 --> https://foo.com/bar/?
480
511
  MATCH_URL = /(https?:\/\/)?([\da-z\.-]+)([\.\:])([\da-z]{2,6})([\/[\da-z\.\-]+]*[\da-z])(\/)?(\?)?/i
@@ -484,32 +515,32 @@ module BlackStack
484
515
  MATCH_CONTENT_SPINNING = /{[^}]+}/
485
516
  MATCH_SPINNED_TEXT = /code me/ # TODO: define this regex for the issue #1226
486
517
 
487
- # -----------------------------------------------------------------------------------------
518
+ # -----------------------------------------------------------------------------------------
488
519
  # Fuzzy String Comparsion Functions: How similar are 2 strings that are not exactly equal.
489
- # -----------------------------------------------------------------------------------------
520
+ # -----------------------------------------------------------------------------------------
490
521
  module SQL
491
522
  def self.string_to_sql_string(s)
492
523
  #return s.force_encoding("UTF-8").gsub("'", "''").to_s
493
524
  return s.gsub("'", "''").to_s
494
525
  end
495
526
  end
496
-
497
- # -----------------------------------------------------------------------------------------
527
+
528
+ # -----------------------------------------------------------------------------------------
498
529
  # Fuzzy String Comparsion Functions: How similar are 2 strings that are not exactly equal.
499
- # -----------------------------------------------------------------------------------------
530
+ # -----------------------------------------------------------------------------------------
500
531
  module Comparing
501
532
  # retorna 0 si los strings son iguales
502
533
  # https://stackoverflow.com/questions/16323571/measure-the-distance-between-two-strings-with-ruby
503
- def self.levenshtein_distance(s, t)
534
+ def self.levenshtein_distance(s, t)
504
535
  s.downcase!
505
536
  t.downcase!
506
-
537
+
507
538
  m = s.length
508
539
  n = t.length
509
540
  return m if n == 0
510
541
  return n if m == 0
511
542
  d = Array.new(m+1) {Array.new(n+1)}
512
-
543
+
513
544
  (0..m).each {|i| d[i][0] = i}
514
545
  (0..n).each {|j| d[0][j] = j}
515
546
  (1..n).each do |j|
@@ -526,7 +557,7 @@ module BlackStack
526
557
  end
527
558
  d[m][n]
528
559
  end
529
-
560
+
530
561
  # retorna la cantidad de palabras con mas de 3 caracteres que se encuentran en el parametro s
531
562
  def self.max_sardi_distance(s)
532
563
  s.downcase!
@@ -541,14 +572,14 @@ module BlackStack
541
572
  }
542
573
  n
543
574
  end
544
-
575
+
545
576
  # retorna la cantidad de palabras con mas de 3 caracteres del parametro s que se encuentran en el parametro t
546
577
  def self.sardi_distance(s, t)
547
578
  s.downcase!
548
579
  t.downcase!
549
580
  s.gsub!(/-/,' ')
550
581
  t.gsub!(/-/,' ')
551
- max_distance = max_sardi_distance(s)
582
+ max_distance = max_sardi_distance(s)
552
583
  ss = s.scan(/\b([a-z]+)\b/)
553
584
  tt = t.scan(/\b([a-z]+)\b/)
554
585
  n = 0
@@ -563,20 +594,20 @@ module BlackStack
563
594
  return max_distance - n
564
595
  end
565
596
  end # module Comparing
566
-
567
- # -----------------------------------------------------------------------------------------
597
+
598
+ # -----------------------------------------------------------------------------------------
568
599
  # Encoding: Make a string nice to be shown into an HTML string.
569
- # -----------------------------------------------------------------------------------------
600
+ # -----------------------------------------------------------------------------------------
570
601
  module Encoding
571
602
  # Then it makes it compatible with UTF-8.
572
- # More details here: https://bitbucket.org/leandro_sardi/blackstack/issues/961
603
+ # More details here: https://bitbucket.org/leandro_sardi/blackstack/issues/961
573
604
  def self.encode_string(s)
574
605
  s.encode("UTF-8")
575
606
  end
576
-
607
+
577
608
  # Escape the string to be shown into an HTML screen.
578
609
  # Then it makes it compatible with UTF-8.
579
- # More details here: https://bitbucket.org/leandro_sardi/blackstack/issues/961
610
+ # More details here: https://bitbucket.org/leandro_sardi/blackstack/issues/961
580
611
  def self.encode_html(s)
581
612
  encode_string(CGI.escapeHTML(s.to_s))
582
613
  end
@@ -584,9 +615,9 @@ module BlackStack
584
615
  # Generates a description string from an exception object.
585
616
  # Eescapes the string to be shown into an HTML screen.
586
617
  # Makes it compatible with UTF-8.
587
- # More details here: https://bitbucket.org/leandro_sardi/blackstack/issues/961
618
+ # More details here: https://bitbucket.org/leandro_sardi/blackstack/issues/961
588
619
  def self.encode_exception(e, include_backtrace=true)
589
- ret = encode_html(e.to_s)
620
+ ret = encode_html(e.to_s)
590
621
  if (include_backtrace == true)
591
622
  e.backtrace.each { |s|
592
623
  ret += "<br/>" + encode_html(s)
@@ -596,8 +627,8 @@ module BlackStack
596
627
  end
597
628
 
598
629
  # Returns a string with a description of a period of time, to be shown in the screen.
599
- # period: it may be 'H', 'D', 'W', 'M', 'Y'
600
- # units: it is a positive integer
630
+ # period: it may be 'H', 'D', 'W', 'M', 'Y'
631
+ # units: it is a positive integer
601
632
  def self.encode_period(period, units)
602
633
  s = "Last "
603
634
  s += units.to_i.to_s + " " if units.to_i > 1
@@ -626,87 +657,87 @@ module BlackStack
626
657
 
627
658
  end # module Encoding
628
659
 
629
- # -----------------------------------------------------------------------------------------
660
+ # -----------------------------------------------------------------------------------------
630
661
  # DateTime
631
- # -----------------------------------------------------------------------------------------
632
- module DateTime
662
+ # -----------------------------------------------------------------------------------------
663
+ module DateTime
633
664
  # Check the string has the format yyyymmddhhmmss.
634
665
  # => Return true if success. Otherwise, return false.
635
666
  # => Year cannot be lower than 1900.
636
- # => Year cannot be higher or equal than 2100.
667
+ # => Year cannot be higher or equal than 2100.
637
668
  def self.datetime_api_check(s)
638
- return false if (s.size!=14)
669
+ return false if (s.size!=14)
639
670
  year = s[0..3]
640
671
  month = s[4..5]
641
- day = s[6..7]
642
- hour = s[8..9]
643
- minute = s[10..11]
644
- second = s[12..13]
672
+ day = s[6..7]
673
+ hour = s[8..9]
674
+ minute = s[10..11]
675
+ second = s[12..13]
645
676
  BlackStack::DateTime::Misc::datetime_values_check(year,month,day,hour,minute,second)
646
677
  end # def datetime_api_check
647
678
 
648
679
  # Check the string has the format yyyy-mm-dd hh:mm:ss.
649
680
  # => Return true if success. Otherwise, return false.
650
681
  # => Year cannot be lower than 1900.
651
- # => Year cannot be higher or equal than 2100.
682
+ # => Year cannot be higher or equal than 2100.
652
683
  def self.datetime_sql_check(s)
653
684
  return false if (s.size!=19)
654
685
  year = s[0..3]
655
686
  month = s[5..6]
656
- day = s[8..9]
657
- hour = s[11..12]
658
- minute = s[14..15]
659
- second = s[17..18]
687
+ day = s[8..9]
688
+ hour = s[11..12]
689
+ minute = s[14..15]
690
+ second = s[17..18]
660
691
  BlackStack::DateTime::Misc::datetime_values_check(year,month,day,hour,minute,second)
661
692
  end # def datetime_sql_check
662
-
693
+
663
694
  # Convierte un string con formato api-datatime (yyyymmddhhmmss) a un string con formato sql-datetime (yyyy-mm-dd hh:mm:ss).
664
695
  def self.datetime_api_to_sql(s)
665
696
  raise "Wrong Api DataTime Format." if (datetime_api_check(s)==false)
666
697
  year = s[0..3]
667
698
  month = s[4..5]
668
- day = s[6..7]
669
- hour = s[8..9]
670
- minute = s[10..11]
671
- second = s[12..13]
672
- ret = "#{year}-#{month}-#{day} #{hour}:#{minute}:#{second}"
699
+ day = s[6..7]
700
+ hour = s[8..9]
701
+ minute = s[10..11]
702
+ second = s[12..13]
703
+ ret = "#{year}-#{month}-#{day} #{hour}:#{minute}:#{second}"
673
704
  return ret
674
- end # def datetime_api_to_sql
675
-
705
+ end # def datetime_api_to_sql
706
+
676
707
  # Convierte un string con formato sql-datatime a un string con formato sql-datetime.
677
708
  def self.datetime_sql_to_api(s)
678
709
  raise "Wrong SQL DataTime Format." if (datetime_sql_check(s)==false)
679
710
  year = s[0..3]
680
711
  month = s[5..6]
681
- day = s[8..9]
682
- hour = s[11..12]
683
- minute = s[14..15]
684
- second = s[17..18]
685
- ret = "#{year}#{month}#{day}#{hour}#{minute}#{second}"
712
+ day = s[8..9]
713
+ hour = s[11..12]
714
+ minute = s[14..15]
715
+ second = s[17..18]
716
+ ret = "#{year}#{month}#{day}#{hour}#{minute}#{second}"
686
717
  return ret
687
718
  end # def datetime_sql_to_api
688
719
  end # module DateTime
689
720
 
690
721
 
691
- # -----------------------------------------------------------------------------------------
722
+ # -----------------------------------------------------------------------------------------
692
723
  # Spinning
693
- # -----------------------------------------------------------------------------------------
724
+ # -----------------------------------------------------------------------------------------
694
725
  module Spinning
695
726
  # Esta funcion retorna una variacion al azar del texto que se pasa.
696
727
  # Esta funcion se ocupa de dividir el texto en partes, para eviar el error "too big to product" que arroja la libraría.
697
728
  def self.random_spinning_variation(text)
698
729
  ret = text
699
-
730
+
700
731
  text.scan(MATCH_CONTENT_SPINNING).each { |s|
701
732
  a = ContentSpinning.new(s).spin
702
733
  rep = a[rand(a.size)]
703
734
  ret = ret.gsub(s, rep)
704
735
  a = nil
705
736
  }
706
-
737
+
707
738
  return ret
708
739
  end
709
-
740
+
710
741
  # retorna true si la sintaxis del texto spineado es correcta
711
742
  # caso contrario retorna false
712
743
  # no soporta spinnings anidados. ejemplo: {my|our|{a car of mine}}
@@ -714,16 +745,16 @@ module BlackStack
714
745
  # valido que exste
715
746
  n = 0
716
747
  s.split('').each { |c|
717
- n+=1 if c=='{'
748
+ n+=1 if c=='{'
718
749
  n-=1 if c=='}'
719
750
  if n!=0 && n!=1
720
751
  #raise "Closing spining char '}' with not previous opening spining char '{'." if n<0
721
752
  #raise "Opening spining char '{' inside another spining block." if n>1
722
753
  return false if n<0 # Closing spining char '}' with not previous opening spining char '{'.
723
754
  return false if n>1 # Opening spining char '{' inside another spining block.
724
- end
755
+ end
725
756
  }
726
-
757
+
727
758
  return false if n!=0
728
759
  =begin
729
760
  # obtengo cada uno de los spinnings
@@ -731,21 +762,21 @@ module BlackStack
731
762
  a = x.split('|')
732
763
  raise "No variations delimited by '|' inside spinning block." if a.size <= 1
733
764
  }
734
- =end
765
+ =end
735
766
  true
736
767
  end
737
-
768
+
738
769
  # returns true if the text is spinned.
739
770
  # otherwise, returns false.
740
771
  def self.spintax?(s)
741
772
  s.scan(MATCH_CONTENT_SPINNING).size > 0
742
773
  end
743
774
  end # module Spinning
744
-
745
-
746
- # -----------------------------------------------------------------------------------------
775
+
776
+
777
+ # -----------------------------------------------------------------------------------------
747
778
  # Miscelaneus
748
- # -----------------------------------------------------------------------------------------
779
+ # -----------------------------------------------------------------------------------------
749
780
  module Misc
750
781
  # make a Ruby string safe for a filesystem.
751
782
  # References:
@@ -756,7 +787,7 @@ module BlackStack
756
787
  # NOTE: File.basename doesn't work right with Windows paths on Unix
757
788
  # get only the filename, not the whole path
758
789
  name.gsub!(/^.*(\\|\/)/, '')
759
-
790
+
760
791
  # Strip out the non-ascii character
761
792
  name.gsub!(/[^0-9A-Za-z.\-]/, '_')
762
793
  end
@@ -765,9 +796,9 @@ module BlackStack
765
796
  end # module Misc
766
797
 
767
798
 
768
- # -----------------------------------------------------------------------------------------
799
+ # -----------------------------------------------------------------------------------------
769
800
  # Email Appending Functions
770
- # -----------------------------------------------------------------------------------------
801
+ # -----------------------------------------------------------------------------------------
771
802
  module Appending
772
803
  APPEND_PATTERN_FNAME_DOT_LNAME = 0
773
804
  APPEND_PATTERN_FNAME = 1
@@ -775,7 +806,7 @@ module BlackStack
775
806
  APPEND_PATTERN_F_LNAME = 3
776
807
  APPEND_PATTERN_F_DOT_LNAME = 4
777
808
 
778
- #
809
+ #
779
810
  def self.name_pattern(pattern, fname, lname)
780
811
  if (pattern==APPEND_PATTERN_FNAME_DOT_LNAME)
781
812
  return "#{fname}.#{lname}"
@@ -792,13 +823,13 @@ module BlackStack
792
823
  end
793
824
  end
794
825
 
795
- #
826
+ #
796
827
  def self.get_email_variations(first_name, last_name, domain, is_a_big_company)
797
828
  variations = Array.new
798
829
  variations << first_name + "." + last_name + "@" + domain
799
830
  variations << first_name[0] + last_name + "@" + domain
800
831
  variations << first_name + "_" + last_name + "@" + domain
801
- variations << first_name[0] + "." + last_name + "@" + domain
832
+ variations << first_name[0] + "." + last_name + "@" + domain
802
833
  if (is_a_big_company == false)
803
834
  variations << last_name + "@" + domain
804
835
  variations << first_name + "@" + domain
@@ -821,20 +852,20 @@ module BlackStack
821
852
  end
822
853
  end # module Appending
823
854
  end # module String
824
-
825
- # -----------------------------------------------------------------------------------------
855
+
856
+ # -----------------------------------------------------------------------------------------
826
857
  # Network
827
- # -----------------------------------------------------------------------------------------
858
+ # -----------------------------------------------------------------------------------------
828
859
  module Netting
829
860
  CALL_METHOD_GET = 'get'
830
861
  CALL_METHOD_POST = 'post'
831
862
  DEFAULT_SSL_VERIFY_MODE = OpenSSL::SSL::VERIFY_NONE
832
863
  SUCCESS = 'success'
833
-
834
- @@lockfiles = []
864
+
865
+ @@lockfiles = []
835
866
 
836
867
  @@max_api_call_channels = 0 # 0 means infinite
837
-
868
+
838
869
  def self.max_api_call_channels()
839
870
  @@max_api_call_channels
840
871
  end
@@ -846,7 +877,7 @@ module BlackStack
846
877
  def self.set(h)
847
878
  @@max_api_call_channels = h[:max_api_call_channels]
848
879
  @@lockfiles = []
849
-
880
+
850
881
  i = 0
851
882
  while i<@@max_api_call_channels
852
883
  @@lockfiles << File.open("./apicall.channel_#{i.to_s}.lock", "w")
@@ -857,18 +888,18 @@ module BlackStack
857
888
 
858
889
  class ApiCallException < StandardError
859
890
  attr_accessor :description
860
-
891
+
861
892
  def initialize(s)
862
893
  self.description = s
863
894
  end
864
-
895
+
865
896
  def to_s
866
897
  self.description
867
898
  end
868
899
  end
869
-
900
+
870
901
  # New call_get
871
- def self.call_get(url, params = {}, ssl_verify_mode=BlackStack::Netting::DEFAULT_SSL_VERIFY_MODE, support_redirections=true)
902
+ def self.call_get(url, params = {}, ssl_verify_mode=BlackStack::Netting::DEFAULT_SSL_VERIFY_MODE, support_redirections=true)
872
903
  uri = URI(url)
873
904
  uri.query = URI.encode_www_form(params)
874
905
  Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https', :verify_mode => ssl_verify_mode) do |http|
@@ -883,7 +914,7 @@ module BlackStack
883
914
  end
884
915
  end
885
916
  end
886
-
917
+
887
918
  # Call the API and return th result.
888
919
  #
889
920
  # Unlike `Net::HTTP::Post`, this method support complex json descriptors in order to submit complex data strucutres to access points.
@@ -891,25 +922,25 @@ module BlackStack
891
922
  #
892
923
  # url: valid internet address
893
924
  # body: hash of body to attach in the call
894
- # ssl_verify_mode: you can disabele SSL verification here.
925
+ # ssl_verify_mode: you can disabele SSL verification here.
895
926
  # max_channels: this method use lockfiles to prevent an excesive number of API calls from each datacenter. There is not allowed more simultaneous calls than max_channels.
896
- #
927
+ #
897
928
  # TODO: parameter support_redirections has been deprecated.
898
929
  #
899
930
  def self.call_post(url, body = {}, ssl_verify_mode=BlackStack::Netting::DEFAULT_SSL_VERIFY_MODE, support_redirections=true)
900
- # issue: https://github.com/leandrosardi/mysaas/issues/59
931
+ # issue: https://github.com/leandrosardi/mysaas/issues/59
901
932
  #
902
933
  # when ruby pushes hash of hashes (or hash of arrays), all values are converted into strings.
903
934
  # and arrays are mapped to the last element only.
904
935
  #
905
936
  # the solution is to convert each element of the hash into a string using `.to_json` method.
906
- #
907
- # references:
937
+ #
938
+ # references:
908
939
  # - https://stackoverflow.com/questions/1667630/how-do-i-convert-a-string-object-into-a-hash-object
909
940
  # - https://stackoverflow.com/questions/67572866/how-to-build-complex-json-to-post-to-a-web-service-with-rails-5-2-and-faraday-ge
910
- #
941
+ #
911
942
  # iterate the keys of the hash
912
- #
943
+ #
913
944
  params = {} # not needed for post calls to access points
914
945
  path = URI::parse(url).path
915
946
  domain = url.gsub(/#{Regexp.escape(path)}/, '')
@@ -939,7 +970,7 @@ module BlackStack
939
970
  if (parsed['status']==BlackStack::Netting::SUCCESS)
940
971
  bSuccess = true
941
972
  else
942
- sError = "Status: #{parsed['status'].to_s}. Description: #{parsed['value'].to_s}."
973
+ sError = "Status: #{parsed['status'].to_s}. Description: #{parsed['value'].to_s}."
943
974
  end
944
975
  rescue Errno::ECONNREFUSED => e
945
976
  sError = "Errno::ECONNREFUSED:" + e.to_console
@@ -947,7 +978,7 @@ module BlackStack
947
978
  sError = "Exception:" + e2.to_console
948
979
  end
949
980
  end # while
950
-
981
+
951
982
  if (bSuccess==false)
952
983
  raise "#{sError}"
953
984
  end
@@ -958,7 +989,7 @@ module BlackStack
958
989
  # to: must be a valid path to a folder.
959
990
  def self.download(url, to)
960
991
  uri = URI(url)
961
- domain = uri.host.start_with?('www.') ? uri.host[4..-1] : uri.host
992
+ domain = uri.host.start_with?('www.') ? uri.host[4..-1] : uri.host
962
993
  path = uri.path
963
994
  filename = path.split("/").last
964
995
  Net::HTTP.start(domain) do |http|
@@ -970,7 +1001,7 @@ module BlackStack
970
1001
  end
971
1002
 
972
1003
  # Return the extension of the last path into an URL.
973
- # Example: get_url_extension("http://connect.data.com/sitemap_index.xml?foo_param=foo_value") => ".xml"
1004
+ # Example: get_url_extension("http://connect.data.com/sitemap_index.xml?foo_param=foo_value") => ".xml"
974
1005
  def self.get_url_extension(url)
975
1006
  return File.extname(URI.parse(url).path.to_s)
976
1007
  end
@@ -1011,12 +1042,12 @@ module BlackStack
1011
1042
  httpc = HTTPClient.new
1012
1043
  resp = httpc.get(url)
1013
1044
  res = resp.header['Location']
1014
-
1045
+
1015
1046
  if res.size == 0
1016
1047
  uri = URI.parse(url)
1017
1048
  uri_params = CGI.parse(uri.query)
1018
- redirected_url = uri_params['url'][0]
1019
-
1049
+ redirected_url = uri_params['url'][0]
1050
+
1020
1051
  if ( redirected_url != nil )
1021
1052
  res = redirected_url
1022
1053
  else
@@ -1040,25 +1071,25 @@ module BlackStack
1040
1071
  # => p = CGI::parse(URI.parse(url).query)
1041
1072
  # => La linea de abajo hace un gsbub que hace que esta url siga funcionando como busqueda de google, y ademas se posible parsearla.
1042
1073
  url = url.gsub("webhp#q=", "webhp?q=")
1043
-
1074
+
1044
1075
  return CGI::parse(URI.parse(url).query)
1045
1076
  end
1046
-
1077
+
1047
1078
  # Add a parameter to the url. It doesn't validate if the param already exists.
1048
1079
  def self.add_param(url, param_name, param_value)
1049
1080
  uri = URI(url)
1050
1081
  params = URI.decode_www_form(uri.query || '')
1051
-
1082
+
1052
1083
  if (params.size==0)
1053
1084
  params << [param_name, param_value]
1054
1085
  uri.query = URI.encode_www_form(params)
1055
1086
  return uri.to_s
1056
1087
  else
1057
1088
  uri.query = URI.encode_www_form(params)
1058
- return uri.to_s + "&" + param_name + "=" + param_value
1089
+ return uri.to_s + "&" + param_name + "=" + param_value
1059
1090
  end
1060
1091
  end
1061
-
1092
+
1062
1093
  # Changes the value of a parameter in the url. It doesn't validate if the param already exists.
1063
1094
  def self.change_param(url, param_name, param_value)
1064
1095
  uri = URI(url)
@@ -1068,10 +1099,10 @@ module BlackStack
1068
1099
  uri.query = URI.encode_www_form(params)
1069
1100
  uri.to_s
1070
1101
  end
1071
-
1102
+
1072
1103
  # Change or add the value of a parameter in the url, depending if the parameter already exists or not.
1073
1104
  def self.set_param(url, param_name, param_value)
1074
- params = BlackStack::Netting::params(url)
1105
+ params = BlackStack::Netting::params(url)
1075
1106
  if ( params.has_key?(param_name) == true )
1076
1107
  newurl = BlackStack::Netting::change_param(url, param_name, param_value)
1077
1108
  else
@@ -1079,24 +1110,24 @@ module BlackStack
1079
1110
  end
1080
1111
  return newurl
1081
1112
  end
1082
-
1113
+
1083
1114
  # get the domain from any url
1084
1115
  def self.getDomainFromUrl(url)
1085
- if (url !~ /^http:\/\//i && url !~ /^https:\/\//i)
1116
+ if (url !~ /^http:\/\//i && url !~ /^https:\/\//i)
1086
1117
  url = "http://#{url}"
1087
1118
  end
1088
-
1119
+
1089
1120
  if (URI.parse(url).host == nil)
1090
- raise "Cannot get domain for #{url}"
1121
+ raise "Cannot get domain for #{url}"
1091
1122
  end
1092
-
1123
+
1093
1124
  if (url.to_s.length>0)
1094
1125
  return URI.parse(url).host.sub(/^www\./, '')
1095
1126
  else
1096
1127
  return nil
1097
1128
  end
1098
1129
  end
1099
-
1130
+
1100
1131
  def self.getDomainFromEmail(email)
1101
1132
  if email.email?
1102
1133
  return email.split("@").last
@@ -1104,35 +1135,35 @@ module BlackStack
1104
1135
  raise "getDomainFromEmail: Wrong email format."
1105
1136
  end
1106
1137
  end
1107
-
1138
+
1108
1139
  def self.getWhoisDomains(domain, allow_heuristic_to_avoid_hosting_companies=false)
1109
1140
  a = Array.new
1110
1141
  c = Whois::Client.new
1111
1142
  r = c.lookup(domain)
1112
-
1143
+
1113
1144
  res = r.to_s.scan(/Registrant Email: (#{BlackStack::Strings::MATCH_EMAIL})/).first
1114
1145
  if (res!=nil)
1115
1146
  a << BlackStack::Netting::getDomainFromEmail(res[0].downcase)
1116
1147
  end
1117
-
1148
+
1118
1149
  res = r.to_s.scan(/Admin Email: (#{BlackStack::Strings::MATCH_EMAIL})/).first
1119
1150
  if (res!=nil)
1120
1151
  a << BlackStack::Netting::getDomainFromEmail(res[0].downcase)
1121
1152
  end
1122
-
1153
+
1123
1154
  res = r.to_s.scan(/Tech Email: (#{BlackStack::Strings::MATCH_EMAIL})/).first
1124
1155
  if (res!=nil)
1125
1156
  a << BlackStack::Netting::getDomainFromEmail(res[0].downcase)
1126
1157
  end
1127
-
1158
+
1128
1159
  # remover duplicados
1129
1160
  a = a.uniq
1130
-
1131
- #
1161
+
1162
+ #
1132
1163
  if (allow_heuristic_to_avoid_hosting_companies==true)
1133
1164
  # TODO: develop this feature
1134
1165
  end
1135
-
1166
+
1136
1167
  return a
1137
1168
  end
1138
1169
 
@@ -1160,11 +1191,11 @@ module BlackStack
1160
1191
  raise "Email #{value} is not valid" if !value.email?
1161
1192
  # extract the domain from the email
1162
1193
  domain = value.split('@').last
1163
- #
1194
+ #
1164
1195
  return domain=~/gmail\.com/ || domain=~/hotmail\.com/ || domain=~/outlook\.com/ || domain=~/yahoo\.com/ || domain=~/comcast\.com/ || domain=~/aol\.com/ || domain=~/msn\.com/ || domain=~/sbcglobal\.net/ ? true : false
1165
1196
  end
1166
1197
 
1167
1198
 
1168
1199
  end # module Netting
1169
-
1200
+
1170
1201
  end # module BlackStack
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blackstack-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.28
4
+ version: 1.2.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leandro Daniel Sardi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-06 00:00:00.000000000 Z
11
+ date: 2025-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: content_spinning