Class: Html2rss::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/html2rss/config.rb,
lib/html2rss/config/schema.rb,
lib/html2rss/config/validator.rb,
lib/html2rss/config/dynamic_params.rb,
lib/html2rss/config/request_headers.rb,
lib/html2rss/config/request_controls.rb,
lib/html2rss/config/selectors_validator.rb,
lib/html2rss/config/auto_source_contract.rb,
lib/html2rss/config/multiple_feeds_config.rb

Overview

The provided configuration is used to generate the RSS feed. This class provides methods to load and process configuration from a YAML file, supporting both single and multiple feed configurations.

Configuration is validated during initialization.

Defined Under Namespace

Modules: Schema Classes: DynamicParams, InvalidConfig, MultipleFeedsConfig, Preparer, RequestControls, RequestHeaders, SelectorsValidator, Validator

Constant Summary collapse

UNSET =

Sentinel to differentiate omitted params from explicit nil.

Object.new.freeze
AutoSourceContract =

Runtime source of truth for validating auto-source config values.

Dry::Schema.Params do # rubocop:disable Metrics/BlockLength
  optional(:scraper).hash do # rubocop:disable Metrics/BlockLength
    optional(:wordpress_api).hash do
      optional(:enabled).filled(:bool)
    end
    optional(:sitemap).hash do
      optional(:enabled).filled(:bool)
      optional(:min_priority).filled(:float)
      optional(:max_age_days).filled(:integer, gt?: 0)
    end
    optional(:schema).hash do
      optional(:enabled).filled(:bool)
    end
    optional(:microdata).hash do
      optional(:enabled).filled(:bool)
    end
    optional(:microformats2).hash do
      optional(:enabled).filled(:bool)
    end
    optional(:json_state).hash do
      optional(:enabled).filled(:bool)
    end
    optional(:meta_oembed).hash do
      optional(:enabled).filled(:bool)
    end
    optional(:semantic_html).hash do
      optional(:enabled).filled(:bool)
      optional(:fallback_anchorless).filled(:bool)
    end
    optional(:html).hash do
      optional(:enabled).filled(:bool)
      optional(:minimum_selector_frequency).filled(:integer, gt?: 0)
      optional(:use_top_selectors).filled(:integer, gt?: 0)
      optional(:fallback_anchorless).filled(:bool)
    end
  end

  optional(:cleanup).hash do
    optional(:keep_different_domain).filled(:bool)
    optional(:min_words_title).filled(:integer, gt?: 0)
  end
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ Config

Initializes the configuration object.

Applies default values and validates the configuration.

Parameters:

  • config (Hash{Symbol => Object})

    the configuration hash.

Raises:



196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/html2rss/config.rb', line 196

def initialize(config)
  @request_controls = RequestControls.from_config(config)
  prepared_config = Preparer.new.call(config)
  validated_config = validated_config_for(prepared_config)

  @config = validated_config.freeze
  @request_controls = request_controls.with_effective_values(
    strategy: validated_config[:strategy],
    max_redirects: validated_config.dig(:request, :max_redirects),
    max_requests: validated_config.dig(:request, :max_requests),
    total_timeout_seconds: validated_config.dig(:request, :total_timeout_seconds)
  )
end

Instance Attribute Details

#request_controlsHtml2rss::Config::RequestControls (readonly)

Returns request controls with provenance.

Returns:



229
230
231
# File 'lib/html2rss/config.rb', line 229

def request_controls
  @request_controls
end

Class Method Details

.auto_source_config(url:, items_selector: nil, request_controls: nil) ⇒ Hash{Symbol => Object}

Builds a top-level auto-source feed config for the public shortcut APIs.

Parameters:

  • url (String)

    source page URL

  • items_selector (String, nil) (defaults to: nil)

    optional selector hint for item extraction

  • request_controls (Html2rss::Config::RequestControls, nil) (defaults to: nil)

    explicit request controls to write

Returns:

  • (Hash{Symbol => Object})

    feed config hash ready for from_hash



124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/html2rss/config.rb', line 124

def auto_source_config(url:, items_selector: nil, request_controls: nil)
  config = {
    channel: default_config[:channel].merge(url:),
    auto_source: AutoSource::DEFAULT_CONFIG
  }

  request_controls ||= RequestControls.new
  request_controls.apply_to(config)

  config[:selectors] = { items: { selector: items_selector, enhance: true } } if items_selector
  config
end

.default_configHash{Symbol => Object}

Provides a default configuration.

Returns:

  • (Hash{Symbol => Object})

    a hash with default configuration values.



141
142
143
144
145
146
147
148
149
# File 'lib/html2rss/config.rb', line 141

def default_config
  {
    strategy: default_strategy_name,
    request: default_request_config,
    channel: { time_zone: 'UTC' },
    headers: RequestHeaders.browser_defaults,
    stylesheets: Html2rss.defaults.stylesheets || []
  }
end

.default_strategy_nameSymbol

Returns the default feed-level strategy plan (+:auto+ or concrete).

Returns:

  • (Symbol)

    the default feed-level strategy plan (+:auto+ or concrete)



152
153
154
# File 'lib/html2rss/config.rb', line 152

def default_strategy_name
  Html2rss.defaults.default_strategy || :auto
end

.from_hash(config, params: UNSET) ⇒ Html2rss::Config

Processes the provided configuration hash, applying dynamic parameters if given, and returns a new configuration object.

Parameters:

  • config (Hash{Symbol => Object})

    the configuration hash.

  • params (Hash{Symbol => Object, Hash{String => Object, nil}}) (defaults to: UNSET)

    dynamic parameters for string formatting.

Returns:



113
114
115
# File 'lib/html2rss/config.rb', line 113

def from_hash(config, params: UNSET)
  new(resolve_effective_config(config, params:))
end

.json_schemaHash{String => Object}

Returns the exported JSON Schema for html2rss configuration.

Returns:

  • (Hash{String => Object})

    JSON Schema represented as a Ruby hash



24
25
26
# File 'lib/html2rss/config.rb', line 24

def json_schema
  Schema.json_schema
end

.json_schema_json(pretty: true) ⇒ String

Returns the exported JSON Schema as JSON.

Parameters:

  • pretty (Boolean) (defaults to: true)

    whether to pretty-print the JSON output

Returns:

  • (String)

    serialized JSON Schema



33
34
35
# File 'lib/html2rss/config.rb', line 33

def json_schema_json(pretty: true)
  pretty ? JSON.pretty_generate(json_schema) : JSON.generate(json_schema)
end

.load_yaml(file, feed_name = nil, multiple_feeds_key: MultipleFeedsConfig::CONFIG_KEY_FEEDS) ⇒ Hash{Symbol => Object}

Loads the feed configuration from a YAML file.

Supports multiple feeds defined under the specified key (default :feeds).

rubocop:disable Metrics/MethodLength

Parameters:

  • file (String)

    the YAML file to load.

  • feed_name (String, nil) (defaults to: nil)

    the feed name when using multiple feeds.

  • multiple_feeds_key (Symbol) (defaults to: MultipleFeedsConfig::CONFIG_KEY_FEEDS)

    the key under which multiple feeds are defined.

Returns:

  • (Hash{Symbol => Object})

    the configuration hash.

Raises:

  • (ArgumentError)

    if the file doesn't exist or feed is not found.



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/html2rss/config.rb', line 85

def load_yaml(file, feed_name = nil, multiple_feeds_key: MultipleFeedsConfig::CONFIG_KEY_FEEDS)
  raise ArgumentError, "File '#{file}' does not exist" unless File.exist?(file)
  raise ArgumentError, "`#{multiple_feeds_key}` is a reserved feed name" if feed_name == multiple_feeds_key

  yaml = YAML.safe_load_file(file, symbolize_names: true)

  return yaml unless yaml.key?(multiple_feeds_key)

  unless feed_name
    available_feeds = yaml.fetch(multiple_feeds_key).keys.join(', ')
    raise ArgumentError,
          "Feed name is required under `#{multiple_feeds_key}`. Available feeds: #{available_feeds}"
  end

  config = yaml.dig(multiple_feeds_key, feed_name.to_sym)
  raise ArgumentError, "Feed '#{feed_name}' not found under `#{multiple_feeds_key}` key." unless config

  MultipleFeedsConfig.to_single_feed(config, yaml, multiple_feeds_key:)
end

.schema_pathString

Returns the packaged JSON Schema file path.

Returns:

  • (String)

    absolute path to the packaged JSON Schema file



58
59
60
# File 'lib/html2rss/config.rb', line 58

def schema_path
  Schema.path
end

.validate(config, params: UNSET) ⇒ Dry::Validation::Result

Validates a configuration hash with the runtime validator.

Parameters:

  • config (Hash{Symbol => Object})

    the configuration hash

  • params (Hash{Symbol => Object, Hash{String => Object, nil}}) (defaults to: UNSET)

    dynamic parameters for string formatting

Returns:

  • (Dry::Validation::Result)

    validation result after defaults are applied



43
44
45
46
47
48
49
50
51
52
# File 'lib/html2rss/config.rb', line 43

def validate(config, params: UNSET)
  prepared_config = prepare_for_validation(resolve_effective_config(config, params:))

  Validator.new.call(prepared_config)
rescue DynamicParams::ParamsMissing => error
  prepared_config = prepare_for_validation(HashUtil.deep_symbolize_keys(config, context: 'config'))
  prepared_config[:dynamic_params_error] = error.message

  Validator.new.call(prepared_config)
end

.validate_yaml(file, feed_name = nil, multiple_feeds_key: MultipleFeedsConfig::CONFIG_KEY_FEEDS, params: UNSET) ⇒ Dry::Validation::Result

Loads and validates a YAML configuration file.

Parameters:

  • file (String)

    the YAML file to load

  • feed_name (String, nil) (defaults to: nil)

    optional feed name for multi-feed files

  • multiple_feeds_key (Symbol) (defaults to: MultipleFeedsConfig::CONFIG_KEY_FEEDS)

    key under which multiple feeds are defined

  • params (Hash{Symbol => Object, Hash{String => Object, nil}}) (defaults to: UNSET)

    dynamic parameters for string formatting

Returns:

  • (Dry::Validation::Result)

    validation result after defaults are applied



70
71
72
# File 'lib/html2rss/config.rb', line 70

def validate_yaml(file, feed_name = nil, multiple_feeds_key: MultipleFeedsConfig::CONFIG_KEY_FEEDS, params: UNSET)
  validate(load_yaml(file, feed_name, multiple_feeds_key:), params:)
end

Instance Method Details

#auto_sourceHash{Symbol => Object, nil}

Returns auto-source configuration.

Returns:

  • (Hash{Symbol => Object, nil})

    auto-source configuration



246
# File 'lib/html2rss/config.rb', line 246

def auto_source = config[:auto_source]

#channelHash{Symbol => Object}

Returns channel configuration.

Returns:

  • (Hash{Symbol => Object})

    channel configuration



234
235
# File 'lib/html2rss/config.rb', line 234

def channel = config[:channel]
# @return [String] source channel URL

#explicit_max_requests?Boolean

Returns whether max_requests was explicitly configured by the caller.

Returns:

  • (Boolean)

    whether max_requests was explicitly configured by the caller



223
224
225
# File 'lib/html2rss/config.rb', line 223

def explicit_max_requests?
  request_controls.explicit?(:max_requests)
end

#headersHash{String => String}

Returns normalized HTTP headers.

Returns:

  • (Hash{String => String})

    normalized HTTP headers



232
233
# File 'lib/html2rss/config.rb', line 232

def headers = config[:headers]
# @return [Hash{Symbol => Object}] channel configuration

#max_redirectsInteger?

Returns configured redirect budget.

Returns:

  • (Integer, nil)

    configured redirect budget



213
214
# File 'lib/html2rss/config.rb', line 213

def max_redirects = request_controls.max_redirects
# @return [Integer, nil] configured request budget

#max_requestsInteger?

Returns configured request budget.

Returns:

  • (Integer, nil)

    configured request budget



215
216
# File 'lib/html2rss/config.rb', line 215

def max_requests = request_controls.max_requests
# @return [Integer, nil] configured request timeout

#requestHash{Symbol => Object}

Returns request envelope configuration.

Returns:

  • (Hash{Symbol => Object})

    request envelope configuration



241
# File 'lib/html2rss/config.rb', line 241

def request = config[:request]

#selectorsHash{Symbol => Object, nil}

Returns selectors configuration.

Returns:

  • (Hash{Symbol => Object, nil})

    selectors configuration



244
245
# File 'lib/html2rss/config.rb', line 244

def selectors = config[:selectors]
# @return [Hash{Symbol => Object, nil}] auto-source configuration

#strategySymbol?

Returns selected request strategy.

Returns:

  • (Symbol, nil)

    selected request strategy



211
212
# File 'lib/html2rss/config.rb', line 211

def strategy = request_controls.strategy
# @return [Integer, nil] configured redirect budget

#stylesheetsArray<Hash>

Returns stylesheet definitions.

Returns:

  • (Array<Hash>)

    stylesheet definitions



219
# File 'lib/html2rss/config.rb', line 219

def stylesheets = config[:stylesheets]

#time_zoneString?

Returns configured channel time zone.

Returns:

  • (String, nil)

    configured channel time zone



238
# File 'lib/html2rss/config.rb', line 238

def time_zone = config.dig(:channel, :time_zone)

#total_timeout_secondsInteger?

Returns configured request timeout.

Returns:

  • (Integer, nil)

    configured request timeout



217
218
# File 'lib/html2rss/config.rb', line 217

def total_timeout_seconds = request_controls.total_timeout_seconds
# @return [Array<Hash>] stylesheet definitions

#urlString

Returns source channel URL.

Returns:

  • (String)

    source channel URL



236
237
# File 'lib/html2rss/config.rb', line 236

def url = config.dig(:channel, :url)
# @return [String, nil] configured channel time zone