Move get_favicon to Pleroma.Instances, use /
authorHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Mon, 2 Mar 2020 04:38:25 +0000 (05:38 +0100)
committerHaelwenn (lanodan) Monnier <contact@hacktivis.me>
Wed, 8 Jul 2020 04:28:39 +0000 (06:28 +0200)
lib/pleroma/application.ex
lib/pleroma/instances.ex
lib/pleroma/user.ex
lib/pleroma/web/mastodon_api/views/account_view.ex
test/fixtures/tesla_mock/https___osada.macgirvin.com.html [new file with mode: 0644]
test/support/http_request_mock.ex
test/web/mastodon_api/views/account_view_test.exs

index 9615af1229a9541bac56506a19ba63f5e59bd23a..c7fc95f75902e2796177807508fe32c58f687a36 100644 (file)
@@ -150,6 +150,7 @@ defmodule Pleroma.Application do
       build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10),
       build_cachex("failed_proxy_url", limit: 2500),
       build_cachex("banned_urls", default_ttl: :timer.hours(24 * 30), limit: 5_000)
+      build_cachex("instances", default_ttl: 25_000, ttl_interval: 1000, limit: 2500)
     ]
   end
 
index 557e8decfdd3c41e3d52e73edaa4469c4c603839..c9b1ed4ce22fdd26caed2522b2acbf995ecd4b8c 100644 (file)
@@ -37,4 +37,32 @@ defmodule Pleroma.Instances do
       url_or_host
     end
   end
+
+  def get_cached_favicon(instance_url) when is_binary(instance_url) do
+    Cachex.fetch!(:instances_cache, instance_url, fn _ -> get_favicon(instance_url) end)
+  end
+
+  def get_cached_favicon(_instance_url) do
+    nil
+  end
+
+  def get_favicon(instance_url) when is_binary(instance_url) do
+    try do
+      with {:ok, %Tesla.Env{body: html}} <-
+             Pleroma.HTTP.get(instance_url, [{:Accept, "text/html"}]),
+           favicon_rel <-
+             html
+             |> Floki.parse_document!()
+             |> Floki.attribute("link[rel=icon]", "href")
+             |> List.first(),
+           favicon_url <- URI.merge(URI.parse(instance_url), favicon_rel) |> to_string(),
+           true <- is_binary(favicon_url) do
+        favicon_url
+      else
+        _ -> nil
+      end
+    rescue
+      _ -> nil
+    end
+  end
 end
index 25ea112a262c4fca130adba306b29d6e75676fc1..e98332744010433cecf68962182e2fe05be66016 100644 (file)
@@ -2253,34 +2253,4 @@ defmodule Pleroma.User do
     |> Map.put(:bio, HTML.filter_tags(user.bio, filter))
     |> Map.put(:fields, fields)
   end
-
-  def get_cached_favicon(%User{} = user) do
-    key = "favicon:#{user.ap_id}"
-    Cachex.fetch!(:user_cache, key, fn _ -> get_favicon(user) end)
-  end
-
-  def get_cached_favicon(_user) do
-    nil
-  end
-
-  def get_favicon(user) do
-    try do
-      with url <- user.ap_id,
-           true <- is_binary(url),
-           {:ok, %Tesla.Env{body: html}} <- Pleroma.HTTP.get(url),
-           favicon_rel <-
-             html
-             |> Floki.parse_document!()
-             |> Floki.attribute("link[rel=icon]", "href")
-             |> List.first(),
-           favicon_url <- URI.merge(URI.parse(url), favicon_rel) |> to_string(),
-           true <- is_binary(favicon_url) do
-        favicon_url
-      else
-        _ -> nil
-      end
-    rescue
-      _ -> nil
-    end
-  end
 end
index efe835e3c257f8dee9638d10d0cea5607fa76c35..3ee50dfd0a18829ce68eddc6c559a390dfb041cd 100644 (file)
@@ -204,6 +204,15 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
         %{}
       end
 
+    favicon =
+      user
+      |> Map.get(:ap_id, "")
+      |> URI.parse()
+      |> URI.merge("/")
+      |> to_string()
+      |> Pleroma.Instances.get_cached_favicon()
+      |> MediaProxy.url()
+
     %{
       id: to_string(user.id),
       username: username_from_nickname(user.nickname),
@@ -246,7 +255,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
         relationship: relationship,
         skip_thread_containment: user.skip_thread_containment,
         background_image: image_url(user.background) |> MediaProxy.url(),
-        favicon: User.get_cached_favicon(user) |> MediaProxy.url()
+        favicon: favicon
       }
     }
     |> maybe_put_role(user, opts[:for])
diff --git a/test/fixtures/tesla_mock/https___osada.macgirvin.com.html b/test/fixtures/tesla_mock/https___osada.macgirvin.com.html
new file mode 100644 (file)
index 0000000..880273d
--- /dev/null
@@ -0,0 +1,301 @@
+<!DOCTYPE html >
+<html prefix="og: http://ogp.me/ns#">
+<head>
+  <title>Osada</title>
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
+<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, user-scalable=0"/>
+<meta property="generator" content="osada"/>
+<link rel="stylesheet" href="http://osada.macgirvin.com/library/fork-awesome/css/fork-awesome.min.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/vendor/twbs/bootstrap/dist/css/bootstrap.min.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/library/bootstrap-tagsinput/bootstrap-tagsinput.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/view/css/bootstrap-red.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/library/datetimepicker/jquery.datetimepicker.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/library/bootstrap-colorpicker/dist/css/bootstrap-colorpicker.min.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/library/tiptip/tipTip.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/library/jgrowl/jquery.jgrowl.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/library/jRange/jquery.range.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/view/css/conversation.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/view/css/widgets.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/view/css/colorbox.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/library/justifiedGallery/justifiedGallery.min.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/view/css/default.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/view/css/mod_home.css?v=2.3" type="text/css" media="screen">
+<link rel="stylesheet" href="http://osada.macgirvin.com/view/theme/redbasic/php/style.pcss?v=2.3" type="text/css" media="screen">
+
+<script>
+
+       var aStr = {
+
+               'delitem'     : "Delete this item?",
+               'comment'     : "Comment",
+               'showmore'    : "<i class='fa fa-chevron-down'></i> show all",
+               'showfewer'   : "<i class='fa fa-chevron-up'></i> show less",
+               'divgrowmore' : "<i class='fa fa-chevron-down'></i> expand",
+               'divgrowless' : "<i class='fa fa-chevron-up'></i> collapse",
+               'pwshort'     : "Password too short",
+               'pwnomatch'   : "Passwords do not match",
+               'everybody'   : "everybody",
+               'passphrase'  : "Secret Passphrase",
+               'passhint'    : "Passphrase hint",
+               'permschange' : "Notice: Permissions have changed but have not yet been submitted.",
+               'closeAll'    : "close all",
+               'nothingnew'  : "Nothing new here",
+               'rating_desc' : "Rate This Channel (this is public)",
+               'rating_val'  : "Rating",
+               'rating_text' : "Describe (optional)",
+               'submit'      : "Submit",
+               'linkurl'     : "Please enter a link URL",
+               'leavethispage' : "Unsaved changes. Are you sure you wish to leave this page?",
+               'location'    : "Location",
+               'lovely'      : "lovely",
+               'wonderful'   : "wonderful",
+               'fantastic'   : "fantastic",
+               'great'       : "great",
+               'nick_invld1' : "Your chosen nickname was either already taken or not valid. Please use our suggestion (",
+               'nick_invld2' : ") or enter a new one.",
+               'nick_valid'  : "Thank you, this nickname is valid.",
+               'name_empty'  : "A channel name is required.",
+               'name_ok1'    : "This is a ",
+               'name_ok2'    : " channel name",
+
+
+
+               't01' : "",
+               't02' : "",
+               't03' : "ago",
+               't04' : "from now",
+               't05' : "less than a minute",
+               't06' : "about a minute",
+               't07' : "%d minutes",
+               't08' : "about an hour",
+               't09' : "about %d hours",
+               't10' : "a day",
+               't11' : "%d days",
+               't12' : "about a month",
+               't13' : "%d months",
+               't14' : "about a year",
+               't15' : "%d years",
+               't16' : " ",
+               't17' : "[]",
+
+               'monthNames' : [ "January","February","March","April","May","June","July","August","September","October","November","December" ],
+               'monthNamesShort' : [ "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" ],
+               'dayNames' : ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
+               'dayNamesShort' : ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
+               'today' : "today",
+               'month' : "month",
+               'week' : "week",
+               'day' : "day",
+               'allday' : "All day"
+       };
+
+</script>
+               
+
+<script src="http://osada.macgirvin.com/view/js/jquery.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/justifiedGallery/jquery.justifiedGallery.min.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/sprintf.js/dist/sprintf.min.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/textcomplete/textcomplete.min.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/view/js/autocomplete.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/jquery.timeago.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/readmore.js/readmore.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/sticky-kit/sticky-kit.min.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/jgrowl/jquery.jgrowl_minimized.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/view/js/acl.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/view/js/webtoolkit.base64.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/jRange/jquery.range.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/colorbox/jquery.colorbox-min.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/jquery.AreYouSure/jquery.are-you-sure.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/tableofcontents/jquery.toc.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/imagesloaded/imagesloaded.pkgd.min.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/bootbox/bootbox.min.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/bootstrap-tagsinput/bootstrap-tagsinput.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/datetimepicker/jquery.datetimepicker.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/library/bootstrap-colorpicker/dist/js/bootstrap-colorpicker.js?v=2.3"></script>
+<script src="http://osada.macgirvin.com/view/theme/redbasic/js/redbasic.js?v=2.3"></script>
+
+
+
+<script>
+       var updateInterval = 80000;
+       var localUser = false;
+       var zid = null;
+       var justifiedGalleryActive = false;
+                       var preloadImages = 0;
+</script>
+
+
+
+<script>$(document).ready(function() { $("#nav-search-text").search_autocomplete('https://osada.macgirvin.com/acl');});</script><script src="http://osada.macgirvin.com/view/js/main.js?v=2.3"></script>
+</head>
+<body>
+               <header></header>
+       <nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-dark"><div class="project-banner" title="Powered by Osada"><a href="https://osada.macgirvin.com/">&#x2638;</a></div>
+<div class="d-lg-none pt-1 pb-1">
+               <a class="btn btn-primary btn-sm text-white" href="#" title="Sign in" id="login_nav_btn_collapse" data-toggle="modal" data-target="#nav-login">
+               Login
+       </a>
+               </div>
+<div class="navbar-toggler-right">
+               <button id="expand-aside" type="button" class="d-lg-none navbar-toggler border-0" data-toggle="offcanvas" data-target="#region_1">
+               <i class="fa fa-arrow-circle-right" id="expand-aside-icon"></i>
+       </button>
+               <button id="menu-btn" class="navbar-toggler border-0" type="button" data-toggle="collapse" data-target="#navbar-collapse-2">
+               <i class="fa fa-bars"></i>
+       </button>
+</div>
+<div class="collapse navbar-collapse" id="navbar-collapse-1">
+       <ul class="navbar-nav mr-auto">
+                               <li class="nav-item d-lg-flex">
+                                               <a class="nav-link" href="#" title="Sign in" id="login_nav_btn" data-toggle="modal" data-target="#nav-login">
+                       Login
+                       </a>
+                                       </li>
+                                                       </ul>
+
+       <div id="banner" class="navbar-text"></div>
+
+       <ul id="nav-right" class="navbar-nav ml-auto">
+               <li class="nav-item collapse clearfix" id="nav-search">
+                       <form class="form-inline" method="get" action="search" role="search">
+                               <input class="form-control form-control-sm mt-1 mr-2" id="nav-search-text" type="text" value="" placeholder="@name, !forum, #tag, content" name="search" title="Search site @name, !forum, #tag, ?docs, content" onclick="this.submit();" onblur="closeMenu('nav-search'); openMenu('nav-search-btn');"/>
+                       </form>
+                       <div id="nav-search-spinner" class="spinner-wrapper">
+                               <div class="spinner s"></div>
+                       </div>
+               </li>
+               <li class="nav-item" id="nav-search-btn">
+                       <a class="nav-link" href="#nav-search" title="Search site @name, !forum, #tag, ?docs, content" onclick="openMenu('nav-search'); closeMenu('nav-search-btn'); $('#nav-search-text').focus(); return false;"><i class="fa fa-fw fa-search"></i></a>
+               </li>
+                                                                               <li class="nav-item dropdown" id="app-menu">
+                       <a class="nav-link" href="#" data-toggle="dropdown"><i class="fa fa-fw fa-bars"></i></a>
+                       <div id="dropdown-menu" class="dropdown-menu dropdown-menu-right">
+                                                                                               <a class="dropdown-item" href="https://osada.macgirvin.com/directory"><i class="generic-icons-nav fa fa-fw fa-sitemap"></i>Directory</a>
+
+
+                                                               <a class="dropdown-item" href="https://osada.macgirvin.com/lang"><i class="generic-icons-nav fa fa-fw fa-language"></i>Language</a>
+
+
+                                                               <a class="dropdown-item" href="https://osada.macgirvin.com/search"><i class="generic-icons-nav fa fa-fw fa-search"></i>Search</a>
+
+
+                                                                                                                       </div>
+               </li>
+       </ul>
+</div>
+<div class="collapse d-lg-none" id="navbar-collapse-2">
+       <div class="navbar-nav mr-auto">
+                                                               <a class="nav-link" href="https://osada.macgirvin.com/directory"><i class="generic-icons-nav fa fa-fw fa-sitemap"></i>Directory</a>
+
+
+                               <a class="nav-link" href="https://osada.macgirvin.com/lang"><i class="generic-icons-nav fa fa-fw fa-language"></i>Language</a>
+
+
+                               <a class="nav-link" href="https://osada.macgirvin.com/search"><i class="generic-icons-nav fa fa-fw fa-search"></i>Search</a>
+
+
+                                                       </div>
+</div>
+</nav>
+       <main>
+               <aside id="region_1"><div class="aside_spacer"><div id="left_aside_wrapper"></div></div></aside>
+               <section id="region_2"><h1 class="home-welcome">Welcome to Osada</h1><form action="https://osada.macgirvin.com/" id="main-login" method="post">
+       <input type="hidden" name="auth-params" value="login"/>
+       <div id="login-main">
+               <div id="login-input" class="form-group">
+                               <div id="id_username_wrapper" class="form-group">
+               <label for="id_username" id="label_username">Login/Email</label>
+               <input class="form-control" name="username" id="id_username" type="text" value="">
+               <small id="help_username" class="form-text text-muted"></small>
+       </div>
+                               <div class="form-group">
+               <label for="id_password">Password</label>
+               <input class="form-control" type="password" name="password" id="id_password" value="">          <small id="help_password" class="form-text text-muted"></small>
+       </div>
+                               <div id="remember_container" class="clearfix form-group checkbox">
+               <label for="id_remember">Remember me</label>
+               <div class="float-right"><input type="checkbox" name="remember" id="id_remember" value="1"/><label class="switchlabel" for="id_remember"> <span class="onoffswitch-inner" data-on="Yes" data-off="No"></span><span class="onoffswitch-switch"></span></label></div>
+               <small class="form-text text-muted"></small>
+       </div>
+                       <button type="submit" name="submit" class="btn btn-block btn-primary">Login</button>
+               </div>
+               <div id="login-extra-links">
+                       <a href="https://osada.macgirvin.com/pubsites" title="Create an account to access services and applications" id="register-link" class="pull-right">Register</a>                 <a href="lostpass" title="Forgot your password?" id="lost-password-link">Password Reset</a>
+               </div>
+               <hr>
+               <a href="rmagic" class="btn btn-block btn-outline-success rmagic-button">Remote Authentication</a>
+       </div>
+                       <input type="hidden" name="0" value=""/>
+       </form>
+<script type="text/javascript"> $(document).ready(function() { $("#id_username").focus();} );</script>
+<div id="nav-login" class="modal" tabindex="-1" role="dialog">
+       <div class="modal-dialog" role="document">
+               <div class="modal-content">
+                       <div class="modal-header">
+                               <h4 class="modal-title">Login</h4>
+                               <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+                       </div>
+                       <div class="modal-body">
+                               <div class="form-group">
+                                       <form action="https://osada.macgirvin.com/" id="main-login" method="post">
+       <input type="hidden" name="auth-params" value="login"/>
+       <div id="login-main">
+               <div id="login-input" class="form-group">
+                               <div id="id_username_wrapper" class="form-group">
+               <label for="id_username" id="label_username">Login/Email</label>
+               <input class="form-control" name="username" id="id_username" type="text" value="">
+               <small id="help_username" class="form-text text-muted"></small>
+       </div>
+                               <div class="form-group">
+               <label for="id_password">Password</label>
+               <input class="form-control" type="password" name="password" id="id_password" value="">          <small id="help_password" class="form-text text-muted"></small>
+       </div>
+                               <div id="remember_me_container" class="clearfix form-group checkbox">
+               <label for="id_remember_me">Remember me</label>
+               <div class="float-right"><input type="checkbox" name="remember_me" id="id_remember_me" value="1"/><label class="switchlabel" for="id_remember_me"> <span class="onoffswitch-inner" data-on="Yes" data-off="No"></span><span class="onoffswitch-switch"></span></label></div>
+               <small class="form-text text-muted"></small>
+       </div>
+                       <button type="submit" name="submit" class="btn btn-block btn-primary">Login</button>
+               </div>
+               <div id="login-extra-links">
+                       <a href="https://osada.macgirvin.com/pubsites" title="Create an account to access services and applications" id="register-link" class="pull-right">Register</a>                 <a href="lostpass" title="Forgot your password?" id="lost-password-link">Password Reset</a>
+               </div>
+               <hr>
+               <a href="rmagic" class="btn btn-block btn-outline-success rmagic-button">Remote Authentication</a>
+       </div>
+                       <input type="hidden" name="0" value=""/>
+       </form>
+
+                               </div>
+                       </div>
+               </div>
+       </div>
+</div>
+                                       <div id="page-footer"></div>
+                       <div id="pause"></div>
+               </section>
+               <aside id="region_3" class="d-none d-xl-table-cell"><div class="aside_spacer"><div id="right_aside_wrapper"></div></div></aside>
+       </main>
+       <footer></footer>
+</body>
+</html>
+<!--
+     FILE ARCHIVED ON 11:49:38 Jan 26, 2019 AND RETRIEVED FROM THE
+     INTERNET ARCHIVE ON 04:27:56 Mar 02, 2020.
+
+     CONTENT MAY BE PROTECTED BY COPYRIGHT (17 U.S.C. SECTION 108(a)(3)).
+-->
+<!--
+playback timings (ms):
+  exclusion.robots: 0.217
+  CDXLines.iter: 14.7 (3)
+  LoadShardBlock: 165.298 (3)
+  esindex: 0.01
+  PetaboxLoader3.datanode: 72.599 (4)
+  exclusion.robots.policy: 0.208
+  RedisCDXSource: 16.804
+  PetaboxLoader3.resolve: 146.316 (4)
+  captures_list: 199.59
+  load_resource: 56.473
+-->
\ No newline at end of file
index 4d33c6250917301e0b635463942a0c333b2bbea0..19a2026544963fa5eece3c5b35d69125efbfbda4 100644 (file)
@@ -1342,10 +1342,18 @@ defmodule HttpRequestMock do
     {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/relay/relay.json")}}
   end
 
-  def get("http://localhost:4001/users/" <> _, _, _, _) do
+  def get("http://localhost:4001/", _, "", Accept: "text/html") do
     {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/7369654.html")}}
   end
 
+  def get("https://osada.macgirvin.com/", _, "", Accept: "text/html") do
+    {:ok,
+     %Tesla.Env{
+       status: 200,
+       body: File.read!("test/fixtures/tesla_mock/https___osada.macgirvin.com.html")
+     }}
+  end
+
   def get(url, query, body, headers) do
     {:error,
      "Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{
index e01a7c1eef641f40ac4b35ea6f5ae4237a54556d..c4341cb2809e50b536b4aec003edcf31bbf79119 100644 (file)
@@ -75,7 +75,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
       pleroma: %{
         ap_id: user.ap_id,
         background_image: "https://example.com/images/asuka_hospital.png",
-        favicon: nil,
+        favicon:
+          "https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png",
         confirmation_pending: false,
         tags: [],
         is_admin: false,
@@ -153,7 +154,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
       pleroma: %{
         ap_id: user.ap_id,
         background_image: nil,
-        favicon: nil,
+        favicon:
+          "https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png",
         confirmation_pending: false,
         tags: [],
         is_admin: false,