Skip to content

Commit

Permalink
Adiciona integração com API da Zamzar para conversão de PDF para TXT (#…
Browse files Browse the repository at this point in the history
…118)

* atualiza deps e cria app de crawler inicial

* feat: adiciona repositório para app cotacoes

* feat: adiciona handlers para entidade cotacao

* feat: adiciona campo em cotacao para verificar se a mesma ja foi importada

* feat: remove app crawler

* feat: adiciona app cotacoes_etl

* feat: cria integração com site da pesagro

* feat: adiciona worker para buscar boletins na pesagro

* testes basicos

* feat: teste do fluxo principal do worker

* corrige estrutura da tabela cotacao

* remove lib req e adiciona tesla

* adiciona schemas para API zamzar

* adiciona integração com a API zamzar

* pequenos ajustes na integração da API zamzar

* add baixada? ao modelo de cotacao e implementa funções extras

* funções extras na integração pesagro

* testes para API zamzar

* fix: corrige testes
  • Loading branch information
Zoey de Souza Pessanha committed Jul 8, 2023
1 parent 1a172ee commit 3493977
Show file tree
Hide file tree
Showing 28 changed files with 374 additions and 46 deletions.
19 changes: 18 additions & 1 deletion apps/cotacoes/lib/cotacoes/handlers/cotacao_handler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,19 @@ defmodule Cotacoes.Handlers.CotacaoHandler do

@impl true
def find_cotacoes_not_ingested do
Repository.find_all_cotacao_by_is_ingested()
Repository.find_all_cotacao_by_not_ingested()
end

@impl true
def find_cotacoes_not_downloaded do
Repository.find_all_cotacao_by_not_downloaded()
end

@impl true
def get_cotacao_file_base_name(cotacao) do
cotacao.link
|> String.split("/")
|> List.last()
end

@impl true
Expand All @@ -27,4 +39,9 @@ defmodule Cotacoes.Handlers.CotacaoHandler do
current = Enum.map(Repository.list_cotacao(), & &1.link)
Enum.reject(cotacoes, &(&1.link in current))
end

@impl true
def set_cotacao_downloaded(cotacao) do
Repository.upsert_cotacao(cotacao, %{baixada?: true})
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ defmodule Cotacoes.Handlers.IManageCotacaoHandler do
alias Cotacoes.Models.Cotacao

@callback find_cotacoes_not_ingested :: list(Cotacao.t())
@callback find_cotacoes_not_downloaded :: list(Cotacao.t())
@callback get_cotacao_file_base_name(Cotacao.t()) :: String.t()
@callback ingest_cotacoes(list(Cotacao.t())) :: :ok
@callback insert_cotacoes!(list(Cotacao.t())) :: :ok
@callback list_cotacao :: list(Cotacao.t())
@callback reject_inserted_cotacoes(list(Cotacao.t())) :: list(Cotacao.t())
@callback set_cotacao_downloaded(Cotacao.t()) ::
{:ok, Cotacao.t()} | {:error, Ecto.Changeset.t()}
end
3 changes: 2 additions & 1 deletion apps/cotacoes/lib/cotacoes/i_manage_repository.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ defmodule Cotacoes.IManageRepository do

@opaque changeset :: Ecto.Changeset.t()

@callback find_all_cotacao_by_is_ingested :: list(Cotacao.t())
@callback find_all_cotacao_by_not_ingested :: list(Cotacao.t())
@callback find_all_cotacao_by_not_downloaded :: list(Cotacao.t())
@callback insert_all_cotacao(list(map)) :: :ok
@callback list_cotacao :: list(Cotacao.t())
@callback update_all_cotacao(list(Cotacao.t()), keyword) :: {:ok, list(Cotacao.t()) | nil}
Expand Down
13 changes: 7 additions & 6 deletions apps/cotacoes/lib/cotacoes/models/cotacao.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ defmodule Cotacoes.Models.Cotacao do
data: Date.t(),
link: binary,
fonte: binary,
importada?: boolean
importada?: boolean,
baixada?: boolean
}

@required_fields ~w(data fonte)a
@optional_fields ~w(link importada?)a
@optional_fields ~w(link importada? baixada?)a

@primary_key false
@primary_key {:link, :string, autogenerate: false}
schema "cotacao" do
field :data, :date, primary_key: true
field :fonte, :string, primary_key: true
field :link, :string
field :data, :date
field :fonte, :string
field :importada?, :boolean, default: false
field :baixada?, :boolean, default: false
field :id, Database.Types.PublicId, autogenerate: true
end

Expand Down
8 changes: 4 additions & 4 deletions apps/cotacoes/lib/cotacoes/models/cotacao_pescado.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule Cotacoes.Models.CotacaoPescado do

@type t :: %CotacaoPescado{
id: binary,
cotacao_data: Date.t(),
cotacao_link: Date.t(),
pescado_codigo: binary,
fonte_nome: binary,
preco_minimo: integer,
Expand All @@ -12,13 +12,13 @@ defmodule Cotacoes.Models.CotacaoPescado do
preco_medio: integer
}

@required_fields ~w(cotacao_data pescado_codigo fonte_nome preco_minimo preco_maximo)a
@required_fields ~w(cotacao_link pescado_codigo fonte_nome preco_minimo preco_maximo)a
@optional_fields ~w(preco_mais_comum preco_medio)a

@primary_key false
schema "cotacoes_pescados" do
field :id, Database.Types.PublicId, autogenerate: true
field :cotacao_data, :date, primary_key: true
field :cotacao_link, :string, primary_key: true
field :pescado_codigo, :string, primary_key: true
field :fonte_nome, :string, primary_key: true
field :preco_minimo, :integer
Expand All @@ -32,7 +32,7 @@ defmodule Cotacoes.Models.CotacaoPescado do
cot_pescado
|> cast(attrs, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
|> foreign_key_constraint(:cotacao_data)
|> foreign_key_constraint(:cotacao_link)
|> foreign_key_constraint(:pescado_codigo)
|> foreign_key_constraint(:fonte_nome)
end
Expand Down
10 changes: 8 additions & 2 deletions apps/cotacoes/lib/cotacoes/repository.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ defmodule Cotacoes.Repository do
@behaviour Cotacoes.IManageRepository

@impl true
def find_all_cotacao_by_is_ingested do
query = from c in Cotacao, where: c.importada?, select: c
def find_all_cotacao_by_not_ingested do
query = from c in Cotacao, where: not c.importada?, select: c
Repo.Replica.all(query)
end

@impl true
def find_all_cotacao_by_not_downloaded do
query = from c in Cotacao, where: not c.baixada?, select: c
Repo.Replica.all(query)
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ defmodule Database.Repo.Migrations.CriaCotacao do
def change do
create table(:cotacao, primary_key: false) do
add :id, :string
add :data, :date, primary_key: true, null: false
add :link, :string
add :data, :date, null: false
add :link, :string, primary_key: true
add :importada?, :boolean, default: false

add :fonte, references(:fonte_cotacao, column: :nome, type: :string),
primary_key: true,
null: false
add :baixada?, :boolean, default: false
add :fonte, references(:fonte_cotacao, column: :nome, type: :string), null: false
end

create index(:cotacao, [:fonte])
create unique_index(:cotacao, [:data])
create index(:cotacao, [:link])
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Database.Repo.Migrations.CriaCotacoesPescados do
def change do
create table(:cotacoes_pescados, primary_key: false) do
add :id, :string
add :cotacao_data, references(:cotacao, column: :data, type: :date), primary_key: true
add :cotacao_link, references(:cotacao, column: :link, type: :string), primary_key: true
add :pescado_codigo, references(:pescado, column: :codigo, type: :string), primary_key: true
add :fonte_nome, references(:fonte_cotacao, column: :nome, type: :string), primary_key: true
add :preco_minimo, :integer
Expand All @@ -13,9 +13,9 @@ defmodule Database.Repo.Migrations.CriaCotacoesPescados do
add :preco_medio, :integer
end

create index(:cotacoes_pescados, [:cotacao_data])
create index(:cotacoes_pescados, [:cotacao_link])
create index(:cotacoes_pescados, [:pescado_codigo])
create index(:cotacoes_pescados, [:fonte_nome])
create unique_index(:cotacoes_pescados, [:cotacao_data, :pescado_codigo, :fonte_nome])
create unique_index(:cotacoes_pescados, [:cotacao_link, :pescado_codigo, :fonte_nome])
end
end
10 changes: 5 additions & 5 deletions apps/cotacoes/test/cotacoes/models/cotacao_pescado_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ defmodule Cotacoes.Models.CotacaoPescadoTest do
pescado = insert(:pescado)

attrs = %{
cotacao_data: cotacao.data,
cotacao_link: cotacao.link,
fonte_nome: fonte.nome,
pescado_codigo: pescado.codigo,
preco_minimo: 1000,
Expand All @@ -23,7 +23,7 @@ defmodule Cotacoes.Models.CotacaoPescadoTest do
changeset = CotacaoPescado.changeset(%CotacaoPescado{}, attrs)

assert changeset.valid?
assert get_change(changeset, :cotacao_data) == cotacao.data
assert get_change(changeset, :cotacao_link) == cotacao.link
assert get_change(changeset, :fonte_nome) == fonte.nome
assert get_change(changeset, :pescado_codigo) == pescado.codigo
assert get_change(changeset, :preco_minimo) == 1000
Expand All @@ -36,7 +36,7 @@ defmodule Cotacoes.Models.CotacaoPescadoTest do
pescado = insert(:pescado)

attrs = %{
cotacao_data: cotacao.data,
cotacao_link: cotacao.link,
fonte_nome: fonte.nome,
pescado_codigo: pescado.codigo,
preco_minimo: 1000,
Expand All @@ -48,7 +48,7 @@ defmodule Cotacoes.Models.CotacaoPescadoTest do
changeset = CotacaoPescado.changeset(%CotacaoPescado{}, attrs)

assert changeset.valid?
assert get_change(changeset, :cotacao_data) == cotacao.data
assert get_change(changeset, :cotacao_link) == cotacao.link
assert get_change(changeset, :fonte_nome) == fonte.nome
assert get_change(changeset, :pescado_codigo) == pescado.codigo
assert get_change(changeset, :preco_minimo) == 1000
Expand All @@ -61,7 +61,7 @@ defmodule Cotacoes.Models.CotacaoPescadoTest do
changeset = CotacaoPescado.changeset(%CotacaoPescado{}, %{})

refute changeset.valid?
assert Keyword.get(changeset.errors, :cotacao_data)
assert Keyword.get(changeset.errors, :cotacao_link)
assert Keyword.get(changeset.errors, :fonte_nome)
assert Keyword.get(changeset.errors, :pescado_codigo)
assert Keyword.get(changeset.errors, :preco_maximo)
Expand Down
10 changes: 5 additions & 5 deletions apps/cotacoes/test/cotacoes/repository_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ defmodule Cotacoes.RepositoryTest do

@moduletag :unit

test "find_all_cotacao_by_is_ingested/0 retorna todas as cotacoes onde importada? é true" do
insert(:cotacao, importada?: true)
test "find_all_cotacao_by_not_ingested/0 retorna todas as cotacoes onde importada? é false" do
insert(:cotacao, importada?: false)
insert(:cotacao, importada?: true, data: ~D[2023-06-07])
found = Repository.find_all_cotacao_by_is_ingested()
found = Repository.find_all_cotacao_by_not_ingested()

assert length(found) == 2
assert Enum.all?(found, & &1.importada?)
assert length(found) == 1
assert Enum.all?(found, &(not &1.importada?))
end

test "insert_all_cotacao/1 insere todas as cotacoes fornecidas" do
Expand Down
5 changes: 3 additions & 2 deletions apps/cotacoes/test/support/factory.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ defmodule Cotacoes.Factory do
data: ~D[2023-05-07],
fonte: insert(:fonte).nome,
link: sequence(:link, &"https://example#{&1}.com"),
importada?: false
importada?: false,
baixada?: false
}
end

def cotacao_pescado_factory do
%CotacaoPescado{
id: Nanoid.generate_non_secure(),
cotacao_data: insert(:cotacao).data,
cotacao_link: insert(:cotacao).link,
fonte_nome: insert(:fonte).nome,
pescado_codigo: insert(:pescado).codigo,
preco_minimo: 1000,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ defmodule CotacoesETL.Adapters.Pesagro.Boletim do
end

def boletim_to_cotacao(%BoletimEntry{link: link}, today) do
%{fonte: "pesagro", link: link, data: today, importada?: false}
%{id: Nanoid.generate(), fonte: "pesagro", link: link, data: today, importada?: false}
end
end
22 changes: 22 additions & 0 deletions apps/cotacoes_etl/lib/cotacoes_etl/application.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
defmodule CotacoesETL.Application do
use Application

alias CotacoesETL.Workers.Pesagro.BoletinsFetcher

@impl true
def start(_, _) do
children =
if config_env() != :test do
[BoletinsFetcher, {Finch, name: PescarteHTTPClient}]
else
[{Finch, name: PescarteHTTPClient}]
end

opts = [strategy: :one_for_one]
Supervisor.start_link(children, opts)
end

defp config_env do
Application.get_env(:cotacoes_etl, :config_env)
end
end
5 changes: 5 additions & 0 deletions apps/cotacoes_etl/lib/cotacoes_etl/integrations.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
defmodule CotacoesETL.Integrations do
alias CotacoesETL.Integrations.PesagroAPI
alias CotacoesETL.Integrations.ZamzarAPI

def pesagro_api do
Application.get_env(:cotacoes_etl, :pesagro_api, PesagroAPI)
end

def zamzar_api do
Application.get_env(:cotacoes_etl, :zamzar_api, ZamzarAPI)
end
end
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
defmodule CotacoesETL.Integrations.IManagePesagroIntegration do
@callback fetch_document! :: Floki.html_tree()
@callback download_file!(link) :: binary
when link: String.t()
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
defmodule CotacoesETL.Integrations.IManageZamzarIntegration do
alias CotacoesETL.Schemas.Zamzar.File, as: FileEntry
alias CotacoesETL.Schemas.Zamzar.Job

@callback start_job!(source_path, target_format) :: Job.t()
when source_path: Path.t(),
target_format: String.t()

@callback retrieve_job!(job_id) :: Job.t()
when job_id: integer

@callback download_converted_file!(file_id, target_path) :: FileEntry.t()
when file_id: integer,
target_path: Path.t()

@callback retrieve_file_info!(file_id) :: FileEntry.t()
when file_id: integer
end
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,16 @@ defmodule CotacoesETL.Integrations.PesagroAPI do

@impl true
def fetch_document! do
raw_document = Req.get!(base_url() <> @path).body
raw_document = Tesla.get!(base_url() <> @path).body

Floki.parse_document!(raw_document)
end

@impl true
def download_file!(link) do
Tesla.get!(link).body
end

@spec fetch_all_boletim_links(Floki.html_tree()) :: list(BoletimEntry.t())
def fetch_all_boletim_links(document) do
document
Expand Down
Loading

0 comments on commit 3493977

Please sign in to comment.