mirror of
https://github.com/philomena-dev/philomena.git
synced 2025-02-19 20:04:23 +01:00
add macro api
This commit is contained in:
parent
1ad4d1c574
commit
c66fe0ca39
3 changed files with 399 additions and 253 deletions
8
lib/philomena/images/query.ex
Normal file
8
lib/philomena/images/query.ex
Normal file
|
@ -0,0 +1,8 @@
|
|||
defmodule Philomena.Images.Query do
|
||||
use Philomena.Search.Lexer,
|
||||
int_fields: ~W(id width height comment_count score upvotes downvotes faves uploader_id faved_by_id tag_count),
|
||||
float_fields: ~W(aspect_ratio wilson_score),
|
||||
date_fields: ~W(created_at updated_at first_seen_at),
|
||||
literal_fields: ~W(namespaced_tags.name faved_by orig_sha512_hash sha512_hash uploader source_url original_format),
|
||||
ngram_fields: ~W(description)
|
||||
end
|
|
@ -13,4 +13,18 @@ defmodule Philomena.Search.Helpers do
|
|||
int_val
|
||||
end
|
||||
end
|
||||
|
||||
def full_choice(combinator \\ empty(), choices)
|
||||
|
||||
def full_choice(combinator, []) do
|
||||
combinator |> eos()
|
||||
end
|
||||
|
||||
def full_choice(combinator, [choice]) do
|
||||
combinator |> concat(choice)
|
||||
end
|
||||
|
||||
def full_choice(combinator, choices) do
|
||||
choice(combinator, choices)
|
||||
end
|
||||
end
|
|
@ -1,4 +1,15 @@
|
|||
defmodule Philomena.Search.Lexer do
|
||||
defmacro __using__(opts) do
|
||||
literal_fields = Keyword.get(opts, :literal, [])
|
||||
ngram_fields = Keyword.get(opts, :ngram, [])
|
||||
bool_fields = Keyword.get(opts, :bool, [])
|
||||
date_fields = Keyword.get(opts, :date, [])
|
||||
float_fields = Keyword.get(opts, :float, [])
|
||||
int_fields = Keyword.get(opts, :int, [])
|
||||
ip_fields = Keyword.get(opts, :ip, [])
|
||||
custom_fields = Keyword.get(opts, :custom, [])
|
||||
|
||||
quote location: :keep do
|
||||
import NimbleParsec
|
||||
import Philomena.Search.Helpers
|
||||
|
||||
|
@ -228,23 +239,62 @@ defmodule Philomena.Search.Lexer do
|
|||
relative_date
|
||||
])
|
||||
|
||||
eq = choice([string(":"), string(".eq:")]) |> unwrap_and_tag(:eq)
|
||||
lt = string(".lt:") |> unwrap_and_tag(:lt)
|
||||
lte = string(".lte:") |> unwrap_and_tag(:lte)
|
||||
gt = string(".gt:") |> unwrap_and_tag(:gt)
|
||||
gte = string(".gte:") |> unwrap_and_tag(:gte)
|
||||
|
||||
range_relation =
|
||||
choice([
|
||||
eq,
|
||||
lt,
|
||||
lte,
|
||||
gt,
|
||||
gte
|
||||
])
|
||||
|
||||
boost = ignore(string("^")) |> unwrap_and_tag(number, :boost)
|
||||
fuzz = ignore(string("~")) |> unwrap_and_tag(number, :fuzz)
|
||||
|
||||
quot = string("\"")
|
||||
|
||||
quoted_term =
|
||||
ignore(quot)
|
||||
|> choice([
|
||||
ignore(string("\\")) |> string("\""),
|
||||
ignore(string("\\")) |> string("\\"),
|
||||
string("\\") |> utf8_char([]),
|
||||
utf8_char(not: ?")
|
||||
bool_value =
|
||||
full_choice(unquote(for f <- bool_fields, do: [string: f]))
|
||||
|> concat(eq)
|
||||
|> concat(bool)
|
||||
|
||||
date_value =
|
||||
full_choice(unquote(for f <- date_fields, do: [string: f]))
|
||||
|> concat(range_relation)
|
||||
|> concat(date)
|
||||
|
||||
float_value =
|
||||
full_choice(unquote(for f <- float_fields, do: [string: f]))
|
||||
|> concat(range_relation)
|
||||
|> concat(number)
|
||||
|
||||
int_value =
|
||||
full_choice(unquote(for f <- int_fields, do: [string: f]))
|
||||
|> concat(range_relation)
|
||||
|> concat(int)
|
||||
|
||||
ip_value =
|
||||
full_choice(unquote(for f <- ip_fields, do: [string: f]))
|
||||
|> concat(eq)
|
||||
|> concat(ip_address)
|
||||
|
||||
numeric =
|
||||
choice([
|
||||
bool_value,
|
||||
date_value,
|
||||
float_value,
|
||||
int_value,
|
||||
ip_value
|
||||
])
|
||||
|> times(min: 1)
|
||||
|> ignore(quot)
|
||||
|> reduce({List, :to_string, []})
|
||||
|> unwrap_and_tag(:term)
|
||||
|
||||
quoted_numeric =
|
||||
ignore(quot) |> concat(numeric) |> ignore(quot)
|
||||
|
||||
stop_words =
|
||||
choice([
|
||||
|
@ -259,20 +309,93 @@ defmodule Philomena.Search.Lexer do
|
|||
])
|
||||
|
||||
defcombinatorp(
|
||||
:simple_term,
|
||||
:text,
|
||||
lookahead_not(stop_words)
|
||||
|> choice([
|
||||
string("\\") |> utf8_char([]),
|
||||
string("(") |> parsec(:simple_term) |> string(")"),
|
||||
string("(") |> parsec(:text) |> string(")"),
|
||||
utf8_char([])
|
||||
])
|
||||
|> times(min: 1)
|
||||
|> reduce({List, :to_string, []})
|
||||
|> unwrap_and_tag(:text)
|
||||
)
|
||||
|
||||
unquoted_term =
|
||||
parsec(:simple_term)
|
||||
text = parsec(:text)
|
||||
|
||||
quoted_text =
|
||||
choice([
|
||||
ignore(string("\\")) |> string("\""),
|
||||
ignore(string("\\")) |> string("\\"),
|
||||
string("\\") |> utf8_char([]),
|
||||
utf8_char(not: ?")
|
||||
])
|
||||
|> times(min: 1)
|
||||
|> reduce({List, :to_string, []})
|
||||
|> unwrap_and_tag(:term)
|
||||
|> unwrap_and_tag(:text)
|
||||
|
||||
literal =
|
||||
full_choice(unquote(for f <- literal_fields, do: [string: f]))
|
||||
|> ignore(eq)
|
||||
|> concat(text)
|
||||
|> tag(:literal)
|
||||
|
||||
ngram =
|
||||
full_choice(unquote(for f <- ngram_fields, do: [string: f]))
|
||||
|> ignore(eq)
|
||||
|> concat(text)
|
||||
|> tag(:ngram)
|
||||
|
||||
custom =
|
||||
full_choice(unquote(for f <- custom_fields, do: [string: f]))
|
||||
|> ignore(string(":"))
|
||||
|> concat(text)
|
||||
|
||||
quoted_literal =
|
||||
ignore(quot)
|
||||
|> full_choice(unquote(for f <- literal_fields, do: [string: f]))
|
||||
|> ignore(eq)
|
||||
|> concat(quoted_text)
|
||||
|> ignore(quot)
|
||||
|> tag(:literal)
|
||||
|
||||
quoted_ngram =
|
||||
ignore(quot)
|
||||
|> full_choice(unquote(for f <- ngram_fields, do: [string: f]))
|
||||
|> ignore(eq)
|
||||
|> concat(quoted_text)
|
||||
|> ignore(quot)
|
||||
|> tag(:ngram)
|
||||
|
||||
quoted_custom =
|
||||
ignore(quot)
|
||||
|> full_choice(unquote(for f <- custom_fields, do: [string: f]))
|
||||
|> ignore(string(":"))
|
||||
|> concat(quoted_text)
|
||||
|> ignore(quot)
|
||||
|> tag(:custom)
|
||||
|
||||
default =
|
||||
text
|
||||
|> tag(:default)
|
||||
|
||||
quoted_default =
|
||||
quoted_text
|
||||
|> tag(:default)
|
||||
|
||||
term =
|
||||
choice([
|
||||
quoted_numeric,
|
||||
quoted_literal,
|
||||
quoted_ngram,
|
||||
quoted_custom,
|
||||
quoted_default,
|
||||
numeric,
|
||||
literal,
|
||||
ngram,
|
||||
custom,
|
||||
default
|
||||
])
|
||||
|
||||
outer =
|
||||
choice([
|
||||
|
@ -284,8 +407,7 @@ defmodule Philomena.Search.Lexer do
|
|||
boost,
|
||||
fuzz,
|
||||
space,
|
||||
quoted_term,
|
||||
unquoted_term
|
||||
term
|
||||
])
|
||||
|
||||
search =
|
||||
|
@ -294,3 +416,5 @@ defmodule Philomena.Search.Lexer do
|
|||
|
||||
defparsec(:search, search)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue