aranha-rails 0.7.0 → 0.7.1

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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.rubocop.yml +25 -0
  4. data/Gemfile +5 -0
  5. data/app/assets/javascripts/aranha/application.js +2 -0
  6. data/app/assets/stylesheets/aranha/application.css +5 -0
  7. data/app/controllers/aranha/addresses_controller.rb +8 -0
  8. data/app/controllers/aranha/processor_configurations_controller.rb +16 -0
  9. data/app/controllers/aranha/start_points_controller.rb +16 -0
  10. data/app/models/aranha/address/delayed_job.rb +39 -0
  11. data/app/models/aranha/address/processor.rb +24 -0
  12. data/app/models/aranha/address/scheduling.rb +49 -0
  13. data/app/models/aranha/address.rb +80 -0
  14. data/app/models/aranha/processor_configuration.rb +51 -0
  15. data/app/models/aranha/start_point.rb +47 -0
  16. data/config/initializers/aranha.rb +5 -0
  17. data/config/locales/en.yml +12 -0
  18. data/config/locales/pt-BR.yml +12 -0
  19. data/config/routes.rb +8 -0
  20. data/db/migrate/20171201021251_create_aranha_addresses.rb +15 -0
  21. data/db/migrate/20181125042102_add_extra_data_to_aranha_addresses.rb +9 -0
  22. data/db/migrate/20201128202212_create_aranha_start_points.rb +13 -0
  23. data/db/migrate/20210720023620_add_delayed_job_to_aranha_addresses.rb +7 -0
  24. data/db/migrate/20210721171416_add_tries_count_to_aranha_addresses.rb +7 -0
  25. data/db/migrate/20210721185222_add_last_error_to_aranha_addresses.rb +7 -0
  26. data/db/migrate/20210814220540_create_aranha_processor_configurations.rb +12 -0
  27. data/db/migrate/20210815160543_add_enabled_to_aranha_processor_configurations.rb +7 -0
  28. data/lib/aranha/rails/version.rb +1 -1
  29. data/spec/rubocop_spec.rb +3 -0
  30. data/spec/spec_helper.rb +4 -0
  31. metadata +36 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36ba45ae4efcdde7c87ec2826a8ae37457c791a7384b4fd3cbdd349f32fe9767
4
- data.tar.gz: fbda8a52654c3640017c0bf7e62cc5c7ef2dbf66d2c5f59d9083685629c78314
3
+ metadata.gz: a7f0c7237e3e9ca7d3f5ddc61973513d2a86750e88d96640879c5cd91a46be91
4
+ data.tar.gz: 59b99c087566e49e93e116d51a05f2c29406d8376640112d52f7c59184543de8
5
5
  SHA512:
6
- metadata.gz: 5aa3e496c87dae2659430b1fe08388a4b32087a5ff3cf5835c7327e43e2fd0e2b5c945a8e4911c29cdd99bd8aada31d0e1289bb11e9f962c170ec6c230e2b7a4
7
- data.tar.gz: cc60ef5294d2af9e2b0066d1cae61ec1c8aecd0d5eccfc005b61509282c7f39911fb9aef399c86b46c833c5a1ad7001f3fc75fa784bac60be17fb5e25864558f
6
+ metadata.gz: 80ec1e16b92e7ae0cb463f64c4f6f35b93876fb0987fc0a6ed9d3a57cb509fba35fcddeae40b6b16ba8901576e3f6da125c79e40b3d246b77887c90e8ba15bee
7
+ data.tar.gz: 82a5d76749efb28e26388b1af4cb2d9208915920124e6d6b881d58a1e598a56de989fb539da363a26d09827e96d6cd985f516815ba633ed38069e2eeefffa92e
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,25 @@
1
+ require:
2
+ - rubocop-rails
3
+ - rubocop-rspec
4
+
5
+ AllCops:
6
+ TargetRubyVersion: 2.4
7
+ TargetRailsVersion: 5.1
8
+
9
+ Layout/LineLength:
10
+ Max: 100
11
+
12
+ Style/AsciiComments:
13
+ Enabled: false
14
+
15
+ Style/Documentation:
16
+ Enabled: false
17
+
18
+ Style/HashEachMethods:
19
+ Enabled: true
20
+
21
+ Style/HashTransformKeys:
22
+ Enabled: true
23
+
24
+ Style/HashTransformValues:
25
+ Enabled: true
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
@@ -0,0 +1,2 @@
1
+ //= require_tree .
2
+ //= require active_scaffold
@@ -0,0 +1,5 @@
1
+ /*
2
+ *= require_tree .
3
+ *= require_self
4
+ *= require active_scaffold
5
+ */
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aranha
4
+ class AddressesController < ::ApplicationController
5
+ active_scaffold :'aranha/address' do |_conf|
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aranha
4
+ class ProcessorConfigurationsController < ::ApplicationController
5
+ before_action :configure_processor_class_options
6
+
7
+ active_scaffold :'aranha/processor_configuration' do |conf|
8
+ conf.columns[:processor_class].form_ui = :select
9
+ end
10
+
11
+ def configure_processor_class_options
12
+ active_scaffold_config.columns[:processor_class].options =
13
+ { options: ::Aranha::ProcessorConfiguration.processor_class_options }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aranha
4
+ class StartPointsController < ::ApplicationController
5
+ before_action :configure_processor_class_options
6
+
7
+ active_scaffold :'aranha/start_point' do |conf|
8
+ conf.columns[:processor_class].form_ui = :select
9
+ end
10
+
11
+ def configure_processor_class_options
12
+ active_scaffold_config.columns[:processor_class].options =
13
+ { options: ::Aranha::StartPoint.processor_class_options }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module Aranha
6
+ class Address < ::ActiveRecord::Base
7
+ class DelayedJob
8
+ common_constructor :address_id
9
+
10
+ def perform
11
+ address_processor.successful? ? perform_on_success : perform_on_error
12
+ end
13
+
14
+ private
15
+
16
+ def address
17
+ address_processor.address
18
+ end
19
+
20
+ def perform_on_success
21
+ # Do nothing
22
+ end
23
+
24
+ def perform_on_error
25
+ address.update!(
26
+ tries_count: address.tries_count + 1,
27
+ last_error: address_processor.error.to_yaml
28
+ )
29
+ address.check_scheduling
30
+ end
31
+
32
+ def address_processor
33
+ @address_processor ||= ::Aranha::AddressProcessor.new(
34
+ ::Aranha::Address.find(address_id)
35
+ )
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module Aranha
6
+ class Address < ::ActiveRecord::Base
7
+ module Processor
8
+ common_concern
9
+
10
+ module ClassMethods
11
+ # @return [Aranha::ProcessorConfiguration]
12
+ def default_processor_configuration
13
+ @default_processor_configuration ||= ::Aranha::ProcessorConfiguration.new
14
+ end
15
+ end
16
+
17
+ # @return [Aranha::ProcessorConfiguration]
18
+ def processor_configuration
19
+ ::Aranha::ProcessorConfiguration.find_by(processor_class: processor) ||
20
+ self.class.default_processor_configuration
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module Aranha
6
+ class Address < ::ActiveRecord::Base
7
+ module Scheduling
8
+ common_concern
9
+
10
+ module ClassMethods
11
+ # @return [Array<Aranha::Address>]
12
+ def expired(time = ::Time.zone.now)
13
+ all.select { |record| record.expired?(time) }
14
+ end
15
+ end
16
+
17
+ def check_scheduling
18
+ ::ActiveRecord::Base.transaction do
19
+ return unless schedule?
20
+
21
+ job = ::Delayed::Job.enqueue(
22
+ ::Aranha::Address::DelayedJob.new(id),
23
+ queue: ::Aranha::Rails::Process::QUEUE
24
+ )
25
+ update!(delayed_job: job)
26
+ end
27
+ end
28
+
29
+ def expired?(time = ::Time.zone.now)
30
+ time >= (created_at + timeout)
31
+ end
32
+
33
+ def init_scheduling
34
+ update!(tries_count: 0, last_error: nil) unless processed?
35
+ check_scheduling
36
+ end
37
+
38
+ def allow_retry?
39
+ tries_count < ::Aranha::Processor::DEFAULT_MAX_TRIES
40
+ end
41
+
42
+ def schedule?
43
+ processed_at.blank? && allow_retry? && delayed_job.blank? && enabled?
44
+ end
45
+
46
+ delegate :enabled?, :timeout, to: :processor_configuration
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/yaml'
4
+ require 'delayed/backend/active_record'
5
+
6
+ module Aranha
7
+ class Address < ::ActiveRecord::Base
8
+ include ::EacRailsUtils::Models::InequalityQueries
9
+ include ::Aranha::Address::Processor
10
+ include ::Aranha::Address::Scheduling
11
+
12
+ add_inequality_queries(:created_at)
13
+
14
+ class << self
15
+ def sanitize_url(url)
16
+ if url.is_a?(Hash)
17
+ ::EacRubyUtils::Yaml.dump(url)
18
+ else
19
+ url.to_s
20
+ end
21
+ end
22
+ end
23
+
24
+ belongs_to :delayed_job, class_name: 'Delayed::Backend::ActiveRecord::Job', dependent: :destroy,
25
+ optional: true
26
+
27
+ validates :url, presence: true, uniqueness: true
28
+ validates :processor, presence: true
29
+ validates :tries_count, presence: true, numericality: { only_integer: true,
30
+ greater_or_equal: 0 }
31
+
32
+ scope :failed, lambda {
33
+ where(processed_at: nil).where.not(last_error: nil)
34
+ }
35
+
36
+ def to_s
37
+ "#{processor}|#{url}"
38
+ end
39
+
40
+ def process
41
+ ActiveRecord::Base.transaction do
42
+ instanciate_processor.process
43
+ self.processed_at = Time.zone.now
44
+ save!
45
+ end
46
+ end
47
+
48
+ def processed?
49
+ processed_at.present?
50
+ end
51
+
52
+ private
53
+
54
+ def instanciate_processor
55
+ processor_instancier.call(*processor_instancier_arguments)
56
+ end
57
+
58
+ def url_to_process
59
+ ::EacRubyUtils::Yaml.load(url)
60
+ end
61
+
62
+ def processor_instancier
63
+ processor.constantize.method(:new)
64
+ end
65
+
66
+ def processor_instancier_arguments
67
+ if processor_instancier_arity == 2 || processor_instancier_arity.negative?
68
+ [url_to_process, EacRubyUtils::Yaml.load(extra_data)]
69
+ elsif processor_instancier_arity == 1
70
+ [processor_instancier.call(url_to_process)]
71
+ else
72
+ raise("#{processor}.initialize should has 1 or 2 or * arguments")
73
+ end
74
+ end
75
+
76
+ def processor_instancier_arity
77
+ processor.constantize.instance_method(:initialize).arity
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/yaml'
4
+
5
+ module Aranha
6
+ class ProcessorConfiguration < ::ActiveRecord::Base
7
+ DEFAULT_TIMEOUT = 12.hours
8
+
9
+ class << self
10
+ # @return [Enumerator<String>]
11
+ def processor_class_list
12
+ ::Set.new(processor_class_list_from_addresses + processor_class_list_from_start_points)
13
+ .to_enum.sort
14
+ end
15
+
16
+ # @return [Hash<String, String>]
17
+ def processor_class_options
18
+ processor_class_list.map { |e| [e, e] }.to_h
19
+ end
20
+
21
+ private
22
+
23
+ # @return [Array<String>]
24
+ def processor_class_list_from_addresses
25
+ ::Aranha::Address.distinct.pluck(:processor)
26
+ end
27
+
28
+ # @return [Array<String>]
29
+ def processor_class_list_from_start_points
30
+ ::Aranha::StartPoint.processor_class_list.to_a
31
+ end
32
+ end
33
+
34
+ validates :processor_class, presence: true
35
+ validate :processor_class_in_list
36
+ validates :timeout_seconds, allow_blank: true,
37
+ numericality: { integer_only: true, greater_than_or_equal_to: 1 }
38
+
39
+ def processor_class_in_list
40
+ return if processor_class.blank?
41
+ return if self.class.processor_class_list.include?(processor_class)
42
+
43
+ errors.add(:processor_class, 'Not in list')
44
+ end
45
+
46
+ # @return [ActiveSupport::Duration]
47
+ def timeout
48
+ timeout_seconds.if_present(DEFAULT_TIMEOUT, &:seconds)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/yaml'
4
+
5
+ module Aranha
6
+ class StartPoint < ::ActiveRecord::Base
7
+ class << self
8
+ def add_processor_class(klass)
9
+ processor_class_list_var.add(klass.to_s)
10
+ end
11
+
12
+ def processor_class_list
13
+ processor_class_list_var.to_enum
14
+ end
15
+
16
+ def processor_class_options
17
+ processor_class_list.map { |e| [e, e] }.to_h
18
+ end
19
+
20
+ private
21
+
22
+ def processor_class_list_var
23
+ @processor_class_list_var ||= Set.new
24
+ end
25
+ end
26
+
27
+ validates :uri, presence: true, uniqueness: true,
28
+ format: { with: ::URI::DEFAULT_PARSER.make_regexp }
29
+ validates :processor_class, presence: true
30
+ validate :processor_class_in_list
31
+
32
+ def extra_data
33
+ extra_data_yaml.nil? ? nil : ::EacRubyUtils::Yaml.load(extra_data_yaml)
34
+ end
35
+
36
+ def extra_data=(value)
37
+ self.extra_data_yaml = ::EacRubyUtils::Yaml.dump(value)
38
+ end
39
+
40
+ def processor_class_in_list
41
+ return if processor_class.blank?
42
+ return if self.class.processor_class_list.include?(processor_class)
43
+
44
+ errors.add(:processor_class, 'Not in list')
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aranha/rails/manager'
4
+
5
+ ::Aranha::Manager.default = ::Aranha::Rails::Manager.instance
@@ -0,0 +1,12 @@
1
+ en:
2
+ activerecord:
3
+ models:
4
+ aranha/address:
5
+ one: Aranha address
6
+ other: Aranha addresses
7
+ aranha/processor_configuration:
8
+ one: Aranha processor configuration
9
+ other: Aranha processors configurations
10
+ aranha/start_point:
11
+ one: Aranha start point
12
+ other: Aranha start points
@@ -0,0 +1,12 @@
1
+ pt-BR:
2
+ activerecord:
3
+ models:
4
+ aranha/address:
5
+ one: Endereço Aranha
6
+ other: Endereços Aranha
7
+ aranha/processor_configuration:
8
+ one: Configuração de processador Aranha
9
+ other: Configuração de processadores Aranha
10
+ aranha/start_point:
11
+ one: Ponto de Partida Aranha
12
+ other: Pontos de Partida Aranha
data/config/routes.rb ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ ::Aranha::Rails::Engine.routes.draw do
4
+ concern :active_scaffold, ActiveScaffold::Routing::Basic.new(association: true)
5
+ resources(:addresses, concerns: :active_scaffold)
6
+ resources(:processor_configurations, concerns: :active_scaffold)
7
+ resources(:start_points, concerns: :active_scaffold)
8
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateAranhaAddresses < (
4
+ Rails.version < '5' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
5
+ )
6
+ def change
7
+ create_table :aranha_addresses do |t|
8
+ t.string :url
9
+ t.string :processor
10
+ t.timestamp :processed_at
11
+
12
+ t.timestamps null: false
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddExtraDataToAranhaAddresses < (
4
+ Rails.version < '5' ? ActiveRecord::Migration : ActiveRecord::Migration[4.2]
5
+ )
6
+ def change
7
+ add_column :aranha_addresses, :extra_data, :text
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateAranhaStartPoints < ActiveRecord::Migration[5.1]
4
+ def change
5
+ create_table :aranha_start_points do |t|
6
+ t.string :uri
7
+ t.string :processor_class
8
+ t.string :extra_data_yaml
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddDelayedJobToAranhaAddresses < ActiveRecord::Migration[5.1]
4
+ def change
5
+ add_reference :aranha_addresses, :delayed_job, foreign_key: false
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddTriesCountToAranhaAddresses < ActiveRecord::Migration[5.1]
4
+ def change
5
+ add_column :aranha_addresses, :tries_count, :integer, null: false, default: 0
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddLastErrorToAranhaAddresses < ActiveRecord::Migration[5.1]
4
+ def change
5
+ add_column :aranha_addresses, :last_error, :text
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateAranhaProcessorConfigurations < ActiveRecord::Migration[5.1]
4
+ def change
5
+ create_table :aranha_processor_configurations do |t|
6
+ t.string :processor_class
7
+ t.integer :timeout_seconds, null: true
8
+
9
+ t.timestamps null: false
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddEnabledToAranhaProcessorConfigurations < ActiveRecord::Migration[5.1]
4
+ def change
5
+ add_column :aranha_processor_configurations, :enabled, :boolean, default: true, null: false
6
+ end
7
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Aranha
4
4
  module Rails
5
- VERSION = '0.7.0'
5
+ VERSION = '0.7.1'
6
6
  end
7
7
  end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ ::EacRubyUtils::Rspec.default_setup.describe_rubocop
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/rspec/default_setup'
4
+ ::EacRubyUtils::Rspec.default_setup_create(::File.expand_path('..', __dir__))
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aranha-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Put here the authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-15 00:00:00.000000000 Z
11
+ date: 2021-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: active_scaffold
@@ -146,6 +146,32 @@ executables: []
146
146
  extensions: []
147
147
  extra_rdoc_files: []
148
148
  files:
149
+ - ".rspec"
150
+ - ".rubocop.yml"
151
+ - Gemfile
152
+ - app/assets/javascripts/aranha/application.js
153
+ - app/assets/stylesheets/aranha/application.css
154
+ - app/controllers/aranha/addresses_controller.rb
155
+ - app/controllers/aranha/processor_configurations_controller.rb
156
+ - app/controllers/aranha/start_points_controller.rb
157
+ - app/models/aranha/address.rb
158
+ - app/models/aranha/address/delayed_job.rb
159
+ - app/models/aranha/address/processor.rb
160
+ - app/models/aranha/address/scheduling.rb
161
+ - app/models/aranha/processor_configuration.rb
162
+ - app/models/aranha/start_point.rb
163
+ - config/initializers/aranha.rb
164
+ - config/locales/en.yml
165
+ - config/locales/pt-BR.yml
166
+ - config/routes.rb
167
+ - db/migrate/20171201021251_create_aranha_addresses.rb
168
+ - db/migrate/20181125042102_add_extra_data_to_aranha_addresses.rb
169
+ - db/migrate/20201128202212_create_aranha_start_points.rb
170
+ - db/migrate/20210720023620_add_delayed_job_to_aranha_addresses.rb
171
+ - db/migrate/20210721171416_add_tries_count_to_aranha_addresses.rb
172
+ - db/migrate/20210721185222_add_last_error_to_aranha_addresses.rb
173
+ - db/migrate/20210814220540_create_aranha_processor_configurations.rb
174
+ - db/migrate/20210815160543_add_enabled_to_aranha_processor_configurations.rb
149
175
  - lib/aranha/rails.rb
150
176
  - lib/aranha/rails/engine.rb
151
177
  - lib/aranha/rails/fixtures_download.rb
@@ -154,6 +180,8 @@ files:
154
180
  - lib/aranha/rails/process.rb
155
181
  - lib/aranha/rails/version.rb
156
182
  - lib/tasks/aranha.rake
183
+ - spec/rubocop_spec.rb
184
+ - spec/spec_helper.rb
157
185
  homepage:
158
186
  licenses: []
159
187
  metadata: {}
@@ -176,4 +204,9 @@ rubygems_version: 3.1.6
176
204
  signing_key:
177
205
  specification_version: 4
178
206
  summary: Put here de description.
179
- test_files: []
207
+ test_files:
208
+ - spec/rubocop_spec.rb
209
+ - spec/spec_helper.rb
210
+ - ".rspec"
211
+ - Gemfile
212
+ - ".rubocop.yml"