Reduce memory usage on addressbook vcf import

This commit is contained in:
the-djmaze 2023-02-09 10:12:13 +01:00
parent e6bdb37ca1
commit 9466fc71a8
3 changed files with 27 additions and 35 deletions

View file

@ -253,15 +253,24 @@ trait Contacts
private function importContactsFromVcfFile(\RainLoop\Model\Account $oAccount, /*resource*/ $rFile): int private function importContactsFromVcfFile(\RainLoop\Model\Account $oAccount, /*resource*/ $rFile): int
{ {
$iCount = 0;
$oAddressBookProvider = $this->AddressBookProvider($oAccount); $oAddressBookProvider = $this->AddressBookProvider($oAccount);
if (\is_resource($rFile) && $oAddressBookProvider && $oAddressBookProvider->IsActive()) { if (\is_resource($rFile) && $oAddressBookProvider && $oAddressBookProvider->IsActive()) {
$sFile = \stream_get_contents($rFile); try
if (\is_string($sFile) && 5 < \strlen($sFile)) { {
$this->Logger()->Write('Import contacts from vcf'); $this->Logger()->Write('Import contacts from vcf');
return $oAddressBookProvider->ImportVcfFile($sFile); foreach (\RainLoop\Providers\AddressBook\Utils::VcfStreamToContacts($rFile) as $oContact) {
if ($oAddressBookProvider->ContactSave($oContact)) {
++$iCount;
} }
} }
return 0; }
catch (\Throwable $oExc)
{
$this->Logger()->WriteException($oExc);
}
}
return $iCount;
} }
private function importContactsFromCsvFile(\RainLoop\Model\Account $oAccount, /*resource*/ $rFile, string $sFileStart): int private function importContactsFromCsvFile(\RainLoop\Model\Account $oAccount, /*resource*/ $rFile, string $sFileStart): int
@ -269,7 +278,9 @@ trait Contacts
$iCount = 0; $iCount = 0;
$oAddressBookProvider = $this->AddressBookProvider($oAccount); $oAddressBookProvider = $this->AddressBookProvider($oAccount);
if (\is_resource($rFile) && $oAddressBookProvider && $oAddressBookProvider->IsActive()) { if (\is_resource($rFile) && $oAddressBookProvider && $oAddressBookProvider->IsActive()) {
$this->oLogger->Write('Import contacts from csv'); try
{
$this->Logger()->Write('Import contacts from csv');
$sDelimiter = ((int)\strpos($sFileStart, ',') > (int)\strpos($sFileStart, ';')) ? ',' : ';'; $sDelimiter = ((int)\strpos($sFileStart, ',') > (int)\strpos($sFileStart, ';')) ? ',' : ';';
foreach (\RainLoop\Providers\AddressBook\Utils::CsvStreamToContacts($rFile, $sDelimiter) as $oContact) { foreach (\RainLoop\Providers\AddressBook\Utils::CsvStreamToContacts($rFile, $sDelimiter) as $oContact) {
if ($oAddressBookProvider->ContactSave($oContact)) { if ($oAddressBookProvider->ContactSave($oContact)) {
@ -277,6 +288,11 @@ trait Contacts
} }
} }
} }
catch (\Throwable $oExc)
{
$this->Logger()->WriteException($oExc);
}
}
return $iCount; return $iCount;
} }

View file

@ -82,24 +82,4 @@ class AddressBook extends AbstractProvider
{ {
return $this->IsActive() ? $this->oDriver->IncFrec($aEmails, $bCreateAuto) : false; return $this->IsActive() ? $this->oDriver->IncFrec($aEmails, $bCreateAuto) : false;
} }
public function ImportVcfFile(string $sVcfData) : int
{
$iCount = 0;
if ($this->IsActive()) {
try
{
foreach (AddressBook\Utils::VcfFileToContacts($sVcfData) as $oContact) {
if ($this->ContactSave($oContact)) {
++$iCount;
}
}
}
catch (\Throwable $oExc)
{
$this->Logger()->WriteException($oExc);
}
}
return $iCount;
}
} }

View file

@ -198,13 +198,9 @@ class Utils
)); ));
} }
public static function VcfFileToContacts(string $sVcfData) : iterable public static function VcfStreamToContacts(/*resource*/ $rFile) : iterable
{ {
$sVcfData = \trim($sVcfData); $oVCardSplitter = new \Sabre\VObject\Splitter\VCard($rFile);
if ("\xef\xbb\xbf" === \substr($sVcfData, 0, 3)) {
$sVcfData = \substr($sVcfData, 3);
}
$oVCardSplitter = new \Sabre\VObject\Splitter\VCard($sVcfData);
if ($oVCardSplitter) { if ($oVCardSplitter) {
while ($oVCard = $oVCardSplitter->getNext()) { while ($oVCard = $oVCardSplitter->getNext()) {
if ($oVCard instanceof \Sabre\VObject\Component\VCard) { if ($oVCard instanceof \Sabre\VObject\Component\VCard) {