Compare commits

..

5 Commits

Author SHA1 Message Date
4e9fb52318 Removing local librairies 2 2023-11-11 15:43:47 +01:00
850d2e7235 Removing local librairies 2023-11-11 15:43:24 +01:00
97645b3476 Move files (again) 2023-11-07 19:41:28 +01:00
ab914a391f Restore language folder 2023-10-20 20:56:11 +02:00
842e02f4bb Move files to follow webpack structure 2023-10-20 20:47:26 +02:00
123 changed files with 162 additions and 70341 deletions

4
cli/cron.sh Normal file
View File

@@ -0,0 +1,4 @@
#!/bin/bash
wget -qO- https://spot.lutran.fr/index.php?a=update_project > /dev/null
#Crontab job: 0 * * * * . /var/www/spot/spot_cron.sh > /dev/null

View File

@@ -14,7 +14,7 @@
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Franzz\\Spot\\": "inc/" "Franzz\\Spot\\": "api/"
}, },
"files": [ "files": [
"settings.php" "settings.php"

69304
geo/snt.gpx

File diff suppressed because it is too large Load Diff

View File

@@ -25,9 +25,6 @@ $oValue = $_REQUEST['value'] ?? '';
$iId = $_REQUEST['id'] ?? 0 ; $iId = $_REQUEST['id'] ?? 0 ;
$sType = $_REQUEST['type'] ?? ''; $sType = $_REQUEST['type'] ?? '';
$sEmail = $_REQUEST['email'] ?? ''; $sEmail = $_REQUEST['email'] ?? '';
$sLat = $_REQUEST['latitude'] ?? '';
$sLng = $_REQUEST['longitude'] ?? '';
$iTimestamp = $_REQUEST['timestamp'] ?? 0;
//Initiate class //Initiate class
$oSpot = new Spot(__FILE__, $sTimezone); $oSpot = new Spot(__FILE__, $sTimezone);
@@ -73,9 +70,6 @@ if($sAction!='')
case 'add_comment': case 'add_comment':
$sResult = $oSpot->addComment($iId, $sContent); $sResult = $oSpot->addComment($iId, $sContent);
break; break;
case 'add_position':
$sResult = $oSpot->addPosition($sLat, $sLng, $iTimestamp);
break;
case 'admin_new': case 'admin_new':
$sResult = $oSpot->createProject(); $sResult = $oSpot->createProject();
break; break;
@@ -94,9 +88,6 @@ if($sAction!='')
case 'sql': case 'sql':
$sResult = $oSpot->getDbBuildScript(); $sResult = $oSpot->getDbBuildScript();
break; break;
case 'build_geojson':
$sResult = $oSpot->buildGeoJSON($sName);
break;
default: default:
$sResult = Main::getJsonResult(false, Main::NOT_FOUND); $sResult = Main::getJsonResult(false, Main::NOT_FOUND);
} }

View File

@@ -36,18 +36,18 @@ class Converter extends PhpObject {
public static function isGeoJsonValid($sCodeName) { public static function isGeoJsonValid($sCodeName) {
$bResult = false; $bResult = false;
$sGpxFilePath = Geo::getFilePath($sCodeName, Gpx::EXT); $sGpxFilePath = Gpx::getFilePath($sCodeName);
$sGeoJsonFilePath = Geo::getFilePath($sCodeName, GeoJson::EXT); $sGeoJsonFilePath = GeoJson::getFilePath($sCodeName);
//No need to generate if gpx is missing //No need to generate if gpx is missing
if(!file_exists($sGpxFilePath) || file_exists($sGeoJsonFilePath) && filemtime($sGeoJsonFilePath) > filemtime(Geo::getFilePath($sCodeName, Gpx::EXT))) $bResult = true; if(!file_exists($sGpxFilePath) || file_exists($sGeoJsonFilePath) && filemtime($sGeoJsonFilePath) > filemtime(Gpx::getFilePath($sCodeName))) $bResult = true;
return $bResult; return $bResult;
} }
} }
class Geo extends PhpObject { class Geo extends PhpObject {
const GEO_FOLDER = 'geo/'; const GEO_FOLDER = '../geo/';
const OPT_SIMPLE = 'simplification'; const OPT_SIMPLE = 'simplification';
protected $asTracks; protected $asTracks;
@@ -55,12 +55,16 @@ class Geo extends PhpObject {
public function __construct($sCodeName) { public function __construct($sCodeName) {
parent::__construct(get_class($this), Settings::DEBUG, PhpObject::MODE_HTML); parent::__construct(get_class($this), Settings::DEBUG, PhpObject::MODE_HTML);
$this->sFilePath = self::getFilePath($sCodeName, static::EXT); $this->sFilePath = self::getFilePath($sCodeName);
$this->asTracks = array(); $this->asTracks = array();
} }
public static function getFilePath($sCodeName, $sExt) { public static function getFilePath($sCodeName) {
return self::GEO_FOLDER.$sCodeName.$sExt; return self::GEO_FOLDER.$sCodeName.static::EXT;
}
public static function getDistFilePath($sCodeName) {
return 'geo/'.$sCodeName.static::EXT;
} }
public function getLog() { public function getLog() {

View File

@@ -168,31 +168,6 @@ class Feed extends PhpObject {
return $bNewMsg; return $bNewMsg;
} }
public function addManualPosition($sLat, $sLng, $iTimestamp) {
$sTimeZone = date_default_timezone_get();
$oDateTime = new \DateTime('@'.$iTimestamp);
$oDateTime->setTimezone(new \DateTimeZone($sTimeZone));
$asWeather = $this->getWeather(array($sLat, $sLng), $iTimestamp);
$asMsg = [
'ref_msg_id' => $iTimestamp.'/man',
'id_feed' => $this->getFeedId(),
'type' => 'OK',
'latitude' => $sLat,
'longitude' => $sLng,
'iso_time' => $oDateTime->format("Y-m-d\TH:i:sO"), //Incorrect ISO 8601 format, but compliant with Spot data
'site_time' => $oDateTime->format(Db::TIMESTAMP_FORMAT),
'timezone' => $sTimeZone,
'unix_time' => $iTimestamp,
'content' => '',
'battery_state' => '',
'posted_on' => date(Db::TIMESTAMP_FORMAT),
];
$iMessageId = $this->oDb->insertRow(self::MSG_TABLE, array_merge($asMsg, $asWeather));
return $iMessageId;
}
private function updateFeed() { private function updateFeed() {
$bNewMsg = false; $bNewMsg = false;
$asData = $this->retrieveFeed(); $asData = $this->retrieveFeed();

View File

@@ -12,7 +12,7 @@ class Media extends PhpObject {
const MEDIA_TABLE = 'medias'; const MEDIA_TABLE = 'medias';
//Media folders //Media folders
const MEDIA_FOLDER = 'files/'; const MEDIA_FOLDER = '../files/';
const THUMB_FOLDER = self::MEDIA_FOLDER.'thumbs/'; const THUMB_FOLDER = self::MEDIA_FOLDER.'thumbs/';
const THUMB_MAX_WIDTH = 400; const THUMB_MAX_WIDTH = 400;

View File

@@ -144,8 +144,8 @@ class Project extends PhpObject {
if($sCodeName != '' && !Converter::isGeoJsonValid($sCodeName)) Converter::convertToGeoJson($sCodeName); if($sCodeName != '' && !Converter::isGeoJsonValid($sCodeName)) Converter::convertToGeoJson($sCodeName);
$asProject['geofilepath'] = Spot::addTimestampToFilePath(Geo::getFilePath($sCodeName, GeoJson::EXT)); $asProject['geofilepath'] = Spot::addTimestampToFilePath(GeoJson::getDistFilePath($sCodeName));
$asProject['gpxfilepath'] = Spot::addTimestampToFilePath(Geo::getFilePath($sCodeName, Gpx::EXT)); $asProject['gpxfilepath'] = Spot::addTimestampToFilePath(Gpx::getDistFilePath($sCodeName));
$asProject['codename'] = $sCodeName; $asProject['codename'] = $sCodeName;
} }
return $bSpecificProj?$asProject:$asProjects; return $bSpecificProj?$asProject:$asProjects;

View File

@@ -40,6 +40,8 @@ class Spot extends Main
const DEFAULT_LANG = 'en'; const DEFAULT_LANG = 'en';
const MAIN_PAGE = 'index';
private Project $oProject; private Project $oProject;
private Media $oMedia; private Media $oMedia;
private User $oUser; private User $oUser;
@@ -158,16 +160,15 @@ class Spot extends Main
); );
} }
public function getAppMainPage() public function getAppParams() {
{
//Cache Page List //Cache Page List
$asPages = array_diff($this->asMasks, array('email_update', 'email_conf')); $asPages = array_diff($this->asMasks, array('email_update', 'email_conf'));
if(!$this->oUser->checkUserClearance(User::CLEARANCE_ADMIN)) { if(!$this->oUser->checkUserClearance(User::CLEARANCE_ADMIN)) {
$asPages = array_diff($asPages, array('admin', 'upload')); $asPages = array_diff($asPages, array('admin', 'upload'));
} }
return parent::getMainPage( $asGlobalVars = array(
array(
'vars' => array( 'vars' => array(
'chunk_size' => self::FEED_CHUNK_SIZE, 'chunk_size' => self::FEED_CHUNK_SIZE,
'default_project_codename' => $this->oProject->getProjectCodeName(), 'default_project_codename' => $this->oProject->getProjectCodeName(),
@@ -180,20 +181,21 @@ class Spot extends Main
'clearances' => User::CLEARANCES, 'clearances' => User::CLEARANCES,
'default_timezone' => Settings::TIMEZONE 'default_timezone' => Settings::TIMEZONE
) )
), );
'index',
return self::getJsonResult(true, '', parent::getParams($asGlobalVars, self::MAIN_PAGE, $asPages));
}
public function getAppMainPage()
{
return parent::getMainPage(
self::MAIN_PAGE,
array( array(
'language' => $this->oLang->getLanguage(), 'language' => $this->oLang->getLanguage(),
'host_url' => $this->asContext['serv_name'], 'host_url' => $this->asContext['serv_name'],
'filepath_css' => self::addTimestampToFilePath('style/spot.css'), 'filepath_css' => self::addTimestampToFilePath('spot.css'),
'filepath_js_d3' => self::addTimestampToFilePath('script/d3.min.js'), 'filepath_js' => self::addTimestampToFilePath('../dist/app.js')
'filepath_js_leaflet' => self::addTimestampToFilePath('script/leaflet.min.js'), )
'filepath_js_jquery' => self::addTimestampToFilePath('script/jquery.min.js'),
'filepath_js_jquery_mods' => self::addTimestampToFilePath('script/jquery.mods.js'),
'filepath_js_spot' => self::addTimestampToFilePath('script/spot.js'),
'filepath_js_lightbox' => self::addTimestampToFilePath('script/lightbox.js')
),
$asPages
); );
} }
@@ -630,13 +632,6 @@ class Spot extends Main
return self::getJsonResult($asResult['result'], $asResult['desc'], $asResult['data']); return self::getJsonResult($asResult['result'], $asResult['desc'], $asResult['data']);
} }
public function addPosition($sLat, $sLng, $iTimestamp) {
$oFeed = new Feed($this->oDb, $this->oProject->getFeedIds()[0]);
$bResult = ($oFeed->addManualPosition($sLat, $sLng, $iTimestamp) > 0);
return self::getJsonResult($bResult, $bResult?'':$this->oDb->getLastError());
}
public function getAdminSettings($sType='') { public function getAdminSettings($sType='') {
$oFeed = new Feed($this->oDb); $oFeed = new Feed($this->oDb);
$asData = array( $asData = array(
@@ -751,10 +746,6 @@ class Spot extends Main
)); ));
} }
public function buildGeoJSON($sCodeName) {
return Converter::convertToGeoJson($sCodeName);
}
public static function decToDms($dValue, $sType) { public static function decToDms($dValue, $sType) {
if($sType=='lat') $sDirection = ($dValue >= 0)?'N':'S'; //Latitude if($sType=='lat') $sDirection = ($dValue >= 0)?'N':'S'; //Latitude
else $sDirection = ($dValue >= 0)?'E':'W'; //Longitude else $sDirection = ($dValue >= 0)?'E':'W'; //Longitude

107
lib/index.php Executable file
View File

@@ -0,0 +1,107 @@
<?php
/* Requests Handler */
//Start buffering
ob_start();
//Run from /dist/
$oLoader = require __DIR__.'/../vendor/autoload.php';
use Franzz\Objects\ToolBox;
use Franzz\Objects\Main;
use Franzz\Spot\Spot;
use Franzz\Spot\User;
ToolBox::fixGlobalVars($argv ?? array());
//Available variables
$sAction = $_REQUEST['a'] ?? '';
$sTimezone = $_REQUEST['t'] ?? '';
$sName = $_GET['name'] ?? '';
$sContent = $_GET['content'] ?? '';
$iProjectId = $_REQUEST['id_project'] ?? 0 ;
$sField = $_REQUEST['field'] ?? '';
$oValue = $_REQUEST['value'] ?? '';
$iId = $_REQUEST['id'] ?? 0 ;
$sType = $_REQUEST['type'] ?? '';
$sEmail = $_REQUEST['email'] ?? '';
//Initiate class
$oSpot = new Spot(__FILE__, $sTimezone);
$oSpot->setProjectId($iProjectId);
$sResult = '';
if($sAction!='')
{
switch($sAction)
{
case 'params':
$sResult = $oSpot->getAppParams();
break;
case 'markers':
$sResult = $oSpot->getMarkers();
break;
case 'next_feed':
$sResult = $oSpot->getNextFeed($iId);
break;
case 'new_feed':
$sResult = $oSpot->getNewFeed($iId);
break;
case 'add_post':
$sResult = $oSpot->addPost($sName, $sContent);
break;
case 'subscribe':
$sResult = $oSpot->subscribe($sEmail, $sName);
break;
case 'unsubscribe':
$sResult = $oSpot->unsubscribe();
break;
case 'unsubscribe_email':
$sResult = $oSpot->unsubscribeFromEmail($iId);
break;
case 'update_project':
$sResult = $oSpot->updateProject();
break;
default:
if($oSpot->checkUserClearance(User::CLEARANCE_ADMIN))
{
switch($sAction)
{
case 'upload':
$sResult = $oSpot->upload();
break;
case 'add_comment':
$sResult = $oSpot->addComment($iId, $sContent);
break;
case 'admin_new':
$sResult = $oSpot->createProject();
break;
case 'admin_get':
$sResult = $oSpot->getAdminSettings();
break;
case 'admin_set':
$sResult = $oSpot->setAdminSettings($sType, $iId, $sField, $oValue);
break;
case 'admin_del':
$sResult = $oSpot->delAdminSettings($sType, $iId);
break;
case 'generate_cron':
$sResult = $oSpot->genCronFile();
break;
case 'sql':
$sResult = $oSpot->getDbBuildScript();
break;
default:
$sResult = Main::getJsonResult(false, Main::NOT_FOUND);
}
}
else $sResult = Main::getJsonResult(false, Main::NOT_FOUND);
}
}
else $sResult = $oSpot->getAppMainPage();
$sDebug = ob_get_clean();
if(Settings::DEBUG && $sDebug!='') $oSpot->addUncaughtError($sDebug);
echo $sResult;

View File

@@ -6,9 +6,6 @@
<div class="bar" style="width: 0%;"></div> <div class="bar" style="width: 0%;"></div>
</div> </div>
<div id="comments"></div> <div id="comments"></div>
<div id="location">
<button id="add_loc"><i class="fa fa-message push"></i>New Position</button>
</div>
<div id="status"></div> <div id="status"></div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
@@ -38,27 +35,6 @@ oSpot.pageInit = function(asHash) {
$('#progress .bar').css('width', progress+'%'); $('#progress .bar').css('width', progress+'%');
} }
}); });
$('#add_loc').click(() => {
if(navigator.geolocation) {
addStatus('Determining position...');
navigator.geolocation.getCurrentPosition(
(position) => {
addStatus('Sending position...');
oSpot.get(
'add_position',
function(asData){addStatus('Position sent');},
{'latitude':position.coords.latitude, 'longitude':position.coords.longitude, 'timestamp':Math.round(position.timestamp / 1000)},
function(sMsgId){addStatus(self.lang(sMsgId));},
);
},
(error) => {
addStatus(error.message);
}
);
}
else addStatus('This browser does not support geolocation');
});
} }
else addStatus(self.lang('upload_mode_archived', [asProject.name]), true); else addStatus(self.lang('upload_mode_archived', [asProject.name]), true);
}; };

View File

@@ -22,7 +22,6 @@
4. Copy settings-sample.php to settings.php and populate 4. Copy settings-sample.php to settings.php and populate
5. Go to #admin and create a new project, feed & maps 5. Go to #admin and create a new project, feed & maps
6. Add a GPX file named <project_codename>.gpx to /geo/ 6. Add a GPX file named <project_codename>.gpx to /geo/
7. Run composer install
## To Do List ## To Do List
* ECMA import/export * ECMA import/export
* Add mail frequency slider * Add mail frequency slider

2
script/d3.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

23
script/leaflet.min.js vendored

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

Before

Width:  |  Height:  |  Size: 821 B

After

Width:  |  Height:  |  Size: 821 B

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 261 KiB

After

Width:  |  Height:  |  Size: 261 KiB

View File

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@@ -9,7 +9,7 @@ $stroke-width-mouse-focus : 1;
$stroke-width-height-focus: 2; $stroke-width-height-focus: 2;
$stroke-width-axis : 2; $stroke-width-axis : 2;
@import 'leaflet/leaflet'; @import '../../node_modules/leaflet/dist/leaflet';
@import 'leaflet/leaflet_heightgraph'; @import 'leaflet/leaflet_heightgraph';
/* Leaflet fixes */ /* Leaflet fixes */
@@ -108,3 +108,7 @@ $stroke-width-axis : 2;
} }
} }
} }
.leaflet-default-icon-path {
background-image: none;
}

View File

@@ -1,4 +1,4 @@
@import 'lightbox/lightbox'; @import '../../node_modules/lightbox2/dist/css/lightbox.css';
@mixin lightbox-icon($icon) { @mixin lightbox-icon($icon) {
background: none; background: none;

Some files were not shown because too many files have changed in this diff Show More