Skip to content
This repository has been archived by the owner on Nov 25, 2020. It is now read-only.

Commit

Permalink
Fix digest (from develop), close session when generating imagick thum…
Browse files Browse the repository at this point in the history
…b, last css compile.
  • Loading branch information
cdujeu committed Jul 12, 2016
1 parent 4b9c93a commit e6e962e
Show file tree
Hide file tree
Showing 3 changed files with 217 additions and 69 deletions.
283 changes: 215 additions & 68 deletions core/src/plugins/core.mailer/Mailer.php
Expand Up @@ -51,6 +51,23 @@
class Mailer extends Plugin implements SqlTableProvider
{

public static $TEMPLATES = [
"html" => [
"body" => '<div id="digest">%s</div>', // Argument section
"section" => '%s%s', // Argument title, listWrapper
"title" => '<h1>%s</h1>', // Argument %var%
"listWrapper" => '<ul>%s</ul>', // Argument list
"list" => '<li>%s</li>' // Argument %var%
],
"plain" => [
"body" => '%s', // Argument section
"section" => '%s%s', // Argument title, listWrapper
"title" => '%s\n\n', // Argument %var%
"listWrapper" => '%s', // Argument list
"list" => '%s\n' // Argument %var%
]
];

public $mailCache;
protected $_dibiDriver;

Expand Down Expand Up @@ -84,6 +101,40 @@ protected function getDibiDriver()
return $this->_dibiDriver;
}

/**
* @return int
* @throws Exception
*/
public function getConsumerLock() {

$workDir = $this->getPluginWorkDir(true);
$consumerLockFile = $workDir . DIRECTORY_SEPARATOR . "/consume_mail_queue.lock";

// Opening the file
$consumerLock = fopen($consumerLockFile, "w");

// Making sure the file gets closed and the lock gets released at the end of the script
register_shutdown_function(function () use ($consumerLock) {
fflush($consumerLock);
flock($consumerLock, LOCK_UN);

fclose($consumerLock);
});

// Retrieving the lock
while (!flock($consumerLock, LOCK_EX)) {
sleep(60);
}

// Writing the time the lock was granted
$time = time();
ftruncate($consumerLock, 0);
fwrite($consumerLock, $time);

return $time;
}


/**
* @param $action
* @param $httpVars
Expand All @@ -96,6 +147,16 @@ public function mailConsumeQueue($action, $httpVars, $fileVars, ContextInterface

if ($action === "consume_mail_queue") {

$verbose = $httpVars["verbose"];

$logInfo = function () {};
if ($verbose) {
$logInfo = function ($str) {
fwrite(STDOUT, $str . "\n");
};
}


$mailer = PluginsService::getInstance($ctx)->getActivePluginsForType("mailer", true);
if (!$mailer instanceof Mailer) {
throw new PydioException("Cannot find active mailer!");
Expand All @@ -106,95 +167,174 @@ public function mailConsumeQueue($action, $httpVars, $fileVars, ContextInterface
if ($this->_dibiDriver["driver"] == "postgre") {
dibi::query("SET bytea_output=escape");
}
$time = time();

// Get the queue consumer lock and the time it was given
$time = $this->getConsumerLock();

try {
$querySQL = dibi::query("SELECT * FROM [ajxp_mail_queue] WHERE [date_event] <= %s", $time);
} catch (DibiException $e) {
throw new PydioException($e->getMessage());
}
$resultsSQL = $querySQL->fetchAll();
$arrayResultsSQL = array();
$output = array("success" => [], "error" => []);
$recipientFormats = array();
if (count($resultsSQL) > 0) {
foreach ($resultsSQL as $value) {
$ajxpNotification = unserialize($value["notification_object"]);
$ajxpAction = $ajxpNotification->getAction();
$ajxpAuthor = $ajxpNotification->getAuthor();
$ajxpNode = new AJXP_Node($value['url']);
try {
@$ajxpNode->loadNodeInfo();
} catch (Exception $e) {
}
if ($ajxpNode->isLeaf() && !$ajxpNode->isRoot()) {
$ajxpContent = $ajxpNode->getParent()->getPath();
} else {
$ajxpContent = $ajxpNode->getPath();
if ($ajxpContent === null) {
$ajxpContent = '/';
}
}
if ($ajxpNode->getRepository() != null) {
$ajxpNodeWorkspace = $ajxpNode->getRepository()->getDisplay();
} else {
$ajxpNodeWorkspace = "Deleted Workspace";
}
$recipientFormats[$value['recipient']] = ($value["html"] == 1);
$ajxpKey = $ajxpAction . "|" . $ajxpAuthor . "|" . $ajxpContent;
$arrayResultsSQL[$value['recipient']][$ajxpNodeWorkspace][$ajxpKey][] = $ajxpNotification;
//$querySQL->fetch();
//$resultsSQL = $querySQL->fetchAll();
$numRows = $querySQL->count();

$results = [];

HTMLWriter::charsetHeader("text/json");

if ($numRows == 0) {
$logInfo("Nothing to process");
$output = array("report" => "Sent 0 emails", "detail" => "");
echo json_encode($output);
return;
}

$logInfo("Processing " . $numRows . " rows.");

// We need to send one email :
// - per user
// - per email type (HTML or PLAIN)
while($value = $querySQL->fetch()) {

// Retrieving user information
$recipient = $value['recipient'];

// Retrieving Email type information
$emailType = ($value["html"] == 1) ? "html" : "plain";

// Retrieving notification information
/** @var Notification $notification */
$notification = unserialize($value["notification_object"]);

$action = $notification->getAction();
$author = $notification->getAuthor();
$node = $notification->getNode();

try {
@$node->loadNodeInfo();
} catch(Exception $e){
}
//this $body must be here because we need this css
$digestTitle = LocaleService::getMessages()["core.mailer.9"];
foreach ($arrayResultsSQL as $recipient => $arrayWorkspace) {
$useHtml = $recipientFormats[$recipient];
$body = $useHtml ? "<div id='digest'>" : "";
foreach ($arrayWorkspace as $workspace => $arrayAjxpKey) {
$key = key($arrayAjxpKey);
$body = $body . '<h1>' . $arrayAjxpKey[$key][0]->getDescriptionLocation() . ', </h1><ul>';
foreach ($arrayAjxpKey as $ajxpKey => $arrayNotif) {
$descs = array();
foreach ($arrayNotif as $notif) {
$desc = $notif->getDescriptionLong(true);
if (array_key_exists($desc, $descs)) {
$descs[$desc]++;
} else {
$descs[$desc] = 1;
}
}
foreach ($descs as $sentence => $occurences) {
$body = $body . '<li>' . $sentence . ($occurences > 1 ? ' (' . count($arrayNotif) . ')' : '') . '</li>';
}
}
$body = $body . '</ul>';

if ($node->isLeaf() && !$node->isRoot()) {
$dirName = $node->getParent()->getPath();
} else {
$dirName = $node->getPath();
if ($dirName === null) {
$dirName = '/';
}
$body .= $useHtml ? "</div>" : "";
}
$key = sprintf("%s|%s|%s", $action, $author, $dirName);

// Retrieving workspace information
if($node->getRepository() != null) {
$workspace = $node->getRepository()->getDisplay();
} else {
$workspace = "Deleted Workspace";
}

$results[$emailType][$recipient][$workspace][$key][] = $notification;
}

$logInfo("Created digest array.");

$subject = LocaleService::getMessages()["core.mailer.9"];

$success = 0;
$errors = [];
foreach ($results as $emailType => $recipients) {

$isHTML = $emailType == "html";

$i = 0;
foreach ($recipients as $recipient => $workspaces) {

$logInfo("Processed " . ++$i . " out of " . count($recipients) . " " . $emailType . " emails " . $recipient);

$body = $this->_buildDigest($workspaces, $emailType);

$success++;
try {
$mailer->sendMail(
$ctx,
array($recipient),
$digestTitle,
[$recipient],
$subject,
$body,
null,
null,
$useHtml
$isHTML
);
$output["success"][] = "Email sent to " . $recipient;
} catch (PydioException $e) {
$output["error"][] = "Sending email to " . $recipient . ": " . $e->getMessage();

$success++;
} catch (\Exception $e) {
$errors[] = "Failed to send email to " . $recipient . ": " . $e->getMessage();
}
}
try {
dibi::query('DELETE FROM [ajxp_mail_queue] WHERE [date_event] <= %s', $time);
} catch (DibiException $e) {
throw new PydioException($e->getMessage());
}
}
HTMLWriter::charsetHeader("text/json");
$output = array("report" => "Sent " . count($output["success"]) . " emails", "detail" => $output);

// Clearing memory
unset($results);

try {
dibi::query('DELETE FROM [ajxp_mail_queue] WHERE [date_event] <= %s', $time);
} catch (DibiException $e) {
throw new PydioException($e->getMessage());
}

$output = array("report" => "Sent ".$success." emails", "errors" => $errors);
echo json_encode($output);
}
}

/**
* @param $workspaces
* @param $emailType
* @return string
*/
private function _buildDigest($workspaces, $emailType) {

$template = self::$TEMPLATES[$emailType];

$sections = [];
foreach ($workspaces as $workspace => $keys) {

$title = "";
$li = [];

foreach ($keys as $key => $notifications) {

$descriptions = [];

/** @var Notification $notification */
foreach ($notifications as $notification) {
if (empty($current)) {
$title = sprintf($template["title"], $notification->getDescriptionLocation());
}

$description = $notification->getDescriptionLong(true);

if(array_key_exists($description, $descriptions)) {
$descriptions[$description]++;
} else {
$descriptions[$description] = 1;
}
}

foreach ($descriptions as $description => $count){
$li[] = sprintf($template["list"], $description . ($count > 1 ? ' ('.$count.')' : ''));
}
}

$listWrapper = sprintf($template["listWrapper"], join("", $li));
$sections[] = sprintf($template["section"], $title, $listWrapper);
}

return sprintf($template["body"], join("", $sections));
}



/**
* @param $int
* @return string
Expand Down Expand Up @@ -279,6 +419,13 @@ protected function computeEmailSendDate($frequencyType, $frequencyDetail)
*/
public function processNotification(Notification &$notification)
{
// Inserting the node information.
try {
$notification->getNode()->loadNodeInfo();
} catch (Exception $e) {
// Do nothing
}

try {
$userObject = UsersService::getUserById($notification->getTarget());
} catch (\Pydio\Core\Exception\UserNotFoundException $e) {
Expand Down
1 change: 1 addition & 0 deletions core/src/plugins/editor.imagick/IMagickPreviewer.php
Expand Up @@ -113,6 +113,7 @@ public function switchAction($action, $httpVars, $filesVars, \Pydio\Core\Model\C
$cache = LocalCache::getItem("imagick_".($this->extractAll?"full":"thumb"), $file, function($masterFile, $targetFile) use ($contextInterface){
return $this->generateJpegsCallback($contextInterface, $masterFile, $targetFile);
});
session_write_close();
$cacheData = $cache->getData();

if (!$this->useOnTheFly && $this->extractAll) { // extract all on first view
Expand Down
2 changes: 1 addition & 1 deletion core/src/plugins/gui.ajax/res/themes/orbit/css/allz.css

Large diffs are not rendered by default.

0 comments on commit e6e962e

Please sign in to comment.