active_connect 0.1.0 → 0.1.1

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: 0d2bd3e27629d16544e40a2cbf963e3060b95c043f88754a84f1be54a11518cd
4
- data.tar.gz: 11fe76063af6c27f221e80eec5a197d9cea4c255e5129179905f79e583553c6a
3
+ metadata.gz: c407dc134ca3ffbcb449c3bf7b44c07206efc8e05a92c30de2026bccdb06a954
4
+ data.tar.gz: eda55e4e6a2aa7747d8d4ad47fdadf5b419fa2c517fdec49191231b1e11bb2ec
5
5
  SHA512:
6
- metadata.gz: 2bc3bd1853322a7a1c553f85487155e9323dd8c8e71e5c95a46de886bde589169f460373c0aaf1c3717eb60cbf53eda503c570f9a09d4f271951854480f11080
7
- data.tar.gz: bcc9dd43b9b9182188f0c152ebc4359226e62ed361eac1f3f3a94ae16d19886118170608c90fd32f98d4508d2f624516ce5251ad6b74180a5b2133273f34c2f6
6
+ metadata.gz: 6bc09c444662721174ee1a1b989806ddf3ad6ceaadc7698cb232f7571e80105c88b759014dfbb82b72367730f50794baa50e6d535c56209cc97d6b867bd3870e
7
+ data.tar.gz: 54f1ed4766f2d61b77d6b461e429574866d3d48ca2d65d9b22cdc3223970e683e854c336b8bedc47250d74a459290c77b635bd47ad2f6d50723fa86f1e483dee
data/README.md CHANGED
@@ -6,7 +6,20 @@ How to use my plugin.
6
6
 
7
7
 
8
8
  # Guide ME
9
+ RAILS_ENV=test rails db:create
9
10
  RAILS_ENV=test rails generate active_connect:install
11
+ RAILS_ENV=test rails test
12
+
13
+ # Create Migration in dummy app
14
+ cd test/dummy/
15
+ RAILS_ENV=test rails generate migration CreateProducts name:string --app=dummy
16
+ RAILS_ENV=test rails db:migrate
17
+
18
+ # Drop
19
+ RAILS_ENV=test rails db:drop
20
+
21
+
22
+ # RAILS_ENV=test rails db:drop
10
23
 
11
24
  ## Installation
12
25
  Add this line to your application's Gemfile:
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+ # app/models/active_connect/active_connect_data.rb
3
+
4
+ require 'yaml'
5
+
6
+ module ActiveConnect
7
+ class ActiveConnectData < ApplicationRecord
8
+ # Include the HTTParty module for making HTTP requests
9
+ include ActiveConnectDataIntegrations::Httparty
10
+ # Define the polymorphic association to the connectable model
11
+ belongs_to :connectable, polymorphic: true
12
+
13
+ # Validate the presence of the service attribute
14
+ validates :service, presence: true
15
+
16
+ # enum status
17
+ enum :status, [:success, :failed]
18
+
19
+ # Master method to fetch data from the service
20
+ def update_data
21
+ config = load_service_config # Load the service-specific configuration
22
+ method_name = "#{config['engine']}_update_data"
23
+
24
+ if respond_to?(method_name, true)
25
+ data = send(method_name)
26
+ parse_data(data)
27
+ else
28
+ raise NoMethodError, "No method defined for engine '#{config['engine']}'"
29
+ end
30
+ end
31
+
32
+ def parse_data(data)
33
+ return unless connectable.respond_to?(:parse_data)
34
+
35
+ # Delegate parsing to the connectable model if it has `parse_data` defined
36
+ connectable.parse_data(data)
37
+ end
38
+
39
+ private
40
+
41
+ # Load service-specific configuration from the YAML file
42
+ def load_service_config
43
+ config = load_yaml_config
44
+ # Validate the service exists in the YAML config
45
+ raise "Service '#{service}' not found in configuration" unless config.key?(service)
46
+ config[service]
47
+ end
48
+
49
+ private
50
+
51
+ # Update the status to error and set the run_at timestamp
52
+ def update_data_failed
53
+ update(status: :error, run_at: Time.current)
54
+ end
55
+
56
+ # Update the status to success and set the run_at timestamp
57
+ def update_data_success
58
+ update(status: :success, run_at: Time.current)
59
+ end
60
+
61
+ # Define the number of request retries defaulting to 0
62
+ def request_retries
63
+ load_service_config.dig('request_retries') || 0
64
+ end
65
+
66
+ # Define the sleep time between requests defaulting to 0 seconds
67
+ def request_sleep
68
+ load_service_config.dig('sleep') || 0
69
+ end
70
+
71
+ # Define the request timeout defaulting to 60 seconds
72
+ def request_timeout
73
+ load_service_config.dig('timeout') || 60
74
+ end
75
+
76
+ # Define the request type defaulting to 'get'
77
+ def request_type
78
+ load_service_config.dig('request_type') || 'get'
79
+ end
80
+
81
+ # Define the URL to request data from defaulting to the 'url' column
82
+ def request_url
83
+ connectable[load_service_config.dig('url_column') || 'url']
84
+ end
85
+
86
+ # Load the YAML file and handle any errors in locating or parsing it
87
+ def load_yaml_config
88
+ config_path = Rails.root.join('config', 'connect.yml')
89
+ YAML.load_file(config_path, aliases: true)
90
+ rescue Errno::ENOENT
91
+ raise "Configuration file 'connect.yml' not found"
92
+ rescue Psych::SyntaxError => e
93
+ raise "YAML syntax error occurred while parsing connect.yml: #{e.message}"
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+ # Path: app/models/concerns/active_connect_data_integrations/http_party.rb
3
+
4
+ require "httparty"
5
+
6
+ module ActiveConnectDataIntegrations
7
+ module Httparty
8
+ extend ActiveSupport::Concern
9
+
10
+ def httparty_update_data
11
+ @tries = 0
12
+ options = { headers: headers_settings, timeout: request_timeout }
13
+ options.merge!(proxy_settings) if proxy_settings
14
+ data = send_request(options)
15
+ data = { status: data.code, body: data.body }
16
+ save_data(data)
17
+ data
18
+ end
19
+
20
+ private
21
+
22
+ def save_data(data)
23
+ data[:status] == 200 ? update_data_success : update_data_failed
24
+ update(data: data)
25
+ end
26
+
27
+ def send_request(options)
28
+ sleep(request_sleep) if request_sleep.positive?
29
+ HTTParty.send(request_type, request_url, options)
30
+ rescue StandardError => e
31
+ retry if (@tries += 1) < request_retries
32
+ raise e
33
+ end
34
+
35
+ def proxy_settings
36
+ base_proxy_settings = {}
37
+ proxy_settings = load_service_config.dig('proxy')
38
+ return unless proxy_settings
39
+ proxy_split = proxy_settings.split(':')
40
+ return unless proxy_split.size > 1
41
+
42
+ base_proxy_settings[:http_proxyaddr] = proxy_split[0]
43
+ base_proxy_settings[:http_proxyport] = proxy_split[1]
44
+ return base_proxy_settings unless proxy_split.size == 4
45
+
46
+ base_proxy_settings[:http_proxyuser] = proxy_split[2]
47
+ base_proxy_settings[:http_proxypass] = proxy_split[3]
48
+ base_proxy_settings
49
+ end
50
+
51
+ def headers_settings
52
+ base_headers = {}
53
+ headers_settings = load_service_config.dig('request_headers')
54
+ return unless headers_settings
55
+
56
+ headers_settings.each do |header_key, header_value|
57
+ base_headers[header_key] = header_value
58
+ end
59
+ base_headers
60
+ end
61
+ end
62
+ end
@@ -4,5 +4,11 @@
4
4
  module ActiveConnect
5
5
  class Engine < ::Rails::Engine
6
6
  isolate_namespace ActiveConnect
7
+
8
+ initializer "active_connect.model_additions" do
9
+ ActiveSupport.on_load(:active_record) do
10
+ include ActiveConnect
11
+ end
12
+ end
7
13
  end
8
14
  end
@@ -1,6 +1,5 @@
1
- # frozen_string_literal: true
2
1
  # Path: lib/active_connect/version.rb
3
-
2
+ #
4
3
  module ActiveConnect
5
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
6
5
  end
@@ -5,5 +5,21 @@ require "active_connect/version"
5
5
  require "active_connect/engine"
6
6
 
7
7
  module ActiveConnect
8
- # Your code goes here...
8
+ extend ActiveSupport::Concern
9
+
10
+ class_methods do
11
+ def has_one_connect(name, service:, dependent: :nullify)
12
+ # Define an association similar to ActiveStorage's `has_one_attached`
13
+ has_one :"#{name}_data", -> { where(service: service) }, class_name: "ActiveConnect::ActiveConnectData", as: :connectable, dependent: dependent
14
+ # Define a method to access the connection service
15
+ define_method(name) do
16
+ public_send("#{name}_data")
17
+ end
18
+
19
+ # Define a `connected?` method to check if a connection exists
20
+ define_method("#{name}_connected?") do
21
+ public_send("#{name}_data").present?
22
+ end
23
+ end
24
+ end
9
25
  end
@@ -18,11 +18,15 @@ module ActiveConnect
18
18
  end
19
19
 
20
20
  def copy_scrape_yml
21
- template "connect.yml", "config/connect.yml"
21
+ template "connect.yml", Rails.root.join("config/connect.yml")
22
22
  end
23
23
 
24
24
  def copy_migrations
25
- migration_template "create_active_connect_data.rb", "db/migrate/create_active_connect_data.rb"
25
+ migration_template "create_active_connect_active_connect_data.rb", Rails.root.join("db/migrate/create_active_connect_active_connect_data.rb")
26
+ end
27
+
28
+ def add_require_to_application
29
+ inject_into_file Rails.root.join("config/application.rb"), "\nrequire 'active_connect'", after: "Bundler.require(*Rails.groups)"
26
30
  end
27
31
  end
28
32
  end
@@ -9,7 +9,7 @@ default: &default
9
9
  http_party:
10
10
  <<: *default
11
11
  engine: "httparty"
12
- proxy: "http://your-proxy-server:port:username:password"
12
+ url_column: "not_url"
13
13
  request_headers:
14
14
  user_agent: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36"
15
15
  request_type: "get"
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
  # lib/generators/active_connect/templates/create_active_connect_data.rb
3
3
  #
4
- class CreateScrapeData < ActiveRecord::Migration[7.0]
4
+ class CreateActiveConnectActiveConnectData < ActiveRecord::Migration[7.0]
5
5
  def change
6
- create_table :active_connect_data do |t|
6
+ create_table :active_connect_active_connect_data do |t|
7
7
  t.references :connectable, polymorphic: true, index: true
8
8
  t.json :data
9
9
  t.datetime :run_at
10
10
  t.integer :status
11
+ t.string :service
11
12
  t.timestamps
12
13
  end
13
14
  end
@@ -10,7 +10,7 @@ module ActiveConnect
10
10
  class_methods do
11
11
  def has_connect(connect_name)
12
12
  # Define scraping settings or initializations here
13
- # You can store configurations in scrape.yml
13
+ # You can store configurations in connect.yml
14
14
  end
15
15
  end
16
16
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_connect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - andersmarkc
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-09 00:00:00.000000000 Z
11
+ date: 2024-11-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -48,15 +48,17 @@ files:
48
48
  - app/helpers/active_connect/application_helper.rb
49
49
  - app/jobs/active_connect/application_job.rb
50
50
  - app/mailers/active_connect/application_mailer.rb
51
+ - app/models/active_connect/active_connect_data.rb
51
52
  - app/models/active_connect/application_record.rb
53
+ - app/models/concerns/active_connect_data_integrations/httparty.rb
52
54
  - app/views/layouts/active_connect/application.html.erb
53
55
  - config/routes.rb
54
56
  - lib/active_connect.rb
55
57
  - lib/active_connect/engine.rb
56
58
  - lib/active_connect/version.rb
57
- - lib/generators/active_scrape/install_generator.rb
58
- - lib/generators/active_scrape/templates/connect.yml
59
- - lib/generators/active_scrape/templates/create_active_connect_data.rb
59
+ - lib/generators/active_connect/install_generator.rb
60
+ - lib/generators/active_connect/templates/connect.yml
61
+ - lib/generators/active_connect/templates/create_active_connect_active_connect_data.rb
60
62
  - lib/tasks/active_connect_tasks.rake
61
63
  homepage: https://github.com/andersmarkc/active_connect
62
64
  licenses:
@@ -65,7 +67,7 @@ metadata:
65
67
  homepage_uri: https://github.com/andersmarkc/active_connect
66
68
  source_code_uri: https://github.com/andersmarkc/active_connect
67
69
  changelog_uri: https://github.com/andersmarkc/active_connect/blob/main/CHANGELOG.md
68
- post_install_message:
70
+ post_install_message:
69
71
  rdoc_options: []
70
72
  require_paths:
71
73
  - lib
@@ -80,8 +82,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
82
  - !ruby/object:Gem::Version
81
83
  version: '0'
82
84
  requirements: []
83
- rubygems_version: 3.1.2
84
- signing_key:
85
+ rubygems_version: 3.4.10
86
+ signing_key:
85
87
  specification_version: 4
86
88
  summary: A scraping utility for Rails applications, designed to work similarly to
87
89
  ActiveStorage.