Spot v2: Project Management

This commit is contained in:
2019-01-26 10:13:06 +01:00
parent 55bb972c5b
commit a538357aba
25 changed files with 1649 additions and 9510 deletions

View File

@@ -2,10 +2,6 @@
class Spot extends Main
{
//Spot Mode
const MODE_HISTO = 'histo';
const MODE_BLOG = 'blog';
//Spot feed
const FEED_HOOK = 'https://api.findmespot.com/spot-main-web/consumer/rest-api/2.0/public/feed/';
const FEED_TYPE_XML = '/message.xml';
@@ -25,19 +21,27 @@ class Spot extends Main
const FEED_CHUNK_SIZE = 15;
/**
* Active Project
* @var Project
*/
private $oProject;
public function __construct($oClassManagement, $sProcessPage)
{
parent::__construct($oClassManagement, $sProcessPage);
$oClassManagement->incClass('cacher', true);
$asClasses = array(
array('name'=>'project', 'project'=>true),
array('name'=>'cacher', 'project'=>true)
);
parent::__construct($oClassManagement, $sProcessPage, $asClasses);
$this->oProject = new Project($this->oDb);
}
protected function install()
{
//Install DB
$this->oDb->install();
//Add feed
//$this->oDb->insertRow(self::FEED_TABLE, array('ref_feed_id'=>Settings::FEED_ID));
}
protected function getSqlOptions()
@@ -46,36 +50,44 @@ class Spot extends Main
(
'tables' => array
(
self::MSG_TABLE => array('ref_msg_id', Db::getId(self::FEED_TABLE), 'type', 'latitude', 'longitude', 'timestamp', 'unix_timestamp', 'content', 'battery_state'),
self::FEED_TABLE => array('ref_feed_id', Db::getId(self::SPOT_TABLE), 'name', 'description', 'status'),
self::SPOT_TABLE => array('ref_spot_id', 'name', 'model'),
self::POST_TABLE => array('name', 'content')
self::MSG_TABLE => array('ref_msg_id', Db::getId(self::FEED_TABLE), 'type', 'latitude', 'longitude', 'timestamp', 'unix_timestamp', 'content', 'battery_state'),
self::FEED_TABLE => array('ref_feed_id', Db::getId(self::SPOT_TABLE), Db::getId(Project::PROJ_TABLE), 'name', 'description', 'status', 'last_update'),
self::SPOT_TABLE => array('ref_spot_id', 'name', 'model'),
Project::PROJ_TABLE => array('name', 'codename', 'active_from', 'active_to', 'geofile', 'timezone'),
self::POST_TABLE => array(Db::getId(Project::PROJ_TABLE), 'name', 'content', 'timestamp')
),
'types' => array
(
'ref_msg_id' => "INT",
'type' => "VARCHAR(20)",
'latitude' => "DECIMAL(7,5)",
'longitude' => "DECIMAL(8,5)",
'timestamp' => "DATETIME",
'unix_timestamp'=> "INT",
'content' => "LONGTEXT",
'battery_state' => "VARCHAR(10)",
'ref_spot_id' => "VARCHAR(10)",
'name' => "VARCHAR(100)",
'model' => "VARCHAR(20)",
'ref_feed_id' => "VARCHAR(40)",
'description' => "VARCHAR(100)",
'status' => "VARCHAR(10)",
'ref_msg_id' => "INT",
'type' => "VARCHAR(20)",
'latitude' => "DECIMAL(7,5)",
'longitude' => "DECIMAL(8,5)",
'timestamp' => "DATETIME",
'unix_timestamp'=> "INT",
'content' => "LONGTEXT",
'battery_state' => "VARCHAR(10)",
'ref_spot_id' => "VARCHAR(10)",
'name' => "VARCHAR(100)",
'codename' => "VARCHAR(100)",
'model' => "VARCHAR(20)",
'ref_feed_id' => "VARCHAR(40)",
'description' => "VARCHAR(100)",
'status' => "VARCHAR(10)",
'active_from' => "DATETIME",
'active_to' => "DATETIME",
'geofile' => "VARCHAR(50)",
'timezone' => "VARCHAR(100)",
'last_update' => "DATETIME"
),
'constraints' => array
(
self::MSG_TABLE => "UNIQUE KEY `uni_ref_msg_id` (`ref_msg_id`)",
self::FEED_TABLE => "UNIQUE KEY `uni_ref_feed_id` (`ref_feed_id`)",
self::SPOT_TABLE => "UNIQUE KEY `uni_ref_spot_id` (`ref_spot_id`)",
self::MSG_TABLE => "INDEX(`ref_msg_id`)",
self::FEED_TABLE => "INDEX(`ref_feed_id`)",
self::SPOT_TABLE => "INDEX(`ref_spot_id`)",
self::MSG_TABLE => "UNIQUE KEY `uni_ref_msg_id` (`ref_msg_id`)",
self::FEED_TABLE => "UNIQUE KEY `uni_ref_feed_id` (`ref_feed_id`)",
self::SPOT_TABLE => "UNIQUE KEY `uni_ref_spot_id` (`ref_spot_id`)",
self::MSG_TABLE => "INDEX(`ref_msg_id`)",
self::FEED_TABLE => "INDEX(`ref_feed_id`)",
self::SPOT_TABLE => "INDEX(`ref_spot_id`)",
Project::PROJ_TABLE => "UNIQUE KEY `uni_proj_name` (`codename`)",
),
'cascading_delete' => array
(
@@ -89,10 +101,14 @@ class Spot extends Main
return parent::getMainPage(
array(
'vars' => array(
'feed_id' => Settings::FEED_ID,
'chunk_size'=> self::FEED_CHUNK_SIZE,
'mode' => Settings::MODE,
'mapbox_key'=> Settings::MAPBOX_KEY
'chunk_size' => self::FEED_CHUNK_SIZE,
'mapbox_key' => Settings::MAPBOX_KEY,
'default_project_codename' => $this->oProject->getProjectCodeName(),
'projects' => $this->oProject->getProjects()
),
'consts' => array(
'modes' => Project::MODES,
'geo_folder'=> Project::GEO_FOLDER
)
),
'index',
@@ -100,16 +116,22 @@ class Spot extends Main
);
}
/* Managing projects */
public function setProjectId($iProjectId=0) {
$this->oProject->setProjectId($iProjectId);
}
/* Getting & Storing messages */
private function getFeed($sRefFeedId=Settings::FEED_ID)
private function getFeed($sRefFeedId)
{
$sUrl = self::FEED_HOOK.$sRefFeedId.self::FEED_TYPE_JSON;
$sContent = file_get_contents($sUrl);
return json_decode($sContent, true);
}
private function updateFeed($sRefFeedId=Settings::FEED_ID)
private function updateFeed($sRefFeedId)
{
$asData = $this->getFeed($sRefFeedId);
$asMsgs = $asData['response']['feedMessageResponse']['messages'];
@@ -122,14 +144,15 @@ class Spot extends Main
$asSpotInfo = array('ref_spot_id'=>$asFirstMsg['messengerId'], 'name'=>$asFirstMsg['messengerName'], 'model'=>$asFirstMsg['modelId']);
$iSpotId = $this->oDb->insertUpdateRow(self::SPOT_TABLE, $asSpotInfo, array('ref_spot_id'));
//Update Feed Info
//Update Feed Info and last update date
$asFeedInfo = array(
'ref_feed_id' => $sRefFeedId,
Db::getId(self::SPOT_TABLE) => $iSpotId,
'name' => $asFeed['name'],
'description' => $asFeed['description'],
'status' => $asFeed['status'],
'led' => date(Db::MYSQL_TIMESTAMP) //update with current time
'ref_feed_id' => $sRefFeedId,
Db::getId(self::SPOT_TABLE) => $iSpotId,
Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId(),
'name' => $asFeed['name'],
'description' => $asFeed['description'],
'status' => $asFeed['status'],
'last_update' => date(Db::TIMESTAMP_FORMAT)
);
$iFeedId = $this->oDb->insertUpdateRow(self::FEED_TABLE, $asFeedInfo, array('ref_feed_id'));
@@ -142,7 +165,7 @@ class Spot extends Main
'type' => $asMsg['messageType'],
'latitude' => $asMsg['latitude'],
'longitude' => $asMsg['longitude'],
'timestamp' => date(Db::MYSQL_TIMESTAMP, strtotime($asMsg['dateTime'])), //Stored in Local Time
'timestamp' => date(Db::TIMESTAMP_FORMAT, strtotime($asMsg['dateTime'])), //Stored in Local Time
'unix_timestamp' => $asMsg['unixTime'], //Stored in UNIX time
'content' => $asMsg['messageContent'],
'battery_state' => $asMsg['batteryState']
@@ -152,7 +175,7 @@ class Spot extends Main
}
}
public function getMessages($sRefFeedId=Settings::FEED_ID)
public function getMessages()
{
/* Adding another point to test
$test = $this->oDb->selectRow(self::MSG_TABLE, 1);
@@ -162,12 +185,7 @@ class Spot extends Main
$test['longitude'] = '172.1936';
$this->oDb->insertUpdateRow(self::MSG_TABLE, $test, array('ref_msg_id')); */
//Check last message & update feed if necessary (max once a day)
$sLastMsg = $this->oDb->selectValue(self::FEED_TABLE, 'led', array('ref_feed_id'=>$sRefFeedId));
if(Settings::MODE!=self::MODE_HISTO && mb_substr($sLastMsg, 0, 10) != date('Y-m-d')) $this->updateFeed($sRefFeedId);
//Extract messages
$asMessages = array_values($this->getSpotMessages());
$asMessages = $this->getSpotMessages();
$bSuccess = !empty($asMessages);
$sDesc = $bSuccess?'':self::NO_DATA;
@@ -202,22 +220,46 @@ class Spot extends Main
private function getSpotMessages()
{
$asInfo = array('from'=>self::MSG_TABLE, 'orderBy'=>array('timestamp'=>'ASC'));
if(Settings::MODE==self::MODE_HISTO) {
$asInfo['constraint'] = array('timestamp'=>Settings::HISTO_SPAN);
$asInfo['constOpe'] = array('timestamp'=>"BETWEEN");
//Get Feed IDs
$asFeeds = $this->oDb->selectRows(array(
'select' => array(Db::getId(self::FEED_TABLE), 'ref_feed_id', 'last_update'),
'from' => self::FEED_TABLE,
'constraint'=> array(Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId()))
);
//Update on Blog Mode and not updated already today
$asAllFeedMessages = array();
foreach($asFeeds as $asFeed) {
//Feed updated once a day in Blog Mode
if($this->oProject->getMode() == Project::MODE_BLOG && mb_substr($asFeed['last_update'], 0, 10) != date('Y-m-d')) {
$this->updateFeed($asFeed['ref_feed_id']);
}
$asInfo = array(
'select' => array('id_message', 'ref_msg_id', 'type', 'latitude', 'longitude', 'timestamp', 'unix_timestamp'),
'from' => self::MSG_TABLE,
'constraint'=> array(
Db::getId(Spot::FEED_TABLE) => $asFeed[Db::getId(self::FEED_TABLE)],
'timestamp' => $this->oProject->getActivePeriod()),
'constOpe' => array(
Db::getId(Spot::FEED_TABLE) => "=",
'timestamp' => "BETWEEN"),
'orderBy' => array('timestamp'=>'ASC'));
$asMessages = $this->oDb->selectRows($asInfo);
foreach($asMessages as $asMessage)
{
$asMessage['unix_timestamp'] = (int) $asMessage['unix_timestamp'];
$asMessage['latitude'] = floatval($asMessage['latitude']);
$asMessage['longitude'] = floatval($asMessage['longitude']);
$asMessage['relative_time'] = Toolbox::getDateTimeDesc($asMessage['unix_timestamp']);
$asMessage['formatted_time'] = date(self::FORMAT_TIME, $asMessage['unix_timestamp']);
$asAllFeedMessages[] = $asMessage;
}
}
$asMessages = $this->oDb->selectRows($asInfo);
foreach($asMessages as $iKey=>$asMessage)
{
$asMessages[$iKey]['unix_timestamp'] = (int) $asMessages[$iKey]['unix_timestamp'];
$asMessages[$iKey]['latitude'] = floatval($asMessages[$iKey]['latitude']);
$asMessages[$iKey]['longitude'] = floatval($asMessages[$iKey]['longitude']);
$asMessages[$iKey]['relative_time'] = Toolbox::getDateTimeDesc($asMessages[$iKey]['unix_timestamp']);
$asMessages[$iKey]['formatted_time'] = date(self::FORMAT_TIME, $asMessages[$iKey]['unix_timestamp']);
}
return $asMessages;
return $asAllFeedMessages;
}
private function getPictures()
@@ -234,9 +276,8 @@ class Spot extends Main
//Get/Create thumbnail
$sThumbnailPath = self::getPicThumbnail($sPicPath);
//Filter on valid time interval (Histo mode only)
if( Settings::MODE != self::MODE_HISTO ||
$iPicTimeStamp >= strtotime(Settings::HISTO_SPAN['from']) && $iPicTimeStamp <= strtotime(Settings::HISTO_SPAN['to'])) {
//Filter on valid time interval
if($iPicTimeStamp >= strtotime($this->oProject->getActivePeriod('from')) && $iPicTimeStamp <= strtotime($this->oProject->getActivePeriod('to'))) {
$asPics[] = array(
'path' => $sPicPath,
@@ -253,15 +294,19 @@ class Spot extends Main
private function getPosts()
{
$asInfo = array('from'=>self::POST_TABLE);
if(Settings::MODE==self::MODE_HISTO) {
$asInfo['constraint'] = array('led'=>Settings::HISTO_SPAN);
$asInfo['constOpe'] = array('led'=>"BETWEEN");
$asInfo = array(
'from' => self::POST_TABLE,
'constraint'=> array(Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId()),
'constOpe' => array(Db::getId(Project::PROJ_TABLE) => "=")
);
if($this->oProject->getMode()==Project::MODE_HISTO) {
$asInfo['constraint']['timestamp'] = $this->oProject->getActivePeriod();
$asInfo['constOpe']['timestamp'] = "BETWEEN";
}
$asPosts = $this->oDb->selectRows($asInfo);
foreach($asPosts as &$asPost) {
$iUnixTimeStamp = strtotime($asPost['led']);
$iUnixTimeStamp = strtotime($asPost['timestamp']);
$asPost['unix_timestamp'] = $iUnixTimeStamp;
$asPost['relative_time'] = Toolbox::getDateTimeDesc($iUnixTimeStamp);
$asPost['formatted_time'] = date(self::FORMAT_TIME, $iUnixTimeStamp);
@@ -320,7 +365,12 @@ class Spot extends Main
public function addPost($sName, $sPost)
{
$asData = array('name'=>mb_strtolower(trim($sName)), 'content'=>trim($sPost));
$asData = array(
Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId(),
'name' => mb_strtolower(trim($sName)),
'content' => trim($sPost),
'timestamp' => date(Db::TIMESTAMP_FORMAT)
);
$iPostId = $this->oDb->insertRow(self::POST_TABLE, $asData);
return self::getJsonResult(($iPostId > 0), '');
}
@@ -337,6 +387,7 @@ class Spot extends Main
{
if(isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] == $this->asContext['serv_name']) {
$asDomains = array();
$sReferer = 'http://spot.lutran.fr';
switch($sMapId) {
case 'mapbox.satellite':
case 'mapbox.streets':
@@ -348,10 +399,19 @@ class Spot extends Main
$sToken = Settings::LINZ_KEY;
$asDomains = array('a', 'b', 'c', 'd');
break;
case 'ign.es':
$sPattern = 'http://www.ign.es/wmts/mapa-raster?request=getTile&format=image/png&layer=MTN&TileMatrixSet=GoogleMapsCompatible&TileMatrix={z}&TileCol={x}&TileRow={y}';
break;
case 'ign.fr':
$sPattern = 'https://wxs.ign.fr/{token}/geoportail/wmts?LAYER=GEOGRAPHICALGRIDSYSTEMS.MAPS&EXCEPTIONS=text/xml&FORMAT=image/jpeg&SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetTile&STYLE=normal&TILEMATRIXSET=PM&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}';
$sToken = Settings::IGN_FR_KEY;
$sReferer = 'https://www.visugpx.com/yfJDwfuTlf';
break;
}
$oCacher = new Cacher($sPattern, $sMapId);
$oCacher->setToken($sToken);
$oCacher->setDomains($asDomains);
$oCacher->setReferer($sReferer);
return $oCacher->pushTile($iX, $iY, $iZ);
}