- Fix Oban self-scheduling chain silently dying (remove unique constraint so after block can schedule next job)
- Fix Natchez and TrueShotAmmo extract_price defaulting to 0 for missing price data
- Fix caliber_matcher redundant String.downcase inside Enum.find (pre-downcase outside loop)
- Fix runner.ex double iteration (Enum.map + Enum.count merged into single Enum.reduce)
- Fix price_stats_for_caliber firing 3 queries instead of 2 (merge all_time + thirty_day via FILTER)
- Fix PSA duplicate Floki.find on same selector (merge extract_title + extract_url)
- Fix PubSub broadcast carrying no caliber IDs (now includes IDs; clients skip irrelevant reloads)
- Fix BulkAmmo ^ anchor skipping non-leading round counts
- Fix TargetSportsUSA fragile exact text match 'Add To Cart' (use case-insensitive contains)
- Fix SgAmmo dead destructure {_, _, _} = row
- Fix text_detector brass/nickel detection order
- Fix Natchez GraphQL string interpolation (add escape_gql_string)
- Fix chart data triple Enum.map merged into single reduce
- Change Oban scraping queue workers from 2 to 1 (only one needed with Process.sleep)
33 lines
864 B
Elixir
33 lines
864 B
Elixir
defmodule Ammoprices.Scraping.CaliberMatcher do
|
|
@moduledoc false
|
|
|
|
def match(title, calibers) do
|
|
downcased_title = String.downcase(title)
|
|
prepped = Enum.map(calibers, &prepare_caliber/1)
|
|
|
|
case Enum.find(prepped, fn caliber ->
|
|
name_matches?(downcased_title, caliber) or alias_matches?(downcased_title, caliber)
|
|
end) do
|
|
nil -> nil
|
|
caliber -> caliber.original
|
|
end
|
|
end
|
|
|
|
defp prepare_caliber(caliber) do
|
|
%{
|
|
original: caliber,
|
|
name: String.downcase(caliber.name),
|
|
aliases: Enum.map(caliber.aliases, &String.downcase/1)
|
|
}
|
|
end
|
|
|
|
defp name_matches?(downcased_title, caliber) do
|
|
String.contains?(downcased_title, caliber.name)
|
|
end
|
|
|
|
defp alias_matches?(downcased_title, caliber) do
|
|
Enum.any?(caliber.aliases, fn a ->
|
|
String.contains?(downcased_title, a)
|
|
end)
|
|
end
|
|
end
|