<commit_before>defmodule BorsNG.ProjectController do
  @moduledoc """
  Shows a list of repositories, a single repository,
  and the repository's settings page.

  n.b.
  We call it a project internally, though it corresponds
  to a GitHub repository. This is to avoid confusing
  a GitHub repo with an Ecto repo.
  """

  use BorsNG.Web, :controller

  alias BorsNG.Worker.Batcher
  alias BorsNG.Database.Context.Permission
  alias BorsNG.Database.Repo
  alias BorsNG.Database.LinkMemberProject
  alias BorsNG.Database.LinkUserProject
  alias BorsNG.Database.Project
  alias BorsNG.Database.Batch
  alias BorsNG.Database.Crash
  alias BorsNG.Database.Patch
  alias BorsNG.Database.User
  alias BorsNG.GitHub
  alias BorsNG.Worker.Syncer

  # Auto-grab the project and check the permissions

  def action(conn, _) do
    do_action(conn, action_name(conn), conn.params)
  end

  defp do_action(conn, action, %{"id" => id} = params) do
    allow_private_repos = Confex.fetch_env!(
      :bors, BorsNG)[:allow_private_repos]
    project = Project
    |> from(preload: [:installation])
    |> Repo.get!(id)
    mode = cond do
      User.has_perm(Repo, conn.assigns.user, project.id) -> :rw
      !allow_private_repos -> :ro
      true -> raise BorsNG.PermissionDeniedError
    end
    apply(__MODULE__, action, [conn, mode, project, params])
  end
  defp do_action(conn, action, params) do
    apply(__MODULE__, action, [conn, params])
  end

  # The actual handlers
  # Two-item ones have a project ID inputed
  # One-item ones don't

  def index(conn, _params) do
    projects = Repo.all(Project.by_owner(conn.assigns.user.id))
    render conn, "index.html", projects: projects
  end

  defp batch_info(batch) do
    %{
      commit: batch.commit,
      patches: Repo.all(Patch.all_for_batch(batch.id)),
      state: batch.state}
  end

  def show(conn, mode, project, _params) do
    batches = project.id
    |> Batch.all_for_project(:incomplete)
    |> Repo.all()
    |> Enum.map(&batch_info/1)
    unbatched_patches = project.id
    |> Patch.all_for_project(:awaiting_review)
    |> Repo.all()
    is_synchronizing = match?(
      [{_, _}],
      Registry.lookup(Syncer.Registry, project.id))
    render conn, "show.html",
      project: project,
      batches: batches,
      is_synchronizing: is_synchronizing,
      unbatched_patches: unbatched_patches,
      mode: mode
  end

  def settings(_, :ro, _, _), do: raise BorsNG.PermissionDeniedError
  def settings(conn, :rw, project, _params) do
    reviewers = Permission.list_users_for_project(:reviewer, project.id)
    members = Permission.list_users_for_project(:member, project.id)
    render conn, "settings.html",<commit_msg>Sort reviewers & members lists<commit_after>defmodule BorsNG.ProjectController do
  @moduledoc """
  Shows a list of repositories, a single repository,
  and the repository's settings page.

  n.b.
  We call it a project internally, though it corresponds
  to a GitHub repository. This is to avoid confusing
  a GitHub repo with an Ecto repo.
  """

  use BorsNG.Web, :controller

  alias BorsNG.Worker.Batcher
  alias BorsNG.Database.Context.Permission
  alias BorsNG.Database.Repo
  alias BorsNG.Database.LinkMemberProject
  alias BorsNG.Database.LinkUserProject
  alias BorsNG.Database.Project
  alias BorsNG.Database.Batch
  alias BorsNG.Database.Crash
  alias BorsNG.Database.Patch
  alias BorsNG.Database.User
  alias BorsNG.GitHub
  alias BorsNG.Worker.Syncer

  # Auto-grab the project and check the permissions

  def action(conn, _) do
    do_action(conn, action_name(conn), conn.params)
  end

  defp do_action(conn, action, %{"id" => id} = params) do
    allow_private_repos = Confex.fetch_env!(
      :bors, BorsNG)[:allow_private_repos]
    project = Project
    |> from(preload: [:installation])
    |> Repo.get!(id)
    mode = cond do
      User.has_perm(Repo, conn.assigns.user, project.id) -> :rw
      !allow_private_repos -> :ro
      true -> raise BorsNG.PermissionDeniedError
    end
    apply(__MODULE__, action, [conn, mode, project, params])
  end
  defp do_action(conn, action, params) do
    apply(__MODULE__, action, [conn, params])
  end

  # The actual handlers
  # Two-item ones have a project ID inputed
  # One-item ones don't

  def index(conn, _params) do
    projects = Repo.all(Project.by_owner(conn.assigns.user.id))
    render conn, "index.html", projects: projects
  end

  defp batch_info(batch) do
    %{
      commit: batch.commit,
      patches: Repo.all(Patch.all_for_batch(batch.id)),
      state: batch.state}
  end

  def show(conn, mode, project, _params) do
    batches = project.id
    |> Batch.all_for_project(:incomplete)
    |> Repo.all()
    |> Enum.map(&batch_info/1)
    unbatched_patches = project.id
    |> Patch.all_for_project(:awaiting_review)
    |> Repo.all()
    is_synchronizing = match?(
      [{_, _}],
      Registry.lookup(Syncer.Registry, project.id))
    render conn, "show.html",
      project: project,
      batches: batches,
      is_synchronizing: is_synchronizing,
      unbatched_patches: unbatched_patches,
      mode: mode
  end

  def settings(_, :ro, _, _), do: raise BorsNG.PermissionDeniedError
  def settings(conn, :rw, project, _params) do
    reviewers = Permission.list_users_for_project(:reviewer, project.id)
    |> Enum.sort_by(fn %User{login: login} ->
      case conn.assigns[:user].login do
        ^login -> ""
        _ -> login
      end
    end)
    members = Permission.list_users_for_project(:member, project.id)
    |> Enum.sort_by(fn %User{login: login} ->
      case conn.assigns[:user].login do
        ^login -> ""
        _ -> login
      end
    end)
    render conn, "settings.html",
{'fraction_non_alphanumeric': 0.10727496917385944, 'fraction_numerical': 0.00035229874933943986, 'mean_word_length': 3.3376623376623376, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3421043', 'n_tokens_mistral': 1932, 'n_tokens_neox': 1868, 'n_words': 460}