diff --git a/lib/frenzy/approved_client.ex b/lib/frenzy/approved_client.ex index 456fcb2..b0f0090 100644 --- a/lib/frenzy/approved_client.ex +++ b/lib/frenzy/approved_client.ex @@ -12,6 +12,17 @@ defmodule Frenzy.ApprovedClient do timestamps() end + @type t() :: %__MODULE__{ + __meta__: Ecto.Schema.Metadata.t(), + id: integer() | nil, + client_id: String.t(), + auth_code: String.t(), + access_token: String.t(), + user: Frenzy.User.t() | Ecto.Association.NotLoaded.t(), + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } + @doc false def changeset(approved_client, attrs) do approved_client diff --git a/lib/frenzy/feed.ex b/lib/frenzy/feed.ex index d4f3c7f..b4da33e 100644 --- a/lib/frenzy/feed.ex +++ b/lib/frenzy/feed.ex @@ -46,6 +46,23 @@ defmodule Frenzy.Feed do timestamps() end + @type t() :: %__MODULE__{ + __meta__: Ecto.Schema.Metadata.t(), + id: integer() | nil, + feed_url: String.t(), + last_updated: DateTime.t() | nil, + site_url: String.t() | nil, + title: String.t() | nil, + filter_enabled: boolean(), + scrape_remote_content: boolean(), + group: Frenzy.Group.t() | Ecto.Association.NotLoaded.t(), + items: [Frenzy.Item.t()] | Ecto.Association.NotLoaded.t(), + filter: Frenzy.Filter.t() | Ecto.Association.NotLoaded.t(), + pipeline_stages: [Frenzy.PipelineStage.t()] | Ecto.Association.NotLoaded.t(), + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } + @doc false def changeset(feed, attrs) do feed diff --git a/lib/frenzy/filter.ex b/lib/frenzy/filter.ex index 27c53d7..f663beb 100644 --- a/lib/frenzy/filter.ex +++ b/lib/frenzy/filter.ex @@ -12,6 +12,17 @@ defmodule Frenzy.Filter do timestamps() end + @type t() :: %__MODULE__{ + __meta__: Ecto.Schema.Metadata.t(), + id: integer() | nil, + mode: String.t(), + score: integer(), + feed: Frenzy.Feed.t() | Ecto.Association.NotLoaded.t(), + rules: [Frenzy.Rule.t()] | Ecto.Association.NotLoaded.t(), + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } + @doc false def changeset(filter, attrs) do filter diff --git a/lib/frenzy/group.ex b/lib/frenzy/group.ex index 9247274..64acc92 100644 --- a/lib/frenzy/group.ex +++ b/lib/frenzy/group.ex @@ -38,6 +38,16 @@ defmodule Frenzy.Group do timestamps() end + @type t() :: %__MODULE__{ + __meta__: Ecto.Schema.Metadata.t(), + id: integer() | nil, + title: String.t(), + user: Frenzy.User.t() | Ecto.Association.NotLoaded.t(), + feeds: [Frenzy.Feed.t()] | Ecto.Association.NotLoaded.t(), + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } + @doc false def changeset(group, attrs) do group diff --git a/lib/frenzy/item.ex b/lib/frenzy/item.ex index 8de62f4..7e7b28b 100644 --- a/lib/frenzy/item.ex +++ b/lib/frenzy/item.ex @@ -49,6 +49,23 @@ defmodule Frenzy.Item do timestamps() end + @type t() :: %__MODULE__{ + __meta__: Ecto.Schema.Metadata.t(), + id: integer() | nil, + content: String.t(), + date: DateTime.t(), + creator: String.t(), + guid: String.t(), + url: String.t(), + read: boolean(), + read_date: DateTime.t(), + title: String.t(), + tombstone: boolean(), + feed: Frenzy.Feed.t() | Ecto.Association.NotLoaded.t(), + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } + @doc false def changeset(item, attrs) do item diff --git a/lib/frenzy/pipeline/filter_stage.ex b/lib/frenzy/pipeline/filter_stage.ex index f18a511..6d56933 100644 --- a/lib/frenzy/pipeline/filter_stage.ex +++ b/lib/frenzy/pipeline/filter_stage.ex @@ -117,7 +117,7 @@ defmodule Frenzy.Pipeline.FilterStage do end def matches(value, "matches_regex", param) do - regex = Regex.compile(param) + {:ok, regex} = Regex.compile(param) String.match?(value, regex) end diff --git a/lib/frenzy/pipeline/scrape_stage.ex b/lib/frenzy/pipeline/scrape_stage.ex index 73301db..6295080 100644 --- a/lib/frenzy/pipeline/scrape_stage.ex +++ b/lib/frenzy/pipeline/scrape_stage.ex @@ -11,13 +11,14 @@ defmodule Frenzy.Pipeline.ScrapeStage do {:error, reason} -> Logger.warn("Unable to get article content for #{url}: #{reason}") - item_params + {:ok, item_params} end end @impl Stage def validate_opts(opts), do: {:ok, opts} + @spec get_article_content(String.t()) :: {:ok, String.t()} | {:error, String.t()} defp get_article_content(url) when is_binary(url) and url != "" do Logger.debug("Getting article from #{url}") @@ -34,6 +35,8 @@ defmodule Frenzy.Pipeline.ScrapeStage do defp get_article_content(_url), do: {:error, "URL must be a non-empty string"} + @spec handle_response(String.t(), HTTPoison.Response.t()) :: + {:ok, String.t()} | {:error, String.t()} defp handle_response(_url, %HTTPoison.Response{status_code: 200, body: body}) do article = Readability.article(body) {:ok, Readability.readable_html(article)} diff --git a/lib/frenzy/pipeline/site/daring_fireball_scrape_stage.ex b/lib/frenzy/pipeline/site/daring_fireball_scrape_stage.ex index 050d77a..11d511e 100644 --- a/lib/frenzy/pipeline/site/daring_fireball_scrape_stage.ex +++ b/lib/frenzy/pipeline/site/daring_fireball_scrape_stage.ex @@ -11,13 +11,14 @@ defmodule Frenzy.Pipeline.Site.DaringFireballScrapeStage do {:error, reason} -> Logger.warn("Unable to get Daring Fireball article content for #{url}: #{reason}") - item_params + {:ok, item_params} end end @impl Stage def validate_opts(opts), do: {:ok, opts} + @spec get_article_content(String.t()) :: {:ok, String.t()} | {:error, String.t()} defp get_article_content(url) when is_binary(url) and url != "" do Logger.debug("Get Daring Fireball article from #{url}") @@ -34,6 +35,8 @@ defmodule Frenzy.Pipeline.Site.DaringFireballScrapeStage do defp get_article_content(_url), do: {:error, "URL must be a non-empty string"} + @spec handle_response(String.t(), HTTPoison.Response.t()) :: + {:ok, String.t()} | {:error, String.t()} defp handle_response(url, %HTTPoison.Response{status_code: 200, body: body}) do html_tree = Floki.parse(body) diff --git a/lib/frenzy/pipeline_stage.ex b/lib/frenzy/pipeline_stage.ex index 483d8eb..31dcf2d 100644 --- a/lib/frenzy/pipeline_stage.ex +++ b/lib/frenzy/pipeline_stage.ex @@ -12,6 +12,17 @@ defmodule Frenzy.PipelineStage do timestamps() end + @type t() :: %__MODULE__{ + __meta__: Ecto.Schema.Metadata.t(), + id: integer() | nil, + index: integer(), + module_name: String.t(), + options: map(), + feed: Frenzy.Feed.t() | Ecto.Association.NotLoaded.t(), + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } + def changeset(stage, attrs) do stage |> cast(attrs, [:index, :module_name, :options]) diff --git a/lib/frenzy/rule.ex b/lib/frenzy/rule.ex index b303507..ba884ee 100644 --- a/lib/frenzy/rule.ex +++ b/lib/frenzy/rule.ex @@ -13,6 +13,18 @@ defmodule Frenzy.Rule do timestamps() end + @type t() :: %__MODULE__{ + __meta__: Ecto.Schema.Metadata.t(), + id: integer() | nil, + mode: String.t(), + property: String.t(), + param: String.t(), + weight: integer(), + filter: Frenzy.Filter.t() | Ecto.Association.NotLoaded.t(), + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } + @doc false def changeset(rule, attrs) do rule diff --git a/lib/frenzy/user.ex b/lib/frenzy/user.ex index fb2aa5c..5163951 100644 --- a/lib/frenzy/user.ex +++ b/lib/frenzy/user.ex @@ -16,6 +16,20 @@ defmodule Frenzy.User do timestamps() end + @type t() :: %__MODULE__{ + __meta__: Ecto.Schema.Metadata.t(), + id: integer() | nil, + username: String.t(), + password: String.t() | nil, + password_hash: String.t(), + fever_password: String.t() | nil, + fever_auth_token: String.t(), + approved_clients: [Frenzy.ApprovedClient.t()] | Ecto.Association.NotLoaded.t(), + groups: [Frenzy.Group.t()] | Ecto.Association.NotLoaded.t(), + inserted_at: NaiveDateTime.t(), + updated_at: NaiveDateTime.t() + } + @doc false def changeset(user, attrs) do user diff --git a/lib/frenzy_web/controllers/fever_controller.ex b/lib/frenzy_web/controllers/fever_controller.ex index f8cdca2..e21d607 100644 --- a/lib/frenzy_web/controllers/fever_controller.ex +++ b/lib/frenzy_web/controllers/fever_controller.ex @@ -226,7 +226,7 @@ defmodule FrenzyWeb.FeverController do Repo.all( from i in Item, where: i.feed_id in ^feed_ids, - where: i.inserted_at > ^since.inserted_at, + where: i.inserted_at > ^since, order_by: [asc: :id], limit: 50 ) @@ -238,7 +238,7 @@ defmodule FrenzyWeb.FeverController do Repo.all( from i in Item, where: i.feed_id in ^feed_ids, - where: i.inserted_at < ^max.inserted_at, + where: i.inserted_at < ^max, order_by: [desc: :id], limit: 50 ) diff --git a/mix.exs b/mix.exs index 71b970d..fbc60a9 100644 --- a/mix.exs +++ b/mix.exs @@ -47,7 +47,9 @@ defmodule Frenzy.MixProject do {:fiet, git: "https://github.com/shadowfacts/fiet.git", branch: "master"}, {:timex, "~> 3.0"}, {:readability, git: "https://github.com/shadowfacts/readability.git", branch: "master"}, - {:bcrypt_elixir, "~> 2.0"} + {:bcrypt_elixir, "~> 2.0"}, + {:dialyxir, "~> 1.0.0-rc.6"}, + {:xml_builder, "~> 2.1.1"} ] end diff --git a/mix.lock b/mix.lock index dec478e..8568c03 100644 --- a/mix.lock +++ b/mix.lock @@ -9,9 +9,11 @@ "cowlib": {:hex, :cowlib, "2.7.0", "3ef16e77562f9855a2605900cedb15c1462d76fb1be6a32fc3ae91973ee543d2", [:rebar3], [], "hexpm"}, "db_connection": {:hex, :db_connection, "2.0.2", "440c05518b0bdca0469dafaf45403597430448c1281def14ef9ccaa41833ea1e", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"}, "decimal": {:hex, :decimal, "1.6.0", "bfd84d90ff966e1f5d4370bdd3943432d8f65f07d3bab48001aebd7030590dcc", [:mix], [], "hexpm"}, + "dialyxir": {:hex, :dialyxir, "1.0.0-rc.6", "78e97d9c0ff1b5521dd68041193891aebebce52fc3b93463c0a6806874557d7d", [:mix], [{:erlex, "~> 0.2.1", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm"}, "ecto": {:hex, :ecto, "3.0.3", "018a3df0956636f84eb3033d807485a7d3dea8474f47b90da5cb8073444c4384", [:mix], [{:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm"}, "ecto_sql": {:hex, :ecto_sql, "3.0.2", "0e04cbc183b91ea0085c502226befcd237a4ac31c204fd4be8d4db6676b5f10d", [:mix], [{:db_connection, "~> 2.0", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.0.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.9.1", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.14.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.2.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"}, "elixir_make": {:hex, :elixir_make, "0.5.2", "96a28c79f5b8d34879cd95ebc04d2a0d678cfbbd3e74c43cb63a76adf0ee8054", [:mix], [], "hexpm"}, + "erlex": {:hex, :erlex, "0.2.4", "23791959df45fe8f01f388c6f7eb733cc361668cbeedd801bf491c55a029917b", [:mix], [], "hexpm"}, "fiet": {:git, "https://github.com/shadowfacts/fiet.git", "bf117bc30a6355a189d05a562127cfaf9e0187ae", [branch: "master"]}, "file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"}, "floki": {:hex, :floki, "0.20.4", "be42ac911fece24b4c72f3b5846774b6e61b83fe685c2fc9d62093277fb3bc86", [:mix], [{:html_entities, "~> 0.4.0", [hex: :html_entities, repo: "hexpm", optional: false]}, {:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"}, @@ -43,4 +45,5 @@ "timex": {:hex, :timex, "3.4.2", "d74649c93ad0e12ce5b17cf5e11fbd1fb1b24a3d114643e86dba194b64439547", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"}, "tzdata": {:hex, :tzdata, "0.5.19", "7962a3997bf06303b7d1772988ede22260f3dae1bf897408ebdac2b4435f4e6a", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}, + "xml_builder": {:hex, :xml_builder, "2.1.1", "2d6d665f09cf1319e3e1c46035755271b414d99ad8615d0bd6f337623e0c885b", [:mix], [], "hexpm"}, }