Commit 10c0bf9fec792840c95986ca271fe780cb7013d9

Thomas de Grivel 2023-11-09T12:44:31

optimize avatar loading, fix gravatar circle class

diff --git a/lib/kmxgit/user_manager.ex b/lib/kmxgit/user_manager.ex
index af02699..29cc3cb 100644
--- a/lib/kmxgit/user_manager.ex
+++ b/lib/kmxgit/user_manager.ex
@@ -148,6 +148,19 @@ defmodule Kmxgit.UserManager do
       limit: 1
   end
  
+  def get_users_by_email(emails) when is_list(emails) do
+    Repo.all(from u in User,
+      where: u.email in ^emails)
+    |> get_users_by_email_map(%{})
+  end
+
+  defp get_users_by_email_map([], acc) do
+    acc
+  end
+  defp get_users_by_email_map([user | rest], acc) do
+    get_users_by_email_map(rest, Map.put(acc, user.email, user))
+  end
+ 
   def register_user(attrs) do
     %User{}
     |> User.registration_changeset(attrs)
diff --git a/lib/kmxgit_web/controllers/repository_controller.ex b/lib/kmxgit_web/controllers/repository_controller.ex
index 495fde3..8af29b0 100644
--- a/lib/kmxgit_web/controllers/repository_controller.ex
+++ b/lib/kmxgit_web/controllers/repository_controller.ex
@@ -22,6 +22,7 @@ defmodule KmxgitWeb.RepositoryController do
   alias Kmxgit.RepositoryManager
   alias Kmxgit.RepositoryManager.Repository
   alias Kmxgit.SlugManager
+  alias Kmxgit.UserManager
   alias Kmxgit.UserManager.User
   alias Kmxgit.Repo
   alias KmxgitWeb.OpParams
@@ -338,7 +339,7 @@ defmodule KmxgitWeb.RepositoryController do
       if op_params && repo && (repo.public_access || Repository.member?(repo, current_user)) do
         org = repo.organisation
         user = repo.user
-        git = setup_git(repo, conn, op, op_params)
+        git = git_setup(repo, conn, op, op_params)
         first_tree = Enum.find_value(git.trees,
           fn {:branch, "master", _} -> "master"
             _ -> false
@@ -563,6 +564,26 @@ defmodule KmxgitWeb.RepositoryController do
     end
   end
 
+  defp git_add_user_email(git, email) do
+    if Enum.find(git.users_email, email) do
+      git
+    else
+      %{git | users_email: [email | git.users_email]}
+    end
+  end
+
+  defp git_add_user_emails(git, []) do
+    git
+  end
+  defp git_add_user_emails(git, [email | rest]) do
+    git_add_user_emails(git_add_user_email(git, email), rest)
+  end
+
+  defp git_put_avatars(git = %{valid: true}) do
+    users_by_email = UserManager.get_users_by_email(Enum.uniq(git.users_email))
+    %{git | users_by_email: users_by_email}
+  end
+
   defp git_put_branches(git = %{valid: true}, repo, conn, op, path) do
     case Git.branches(Repository.full_slug(repo)) do
       {:ok, branches} ->
@@ -598,22 +619,25 @@ defmodule KmxgitWeb.RepositoryController do
     git
   end
 
-  defp git_log(repo, tree, path) do
+  defp git_put_log(git, repo, tree, path) do
     slug = Repository.full_slug(repo)
-    case Git.log(slug, tree, path || "") do
-      {:ok, log} -> Enum.map log, fn log1 ->
-          ci_status_path = "priv/ci/#{Repository.full_slug(repo)}/ci/status/rbpkg_ci.#{repo.slug}.commit_#{log1.hash}.status"
-          if File.exists?(ci_status_path) do
-            {:ok, ci_status} = File.read(ci_status_path)
-            %{log1 | ci_status: String.trim(ci_status)}
-          else
-            log1
+    log = case Git.log(slug, tree, path || "") do
+            {:ok, log} -> Enum.map log, fn log1 ->
+                ci_status_path = "priv/ci/#{Repository.full_slug(repo)}/ci/status/rbpkg_ci.#{repo.slug}.commit_#{log1.hash}.status"
+                if File.exists?(ci_status_path) do
+                  {:ok, ci_status} = File.read(ci_status_path)
+                  %{log1 | ci_status: String.trim(ci_status)}
+                else
+                  log1
+                end
+              end
+            {:error, reason} ->
+              Logger.error(inspect(reason))
+              nil
           end
-        end
-      {:error, reason} ->
-        Logger.error(inspect(reason))
-        nil
-    end
+    emails = Enum.map(log, & &1.author_email) |> Enum.uniq()
+    %{git | log: log}
+    |> git_add_user_emails(emails)
   end
 
   defp git_put_content(git = %{files: [%{name: name, sha1: sha1, type: :blob}], valid: true}, repo, path) do
@@ -647,14 +671,14 @@ defmodule KmxgitWeb.RepositoryController do
   defp git_put_log1(git = %{valid: true}, repo, tree, path) do
     slug = Repository.full_slug(repo)
     log1 = case Git.log(slug, tree, path || "", 0, 1) do
-             {:ok, [log1]} ->
-               ci_status_path = "priv/ci/#{Repository.full_slug(repo)}/ci/status/rbpkg_ci.#{repo.slug}.commit_#{log1.hash}.status"
+             {:ok, [commit]} ->
+               ci_status_path = "priv/ci/#{Repository.full_slug(repo)}/ci/status/rbpkg_ci.#{repo.slug}.commit_#{commit.hash}.status"
                IO.inspect(ci_status_path)
                if File.exists?(ci_status_path) do
                  {:ok, ci_status} = File.read(ci_status_path)
-                 %{log1 | ci_status: String.trim(ci_status)}
+                 %{commit | ci_status: String.trim(ci_status)}
                else
-                 log1
+                 commit
                end
              {:ok, _result} ->
                #IO.inspect({:log1, result})
@@ -664,6 +688,7 @@ defmodule KmxgitWeb.RepositoryController do
                nil
            end
     %{git | log1: log1}
+    |> git_add_user_email(log1.author_email)
   end
   defp git_put_log1(git, _, _, _) do
     git
@@ -740,6 +765,29 @@ defmodule KmxgitWeb.RepositoryController do
     git
   end
 
+  defp git_setup(repo, conn, op, op_params) do
+    %{trees: [],
+      content: nil,
+      content_lang: nil,
+      content_html: nil,
+      content_type: nil,
+      filename: nil,
+      files: [],
+      line_numbers: nil,
+      log: nil,
+      log1: nil,
+      markdown_html: nil,
+      path: op_params.path,
+      readme: [],
+      release: nil,
+      status: "",
+      tags: [],
+      users_by_email: %{},
+      users_email: [],
+      valid: true}
+      |> git_put_branches(repo, conn, op, op_params.path)
+  end
+
   @lang_ext %{
     "ex" => "elixir",
     "exs" => "elixir",
@@ -778,27 +826,7 @@ defmodule KmxgitWeb.RepositoryController do
       MIME.type(ext)
     end
   end
-
-  defp setup_git(repo, conn, op, op_params) do
-    %{trees: [],
-      content: nil,
-      content_lang: nil,
-      content_html: nil,
-      content_type: nil,
-      filename: nil,
-      files: [],
-      line_numbers: nil,
-      log1: nil,
-      markdown_html: nil,
-      path: op_params.path,
-      readme: [],
-      release: nil,
-      status: "",
-      tags: [],
-      valid: true}
-      |> git_put_branches(repo, conn, op, op_params.path)
-  end
-
+  
   defp show_op(conn, :blob, %{git: git, path: path, repo: repo, tree: tree}) do
     git = git
     |> git_put_files(repo, tree, path, conn)
@@ -857,6 +885,7 @@ defmodule KmxgitWeb.RepositoryController do
     git = git
     |> git_put_log1(repo, tree, path)
     |> git_put_commit(repo, conn, op, tree, path)
+    |> git_put_avatars()
     #IO.inspect(git)
     diff = case Git.diff(Repository.full_slug(repo), "#{git.log1.hash}~1", git.log1.hash) do
              {:ok, diff} -> diff
@@ -896,16 +925,19 @@ defmodule KmxgitWeb.RepositoryController do
     end
   end
   defp show_op(conn, :log, %{tree: tree, git: git, org: org, path: path, repo: repo}) do
-    log = git_log(repo, tree, path)
+    git = git
+    |> git_put_log(repo, tree, path)
+    |> git_put_avatars()
+
     #IO.inspect([:log, tree: tree, git: git, path: path, log: log])
-    if log do
+    if git.log do
       conn
       |> assign(:tree, tree)
       |> assign(:tree_url, Routes.repository_path(conn, :show, Repository.owner_slug(repo), Repository.splat(repo, ["_log", tree] ++ (if path, do: String.split(path, "/"), else: []))))
       |> assign_current_organisation(org)
       |> assign(:current_repository, repo)
       |> assign(:git, git)
-      |> assign(:log, log)
+      |> assign(:log, git.log)
       |> assign(:path, path)
       |> assign(:repo, repo)
       |> render("log.html")
@@ -918,6 +950,8 @@ defmodule KmxgitWeb.RepositoryController do
     |> git_put_log1(repo, tree, path)
     |> git_put_release(repo, tree, conn)
     |> git_put_tags(repo, conn, op, nil)
+    |> git_put_avatars()
+
     tag = Enum.find(git.tags, fn tag -> tag == tree end)
     if git.log1 && tag do
       conn
@@ -940,6 +974,7 @@ defmodule KmxgitWeb.RepositoryController do
     |> git_put_readme(repo)
     |> git_put_log1(repo, tree, path)
     |> git_put_tags(repo, conn, op, path)
+    |> git_put_avatars()
     if (git.content == nil) && ! String.match?(conn.request_path, ~r(/$)) do
       redirect conn, to: conn.request_path <> "/"
     else
diff --git a/lib/kmxgit_web/templates/organisation/show.html.heex b/lib/kmxgit_web/templates/organisation/show.html.heex
index e0582f0..970f51c 100644
--- a/lib/kmxgit_web/templates/organisation/show.html.heex
+++ b/lib/kmxgit_web/templates/organisation/show.html.heex
@@ -73,7 +73,7 @@
                 </th>
                 <td>
                   <%= for user <- @org.users do %>
-                    <%= render(KmxgitWeb.UserView, "avatar.html", conn: @conn, email: user.email, size: 48, title: User.login(user), class: "") %>
+                    <%= render(KmxgitWeb.UserView, "avatar.html", conn: @conn, user: user, email: user.email, size: 48, title: User.login(user), class: "") %>
                   <% end %>
                 </td>
               </tr>
diff --git a/lib/kmxgit_web/templates/repository/commit.html.heex b/lib/kmxgit_web/templates/repository/commit.html.heex
index 736752c..2c35566 100644
--- a/lib/kmxgit_web/templates/repository/commit.html.heex
+++ b/lib/kmxgit_web/templates/repository/commit.html.heex
@@ -15,7 +15,7 @@
         <%= @commit.hash %>
       </h2>
       <div>
-        <%= render(KmxgitWeb.UserView, "avatar.html", conn: @conn, email: @commit.author_email, size: 48, title: @commit.author, class: "commit-avatar") %>
+        <%= render(KmxgitWeb.UserView, "avatar.html", conn: @conn, user: Map.get(@git.users_by_email, @commit.author_email), email: @commit.author_email, size: 48, title: @commit.author, class: "commit-avatar") %>
         <%= NaiveDateTime.add(~N[1970-01-01 00:00:00], @commit.date) %>
         <p>
           <%= @commit.message %>
diff --git a/lib/kmxgit_web/templates/repository/log.html.heex b/lib/kmxgit_web/templates/repository/log.html.heex
index f952eb9..03cee3b 100644
--- a/lib/kmxgit_web/templates/repository/log.html.heex
+++ b/lib/kmxgit_web/templates/repository/log.html.heex
@@ -32,7 +32,7 @@
           <%= for commit <- @log do %>
             <tr class="commit">
               <td class="author">
-                <%= render(KmxgitWeb.UserView, "avatar.html", conn: @conn, email: commit.author_email, size: 48, title: commit.author, class: "") %>
+                <%= render(KmxgitWeb.UserView, "avatar.html", conn: @conn, user: Map.get(@git.users_by_email, commit.author_email), email: commit.author_email, size: 48, title: commit.author, class: "") %>
               </td>
               <td class="hash">
                 <%= link String.slice(commit.hash, 0..7), id: commit.hash, to: Routes.repository_path(@conn, :show, Repository.owner_slug(@repo), Repository.splat(@repo, ["_commit", commit.hash])) %>
diff --git a/lib/kmxgit_web/templates/repository/show_commit_message.html.heex b/lib/kmxgit_web/templates/repository/show_commit_message.html.heex
index 3844ab9..65010d5 100644
--- a/lib/kmxgit_web/templates/repository/show_commit_message.html.heex
+++ b/lib/kmxgit_web/templates/repository/show_commit_message.html.heex
@@ -11,7 +11,7 @@
         to: Routes.repository_path(@conn, :show, Repository.owner_slug(@repo), Repository.splat(@repo, ["_commit", @git.log1.hash])) do %><%= String.slice(@git.log1.hash, 0..7) %><% end %>
         <br/>
         <span class="property"><%= gettext "Author" %> :</span>
-        <%= render(KmxgitWeb.UserView, "avatar.html", conn: @conn, email: @git.log1.author_email, size: 48, right: @git.log1.author, title: @git.log1.author, class: "commit-avatar") %>
+        <%= render(KmxgitWeb.UserView, "avatar.html", conn: @conn, user: Map.get(@git.users_by_email, @git.log1.author_email), email: @git.log1.author_email, size: 48, right: @git.log1.author, title: @git.log1.author, class: "commit-avatar") %>
         <br/>
         <span class="property"><%= gettext "Date" %> :</span>
         <%= NaiveDateTime.add(~N[1970-01-01 00:00:00], @git.log1.date) %>
diff --git a/lib/kmxgit_web/templates/repository/show_properties.html.heex b/lib/kmxgit_web/templates/repository/show_properties.html.heex
index 83cb611..92822af 100644
--- a/lib/kmxgit_web/templates/repository/show_properties.html.heex
+++ b/lib/kmxgit_web/templates/repository/show_properties.html.heex
@@ -47,7 +47,7 @@
           </th>
           <td>
             <%= for user <- @members do %>
-              <%= render(KmxgitWeb.UserView, "avatar.html", conn: @conn, email: user.email, size: 48, title: User.login(user), class: "") %>
+              <%= render(KmxgitWeb.UserView, "avatar.html", conn: @conn, user: user, email: user.email, size: 48, title: User.login(user), class: "") %>
             <% end %>
           </td>
         </tr>
@@ -81,10 +81,6 @@
             </td>
           </tr>
         <% end %>
-        <tr>
-          <th><%= gettext("Disk usage") %></th>
-          <td><%= disk_usage(@disk_usage) %></td>
-        </tr>
       </table>
     </li>
   </ul>
diff --git a/lib/kmxgit_web/templates/repository/tag.html.heex b/lib/kmxgit_web/templates/repository/tag.html.heex
index 509a229..86be48d 100644
--- a/lib/kmxgit_web/templates/repository/tag.html.heex
+++ b/lib/kmxgit_web/templates/repository/tag.html.heex
@@ -30,7 +30,7 @@
         </tr>
         <tr>
           <th><%= gettext("Author") %></th>
-          <td>  <%= render(KmxgitWeb.UserView, "avatar.html", conn: @conn, email: @git.log1.author_email, size: 48, title: @git.log1.author, class: "commit-avatar") %>
+          <td>  <%= render(KmxgitWeb.UserView, "avatar.html", conn: @conn, user: Map.get(@git.users_by_email, @git.log1.author_email), email: @git.log1.author_email, size: 48, title: @git.log1.author, class: "commit-avatar") %>
 </td>
         </tr>
         <tr>
diff --git a/lib/kmxgit_web/templates/user/avatar.html.heex b/lib/kmxgit_web/templates/user/avatar.html.heex
index 08f3542..6237141 100644
--- a/lib/kmxgit_web/templates/user/avatar.html.heex
+++ b/lib/kmxgit_web/templates/user/avatar.html.heex
@@ -3,10 +3,9 @@ if @right, do: " #{@right}", else: nil
 rescue
 _ -> nil
 end %>
-<% user = UserManager.get_user_by_email(@email) %>
-<%= if user do %>
-  <% avatar_path = Avatar.path(user, @size) %>
-  <%= link to: Routes.slug_path(@conn, :show, User.login(user)) do %><%= if File.exists?(avatar_path) do %><%= img_tag(Routes.user_path(@conn, :avatar, User.login(user), @size), alt: @title, title: @title, class: "#{@class} circle") %><% else %><img src={Exgravatar.gravatar_url(@email, s: @size)} alt={@title} title={@title} class={@class} /><% end %><%= right %><% end %>
+<%= if @user do %>
+  <% avatar_path = Avatar.path(@user, @size) %>
+  <%= link to: Routes.slug_path(@conn, :show, User.login(@user)) do %><%= if File.exists?(avatar_path) do %><%= img_tag(Routes.user_path(@conn, :avatar, User.login(@user), @size), alt: @title, title: @title, class: "#{@class} circle") %><% else %><img src={Exgravatar.gravatar_url(@email, s: @size)} alt={@title} title={@title} class={"#{@class} circle"} /><% end %><%= right %><% end %>
 <% else %>
-  <img src={Exgravatar.gravatar_url(@email, s: @size)} alt={@title} title={@title} class={@class} />
+  <img src={Exgravatar.gravatar_url(@email, s: @size)} alt={@title} title={@title} class={"#{@class} circle"} />
 <% end %>
diff --git a/lib/kmxgit_web/templates/user/show.html.heex b/lib/kmxgit_web/templates/user/show.html.heex
index 29a96ce..538de64 100644
--- a/lib/kmxgit_web/templates/user/show.html.heex
+++ b/lib/kmxgit_web/templates/user/show.html.heex
@@ -1,7 +1,7 @@
 <div class="container-fluid">
   <div class="row">
     <div class="col col-12">
-      <%= render("avatar.html", conn: @conn, email: @user.email, size: 256, title: User.login(@user), class: "avatar-lg") %>
+      <%= render("avatar.html", conn: @conn, user: @user, email: @user.email, size: 256, title: User.login(@user), class: "avatar-lg") %>
       <h1><%= @user.name %> (<%= User.login(@user) %>)</h1>
       <div class="col col-12 col-md-8">
         <%= if @user.description do %>
diff --git a/lib/kmxgit_web/views/user_view.ex b/lib/kmxgit_web/views/user_view.ex
index 6fbfaba..3966cc1 100644
--- a/lib/kmxgit_web/views/user_view.ex
+++ b/lib/kmxgit_web/views/user_view.ex
@@ -15,6 +15,5 @@ defmodule KmxgitWeb.UserView do
   use KmxgitWeb, :view
 
   alias Kmxgit.RepositoryManager.Repository
-  alias Kmxgit.UserManager
   alias Kmxgit.UserManager.{Avatar, User}
 end