Skip to content

Commit

Permalink
Bigchange for contact image avatar support #115
Browse files Browse the repository at this point in the history
  • Loading branch information
the-djmaze committed Nov 22, 2022
1 parent 113a421 commit 5069bc2
Show file tree
Hide file tree
Showing 32 changed files with 131 additions and 28 deletions.
19 changes: 19 additions & 0 deletions plugins/avatars/avatars.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@
view.viewUserPicVisible = ko.observable(false);

view.message.subscribe(msg => {
view.viewUserPicVisible(false);
if (msg) {
let from = msg.from[0],
bimi = 'pass' == from.dkimStatus ? 1 : 0;
// view.viewUserPic(`?Avatar/${bimi}/${encodeURIComponent(from.email)}`);
// view.viewUserPicVisible(true);
rl.pluginRemoteRequest((iError, data) => {
if (!iError && data?.Result.type) {
view.viewUserPic(`data:${data.Result.type};base64,${data.Result.data}`);
Expand All @@ -38,6 +40,23 @@
}
});
}
/*
if ('MailMessageList' === e.detail.viewModelTemplateID) {
const
template = document.getElementById('MailMessageList' ),
messageCheckbox = template.content.querySelector('.messageCheckbox');
messageCheckbox.dataset.bind = 'attr:{style:$root.viewUserPic($data)}';
e.detail.viewUserPic = msg => {
let from = msg.from[0],
bimi = 'pass' == from.dkimStatus ? 1 : 0;
return `background:no-repeat url("?Avatar/${bimi}/${encodeURIComponent(from.email)}") center / contain`;
return `background:no-repeat url("?Avatar/${bimi}/${encodeURIComponent(from.email)}") right / 32px;width:68px`;
};
.checkboxMessage {
background: #000;
}
}
*/
});

})(window.rl);
Binary file modified plugins/avatars/images/services/amazon.com.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified plugins/avatars/images/services/apple.com.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed plugins/avatars/images/services/cnet.online.com.png
Binary file not shown.
Binary file removed plugins/avatars/images/services/connect.asana.com.png
Binary file not shown.
Binary file removed plugins/avatars/images/services/e.paypal.com.png
Binary file not shown.
Binary file removed plugins/avatars/images/services/em.ea.com.png
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed plugins/avatars/images/services/email.skype.com.png
Binary file not shown.
Binary file removed plugins/avatars/images/services/facebookmail.com.png
Binary file not shown.
Binary file modified plugins/avatars/images/services/google.com.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed plugins/avatars/images/services/id.apple.com.png
Binary file not shown.
Binary file removed plugins/avatars/images/services/intl.paypal.com.png
Binary file not shown.
Binary file modified plugins/avatars/images/services/microsoft.com.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file removed plugins/avatars/images/services/myspace.com.png
Binary file not shown.
Binary file removed plugins/avatars/images/services/news.myspace.com.png
Binary file not shown.
Binary file removed plugins/avatars/images/services/news.onlive.com.png
Binary file not shown.
Binary file removed plugins/avatars/images/services/plus.google.com.png
Binary file not shown.
Binary file not shown.
Binary file removed plugins/avatars/images/services/reply.ebay.com.png
Binary file not shown.
Binary file removed plugins/avatars/images/services/reply1.ebay.com.png
Binary file not shown.
Binary file removed plugins/avatars/images/services/reply2.ebay.com.png
Binary file not shown.
Binary file removed plugins/avatars/images/services/reply3.ebay.com.png
Binary file not shown.
85 changes: 59 additions & 26 deletions plugins/avatars/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin
URL = 'https://snappymail.eu/',
VERSION = '1.0',
RELEASE = '2022-11-11',
REQUIRED = '2.21.0',
REQUIRED = '2.22.0',
CATEGORY = 'Contacts',
LICENSE = 'MIT',
DESCRIPTION = '';
Expand Down Expand Up @@ -53,60 +53,93 @@ private static function getAvatar(string $sEmail, bool $bBimi) : ?array
return null;
}

// $this->verifyCacheByKey($sEmail);
$oActions = \RainLoop\Api::Actions();
$oActions->verifyCacheByKey($sEmail);

// DATA_IMAGE_USER_DOT_PIC
$sDomain = \explode('@', $sEmail);
$sDomain = \array_pop($sDomain);

$BIMI = $bBimi ? \SnappyMail\DNS::BIMI($sDomain) : null;
// TODO: process $BIMI value
$aResult = null;

// TODO: lookup contacts vCard
$oAccount = $oActions->getAccountFromToken();
if ($oAccount) {
$oAddressBookProvider = $oActions->AddressBookProvider($oAccount);
if ($oAddressBookProvider) {
$oContact = $oAddressBookProvider->GetContactByEmail($sEmail);
if ($oContact && $oContact->vCard && $oContact->vCard['PHOTO']) {
$aResult = [
'text/vcard',
$oContact->vCard
];
}
}
}

if (!$aResult) {
$sDomain = \explode('@', $sEmail);
$sDomain = \array_pop($sDomain);

// TODO: make this optional
$aResult = static::Gravatar($sEmail);
$aUrls = [];

if (!$aResult && \file_exists(__DIR__ . '/images/services/'.$sDomain.'.png')) {
$aResult = [
'image/png',
\file_get_contents(__DIR__ . '/images/services/'.$sDomain.'.png')
];
$BIMI = $bBimi ? \SnappyMail\DNS::BIMI($sDomain) : null;
if ($BIMI) {
$aUrls[] = $BIMI;
// $aResult = ['text/uri-list', $BIMI];
\SnappyMail\Log::debug('Avatar', "BIMI {$sDomain} for {$sUrl}");
} else {
\SnappyMail\Log::notice('Avatar', "BIMI 404 for {$sDomain}");
}

// TODO: make Gravatar optional
$sAsciiEmail = \MailSo\Base\Utils::IdnToAscii($sEmail, true);
$aUrls[] = 'http://gravatar.com/avatar/'.\md5(\strtolower($sAsciiEmail)).'?s=80&d=404';

foreach ($aUrls as $sUrl) {
if ($aResult = static::getUrl($sUrl)) {
break;
}
}
}

if (!$aResult) {
$aResult = [
'image/png',
\file_get_contents(__DIR__.'/images/empty-contact.png')
$aServices = [
"services/{$sDomain}",
'services/' . \preg_replace('/^.+\\.([^.]+\\.[^.]+)$/D', '$1', $sDomain),
'empty-contact' // DATA_IMAGE_USER_DOT_PIC
];
foreach ($aServices as $service) {
if (\file_exists(__DIR__ . "/images/{$service}.png")) {
$aResult = [
'image/png',
\file_get_contents(__DIR__ . "/images/{$service}.png")
];
break;
}
}
}

// $this->cacheByKey($sEmail);
$oActions->cacheByKey($sEmail);

return $aResult;
}

private static function Gravatar(string $sEmail) : ?array
private static function getUrl(string $sUrl) : ?array
{
$sEmail = \MailSo\Base\Utils::IdnToAscii($sEmail, true);
$sGravatarUrl = 'http://gravatar.com/avatar/'.\md5(\strtolower($sEmail)).'?s=80&d=404';
$oHTTP = \SnappyMail\HTTP\Request::factory(/*'socket' or 'curl'*/);
$oHTTP->proxy = \RainLoop\Api::Config()->Get('labs', 'curl_proxy', '');
$oHTTP->proxy_auth = \RainLoop\Api::Config()->Get('labs', 'curl_proxy_auth', '');
$oHTTP->max_response_kb = 0;
$oHTTP->timeout = 15; // timeout in seconds.
$oResponse = $oHTTP->doRequest('GET', $sGravatarUrl);
$oResponse = $oHTTP->doRequest('GET', $sUrl);
if ($oResponse) {
if (200 === $oResponse->status && \str_starts_with($oResponse->getHeader('content-type'), 'image/')) {
return [
$oResponse->getHeader('content-type'),
$oResponse->body
];
}
\SnappyMail\Log::notice('Gravatar', "error {$oResponse->status} for {$sGravatarUrl}");
\SnappyMail\Log::notice('Avatar', "error {$oResponse->status} for {$sUrl}");
} else {
\SnappyMail\Log::warning('Gravatar', "failed for {$sGravatarUrl}");
\SnappyMail\Log::warning('Avatar', "failed for {$sUrl}");
}
return null;
}

}
6 changes: 6 additions & 0 deletions plugins/kolab/KolabAddressBook.php
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,12 @@ public function GetContacts(int $iOffset = 0, int $iLimit = 20, string $sSearch
return $aResult;
}

public function GetContactByEmail(string $sEmail) : ?Contact;
{
// TODO
return null;
}

public function GetContactByID($mID, bool $bIsStrID = false) : ?Contact
{
if ($bIsStrID) {
Expand Down
2 changes: 1 addition & 1 deletion plugins/kolab/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class KolabPlugin extends \RainLoop\Plugins\AbstractPlugin
RELEASE = '2022-09-06',
CATEGORY = 'Contacts',
DESCRIPTION = 'Use an Address Book of Kolab.',
REQUIRED = '2.18.0';
REQUIRED = '2.22.0';

public function Init() : void
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ public function GetContacts(int $iOffset = 0, int $iLimit = 20, string $sSearch
) : array();
}

public function GetContactByEmail(string $sEmail) : ?AddressBook\Classes\Contact
{
return $this->IsActive() ? $this->oDriver->GetContactByEmail($sEmail) : null;
}

public function GetContactByID($mID, bool $bIsStrID = false) : ?AddressBook\Classes\Contact
{
return $this->IsActive() ? $this->oDriver->GetContactByID($mID, $bIsStrID) : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ public function DeleteAllContacts(string $sEmail) : bool;

public function GetContacts(int $iOffset = 0, int $iLimit = 20, string $sSearch = '', int &$iResultCount = 0) : array;

public function GetContactByEmail(string $sEmail) : ?Classes\Contact;

public function GetContactByID($mID, bool $bIsStrID = false) : ?Classes\Contact;

public function GetSuggestions(string $sSearch, int $iLimit = 20) : array;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,40 @@ public function GetContacts(int $iOffset = 0, int $iLimit = 20, string $sSearch
return [];
}

/**
* @param mixed $mID
*/
public function GetContactByEmail(string $sEmail) : ?Contact
{
$sLowerSearch = $this->specialConvertSearchValueLower($sEmail);

$sSql = 'SELECT
DISTINCT id_contact
FROM rainloop_ab_properties
WHERE id_user = :id_user
AND prop_type = '.PropertyType::JCARD.'
AND ('.
'prop_value LIKE :search ESCAPE \'=\''
. (\strlen($sLowerSearch) ? ' OR (prop_value_lower <> \'\' AND prop_value_lower LIKE :search_lower ESCAPE \'=\')' : '').
')';
$aParams = array(
':id_user' => array($this->iUserID, \PDO::PARAM_INT),
':search' => array($this->specialConvertSearchValue($sEmail, '='), \PDO::PARAM_STR)
);
if (\strlen($sLowerSearch)) {
$aParams[':search_lower'] = array($sLowerSearch, \PDO::PARAM_STR);
}

$oContact = null;
$iIdContact = 0;

$aContacts = $this->getContactsFromPDO(
$this->prepareAndExecute($sSql, $aParams)
);

return $aContacts ? $aContacts[0] : null;
}

/**
* @param mixed $mID
*/
Expand Down
6 changes: 5 additions & 1 deletion snappymail/v/0.0.0/app/libraries/snappymail/dns.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

abstract class DNS
{
/**
* $domain = 'bimigroup.org'
* Then a TXT lookup is done on 'default._bimi.bimigroup.org'
*/
public static function BIMI(string $domain) : string
{
$oCache = \RainLoop\Api::Actions()->Cacher();
Expand All @@ -18,7 +22,7 @@ public static function BIMI(string $domain) : string
}
if (null === $BIMI) {
$BIMI = '';
$values = \dns_get_record($domain, \DNS_TXT);
$values = \dns_get_record("default._bimi.{$domain}", \DNS_TXT);
if ($values) {
foreach ($values as $value) {
if (\str_starts_with($value['txt'], 'v=BIMI1')) {
Expand Down

0 comments on commit 5069bc2

Please sign in to comment.