eac_rails_remotes 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ad2ac8698baa47735671800fe9a737b2c0fe5330e73964dd4156acceae7c2019
4
+ data.tar.gz: e3e71fc55d8a5f2cb6b28aa2ac44643ae29d15550bc4778c00341873bbb7ec10
5
+ SHA512:
6
+ metadata.gz: 69fdf3ebfa1841ca012def980872fad6e83e7efde4a5d9793890e1836fd6f63145c0b3c4a88a3cea5076e21a23dcabf21a3fcf1333766ba82482e2159670acf0
7
+ data.tar.gz: ce03870632e332c6366f5b33e8eb296d066af6f871033c5a204dea29362a08ddfb2a57e336b9a387711ec1707ac7c138b91ffc209c6e1e918aa138a446cfa17f
@@ -0,0 +1,2 @@
1
+ //= require_tree .
2
+ //= require eac_active_scaffold
@@ -0,0 +1 @@
1
+ @import 'eac_active_scaffold';
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRailsRemotes
4
+ class InstancesController < ApplicationController
5
+ before_action :localize_options
6
+
7
+ active_scaffold :'eac_rails_remotes/instance' do |conf|
8
+ conf.actions.exclude :create, :update
9
+ conf.columns[:export_status].form_ui = :select
10
+ conf.columns[:entity].form_ui = :select
11
+ conf.actions.swap :search, :field_search
12
+ conf.field_search.columns = :entity, :export_status
13
+ end
14
+
15
+ private
16
+
17
+ def localize_options
18
+ active_scaffold_config.columns[:export_status].options = {
19
+ options: ::EacRailsRemotes::Instance.lists.export_status.options
20
+ }
21
+ active_scaffold_config.columns[:entity].options = {
22
+ options: ::EacRailsRemotes::Instance.select(:entity).order(entity: :asc).distinct
23
+ .pluck(:entity)
24
+ }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacRailsRemotes
6
+ class Instance < ::ActiveRecord::Base
7
+ self.table_name = 'eac_rails_remotes_instances'
8
+ enable_listable
9
+ lists.add_integer :export_status, :new_data, :ok, :error
10
+
11
+ validates :source, presence: true
12
+ validates :entity, presence: true
13
+ validates :code, presence: true, uniqueness: { scope: %i[source entity] }
14
+ validates :data, presence: true
15
+ validates :export_status, presence: true, inclusion: { in: lists.export_status.values }
16
+
17
+ belongs_to :target, polymorphic: true, optional: true
18
+
19
+ scope :pendent, lambda {
20
+ where.not(export_status: EXPORT_STATUS_OK)
21
+ }
22
+
23
+ def to_s
24
+ "#{source}|#{entity}|#{code}"
25
+ end
26
+
27
+ def export
28
+ Rails.logger.info("Exporting #{self}")
29
+ t = target || entity_class.new
30
+ t.attributes = target_attributes
31
+ if t.save
32
+ update!(export_status: EXPORT_STATUS_OK, export_message: '', target: t)
33
+ else
34
+ update!(export_status: EXPORT_STATUS_ERROR,
35
+ export_message: target_export_message(t))
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def target_attributes
42
+ Hash[EacRubyUtils::Yaml.load(data).map { |k, v| target_attribute(k, v) }]
43
+ end
44
+
45
+ def target_attribute(attr, value)
46
+ a = entity_association_class(attr)
47
+ return [attr, value] unless a
48
+
49
+ ri = self.class.find_by(source: source, entity: a.klass.name, code: value)
50
+ [a.name, ri ? ri.target : nil]
51
+ end
52
+
53
+ # @return [ActiveRecord::Reflection::BelongsToReflection, nil]
54
+ def entity_association_class(attribute)
55
+ entity_class.reflect_on_all_associations(:belongs_to)
56
+ .find { |x| x.foreign_key.to_sym == attribute.to_sym }
57
+ end
58
+
59
+ def entity_class
60
+ entity.constantize
61
+ end
62
+
63
+ def target_export_message(target)
64
+ "ATTRIBUTES: #{target.attributes}\nERRORS: #{target.errors.messages}\n"
65
+ end
66
+
67
+ class << self
68
+ def import(record)
69
+ ri = where(source: record[:source], entity: record[:entity], code: record[:code])
70
+ .first_or_initialize
71
+ ri.data = record[:data].to_yaml
72
+ ri.export_status = EXPORT_STATUS_NEW_DATA
73
+ ri.save!
74
+ ri
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,20 @@
1
+ ---
2
+ en:
3
+ activerecord:
4
+ models:
5
+ eac_rails_remotes/instance:
6
+ one: Remote instance
7
+ other: Remote instances
8
+ eac_ruby_utils:
9
+ listable:
10
+ remote_instance:
11
+ export_status:
12
+ error:
13
+ label: Error
14
+ description: Failed export.
15
+ new_data:
16
+ label: Novo registro
17
+ description: Record was imported, but not exported yet.
18
+ ok:
19
+ label: Ok
20
+ description: Successful export.
@@ -0,0 +1,20 @@
1
+ ---
2
+ pt-BR:
3
+ activerecord:
4
+ models:
5
+ eac_rails_remotes/instance:
6
+ one: Instância remota
7
+ other: Instâncias remotas
8
+ eac_ruby_utils:
9
+ listable:
10
+ eac_rails_remotes/instance:
11
+ export_status:
12
+ error:
13
+ label: Erro
14
+ description: Exportação mal-sucedida.
15
+ new_data:
16
+ label: Novo registro
17
+ description: Registro foi importado, mas não exportado.
18
+ ok:
19
+ label: Ok
20
+ description: Exportação bem-sucedida.
data/config/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ ::EacRailsRemotes::Engine.routes.draw do
4
+ resources(:instances, concerns: active_scaffold)
5
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateEacRailsRemotesInstances < ActiveRecord::Migration[5.2]
4
+ def change
5
+ create_table :eac_rails_remotes_instances do |t|
6
+ t.string :source
7
+ t.string :entity
8
+ t.string :code
9
+ t.references :target, polymorphic: true
10
+ t.text :data
11
+ t.integer :export_status
12
+ t.text :export_message
13
+
14
+ t.timestamps null: false
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency 'eac_active_scaffold/engine'
4
+ require_dependency 'eac_rails_utils/engine_helper'
5
+
6
+ module EacRailsRemotes
7
+ class Engine < ::Rails::Engine
8
+ include ::EacRailsUtils::EngineHelper
9
+ isolate_namespace ::EacRailsRemotes
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRailsRemotes
4
+ class ExportAll
5
+ def perform
6
+ ::EacRailsRemotes::Instance.pendent.each(&:export)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRailsRemotes
4
+ class ImportFile
5
+ def initialize(file)
6
+ @file = file
7
+ end
8
+
9
+ def perform
10
+ @counter = Counter.new
11
+ YAML.load_file(@file).each do |r|
12
+ @counter.add_found(r[:source], r[:entity])
13
+ ::EacRailsRemotes::Instance.import(r)
14
+ end
15
+ @counter.show_counts
16
+ end
17
+
18
+ private
19
+
20
+ def init_counts
21
+ @initial_counts = current_counts
22
+ @counts = Hash[@initial_counts.keys.map { |k| [k, 0] }]
23
+ end
24
+
25
+ class Counter
26
+ def initialize
27
+ @initial_counts = current_counts
28
+ @counts = ActiveSupport::HashWithIndifferentAccess.new
29
+ end
30
+
31
+ def add_found(source, entity)
32
+ @counts[entity_to_s(source, entity)] ||= 0
33
+ @counts[entity_to_s(source, entity)] += 1
34
+ end
35
+
36
+ def show_counts
37
+ Rails.logger.info('Counts')
38
+ counts_to_show.each do |l, es|
39
+ Rails.logger.info(" * #{l}:")
40
+ es.each do |e, c|
41
+ Rails.logger.info(" * #{e}: #{c}")
42
+ end
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def counts_to_show
49
+ {
50
+ 'Initial' => initial_counts,
51
+ 'Found' => found_counts,
52
+ 'New' => new_counts,
53
+ 'Final' => current_counts
54
+ }
55
+ end
56
+
57
+ def entity_to_s(source, entity = nil)
58
+ if source.is_a?(::EacRailsRemotes::Instance)
59
+ entity = source.entity
60
+ source = source.source
61
+ elsif source.is_a?(Hash)
62
+ entity = source[:entity]
63
+ source = source[:source]
64
+ end
65
+ "#{source}|#{entity}"
66
+ end
67
+
68
+ def entity_to_h(entity)
69
+ if entity.is_a?(String)
70
+ m = /\A([^\|]+)\|([^\|]+)\z/.match(entity)
71
+ return { source: m[1], entity: m[2] } if m
72
+
73
+ raise "Entity pattern no matched: \"#{entity}\""
74
+ elsif entity.is_a?(::EacRailsRemotes::Instance)
75
+ return { source: entity.source, entity: entity.entity }
76
+ elsif entity.is_a?(Hash)
77
+ return entity
78
+ end
79
+ raise "Entity class not mapped: #{entity}|#{entity.class}"
80
+ end
81
+
82
+ def initial_counts
83
+ Hash[@counts.keys.map { |e, _c| [e, initial_count(e)] }]
84
+ end
85
+
86
+ def found_counts
87
+ @counts
88
+ end
89
+
90
+ def new_counts
91
+ Hash[@counts.keys.map { |e| [e, current_count(e) - initial_count(e)] }]
92
+ end
93
+
94
+ def initial_count(entity)
95
+ @initial_counts[entity_to_s(entity)] ||= 0
96
+ @initial_counts[entity_to_s(entity)]
97
+ end
98
+
99
+ def current_counts
100
+ r = ActiveSupport::HashWithIndifferentAccess.new
101
+ current_entities.each do |e|
102
+ r[entity_to_s(e)] = current_count(e)
103
+ end
104
+ r
105
+ end
106
+
107
+ def current_count(entity)
108
+ entity = entity_to_h(entity)
109
+ ::EacRailsRemotes::Instance.where(source: entity[:source], entity: entity[:entity]).count
110
+ end
111
+
112
+ def current_entities
113
+ ::EacRailsRemotes::Instance.select(:source, :entity).distinct
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRailsRemotes
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacRailsRemotes
6
+ require_sub __FILE__
7
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :eac_rails_remotes do
4
+ desc 'Import content from file'
5
+ task :import_file, [:file] => :environment do |_t, args|
6
+ ::EacRailsRemotes::ImportFile.new(args.file).perform
7
+ end
8
+
9
+ desc 'Export pending remote instances'
10
+ task export_all: :environment do |_t, _args|
11
+ ::EacRailsRemotes::Instance.new.perform
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: eac_rails_remotes
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Put here the authors
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-05-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: eac_active_scaffold
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.2'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.2.3
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.2'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.2.3
33
+ - !ruby/object:Gem::Dependency
34
+ name: eac_rails_utils
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.17'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 0.17.1
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '0.17'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 0.17.1
53
+ - !ruby/object:Gem::Dependency
54
+ name: eac_ruby_utils
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '0.117'
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '0.117'
67
+ - !ruby/object:Gem::Dependency
68
+ name: eac_rails_gem_support
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '0.7'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '0.7'
81
+ - !ruby/object:Gem::Dependency
82
+ name: eac_ruby_gem_support
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '0.5'
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 0.5.1
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '0.5'
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: 0.5.1
101
+ description:
102
+ email:
103
+ executables: []
104
+ extensions: []
105
+ extra_rdoc_files: []
106
+ files:
107
+ - app/assets/javascripts/eac_rails_remotes/application.js
108
+ - app/assets/stylesheets/eac_rails_remotes/application.scss
109
+ - app/controllers/eac_rails_remotes/instances_controller.rb
110
+ - app/models/eac_rails_remotes/instance.rb
111
+ - config/locales/en.yml
112
+ - config/locales/pt-BR.yml
113
+ - config/routes.rb
114
+ - db/migrate/20230521002623_create_eac_rails_remotes_instances.rb
115
+ - lib/eac_rails_remotes.rb
116
+ - lib/eac_rails_remotes/engine.rb
117
+ - lib/eac_rails_remotes/export_all.rb
118
+ - lib/eac_rails_remotes/import_file.rb
119
+ - lib/eac_rails_remotes/version.rb
120
+ - lib/tasks/eac_rails_remotes.rake
121
+ homepage:
122
+ licenses: []
123
+ metadata: {}
124
+ post_install_message:
125
+ rdoc_options: []
126
+ require_paths:
127
+ - lib
128
+ required_ruby_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ required_rubygems_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubygems_version: 3.1.6
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: Put here de description.
143
+ test_files: []