Skip to content

Commit

Permalink
Merge pull request #14 from protofire/staging-harmony
Browse files Browse the repository at this point in the history
Staging harmony
  • Loading branch information
DenSmolonski authored Sep 11, 2024
2 parents 9572370 + 55cb4d6 commit b8308e8
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 0 deletions.
2 changes: 2 additions & 0 deletions apps/block_scout_web/lib/block_scout_web/api_router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ defmodule BlockScoutWeb.ApiRouter do

get("/logs-csv", AddressTransactionController, :logs_csv)

get("/smart-contracts-csv", V2.SmartContractController, :smart_contracts_csv)

scope "/health" do
get("/", HealthController, :health)
get("/liveness", HealthController, :liveness)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ defmodule BlockScoutWeb.API.V2.SmartContractController do
alias Explorer.SmartContract.{Reader, Writer}
alias Explorer.SmartContract.Solidity.PublishHelper
alias Explorer.ThirdPartyIntegrations.SolidityScan
alias Explorer.Chain.CSVExport.SmartContractsCsvExporter
alias Plug.Conn

@smart_contract_address_options [
necessity_by_association: %{
Expand Down Expand Up @@ -295,6 +297,82 @@ defmodule BlockScoutWeb.API.V2.SmartContractController do
def prepare_args(list) when is_list(list), do: list
def prepare_args(other), do: [other]

def smart_contracts_csv(conn, params) do
items_csv(conn, params, SmartContractsCsvExporter)
end

defp items_csv(
conn,
%{
"from_period" => from_period,
"to_period" => to_period,
},
csv_export_module
) do
with true <- Application.get_env(:block_scout_web, :recaptcha)[:is_disabled] do
csv_export_module.export(from_period, to_period)
|> Enum.reduce_while(put_resp_params(conn), fn chunk, conn ->
case Conn.chunk(conn, chunk) do
{:ok, conn} ->
{:cont, conn}

{:error, :closed} ->
{:halt, conn}
end
end)
else
:error ->
unprocessable_entity(conn)

false ->
not_found(conn)
end
end

defp items_csv(
conn,
%{
"from_period" => from_period,
"to_period" => to_period,
"recaptcha_response" => recaptcha_response
},
csv_export_module
) do
with {:recaptcha, true} <- {:recaptcha, captcha_helper().recaptcha_passed?(recaptcha_response)} do
csv_export_module.export(from_period, to_period)
|> Enum.reduce_while(put_resp_params(conn), fn chunk, conn ->
case Conn.chunk(conn, chunk) do
{:ok, conn} ->
{:cont, conn}

{:error, :closed} ->
{:halt, conn}
end
end)
else
:error ->
unprocessable_entity(conn)

{:recaptcha, false} ->
not_found(conn)
end
end

defp captcha_helper do
:block_scout_web
|> Application.get_env(:captcha_helper)
end

defp items_csv(conn, _, _), do: not_found(conn)

defp put_resp_params(conn) do
conn
|> put_resp_content_type("application/csv")
|> put_resp_header("content-disposition", "attachment;")
|> put_resp_cookie("csv-downloaded", "true", max_age: 86_400, http_only: false)
|> send_chunked(200)
end

defp validate_smart_contract(params, address_hash_string) do
with {:format, {:ok, address_hash}} <- {:format, Chain.string_to_address_hash(address_hash_string)},
{:ok, false} <- AccessHelper.restricted_access?(address_hash_string, params),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
defmodule Explorer.Chain.CSVExport.SmartContractsCsvExporter do
@moduledoc """
Exports smart contracts to a csv file.
"""

alias Explorer.Chain.{SmartContract, Address}
alias Explorer.Chain.CSVExport.Helper

def export(from_period, to_period) do
SmartContract.verified_contracts_by_date_range(from_period, to_period)
|> to_csv_format()
|> Helper.dump_to_stream()
end

defp to_csv_format(smart_contracts) do
row_names = [
"contract_address",
"contract_name",
"chain",
]
chain_id = Application.get_env(:block_scout_web, :chain_id)
smart_contracts_list =
smart_contracts
|> Stream.map(fn smart_contract ->
[
Address.checksum(smart_contract.address_hash),
smart_contract.name,
chain_id,
]
end)

Stream.concat([row_names], smart_contracts_list)
end
end
14 changes: 14 additions & 0 deletions apps/explorer/lib/explorer/chain/smart_contract.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1294,6 +1294,20 @@ defmodule Explorer.Chain.SmartContract do
|> Chain.select_repo(options).all()
end

def verified_contracts_by_date_range(from_period, to_period) do
query = from(contract in __MODULE__)
date_format = "%Y-%m-%d"

query
|> where(
[contract],
contract.inserted_at >= ^Timex.parse!(from_period, date_format, :strftime) and
contract.inserted_at <= ^Timex.parse!(to_period, date_format, :strftime)
)
|> order_by(desc: :id)
|> Chain.select_repo([]).all()
end

defp search_contracts(basic_query, nil), do: basic_query

defp search_contracts(basic_query, search_string) do
Expand Down

0 comments on commit b8308e8

Please sign in to comment.