- new "inactive" status column, closed #489

- added new "inactive" character_log status
- improved "inactive" character_log cronjob timings
This commit is contained in:
Exodus4D
2017-05-06 13:24:56 +02:00
parent 7216585d0b
commit 372df12624
12 changed files with 374 additions and 68 deletions

View File

@@ -23,8 +23,11 @@ downtime = 0 11 * * *
; delete expired connections (e.g. EOL)
deleteConnections = Cron\MapUpdate->deleteConnections, @fiveMinutes
; disable character log data
deactivateLogData = Cron\CharacterUpdate->deactivateLogData, @instant
; delete character log data
deleteLogData = Cron\CharacterUpdate->deleteLogData, @tenMinutes
deleteLogData = Cron\CharacterUpdate->deleteLogData, @instant
; delete expired signatures
deleteSignatures = Cron\MapUpdate->deleteSignatures, @halfHour

View File

@@ -13,32 +13,90 @@ use Model;
class CharacterUpdate {
const CHARACTER_LOG_ACTIVE = 300;
const CHARACTER_LOG_INACTIVE = 300;
/**
* delete all character log data
* get "active" time for character log data in seconds
* -> get default value in case of nothing found in *.ini file
* @param \Base $f3
* @return int
*/
protected function getCharacterLogActiveTime($f3){
$logActiveTime = (int)$f3->get('PATHFINDER.CACHE.CHARACTER_LOG_ACTIVE');
return ($logActiveTime >= 0) ? $logActiveTime : self::CHARACTER_LOG_ACTIVE;
}
/**
* get "incactive" time for character log data in seconeds
* @param \Base $f3
* @return int
*/
protected function getCharacterLogInactiveTime($f3){
$logInactiveTime = (int)$f3->get('PATHFINDER.CACHE.CHARACTER_LOG_INACTIVE');
return ($logInactiveTime >= 0) ? $logInactiveTime : self::CHARACTER_LOG_INACTIVE;
}
/**
* set character log data as inactive in case of not changed within X seconds
* >> php index.php "/cron/deactivateLogData"
* @param \Base $f3
*/
function deactivateLogData($f3){
DB\Database::instance()->getDB('PF');
$logActiveTime = $this->getCharacterLogActiveTime($f3);
/**
* @var $characterLogModel Model\CharacterLogModel
*/
$characterLogModel = Model\BasicModel::getNew('CharacterLogModel', 0);
// find expired character logs
$characterLogs = $characterLogModel->find([
'active = :active AND TIMESTAMPDIFF(SECOND, updated, NOW() ) > :lifetime',
':active' => 1,
':lifetime' => $logActiveTime
]);
if(is_object($characterLogs)){
foreach($characterLogs as $characterLog){
/**
* @var $characterLog Model\CharacterLogModel
*/
$characterLog->setActive(false);
$characterLog->save();
}
}
}
/**
* delete all character log data that were set to "active = 0" after X seconds of no changes
* -> see deactivateLogData()
* >> php index.php "/cron/deleteLogData"
* @param \Base $f3
*/
function deleteLogData($f3){
$logExpire = (int)$f3->get('PATHFINDER.CACHE.CHARACTER_LOG');
DB\Database::instance()->getDB('PF');
$logInactiveTime = $this->getCharacterLogInactiveTime($f3);
if($logExpire > 0){
DB\Database::instance()->getDB('PF');
/**
* @var $characterLogModel Model\CharacterLogModel
*/
$characterLogModel = Model\BasicModel::getNew('CharacterLogModel', 0);
/**
* @var $characterLogModel Model\CharacterLogModel
*/
$characterLogModel = Model\BasicModel::getNew('CharacterLogModel', 0);
// find expired character logs
$characterLogs = $characterLogModel->find([
'active = :active AND TIMESTAMPDIFF(SECOND, updated, NOW() ) > :lifetime',
':active' => 0,
':lifetime' => $logInactiveTime
]);
// find expired character logs
$characterLogs = $characterLogModel->find([
'TIMESTAMPDIFF(SECOND, updated, NOW() ) > :lifetime',
':lifetime' => $logExpire
]);
if(is_object($characterLogs)){
foreach($characterLogs as $characterLog){
$characterLog->erase();
}
if(is_object($characterLogs)){
foreach($characterLogs as $characterLog){
/**
* @var $characterLog Model\CharacterLogModel
*/
$characterLog->erase();
}
}
}

View File

@@ -48,14 +48,6 @@ abstract class BasicModel extends \DB\Cortex {
*/
protected $validate = [];
/**
* enables change for "active" column
* -> see setActive();
* -> $this->active = false; will NOT work (prevent abuse)!
* @var bool
*/
protected $allowActiveChange = false;
/**
* enables check for $fieldChanges on update/insert
* -> fields that should be checked need an "activity-log" flag
@@ -64,6 +56,14 @@ abstract class BasicModel extends \DB\Cortex {
*/
protected $enableActivityLogging = true;
/**
* enables change for "active" column
* -> see setActive();
* -> $this->active = false; will NOT work (prevent abuse)!
* @var bool
*/
private $allowActiveChange = false;
/**
* getData() cache key prefix
* -> do not change, otherwise cached data is lost

View File

@@ -116,6 +116,7 @@ class CharacterLogModel extends BasicModel {
public function getData(){
$logData = (object) [];
$logData->active = $this->active;
$logData->system = (object) [];
$logData->system->id = (int)$this->systemId;
$logData->system->name = $this->systemName;
@@ -134,16 +135,60 @@ class CharacterLogModel extends BasicModel {
}
/**
* setter for systemId
* @param int $systemId
* @return int
*/
public function set_systemId($systemId){
if($this->systemId != $systemId){
$this->setActive(true);
}
if($systemId > 0){
$this->updateCharacterSessionLocation($systemId);
}
return $systemId;
}
/**
* setter for $shipTypeId
* @param int $shipTypeId
* @return int
*/
public function set_shipTypeId($shipTypeId){
if($this->shipTypeId != $shipTypeId){
$this->setActive(true);
}
return $shipTypeId;
}
/**
* setter for $shipId
* @param int $shipId
* @return int
*/
public function set_shipId($shipId){
if($this->shipId != $shipId){
$this->setActive(true);
}
return $shipId;
}
/**
* setter for $stationId
* @param int $stationId
* @return int
*/
public function set_stationId($stationId){
if($this->stationId != $stationId){
$this->setActive(true);
}
return $stationId;
}
/**
* Event "Hook" function
* return false will stop any further action

View File

@@ -266,8 +266,14 @@ class MapModel extends BasicModel {
// get blank system
$systemController = new System();
$systems = $systemController->getSystemModelByIds([$systemId]);
$system = reset($systems);
$system->mapId = $this->_id;
if( count($systems) ){
$system = reset($systems);
$system->mapId = $this->_id;
}else{
// should NEVER happen -> systemId does NOT exist in New Eden!!
$this->getF3()->error(500, 'SystemId "' . $systemId . '"" does not exist in EVE!' );
}
}
$system->setActive(true);
@@ -834,6 +840,15 @@ class MapModel extends BasicModel {
// get data of characters which have with map access
$activeUserCharactersData = $this->getCharactersData();
// sort characters by "active" status
$sortByActiveLog = function($a, $b){
if($a->log->active == $b->log->active){
return 0;
}else{
return ($a->log->active && !$b->log->active) ? 0 : 1;
}
};
$mapUserData = (object)[];
$mapUserData->config = (object)[];
$mapUserData->config->id = $this->id;
@@ -857,14 +872,15 @@ class MapModel extends BasicModel {
unset($activeUserCharactersData[$key]);
}
}else{
// user has NO log data. If its an corp/ally map not each member is active
// user is not relevant for this function!
// character has NO log data. If its an corp/ally map not each member is active
// -> character is not relevant for this function!
unset($activeUserCharactersData[$key]);
}
}
// add system if active users were found
if(count($systemUserData->user) > 0){
usort($systemUserData->user, $sortByActiveLog);
$mapUserData->data->systems[] = $systemUserData;
}
}

View File

@@ -127,8 +127,10 @@ EXECUTION_LIMIT = 50
; CACHE ===========================================================================================
[PATHFINDER.CACHE]
; expire time for character log data (seconds) (default: 5min)
CHARACTER_LOG = 300
; mark characters inactive if nothing (ship/system/...) changed within X seconds (default: 5min)
CHARACTER_LOG_ACTIVE = 300
; delete character log data if "inactive" for X seconds (seconds) (default: 10min)
CHARACTER_LOG_INACTIVE = 300
; expire time for static system data (seconds) (default: 20d)
CONSTELLATION_SYSTEMS = 1728000
; max expire time. Expired cache files will be deleted by cronjob (seconds) (default: 10d)

View File

@@ -34,7 +34,12 @@ define([
tableCellEllipsisClass: 'pf-table-cell-ellipsis',
tableCellEllipsis80Class: 'pf-table-cell-80',
tableCellEllipsis90Class: 'pf-table-cell-90'
tableCellEllipsis90Class: 'pf-table-cell-90',
// toolbar
toolbarClass: 'pf-map-overlay-toolbar', // class for toolbar - content
toolbarIconClass: 'pf-map-overlay-toolbar-icon', // class for toolbar icon
toolbarCheckboxClass: 'pf-map-overlay-toolbar-checkbox' // class for toolbar checkbox
};
/**
@@ -322,7 +327,6 @@ define([
text: MapUtil.config.defaultLocalJumpRadius
}).attr('title', 'jumps')
)
);
let headline = $('<div>', {
@@ -342,6 +346,8 @@ define([
content.append(headline);
content.append(table);
// toolbar not used for now
// content.append(initToolbar());
overlay.append(overlayMain);
overlay.append(content);
@@ -509,6 +515,44 @@ define([
});
};
let initToolbar = () => {
let getCheckbox = (options) => {
return $('<div>', {
class: [config.toolbarCheckboxClass, 'checkbox'].join(' ')
}).append(
$('<input>', {
type: 'checkbox',
id: options.id,
name: options.name,
value: options.value,
checked: 'checked'
}),
$('<label>',{
'for': options.id,
html: options.label
})
);
};
let toolbar = $('<div>', {
class: [config.toolbarClass].join(' ')
}).append(
$('<i>', {
class: ['fa', 'fa-fw', 'fa-lg', 'fa-filter', config.toolbarIconClass, 'pull-left'].join(' ')
}),
getCheckbox({
id: 'test',
name: 'filter_character_active',
value: 1,
checked: true,
label: 'active'
})
);
return toolbar;
};
/**
* Clear Overlay and "Reset"
* @param mapId

View File

@@ -142,7 +142,7 @@ define([
};
/**
* loads the system info table into an element
* loads system info table into an element
* @param mapData
*/
$.fn.loadSystemInfoTable = function(mapData){
@@ -463,7 +463,7 @@ define([
};
/**
* loads the connection info table into an element
* loads connection info table into an element
* @param mapData
*/
$.fn.loadConnectionInfoTable = function(mapData){
@@ -611,6 +611,10 @@ define([
});
};
/**
* loads user info table into an element
* @param mapData
*/
$.fn.loadUsersInfoTable = function(mapData){
let usersElement = $(this);
@@ -629,7 +633,9 @@ define([
// init table tooltips
let tooltipElements = usersElement.find('[data-toggle="tooltip"]');
tooltipElements.tooltip();
tooltipElements.tooltip({
container: usersElement.parent()
});
});
let getIconForInformationWindow = () => {
@@ -659,7 +665,7 @@ define([
paging: true,
lengthMenu: [[5, 10, 20, 50, -1], [5, 10, 20, 50, 'All']],
ordering: true,
order: [ 1, 'asc' ],
order: [[ 0, 'desc' ], [ 4, 'asc' ]],
autoWidth: false,
hover: false,
data: usersData,
@@ -672,6 +678,25 @@ define([
columnDefs: [
{
targets: 0,
title: '<i title="active" data-toggle="tooltip" class="fa fa-user text-right"></i>',
width: '10px',
orderable: true,
searchable: false,
className: ['text-center'].join(' '),
data: 'log.active',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
let icon = value ? 'fa-user' : 'fa-user-o';
value = '<i class="fa ' + icon + '"></i>';
}
return value;
}
}
},
{
targets: 1,
title: '',
width: '26px',
orderable: false,
@@ -680,23 +705,31 @@ define([
data: 'log.ship',
render: {
_: function(data, type, row, meta){
return '<img src="' + Init.url.ccpImageServer + 'Render/' + data.typeId + '_32.png" />';
let value = data;
if(type === 'display'){
value = '<img src="' + Init.url.ccpImageServer + 'Render/' + value.typeId + '_32.png" />';
}
return value;
}
}
},{
targets: 1,
targets: 2,
title: 'ship',
orderable: true,
searchable: true,
data: 'log.ship',
render: {
_: function(data, type, row){
return data.typeName + '&nbsp;<i class="fa fa-fw fa-question-circle pf-help" title="' + data.name + '" data-toggle="tooltip"></i>';
let value = data;
if(type === 'display'){
value = data.typeName + '&nbsp;<i class="fa fa-fw fa-question-circle pf-help" title="' + value.name + '" data-toggle="tooltip"></i>';
}
return value;
},
sort: 'typeName'
}
},{
targets: 2,
targets: 3,
title: '',
width: '26px',
orderable: false,
@@ -705,11 +738,15 @@ define([
data: 'id',
render: {
_: function(data, type, row, meta){
return '<img src="' + Init.url.ccpImageServer + 'Character/' + data + '_32.jpg" />';
let value = data;
if(type === 'display'){
value = '<img src="' + Init.url.ccpImageServer + 'Character/' + value + '_32.jpg" />';
}
return value;
}
}
},{
targets: 3,
targets: 4,
title: 'pilot',
orderable: true,
searchable: true,
@@ -732,7 +769,7 @@ define([
});
}
},{
targets: 4,
targets: 5,
title: '',
width: '26px',
orderable: false,
@@ -741,11 +778,15 @@ define([
data: 'corporation',
render: {
_: function(data, type, row, meta){
return '<img src="' + Init.url.ccpImageServer + 'Corporation/' + data.id + '_32.png" />';
let value = data;
if(type === 'display'){
value = '<img src="' + Init.url.ccpImageServer + 'Corporation/' + value.id + '_32.png" />';
}
return value;
}
}
},{
targets: 5,
targets: 6,
title: 'corporation',
orderable: true,
searchable: true,
@@ -768,7 +809,7 @@ define([
});
}
},{
targets: 6,
targets: 7,
title: 'system',
orderable: true,
searchable: true,
@@ -778,7 +819,7 @@ define([
sort: 'name'
}
},{
targets: 7,
targets: 8,
title: 'station',
orderable: true,
searchable: true,

File diff suppressed because one or more lines are too long

View File

@@ -34,7 +34,12 @@ define([
tableCellEllipsisClass: 'pf-table-cell-ellipsis',
tableCellEllipsis80Class: 'pf-table-cell-80',
tableCellEllipsis90Class: 'pf-table-cell-90'
tableCellEllipsis90Class: 'pf-table-cell-90',
// toolbar
toolbarClass: 'pf-map-overlay-toolbar', // class for toolbar - content
toolbarIconClass: 'pf-map-overlay-toolbar-icon', // class for toolbar icon
toolbarCheckboxClass: 'pf-map-overlay-toolbar-checkbox' // class for toolbar checkbox
};
/**
@@ -322,7 +327,6 @@ define([
text: MapUtil.config.defaultLocalJumpRadius
}).attr('title', 'jumps')
)
);
let headline = $('<div>', {
@@ -342,6 +346,8 @@ define([
content.append(headline);
content.append(table);
// toolbar not used for now
// content.append(initToolbar());
overlay.append(overlayMain);
overlay.append(content);
@@ -509,6 +515,44 @@ define([
});
};
let initToolbar = () => {
let getCheckbox = (options) => {
return $('<div>', {
class: [config.toolbarCheckboxClass, 'checkbox'].join(' ')
}).append(
$('<input>', {
type: 'checkbox',
id: options.id,
name: options.name,
value: options.value,
checked: 'checked'
}),
$('<label>',{
'for': options.id,
html: options.label
})
);
};
let toolbar = $('<div>', {
class: [config.toolbarClass].join(' ')
}).append(
$('<i>', {
class: ['fa', 'fa-fw', 'fa-lg', 'fa-filter', config.toolbarIconClass, 'pull-left'].join(' ')
}),
getCheckbox({
id: 'test',
name: 'filter_character_active',
value: 1,
checked: true,
label: 'active'
})
);
return toolbar;
};
/**
* Clear Overlay and "Reset"
* @param mapId

View File

@@ -142,7 +142,7 @@ define([
};
/**
* loads the system info table into an element
* loads system info table into an element
* @param mapData
*/
$.fn.loadSystemInfoTable = function(mapData){
@@ -463,7 +463,7 @@ define([
};
/**
* loads the connection info table into an element
* loads connection info table into an element
* @param mapData
*/
$.fn.loadConnectionInfoTable = function(mapData){
@@ -611,6 +611,10 @@ define([
});
};
/**
* loads user info table into an element
* @param mapData
*/
$.fn.loadUsersInfoTable = function(mapData){
let usersElement = $(this);
@@ -629,7 +633,9 @@ define([
// init table tooltips
let tooltipElements = usersElement.find('[data-toggle="tooltip"]');
tooltipElements.tooltip();
tooltipElements.tooltip({
container: usersElement.parent()
});
});
let getIconForInformationWindow = () => {
@@ -659,7 +665,7 @@ define([
paging: true,
lengthMenu: [[5, 10, 20, 50, -1], [5, 10, 20, 50, 'All']],
ordering: true,
order: [ 1, 'asc' ],
order: [[ 0, 'desc' ], [ 4, 'asc' ]],
autoWidth: false,
hover: false,
data: usersData,
@@ -672,6 +678,25 @@ define([
columnDefs: [
{
targets: 0,
title: '<i title="active" data-toggle="tooltip" class="fa fa-user text-right"></i>',
width: '10px',
orderable: true,
searchable: false,
className: ['text-center'].join(' '),
data: 'log.active',
render: {
_: function(data, type, row, meta){
let value = data;
if(type === 'display'){
let icon = value ? 'fa-user' : 'fa-user-o';
value = '<i class="fa ' + icon + '"></i>';
}
return value;
}
}
},
{
targets: 1,
title: '',
width: '26px',
orderable: false,
@@ -680,23 +705,31 @@ define([
data: 'log.ship',
render: {
_: function(data, type, row, meta){
return '<img src="' + Init.url.ccpImageServer + 'Render/' + data.typeId + '_32.png" />';
let value = data;
if(type === 'display'){
value = '<img src="' + Init.url.ccpImageServer + 'Render/' + value.typeId + '_32.png" />';
}
return value;
}
}
},{
targets: 1,
targets: 2,
title: 'ship',
orderable: true,
searchable: true,
data: 'log.ship',
render: {
_: function(data, type, row){
return data.typeName + '&nbsp;<i class="fa fa-fw fa-question-circle pf-help" title="' + data.name + '" data-toggle="tooltip"></i>';
let value = data;
if(type === 'display'){
value = data.typeName + '&nbsp;<i class="fa fa-fw fa-question-circle pf-help" title="' + value.name + '" data-toggle="tooltip"></i>';
}
return value;
},
sort: 'typeName'
}
},{
targets: 2,
targets: 3,
title: '',
width: '26px',
orderable: false,
@@ -705,11 +738,15 @@ define([
data: 'id',
render: {
_: function(data, type, row, meta){
return '<img src="' + Init.url.ccpImageServer + 'Character/' + data + '_32.jpg" />';
let value = data;
if(type === 'display'){
value = '<img src="' + Init.url.ccpImageServer + 'Character/' + value + '_32.jpg" />';
}
return value;
}
}
},{
targets: 3,
targets: 4,
title: 'pilot',
orderable: true,
searchable: true,
@@ -732,7 +769,7 @@ define([
});
}
},{
targets: 4,
targets: 5,
title: '',
width: '26px',
orderable: false,
@@ -741,11 +778,15 @@ define([
data: 'corporation',
render: {
_: function(data, type, row, meta){
return '<img src="' + Init.url.ccpImageServer + 'Corporation/' + data.id + '_32.png" />';
let value = data;
if(type === 'display'){
value = '<img src="' + Init.url.ccpImageServer + 'Corporation/' + value.id + '_32.png" />';
}
return value;
}
}
},{
targets: 5,
targets: 6,
title: 'corporation',
orderable: true,
searchable: true,
@@ -768,7 +809,7 @@ define([
});
}
},{
targets: 6,
targets: 7,
title: 'system',
orderable: true,
searchable: true,
@@ -778,7 +819,7 @@ define([
sort: 'name'
}
},{
targets: 7,
targets: 8,
title: 'station',
orderable: true,
searchable: true,

View File

@@ -169,6 +169,18 @@ $mapWidth: 2500px ;
.dataTables_empty{
white-space: nowrap;
}
.pf-map-overlay-toolbar{
.pf-map-overlay-toolbar-icon{
vertical-align: 0; // overwrite default
margin-top: 14px;
}
.pf-map-overlay-toolbar-checkbox{
display: inline-block;
margin-bottom: 0; // overwrite default
}
}
}
.pf-map-overlay-local-main{