Added Libravatar support

This commit is contained in:
M66B
2022-03-08 10:20:57 +01:00
parent 32921af0de
commit fb52254c73
6 changed files with 113 additions and 8 deletions

View File

@@ -90,7 +90,7 @@ import javax.net.ssl.SSLSession;
public class ContactInfo {
private String email;
private Bitmap bitmap;
private String type;
private String type; // contact, vmc, gravatar, libravatar, favicon, identicon, letter, unknown
private boolean verified;
private String displayName;
private Uri lookupUri;
@@ -159,6 +159,10 @@ public class ContactInfo {
return lookupUri;
}
boolean isEmailBased() {
return ("gravatar".equals(type) || "libravatar".equals(type));
}
boolean isKnown() {
return known;
}
@@ -258,6 +262,7 @@ public class ContactInfo {
boolean avatars = prefs.getBoolean("avatars", true);
boolean bimi = prefs.getBoolean("bimi", false);
boolean gravatars = prefs.getBoolean("gravatars", false);
boolean libravatars = prefs.getBoolean("libravatars", false);
boolean favicons = prefs.getBoolean("favicons", false);
boolean generated = prefs.getBoolean("generated_icons", true);
boolean identicons = prefs.getBoolean("identicons", false);
@@ -308,7 +313,7 @@ public class ContactInfo {
// Favicon
if (info.bitmap == null &&
!EntityFolder.JUNK.equals(folderType) &&
(bimi || (gravatars && canGravatars()) || favicons)) {
(bimi || (canGravatars() && (gravatars || libravatars)) || favicons)) {
String d = UriHelper.getEmailDomain(info.email);
if (d != null) {
// Prevent using Doodles
@@ -334,6 +339,8 @@ public class ContactInfo {
File[] files = null;
if (gravatars && canGravatars()) {
File f = new File(dir, email + ".gravatar");
if (!f.exists())
f = new File(dir, email + ".libravatar");
if (f.exists())
files = new File[]{f};
}
@@ -404,6 +411,49 @@ public class ContactInfo {
}
}));
if (libravatars && canGravatars())
futures.add(executorFavicon.submit(new Callable<Favicon>() {
@Override
public Favicon call() throws Exception {
// https://wiki.libravatar.org/api/
String baseUrl = BuildConfig.LIBRAVATAR_URI;
for (String dns : BuildConfig.LIBRAVATAR_DNS.split(",")) {
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, dns + "." + domain, "srv");
if (records.length > 0) {
baseUrl = (records[0].port == 443 ? "https" : "http") + "://" + records[0].name + "/avatar/";
break;
}
}
String hash = Helper.md5(email.getBytes());
URL url = new URL(baseUrl + hash + "?d=404");
Log.i("Libravatar key=" + email + " url=" + url);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(GRAVATAR_TIMEOUT);
urlConnection.setConnectTimeout(GRAVATAR_TIMEOUT);
urlConnection.setRequestProperty("User-Agent", WebViewEx.getUserAgent(context));
urlConnection.connect();
try {
int status = urlConnection.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
// Positive reply
Bitmap bitmap = BitmapFactory.decodeStream(urlConnection.getInputStream());
return (bitmap == null ? null : new Favicon(bitmap, "libravatar", false));
} else if (status == HttpURLConnection.HTTP_NOT_FOUND) {
// Negative reply
return null;
} else
throw new IOException("Error " + status + ": " + urlConnection.getResponseMessage());
} finally {
urlConnection.disconnect();
}
}
}));
if (favicons) {
String host = domain;
while (host.indexOf('.') > 0) {
@@ -480,7 +530,7 @@ public class ContactInfo {
// Add to cache
File output = new File(dir,
("gravatar".equals(info.type) ? email : domain) +
(info.isEmailBased() ? email : domain) +
"." + info.type +
(info.verified ? "_verified" : ""));
try (OutputStream os = new BufferedOutputStream(new FileOutputStream(output))) {

View File

@@ -106,6 +106,8 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
private SwitchCompat swBimi;
private SwitchCompat swGravatars;
private TextView tvGravatarsHint;
private SwitchCompat swLibravatars;
private ImageButton ibLibravatars;
private SwitchCompat swFavicons;
private SwitchCompat swFaviconsPartial;
private TextView tvFaviconsHint;
@@ -184,7 +186,7 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
"nav_options", "nav_count", "nav_unseen_drafts", "nav_count_pinned", "navbar_colorize",
"threading", "threading_unread", "indentation", "seekbar", "actionbar", "actionbar_color",
"highlight_unread", "highlight_color", "color_stripe", "color_stripe_wide",
"avatars", "bimi", "gravatars", "favicons", "favicons_partial", "generated_icons", "identicons",
"avatars", "bimi", "gravatars", "libravatars", "favicons", "favicons_partial", "generated_icons", "identicons",
"circular", "saturation", "brightness", "threshold",
"email_format", "prefer_contact", "only_contact", "distinguish_contacts", "show_recipients",
"font_size_sender", "sender_ellipsize",
@@ -254,6 +256,8 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
ibBimi = view.findViewById(R.id.ibBimi);
swGravatars = view.findViewById(R.id.swGravatars);
tvGravatarsHint = view.findViewById(R.id.tvGravatarsHint);
swLibravatars = view.findViewById(R.id.swLibravatars);
ibLibravatars = view.findViewById(R.id.ibLibravatars);
swFavicons = view.findViewById(R.id.swFavicons);
swFaviconsPartial = view.findViewById(R.id.swFaviconsPartial);
tvFaviconsHint = view.findViewById(R.id.tvFaviconsHint);
@@ -712,6 +716,21 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
}
});
swLibravatars.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("libravatars", checked).apply();
ContactInfo.clearCache(compoundButton.getContext());
}
});
ibLibravatars.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.view(v.getContext(), Uri.parse(BuildConfig.LIBRAVATAR_INFO), true);
}
});
swFavicons.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
@@ -1302,6 +1321,7 @@ public class FragmentOptionsDisplay extends FragmentBase implements SharedPrefer
swAvatars.setChecked(prefs.getBoolean("avatars", true));
swBimi.setChecked(prefs.getBoolean("bimi", false));
swGravatars.setChecked(prefs.getBoolean("gravatars", false));
swLibravatars.setChecked(prefs.getBoolean("libravatars", false));
swFavicons.setChecked(prefs.getBoolean("favicons", false));
swFaviconsPartial.setChecked(prefs.getBoolean("favicons_partial", true));
swFaviconsPartial.setEnabled(swFavicons.isChecked());