eco-helpers 1.0.11 → 1.0.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b3d434c6d214ef71d15aa9c2d334b9e5545c057f8fd9cb702f27080ad7b96a57
4
- data.tar.gz: 35d9e89911c0aee5f0550eaabcaa6aecdcfd5a6bf97f6d8a53db416fcc957535
3
+ metadata.gz: b7816ce8532e8e6f2214b58e5fa94ecb65ec9bd86cc4efa0691001fec78cfb7e
4
+ data.tar.gz: '0539d3a69ced5ad94f0245e2ccc768818534344b46c6d455af358c5e84ababfd'
5
5
  SHA512:
6
- metadata.gz: 24eb7ad2d08a96c2a171e1b5bd41d988f561bbafc764f91df3152a36dec887c456600356fab112d7b95f476eccd742f187a9f3adca19fc05464a85cf34e95a74
7
- data.tar.gz: 05a8af94fcf4e966868c447d0e907424c9e615ad942126fc50e6ed53abb7025098edbaea922c060b2e87cadde1e0296dc54f51ed6d71a1198fece5e1753c0766
6
+ metadata.gz: 965d612b80244b63cfae420eaa97a28ec2935d1299dfaec5d9220a4de732442904ea6995e0536f559ab49bb6a52af0d71fee7d1a69209c0a1d92c6317f24c811
7
+ data.tar.gz: a0ea67d65af9e01a36395da5585b1226ea4bcf70a0b71f7ab0718fd4ae9e31cb2d4cf50f95dec1c5267fd338d1816ed2985a1a1bf2f55265d69339f895531aee
@@ -32,6 +32,8 @@ Gem::Specification.new do |s|
32
32
  s.add_dependency 'aws-sdk-s3', '~> 1.30', '>= 1.30.1'
33
33
  s.add_dependency 'aws-sdk-ses', '~> 1.14', '>= 1.14.0'
34
34
  s.add_dependency 'dotenv', '~> 2.6', '>= 2.6.0'
35
+ s.add_dependency 'net-sftp', '~> 2.1', '>= 2.1.2'
35
36
  s.add_dependency 'faker', '~> 2', '>= 2.1'
36
37
  s.add_dependency 'distribution', '~> 0.7', '>= 0.7.3'
38
+
37
39
  end
@@ -2,6 +2,8 @@ module Eco
2
2
  module API
3
3
  module Common
4
4
  module People
5
+
6
+ # Class to define a set of default attribute parsers
5
7
  class DefaultParsers < PersonParser
6
8
 
7
9
  def initialize(*args)
@@ -11,7 +11,8 @@ module Eco
11
11
  arr_hash = []
12
12
  CSV.parse(data, headers: true).each do |row|
13
13
  row_hash = row.headers.uniq.each_with_object({}) do |attr, hash|
14
- hash[attr] = row[attr]
14
+ value = row[attr]
15
+ hash[attr] = value.to_s.empty?? nil : value
15
16
  end
16
17
  arr_hash.push(row_hash)
17
18
  end
@@ -27,6 +27,8 @@ module Eco
27
27
  attr('external_id', *args).first
28
28
  end
29
29
 
30
+ # Helper to dump the entries into a CSV
31
+ # @param filename [String] the destination file
30
32
  def export(filename)
31
33
  CSV.open(filename, "w") do |csv|
32
34
  entry = self.first
@@ -38,6 +40,7 @@ module Eco
38
40
  end
39
41
  end
40
42
 
43
+ # Search function to find an `entry` based on one of different options
41
44
  def entry(id: nil, external_id: nil, email: nil)
42
45
  init_caches
43
46
  pers = nil
@@ -48,6 +51,8 @@ module Eco
48
51
  pers
49
52
  end
50
53
 
54
+ # Search function to find an `entry` based on one of different options
55
+ # see Eco::API::Common::People::Entries#entry
51
56
  def find(object)
52
57
  id = object.respond_to?("id")? object.send("id") : nil
53
58
  external_id = object.respond_to?("external_id")? object.send("external_id") : nil
@@ -21,13 +21,17 @@ module Eco
21
21
 
22
22
  @source_person_parser = person_parser
23
23
 
24
+ # load default parsers
24
25
  @person_parser = Eco::API::Common::People::DefaultParsers.new(schema: @schema)
26
+ # merge the custom parsers
25
27
  @person_parser = @person_parser.merge(@source_person_parser)
26
28
  @person_parser_patch_version = @source_person_parser.patch_version
27
29
 
28
30
  @attr_map = attr_map
29
31
  end
30
32
 
33
+ # provides with a Eco::API::Common::People::PersonParser object (collection of attribute parsers)
34
+ # @note if the custom person parser has changed, it updates the copy of this EntryFactory instance
31
35
  def person_parser
32
36
  if @person_parser_patch_version < @source_person_parser.patch_version
33
37
  @person_parser.merge(@source_person_parser)
@@ -9,6 +9,7 @@ end
9
9
 
10
10
  require_relative 'session/logger'
11
11
  require_relative 'session/mailer'
12
+ require_relative 'session/sftp'
12
13
  require_relative 'session/s3_uploader'
13
14
  require_relative 'session/file_manager'
14
15
  require_relative 'session/environment'
@@ -40,6 +40,18 @@ module Eco
40
40
  enviro.file_manager
41
41
  end
42
42
 
43
+ def mailer
44
+ enviro.mailer
45
+ end
46
+
47
+ def sftp
48
+ enviro.sftp
49
+ end
50
+
51
+ def s3uploader
52
+ enviro.s3uploader
53
+ end
54
+
43
55
  def logger
44
56
  enviro.logger
45
57
  end
@@ -9,7 +9,7 @@ module Eco
9
9
  attr_reader :config, :session
10
10
  attr_reader :api #, :host, :version
11
11
  attr_reader :file_manager, :logger
12
- attr_reader :mailer, :s3uploader
12
+ attr_reader :mailer, :sftp, :s3uploader
13
13
 
14
14
  alias_method :fm, :file_manager
15
15
 
@@ -31,6 +31,10 @@ module Eco
31
31
  @mailer ||= Eco::API::Common::Session::Mailer.new(enviro: self)
32
32
  end
33
33
 
34
+ def sftp
35
+ @sftp ||= Eco::API::Common::Session::SFTP.new(enviro: self)
36
+ end
37
+
34
38
  def s3upoader
35
39
  @s3uploader ||= Eco::API::Common::Session::S3Uploader.new(enviro: self)
36
40
  end
@@ -0,0 +1,108 @@
1
+ require "net/sftp"
2
+ require 'dotenv/load'
3
+
4
+ module Eco
5
+ module API
6
+ module Common
7
+ module Session
8
+ class SFTP
9
+
10
+ def initialize (enviro:)
11
+ raise "Required Environment object (enviro:). Given: #{enviro}" if enviro && !enviro.is_a?(Eco::API::Common::Session::Environment)
12
+ @enviro = enviro
13
+ end
14
+
15
+ # @see Net::SFTP::Session
16
+ def sftp_session
17
+ begin
18
+ @sftp_session ||= Net::SFTP.start(
19
+ fetch_host,
20
+ fetch_user,
21
+ keys: fetch_key_files,
22
+ keys_only: true,
23
+ non_interactive: true
24
+ )
25
+ rescue Exception => e
26
+ logger.error("Could not open SFTP session. Possible misconfiguration: #{e}")
27
+ exit(1)
28
+ end
29
+ @sftp_session
30
+ end
31
+
32
+ # @see Net::SFTP::Operations::Dir#entries
33
+ def entries(path)
34
+ sftp_session.dir.entries(path).sort_by {|rf| rf.name}
35
+ end
36
+
37
+ # **Files** of the remote directory.
38
+ # @see Net::SFTP::Operations::Dir#entries
39
+ # @param path [String] remote directory `path`
40
+ # @param pattern [Regexp] if given, filters by using this pattern
41
+ # @return [Array<Net::SFTP::Protocol::V01::Name>]
42
+ def files(path, pattern: nil)
43
+ entries = entries(path).select {|remote_file| remote_file.file?}
44
+ return entries unless pattern
45
+ entries.select {|remote_file| remote_file.name =~ pattern}
46
+ end
47
+
48
+ # **Folders** of the remote directory.
49
+ # @see Net::SFTP::Operations::Dir#entries
50
+ # @param path [String] remote directory `path`
51
+ # @param pattern [Regexp] if given, filters by using this pattern
52
+ # @return [Array<Net::SFTP::Protocol::V01::Name>]
53
+ def folders(path, pattern: nil)
54
+ entries = entries(path).select {|remote_file| remote_file.directory?}
55
+ return entries unless pattern
56
+ entries.select {|remote_file| remote_file.name =~ pattern}
57
+ end
58
+
59
+ # @see Net::SFTP::Session#rename
60
+ def move(fullname_source, fullname_dest, flags=nil, &callback)
61
+ sftp_session.rename!(fullname_source, fullname_dest, flags, &callback)
62
+ end
63
+
64
+ # Downloads the files specified to a local folder
65
+ # @see Net::SFTP::Operations::Download
66
+ # @param files [String, Array<String>] full path to remote file(s) to be downloaded
67
+ # @param local_folder [String] local destination folder (`"."` if not specified)
68
+ def download(files, local_folder: nil)
69
+ [files].flatten.compact.map do |fullname|
70
+ dest_fullname = File.join(local_folder || ".", File.basename(fullname))
71
+ sftp_session.download(fullname, dest_fullname)
72
+ end.each do |dw|
73
+ # run SSH event loop while dw.active?
74
+ dw.wait
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def logger
81
+ @enviro&.logger || ::Logger.new(IO::NULL)
82
+ end
83
+
84
+ def config
85
+ @enviro.config || {}
86
+ end
87
+
88
+ def fetch_host
89
+ config.sftp.host || ENV['SFTP_HOST']
90
+ end
91
+
92
+ def fetch_user
93
+ config.sftp.user || ENV['SFTP_USERNAME']
94
+ end
95
+
96
+ def fetch_key_files
97
+ [config.sftp.key_file || ENV['SFTP_KEY_FILE']]
98
+ end
99
+
100
+ def fetch_base_path
101
+ config.sftp.base_path || ENV['SFTP_BASE_PATH']
102
+ end
103
+
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -42,7 +42,7 @@ module Eco
42
42
  def mail_to(**kargs)
43
43
  mail.mail(**kargs)
44
44
  end
45
-
45
+
46
46
  def s3upload(content: nil, file: nil, directory: nil)
47
47
  if content && file
48
48
  s3uploader.upload(file, content)
@@ -28,6 +28,10 @@ module Eco
28
28
  self["apis"] ||= Eco::API::Session::Config::Apis.new(config: self)
29
29
  end
30
30
 
31
+ def sftp
32
+ self["sftp"] ||= Eco::API::Session::Config::SFTP.new(config: self)
33
+ end
34
+
31
35
  def logger
32
36
  self["logger"] ||= Eco::API::Session::Config::Logger.new(config: self)
33
37
  end
@@ -108,6 +112,10 @@ module Eco
108
112
  self
109
113
  end
110
114
 
115
+ def active_enviro
116
+ apis.active_root_name
117
+ end
118
+
111
119
  def api(logger = ::Logger.new(IO::NULL))
112
120
  apis.api(logger)
113
121
  end
@@ -294,6 +302,7 @@ require_relative 'config/api'
294
302
  require_relative 'config/apis'
295
303
  require_relative 'config/logger'
296
304
  require_relative 'config/mailer'
305
+ require_relative 'config/sftp'
297
306
  require_relative 'config/s3_storage'
298
307
  require_relative 'config/files'
299
308
  require_relative 'config/people'
@@ -0,0 +1,59 @@
1
+ module Eco
2
+ module API
3
+ class Session
4
+ class Config
5
+ class SFTP < BaseConfig
6
+
7
+ def host=(value)
8
+ self["host"] = value
9
+ end
10
+
11
+ def host
12
+ self["host"]
13
+ end
14
+
15
+ def user=(value)
16
+ self["user"] = value
17
+ end
18
+
19
+ def user
20
+ self["user"]
21
+ end
22
+
23
+ def key_file=(key)
24
+ self["key_file"] = key
25
+ end
26
+
27
+ def key_file
28
+ self["key_file"]
29
+ end
30
+
31
+ def base_path=(path)
32
+ self["base_path"] = path
33
+ end
34
+
35
+ def base_path
36
+ self["base_path"]
37
+ end
38
+
39
+ def enviro_subpaths=(hash)
40
+ self["enviro_subpaths"] = hash
41
+ end
42
+
43
+ def enviro_subpaths
44
+ self["enviro_subpaths"]
45
+ end
46
+
47
+ def enviro_subpath
48
+ enviro_subpaths[config.active_enviro]
49
+ end
50
+
51
+ def remote_folder
52
+ base_path + "/" + enviro_subpath
53
+ end
54
+
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,6 +1,7 @@
1
1
  module Eco
2
2
  module API
3
3
  class UseCases
4
+ # Core class of UseCases. It basically defines and manages allowed `types`
4
5
  class BaseCase
5
6
 
6
7
  class InvalidType < Exception
@@ -11,7 +12,7 @@ module Eco
11
12
  end
12
13
  end
13
14
 
14
- @types = [:import, :filter, :transform, :sync, :export]
15
+ @types = [:import, :filter, :transform, :sync, :export, :other]
15
16
 
16
17
  class << self
17
18
  attr_reader :types
@@ -1,8 +1,9 @@
1
1
  module Eco
2
2
  module API
3
3
  class UseCases
4
+ # Basic class to manage InputOuput for usecases
4
5
  class BaseIO < BaseCase
5
- @types = [:import, :filter, :transform, :sync, :export]
6
+ @types = BaseCase.types
6
7
 
7
8
  class << self
8
9
  def input_required?(type)
@@ -2,7 +2,7 @@ module Eco
2
2
  module API
3
3
  class UseCases
4
4
  class UseCase < BaseCase
5
- @types = [:import, :filter, :transform, :sync, :export]
5
+ @types = BaseCase.types
6
6
 
7
7
  attr_reader :name, :type, :times_launched
8
8
  attr_reader :options
@@ -1,12 +1,13 @@
1
1
  module Eco
2
2
  module API
3
3
  class UseCases
4
+ # Class that enables to chain multiple UseCase
4
5
  class UseCaseChain < UseCase
6
+ @types = UseCase.types
7
+
5
8
  MAX_CHAINS = 70
6
9
  @@num_chains = 0
7
10
 
8
- @types = [:import, :filter, :transform, :sync, :export]
9
-
10
11
  def initialize(name = nil, type: nil, root:, usecase: nil, &block)
11
12
  if usecase
12
13
  raise "Expected Eco::API::UseCases::UseCase. Given #{usecase.class}" if !usecase.is_a?(Eco::API::UseCases::UseCase)
@@ -1,28 +1,38 @@
1
1
  module Eco
2
2
  module API
3
3
  class UseCases
4
+
5
+ # InputOutput class for usecases.
6
+ # @note Same as Eco::API::UseCases::BaseIO but:
7
+ # - includes `type` of usecase
8
+ # - provides a helper to `chain` InputOutput between usecases
9
+ # @attr_reader usecase [Eco::API::UseCases::UseCase] the usecase this InputOuput is linked to
4
10
  class UseCaseIO < BaseIO
5
- @types = [:import, :filter, :transform, :sync, :export]
11
+ @types = BaseIO.types
6
12
 
7
13
  attr_reader :usecase
8
14
 
15
+ # @see Eco::API::UseCases::BaseIO#initialize
9
16
  def initialize(usecase:, **kargs)
10
17
  self.usecase = usecase
11
18
  super(**kargs)
12
19
  end
13
20
 
14
- # @see Eco::API::UseCases::BaseIO
21
+ # @see Eco::API::UseCases::BaseIO#new
15
22
  # @param usecase [Eco::API::UseCases::UseCase] target usecase
16
23
  # @return [Eco::API::UseCases::UseCaseIO]
17
24
  def new(usecase:, **kargs)
18
25
  super(**kargs.merge(usecase: usecase))
19
26
  end
20
27
 
28
+
29
+ # @param value [Eco::API::UseCases::UseCase] the usecase this InputOuput should be linked to
21
30
  def usecase=(value)
22
31
  raise "It should be a Eco::API::UseCases::UseCase. Given: #{value}" if !value.is_a?(Eco::API::UseCases::UseCase)
23
32
  @usecase = value
24
33
  end
25
34
 
35
+ # @return [Symbol] the `type` of the UseCase this InputOuput is linked to
26
36
  def type
27
37
  @usecase.type
28
38
  end
@@ -31,6 +41,8 @@ module Eco
31
41
  raise "Can't modify type depends on the usecase linked to this IO object"
32
42
  end
33
43
 
44
+ # @see Eco::API::UseCases::BaseIO#params
45
+ # Same as its superclass but adding `usecase` parameter
34
46
  def params(keyed: false)
35
47
  super(keyed: keyed).tap do |res|
36
48
  if keyed
@@ -6,6 +6,8 @@ ASSETS.cli.config do |cnf|
6
6
  get: {from: :remote, type: :full}
7
7
  })
8
8
  people = session.do.file_people
9
+ elsif SCR.get_arg("-no-people")
10
+ people = Eco::API::Organization::People.new([])
9
11
  elsif SCR.get_arg("-people-from-backup")
10
12
  file = SCR.get_arg("-people-from-backup", with_param: true)
11
13
  options.deep_merge!(people: {
@@ -1,3 +1,3 @@
1
1
  module Eco
2
- VERSION = "1.0.11"
2
+ VERSION = "1.0.12"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eco-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.11
4
+ version: 1.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oscar Segura
@@ -178,6 +178,26 @@ dependencies:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
180
  version: '2.6'
181
+ - !ruby/object:Gem::Dependency
182
+ name: net-sftp
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '2.1'
188
+ - - ">="
189
+ - !ruby/object:Gem::Version
190
+ version: 2.1.2
191
+ type: :runtime
192
+ prerelease: false
193
+ version_requirements: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - "~>"
196
+ - !ruby/object:Gem::Version
197
+ version: '2.1'
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: 2.1.2
181
201
  - !ruby/object:Gem::Dependency
182
202
  name: faker
183
203
  requirement: !ruby/object:Gem::Requirement
@@ -261,6 +281,7 @@ files:
261
281
  - lib/eco/api/common/session/logger.rb
262
282
  - lib/eco/api/common/session/mailer.rb
263
283
  - lib/eco/api/common/session/s3_uploader.rb
284
+ - lib/eco/api/common/session/sftp.rb
264
285
  - lib/eco/api/common/version_patches.rb
265
286
  - lib/eco/api/common/version_patches/ecoportal_api.rb
266
287
  - lib/eco/api/common/version_patches/ecoportal_api/account_preferences.rb
@@ -302,6 +323,7 @@ files:
302
323
  - lib/eco/api/session/config/people.rb
303
324
  - lib/eco/api/session/config/post_launch.rb
304
325
  - lib/eco/api/session/config/s3_storage.rb
326
+ - lib/eco/api/session/config/sftp.rb
305
327
  - lib/eco/api/session/config/workflow.rb
306
328
  - lib/eco/api/session/task.rb
307
329
  - lib/eco/api/usecases.rb