Progress on notifications

* Added main mail class
* notification class extends mail class
* Added mail template for IDLE workers
* Added notification table to SQL structure

This works already but once notified the status is not reset as soon as
a worker is active again. Need to think of a system to do that
automatically.

Addresses #116
This commit is contained in:
Sebastian Grewe 2013-06-07 14:42:29 +02:00
parent c69fbe4fc4
commit 9ac2dadd97
7 changed files with 193 additions and 3 deletions

42
cronjobs/notifications.php Executable file
View File

@ -0,0 +1,42 @@
#!/usr/bin/php
<?php
/*
Copyright:: 2013, Sebastian Grewe
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// Include all settings and classes
require_once('shared.inc.php');
$aWorkers = $worker->getAllIdleWorkers();
if (empty($aWorkers)) {
verbose("No idle workers found\n");
exit;
}
foreach ($aWorkers as $aWorker) {
$aData = $aWorker;
$aData['username'] = $user->getUserName($aWorker['account_id']);
$aData['email'] = $user->getUserEmail($aData['username']);
if (!$notification->isNotified($aData)) {
if (!$notification->addNotification('idle_worker', $aData) && $notification->sendMail('sebastian@grewe.ca', 'idle_worker', $aData))
verbose("Unable to send notification: " . $notification->getError() . "\n");
} else {
verbose("Already notified for this worker\n");
}
}
?>

View File

@ -14,3 +14,5 @@ require_once(CLASS_DIR . '/worker.class.php');
require_once(CLASS_DIR . '/statistics.class.php');
require_once(CLASS_DIR . '/transaction.class.php');
require_once(CLASS_DIR . '/setting.class.php');
require_once(CLASS_DIR . '/mail.class.php');
require_once(CLASS_DIR . '/notification.class.php');

View File

@ -0,0 +1,58 @@
<?php
// Make sure we are called from index.php
if (!defined('SECURITY'))
die('Hacking attempt');
class Mail {
private $sError = '';
public function setDebug($debug) {
$this->debug = $debug;
}
public function setMysql($mysqli) {
$this->mysqli = $mysqli;
}
public function setSmarty($smarty) {
$this->smarty = $smarty;
}
public function setConfig($config) {
$this->config = $config;
}
private function checkStmt($bState) {
$this->debug->append("STA " . __METHOD__, 4);
if ($bState ===! true) {
$this->debug->append("Failed to prepare statement: " . $this->mysqli->error);
$this->setErrorMessage('Internal application Error');
return false;
}
return true;
}
public function sendMail($email, $template, $vars) {
$this->smarty->assign('WEBSITENAME', $this->config['website']['name']);
$headers = 'From: Website Administration <' . $this->config['website']['email'] . ">\n";
$headers .= "MIME-Version: 1.0\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
if (mail($email,
$this->smarty->fetch(BASEPATH . 'templates/mail/subject.tpl'),
$this->smarty->fetch(BASEPATH . 'templates/mail/' . $template . '.tpl'),
$headers)) {
return true;
} else {
$this->setErrorMessage("Unable to send mail");
return false;
}
return false;
}
}
// Make our class available automatically
$mail = new Mail ();
$mail->setDebug($debug);
$mail->setMysql($mysqli);
$mail->setSmarty($smarty);
$mail->setConfig($config);
?>

View File

@ -0,0 +1,45 @@
<?php
// Make sure we are called from index.php
if (!defined('SECURITY'))
die('Hacking attempt');
class Notification extends Mail {
var $table = 'notifications';
/**
* We check our notification table for existing data
* so we can avoid duplicate entries
**/
public function isNotified($aData) {
$data = json_encode($aData);
$stmt = $this->mysqli->prepare("SELECT id FROM $this->table WHERE data = ? LIMIT 1");
if ($stmt && $stmt->bind_param('s', $data) && $stmt->execute() && $stmt->store_result() && $stmt->num_rows == 1)
return true;
// Catchall
// Does not seem to have a notification set
return false;
}
/**
* Add a new notification to the table
* @param type string Type of the notification
* @return bool
**/
public function addNotification($type, $data) {
// Store notification data as json
$data = json_encode($data);
$stmt = $this->mysqli->prepare("INSERT INTO $this->table (type, data) VALUES (?,?)");
if ($stmt && $stmt->bind_param('ss', $type, $data) && $stmt->execute())
return true;
$this->debug->append("Failed to add notification for $type with $data: " . $this->mysqli->error);
$this->setErrorMessage("Unable to add new notification");
return false;
}
}
$notification = new Notification();
$notification->setDebug($debug);
$notification->setMysql($mysqli);
$notification->setSmarty($smarty);
$notification->setConfig($config);

View File

@ -58,6 +58,26 @@ class Worker {
return false;
}
/**
* Fetch all IDLE workers that have monitoring enabled
* @param none
* @return data array Workers in IDLE state and monitoring enabled
**/
public function getAllIdleWorkers() {
$this->debug->append("STA " . __METHOD__, 4);
$stmt = $this->mysqli->prepare("
SELECT account_id, id, username
FROM " . $this->table . "
WHERE monitor = 1 AND ( SELECT SIGN(COUNT(id)) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) = 0");
if ($this->checkStmt($stmt) && $stmt->execute() && $result = $stmt->get_result())
return $result->fetch_all(MYSQLI_ASSOC);
// Catchall
$this->setErrorMessage("Unable to fetch IDLE, monitored workers");
echo $this->mysqli->error;
return false;
}
/**
* Fetch all workers for an account
* @param account_id int User ID

View File

@ -0,0 +1,9 @@
<html>
<body>
<p>One of your workers is currently IDLE.</p>
<p>Since monitoring is enabled for this worker, this notification was sent.</p>
<p>Please check your workers!</p>
<br/>
<br/>
</body>
</html>

View File

@ -3,7 +3,7 @@
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jun 06, 2013 at 09:01 PM
-- Generation Time: Jun 07, 2013 at 02:42 PM
-- Server version: 5.5.31-0ubuntu0.13.04.1
-- PHP Version: 5.4.9-4ubuntu2
@ -69,6 +69,20 @@ CREATE TABLE IF NOT EXISTS `blocks` (
-- --------------------------------------------------------
--
-- Table structure for table `notifications`
--
CREATE TABLE IF NOT EXISTS `notifications` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(25) NOT NULL,
`data` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Table structure for table `pool_worker`
--
@ -136,7 +150,7 @@ CREATE TABLE IF NOT EXISTS `shares_archive` (
PRIMARY KEY (`id`),
UNIQUE KEY `share_id` (`share_id`),
KEY `time` (`time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Archive shares for potential later debugging purposes';
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Archive shares for potential later debugging purposes';
-- --------------------------------------------------------
@ -153,7 +167,7 @@ CREATE TABLE IF NOT EXISTS `statistics_shares` (
PRIMARY KEY (`id`),
KEY `account_id` (`account_id`),
KEY `block_id` (`block_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------