Initial commit on Forgejo
Fresh repository history for elektrine/tarakan hosted at https://git.elektrine.com/elektrine/tarakan.
This commit is contained in:
commit
af6077b9c3
455 changed files with 78366 additions and 0 deletions
139
lib/tarakan_web/live/explore_live.ex
Normal file
139
lib/tarakan_web/live/explore_live.ex
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
defmodule TarakanWeb.ExploreLive do
|
||||
use TarakanWeb, :live_view
|
||||
|
||||
alias Tarakan.Activity
|
||||
alias Tarakan.Infestations
|
||||
alias Tarakan.Reputation
|
||||
alias TarakanWeb.Presence
|
||||
|
||||
@wire_limit 50
|
||||
# A search sweeps a wider slice of history than the visible window.
|
||||
@search_scan_limit 200
|
||||
@presence_topic "explore:observers"
|
||||
|
||||
# Product language: Reports / Checks. Wire kinds stay :scan / :verdict internally.
|
||||
@kinds %{
|
||||
"all" => nil,
|
||||
"registrations" => :registration,
|
||||
"reports" => :scan,
|
||||
"checks" => :verdict,
|
||||
"comments" => :comment
|
||||
}
|
||||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
if connected?(socket) do
|
||||
Activity.subscribe()
|
||||
Reputation.subscribe()
|
||||
Phoenix.PubSub.subscribe(Tarakan.PubSub, @presence_topic)
|
||||
{:ok, _ref} = Presence.track(self(), @presence_topic, socket.id, %{})
|
||||
end
|
||||
|
||||
{:ok,
|
||||
socket
|
||||
|> assign(:page_title, "Explore")
|
||||
|> assign(
|
||||
:meta_description,
|
||||
"Public record: Reports, Checks, registrations, discussion."
|
||||
)
|
||||
|> assign(:canonical_path, ~p"/explore")
|
||||
|> assign(:kind, "all")
|
||||
|> assign(:query, "")
|
||||
|> assign(:watcher_count, watcher_count())
|
||||
|> assign(:hot_findings, Activity.hot_findings())
|
||||
|> assign(:infestations, Infestations.list_infestations(min_repos: 2, days: 30, limit: 5))
|
||||
|> load_wire()}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("filter", %{"kind" => kind}, socket) when is_map_key(@kinds, kind) do
|
||||
{:noreply, socket |> assign(:kind, kind) |> load_wire()}
|
||||
end
|
||||
|
||||
def handle_event("search", params, socket) do
|
||||
query = params |> Map.get("q", "") |> String.trim()
|
||||
{:noreply, socket |> assign(:query, query) |> load_wire()}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_info({:activity, entry}, socket) do
|
||||
if matches?(entry, socket.assigns.kind, socket.assigns.query) do
|
||||
{:noreply, stream_insert(socket, :wire, entry, at: 0, limit: @wire_limit)}
|
||||
else
|
||||
{:noreply, socket}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_info({:vote_changed, "canonical_finding", _id}, socket) do
|
||||
{:noreply, assign(socket, :hot_findings, Activity.hot_findings())}
|
||||
end
|
||||
|
||||
def handle_info({:vote_changed, _subject_type, _id}, socket), do: {:noreply, socket}
|
||||
|
||||
def handle_info(%Phoenix.Socket.Broadcast{event: "presence_diff"}, socket) do
|
||||
{:noreply, assign(socket, :watcher_count, watcher_count())}
|
||||
end
|
||||
|
||||
defp load_wire(socket) do
|
||||
%{kind: kind, query: query} = socket.assigns
|
||||
scan_limit = if query == "", do: @wire_limit, else: @search_scan_limit
|
||||
|
||||
# Scope the kind in the query so a rare kind returns its own `scan_limit`
|
||||
# rows instead of being crowded out of the merged newest-N window.
|
||||
entries =
|
||||
scan_limit
|
||||
|> Activity.recent(verified_only: false, kind: Map.fetch!(@kinds, kind))
|
||||
|> Enum.filter(&matches_query?(&1, query))
|
||||
|> Enum.take(@wire_limit)
|
||||
|
||||
stream(socket, :wire, entries, reset: true)
|
||||
end
|
||||
|
||||
defp matches?(entry, kind, query) do
|
||||
matches_kind?(entry, kind) and matches_query?(entry, query)
|
||||
end
|
||||
|
||||
defp matches_kind?(_entry, "all"), do: true
|
||||
defp matches_kind?(entry, kind), do: entry.kind == Map.fetch!(@kinds, kind)
|
||||
|
||||
defp matches_query?(_entry, ""), do: true
|
||||
|
||||
defp matches_query?(entry, query) do
|
||||
haystack =
|
||||
[
|
||||
Map.get(entry, :handle),
|
||||
Map.get(entry, :finding_title),
|
||||
entry.host,
|
||||
"#{entry.owner}/#{entry.name}"
|
||||
]
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|> Enum.join(" ")
|
||||
|> String.downcase()
|
||||
|
||||
String.contains?(haystack, String.downcase(query))
|
||||
end
|
||||
|
||||
defp watcher_count do
|
||||
@presence_topic |> Presence.list() |> map_size()
|
||||
end
|
||||
|
||||
# Reviews and verdicts live on the security tab; comments on the finding
|
||||
# page; a registration points at the repository itself.
|
||||
defp wire_entry_path(%{kind: :registration} = entry) do
|
||||
TarakanWeb.RepositoryPaths.repository_path(entry)
|
||||
end
|
||||
|
||||
defp wire_entry_path(%{kind: :comment} = entry) do
|
||||
"/findings/#{entry.finding_public_id}"
|
||||
end
|
||||
|
||||
defp wire_entry_path(entry) do
|
||||
TarakanWeb.RepositoryPaths.repository_security_path(entry)
|
||||
end
|
||||
|
||||
defp ledger_time(%DateTime{} = datetime) do
|
||||
Calendar.strftime(datetime, "%Y-%m-%d %H:%M")
|
||||
end
|
||||
|
||||
defp filter_active?(current, value), do: current == value
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue