Move get_favicon to Pleroma.Instances, use /

This commit is contained in:
Haelwenn (lanodan) Monnier 2020-03-02 05:38:25 +01:00
parent f6d09fafee
commit 6a679d80c9
No known key found for this signature in database
GPG key ID: D5B7A8E43C997DEE
7 changed files with 353 additions and 34 deletions

View file

@ -150,6 +150,7 @@ defp cachex_children do
build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10), build_cachex("emoji_packs", expiration: emoji_packs_expiration(), limit: 10),
build_cachex("failed_proxy_url", limit: 2500), build_cachex("failed_proxy_url", limit: 2500),
build_cachex("banned_urls", default_ttl: :timer.hours(24 * 30), limit: 5_000) 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 end

View file

@ -37,4 +37,32 @@ def host(url_or_host) when is_binary(url_or_host) do
url_or_host url_or_host
end end
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 end

View file

@ -2253,34 +2253,4 @@ def sanitize_html(%User{} = user, filter) do
|> Map.put(:bio, HTML.filter_tags(user.bio, filter)) |> Map.put(:bio, HTML.filter_tags(user.bio, filter))
|> Map.put(:fields, fields) |> Map.put(:fields, fields)
end 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 end

View file

@ -204,6 +204,15 @@ defp do_render("show.json", %{user: user} = opts) do
%{} %{}
end 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), id: to_string(user.id),
username: username_from_nickname(user.nickname), username: username_from_nickname(user.nickname),
@ -246,7 +255,7 @@ defp do_render("show.json", %{user: user} = opts) do
relationship: relationship, relationship: relationship,
skip_thread_containment: user.skip_thread_containment, skip_thread_containment: user.skip_thread_containment,
background_image: image_url(user.background) |> MediaProxy.url(), background_image: image_url(user.background) |> MediaProxy.url(),
favicon: User.get_cached_favicon(user) |> MediaProxy.url() favicon: favicon
} }
} }
|> maybe_put_role(user, opts[:for]) |> maybe_put_role(user, opts[:for])

View file

@ -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
-->

View file

@ -1342,10 +1342,18 @@ def get("https://relay.mastodon.host/actor", _, _, _) do
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/relay/relay.json")}} {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/relay/relay.json")}}
end 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")}} {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/7369654.html")}}
end 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 def get(url, query, body, headers) do
{:error, {:error,
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{ "Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{

View file

@ -75,7 +75,8 @@ test "Represent a user account" do
pleroma: %{ pleroma: %{
ap_id: user.ap_id, ap_id: user.ap_id,
background_image: "https://example.com/images/asuka_hospital.png", 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, confirmation_pending: false,
tags: [], tags: [],
is_admin: false, is_admin: false,
@ -153,7 +154,8 @@ test "Represent a Service(bot) account" do
pleroma: %{ pleroma: %{
ap_id: user.ap_id, ap_id: user.ap_id,
background_image: nil, background_image: nil,
favicon: nil, favicon:
"https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png",
confirmation_pending: false, confirmation_pending: false,
tags: [], tags: [],
is_admin: false, is_admin: false,