79 lines
3.4 KiB
Elixir
79 lines
3.4 KiB
Elixir
defmodule FeedReader do
|
|
@moduledoc """
|
|
Standalone feed fetching and parsing library.
|
|
|
|
This module exposes the public format detection and validation helpers.
|
|
"""
|
|
|
|
@typedoc "`:rss`, `:atom`, `:rdf`, `:unknown`, or a custom format's atom ID."
|
|
@type format_id :: atom()
|
|
|
|
@doc """
|
|
Detects a format from a bounded binary prefix.
|
|
|
|
## Options
|
|
- `:max_detection_bytes` — `pos_integer()`; default `65_536`; invalid values yield `:unknown`.
|
|
- `:formats` — list of modules, checked after RSS, Atom, and RDF in list order; duplicates removed.
|
|
Custom modules provide `matches_prefix?/1` and `id/0`.
|
|
"""
|
|
@spec detect_format(binary(), keyword()) :: format_id()
|
|
def detect_format(content, opts \\ []) do
|
|
FeedReader.FormatDetector.detect(content, opts)
|
|
end
|
|
|
|
@doc """
|
|
Checks only the bounded-prefix signature for a format ID or module.
|
|
|
|
## Options
|
|
- `:max_detection_bytes` — `pos_integer()`, default `65_536`; invalid values yield `false`.
|
|
- `:formats` — custom modules used to resolve custom format IDs. Modules provide
|
|
`matches_prefix?/1` and `id/0`; passing the format module directly also works.
|
|
"""
|
|
@spec validate(binary(), atom() | module(), keyword()) :: boolean()
|
|
def validate(content, format, opts \\ []) do
|
|
FeedReader.FormatDetector.validate(content, format, opts)
|
|
end
|
|
|
|
@doc """
|
|
Lazily parses a caller-owned local XML file in one SAX pass.
|
|
|
|
The returned session emits feed metadata before normalized items. The file is
|
|
never removed by the library, including when enumeration stops early.
|
|
|
|
## Options
|
|
|
|
- `:format` — an atom format ID (`:rss`, `:atom`, or `:rdf`) or a format
|
|
module. When omitted, the format is detected from the file prefix.
|
|
- `:formats` — a list of additional format modules. They are checked after
|
|
the built-in RSS, Atom, and RDF formats and may be selected with `:format`.
|
|
Custom modules must implement `FeedReader.Format`.
|
|
- `:chunk_size` — positive integer number of bytes supplied to the XML parser
|
|
per chunk. Defaults to `65_536`.
|
|
- `:max_detection_bytes` — positive integer limit for the prefix inspected
|
|
during format detection. Defaults to `65_536`. Invalid values produce
|
|
`{:error, :unknown}` unless a valid explicit `:format` is supplied.
|
|
- `:feed_url` — optional source URL passed to format normalizers and stored in
|
|
the normalized feed metadata. Defaults to `nil`.
|
|
- `:max_xml_events` — non-negative integer maximum SAX events. Defaults to
|
|
`1_000_000`.
|
|
- `:max_xml_depth` — non-negative integer maximum XML nesting depth. Defaults
|
|
to `256`.
|
|
- `:max_attributes_per_element` — non-negative integer maximum attributes on
|
|
one element. Defaults to `128`.
|
|
- `:max_attribute_bytes` — non-negative integer maximum bytes used by one
|
|
element's attributes. Defaults to `65_536`.
|
|
- `:max_feed_metadata_bytes` — non-negative integer maximum retained feed
|
|
metadata bytes. Defaults to `1_048_576`.
|
|
- `:max_item_bytes` — non-negative integer maximum retained bytes for one
|
|
item. Defaults to `4_194_304`.
|
|
|
|
Zero is valid for resource limits. Missing or invalid resource-limit values
|
|
use their defaults. Additional options are passed through to the selected
|
|
format implementation.
|
|
"""
|
|
@spec stream_file(Path.t(), keyword()) :: {:ok, FeedReader.Session.t()} | {:error, term()}
|
|
def stream_file(path, opts \\ []) do
|
|
FeedReader.Parser.stream_file(path, opts)
|
|
end
|
|
end
|