commit
d986ed93b8
61
cronjobs/notifications.php
Executable file
61
cronjobs/notifications.php
Executable file
@ -0,0 +1,61 @@
|
||||
#!/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');
|
||||
|
||||
// Find all IDLE workers
|
||||
$aWorkers = $worker->getAllIdleWorkers();
|
||||
if (empty($aWorkers)) {
|
||||
verbose("No idle workers found\n");
|
||||
} else {
|
||||
foreach ($aWorkers as $aWorker) {
|
||||
$aData = $aWorker;
|
||||
$aData['username'] = $user->getUserName($aWorker['account_id']);
|
||||
$aData['subject'] = 'IDLE Worker : ' . $aWorker['username'];
|
||||
$aData['email'] = $user->getUserEmail($aData['username']);
|
||||
if ( $notification->isNotified($aData) ) {
|
||||
verbose("Worker already notified\n");
|
||||
continue;
|
||||
}
|
||||
if ($notification->addNotification('idle_worker', $aData) && $notification->sendMail($aData['email'], 'idle_worker', $aData)) {
|
||||
verbose ("Notified " . $aData['email'] . " for IDLE worker " . $aWorker['username'] . "\n");
|
||||
} else {
|
||||
verbose("Unable to send notification: " . $notification->getError() . "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We notified, lets check which recovered
|
||||
$aNotifications = $notification->getAllActive();
|
||||
foreach ($aNotifications as $aNotification) {
|
||||
$aData = json_decode($aNotification['data'], true);
|
||||
$aWorker = $worker->getWorker($aData['id']);
|
||||
if ($aWorker['active'] == 1) {
|
||||
if ($notification->setInactive($aNotification['id'])) {
|
||||
verbose("Marked notification " . $aNotification['id'] . " as inactive\n");
|
||||
} else {
|
||||
verbose("Failed to set notification inactive for " . $aWorker['username'] . "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@ -16,7 +16,7 @@ PIDFILE='/tmp/mmcfe-ng-cron.pid'
|
||||
CRONHOME='.'
|
||||
|
||||
# List of cruns to execute
|
||||
CRONS="findblock.php proportional_payout.php blockupdate.php auto_payout.php tickerupdate.php"
|
||||
CRONS="findblock.php proportional_payout.php blockupdate.php auto_payout.php tickerupdate.php notifications.php"
|
||||
|
||||
# Additional arguments to pass to cronjobs
|
||||
CRONARGS="-v"
|
||||
|
||||
@ -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');
|
||||
|
||||
65
public/include/classes/mail.class.php
Normal file
65
public/include/classes/mail.class.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?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;
|
||||
}
|
||||
public function setErrorMessage($msg) {
|
||||
$this->sError = $msg;
|
||||
}
|
||||
public function getError() {
|
||||
return $this->sError;
|
||||
}
|
||||
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, $aData) {
|
||||
$this->smarty->assign('WEBSITENAME', $this->config['website']['name']);
|
||||
$this->smarty->assign('SUBJECT', $aData['subject']);
|
||||
$this->smarty->assign('DATA', $aData);
|
||||
$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);
|
||||
|
||||
?>
|
||||
80
public/include/classes/notification.class.php
Normal file
80
public/include/classes/notification.class.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
// Make sure we are called from index.php
|
||||
if (!defined('SECURITY'))
|
||||
die('Hacking attempt');
|
||||
|
||||
class Notification extends Mail {
|
||||
var $table = 'notifications';
|
||||
|
||||
public function setInactive($id) {
|
||||
$field = array(
|
||||
'name' => 'active',
|
||||
'type' => 'i',
|
||||
'value' => 0
|
||||
);
|
||||
return $this->updateSingle($id, $field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a single row in a table
|
||||
* @param userID int Account ID
|
||||
* @param field string Field to update
|
||||
* @return bool
|
||||
**/
|
||||
private function updateSingle($id, $field) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$stmt = $this->mysqli->prepare("UPDATE $this->table SET " . $field['name'] . " = ? WHERE id = ? LIMIT 1");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param($field['type'].'i', $field['value'], $id) && $stmt->execute())
|
||||
return true;
|
||||
$this->debug->append("Unable to update " . $field['name'] . " with " . $field['value'] . " for ID $id");
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* 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 = ? AND active = 1 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
|
||||
$this->setErrorMessage("Unable to run query: " . $this->mysqli->error);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all active notifications
|
||||
**/
|
||||
public function getAllActive() {
|
||||
$stmt =$this->mysqli->prepare("SELECT id, data FROM $this->table WHERE active = 1 LIMIT 1");
|
||||
if ($stmt && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_all(MYSQLI_ASSOC);
|
||||
// Catchall
|
||||
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, active) VALUES (?,?,1)");
|
||||
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);
|
||||
@ -486,6 +486,7 @@ class User {
|
||||
}
|
||||
$smarty->assign('TOKEN', $token);
|
||||
$smarty->assign('USERNAME', $username);
|
||||
$smarty->assign('SUBJECT', 'Password Reset Request');
|
||||
$smarty->assign('WEBSITENAME', $this->config['website']['name']);
|
||||
$headers = 'From: Website Administration <' . $this->config['website']['email'] . ">\n";
|
||||
$headers .= "MIME-Version: 1.0\n";
|
||||
|
||||
@ -43,17 +43,60 @@ class Worker {
|
||||
public function updateWorkers($account_id, $data) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$username = $this->user->getUserName($account_id);
|
||||
$iFailed = 0;
|
||||
foreach ($data as $key => $value) {
|
||||
// Prefix the WebUser to Worker name
|
||||
$value['username'] = "$username." . $value['username'];
|
||||
$stmt = $this->mysqli->prepare("UPDATE $this->table SET password = ?, username = ? WHERE account_id = ? AND id = ?");
|
||||
if ($this->checkStmt($stmt)) {
|
||||
if (!$stmt->bind_param('ssii', $value['password'], $value['username'], $account_id, $key)) return false;
|
||||
if (!$stmt->execute()) return false;
|
||||
$stmt->close();
|
||||
}
|
||||
$stmt = $this->mysqli->prepare("UPDATE $this->table SET password = ?, username = ?, monitor = ? WHERE account_id = ? AND id = ?");
|
||||
if ( ! ( $this->checkStmt($stmt) && $stmt->bind_param('ssiii', $value['password'], $value['username'], $value['monitor'], $account_id, $key) && $stmt->execute()) )
|
||||
$iFailed++;
|
||||
}
|
||||
return true;
|
||||
if ($iFailed == 0)
|
||||
return true;
|
||||
// Catchall
|
||||
$this->setErrorMessage('Failed to update ' . $iFailed . ' 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 a specific worker and its status
|
||||
* @param id int Worker ID
|
||||
* @return mixed array Worker details
|
||||
**/
|
||||
public function getWorker($id) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT id, username, password, monitor,
|
||||
( SELECT SIGN(COUNT(id)) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS active,
|
||||
( SELECT ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ")/600/1000) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS hashrate
|
||||
FROM $this->table
|
||||
WHERE id = ?
|
||||
");
|
||||
if ($this->checkStmt($stmt) && $stmt->bind_param('i', $id) && $stmt->execute() && $result = $stmt->get_result())
|
||||
return $result->fetch_assoc();
|
||||
// Catchall
|
||||
echo $this->mysqli->error;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,7 +107,7 @@ class Worker {
|
||||
public function getWorkers($account_id) {
|
||||
$this->debug->append("STA " . __METHOD__, 4);
|
||||
$stmt = $this->mysqli->prepare("
|
||||
SELECT id, username, password,
|
||||
SELECT id, username, password, monitor,
|
||||
( SELECT SIGN(COUNT(id)) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS active,
|
||||
( SELECT ROUND(COUNT(id) * POW(2, " . $this->config['difficulty'] . ")/600/1000) FROM " . $this->share->getTableName() . " WHERE username = $this->table.username AND time > DATE_SUB(now(), INTERVAL 10 MINUTE)) AS hashrate
|
||||
FROM $this->table
|
||||
|
||||
@ -16,10 +16,10 @@ $smarty = new Smarty;
|
||||
|
||||
// Assign our local paths
|
||||
$debug->append('Define Smarty Paths', 3);
|
||||
$smarty->template_dir = 'templates/' . THEME . '/';
|
||||
$smarty->compile_dir = 'templates/compile/';
|
||||
$smarty->template_dir = BASEPATH . 'templates/' . THEME . '/';
|
||||
$smarty->compile_dir = BASEPATH . 'templates/compile/';
|
||||
|
||||
// Optional smarty caching, check Smarty documentation for details
|
||||
$smarty->caching = $config['cache'];
|
||||
$smarty->cache_dir = "templates/cache";
|
||||
$smarty->cache_dir = BASEPATH . "templates/cache";
|
||||
?>
|
||||
|
||||
9
public/templates/mail/idle_worker.tpl
Normal file
9
public/templates/mail/idle_worker.tpl
Normal file
@ -0,0 +1,9 @@
|
||||
<html>
|
||||
<body>
|
||||
<p>One of your workers is currently IDLE: {$DATA.username}</p>
|
||||
<p>Since monitoring is enabled for this worker, this notification was sent.</p>
|
||||
<p>Please check your workers!</p>
|
||||
<br/>
|
||||
<br/>
|
||||
</body>
|
||||
</html>
|
||||
@ -1 +1 @@
|
||||
[ {$WEBSITENAME} ] Password Reset Request
|
||||
[ {$WEBSITENAME} ] {$SUBJECT}
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
<td>Worker Name</td>
|
||||
<td>Password</td>
|
||||
<td class="center">Active</td>
|
||||
<td class="center">Monitor</td>
|
||||
<td class="right">Khash/s</td>
|
||||
<td> </td>
|
||||
<td> </td>
|
||||
@ -20,6 +21,7 @@
|
||||
<td{if $WORKERS[worker].active} style="color: orange"{/if}>{$username.0|escape}.<input name="data[{$WORKERS[worker].id}][username]" value="{$username.1|escape}" size="10" /></td>
|
||||
<td><input type="text" name="data[{$WORKERS[worker].id}][password]" value="{$WORKERS[worker].password|escape}" size="10"></td>
|
||||
<td class="center"><img src="{$PATH}/images/{if $WORKERS[worker].active}success{else}error{/if}.gif" /></td>
|
||||
<td class="center"><input type="checkbox" name="data[{$WORKERS[worker].id}][monitor]" value="1" {if $WORKERS[worker].monitor}checked{/if} /></td>
|
||||
<td class="right">{$WORKERS[worker].hashrate|number_format}</td>
|
||||
<td align="right"><a href="{$smarty.server.PHP_SELF}?page={$smarty.request.page|escape}&action={$smarty.request.action|escape}&do=delete&id={$WORKERS[worker].id|escape}"><button style="padding:5px" type="button">Delete</button></a></td>
|
||||
</tr>
|
||||
|
||||
@ -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 03:39 PM
|
||||
-- Server version: 5.5.31-0ubuntu0.13.04.1
|
||||
-- PHP Version: 5.4.9-4ubuntu2
|
||||
|
||||
@ -65,7 +65,24 @@ CREATE TABLE IF NOT EXISTS `blocks` (
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `height` (`height`,`blockhash`),
|
||||
KEY `time` (`time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Discovered blocks persisted from Litecoin Service';
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Discovered blocks persisted from Litecoin Service';
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `notifications`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `notifications` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`type` varchar(25) NOT NULL,
|
||||
`data` varchar(255) NOT NULL,
|
||||
`active` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `active` (`active`),
|
||||
KEY `data` (`data`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
||||
@ -173,7 +190,7 @@ CREATE TABLE IF NOT EXISTS `transactions` (
|
||||
KEY `block_id` (`block_id`),
|
||||
KEY `account_id` (`account_id`),
|
||||
KEY `type` (`type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user