moved files into subdirs

This commit is contained in:
asohh 2025-10-13 16:28:20 +02:00
commit 10fcf55b10
242 changed files with 23 additions and 0 deletions

View file

@ -0,0 +1,8 @@
FROM ghcr.io/asohh/fedora-minimal-containers/php-cli:43
RUN microdnf install -y php-mysqli php-bcmath php-xml gunzip https://raw.githubusercontent.com/rpmsphere/x86_64/master/d/dcron-4.5-7.1.x86_64.rpm && microdnf clean all
COPY ./utils/* /opt/
COPY ./data_init/*.sql /opt/init/init.sql
ENTRYPOINT ["/opt/entrypoint.sh"]
CMD ["/usr/sbin/dcrond", "-f" ]

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
<?php
define('REPLICATE_URL', 'https://planet.openstreetmap.org/replication/minute');
define('MYSQL_HOST', getenv('MYSQL_HOST'));
define('MYSQL_DB', getenv('MYSQL_DB'));
define('MYSQL_USER', getenv('MYSQL_USER'));
define('MYSQL_PASSWORD', getenv('MYSQL_PASSWORD'));
define('USE_STATISTICS', false);
define('WEBSERVICE_COUNTRY_URL', 'http://api.geonames.org/countryCode');
define('WEBSERVICE_USER', 'xxxxxxxx');
define('MAX_WEBREQUESTS_PER_HOUR', 1000);
?>

View file

@ -0,0 +1,29 @@
#!/bin/sh
set -e
####################################################################################################
### Crontab settings
####################################################################################################
cat<<EOF | dcrontab -
# min hour day month weekday command
5 * * * * sh /opt/update_camera.sh
EOF
####################################################################################################
### Run prescripts
####################################################################################################
php /opt/init_db.php
#TODO add db_migrations
echo "Prescripts done"
####################################################################################################
### Run cmd
####################################################################################################
# see: https://github.com/dubiousjim/dcron/issues/13
# ignore using `exec` for `dcron` to get another pid instead of `1`
# exec "$@"
"$@"

View file

@ -0,0 +1,21 @@
<?php
include "config.php";
$mysqli = new mysqli(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB);
if($mysqli->connect_errno) {
echo "Error while connecting to DB : $mysqli->error \n" ;
exit(1);
}
$mysqli->autocommit(FALSE);
$result = $mysqli->query("SELECT * FROM sync_state WHERE k = 'sequenceNumber'");
while($row = $result->fetch_assoc()) {
echo $row["v"];
}
$mysqli->close();
?>

View file

@ -0,0 +1,97 @@
<?php
// Admin credentials (must have privileges to create DB/users)
$dbHost = getenv('MYSQL_HOST');
$dbAdmin = getenv('MYSQL_USER');
$dbPassword = getenv('MYSQL_PASSWORD');
$dbName = getenv('MYSQL_DB');
// Variables for new users
$cameraUser = getenv('CAMERA_USER');
$cameraPassword = getenv('CAMERA_USER_PASSWORD');
$camSelectUser = getenv('CAMERA_SELECT_USER');
$camSelectPassword = getenv('CAMERA_SELECT_USER_PASSWORD');
// Connect to MySQL
$conn = new mysqli($dbHost, $dbAdmin, $dbPassword);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
if (!$conn->query("CREATE DATABASE IF NOT EXISTS $dbName")) {
echo "Error creating database: " . $conn->error . "\n";
}
if (!$conn->select_db($dbName)) {
die("Error selecting database: " . $conn->error);
}
// Create camera user
$conn->query("CREATE USER IF NOT EXISTS '$cameraUser'@'%' IDENTIFIED BY '$cameraPassword'");
$conn->query("GRANT ALL PRIVILEGES ON $dbName.* TO '$cameraUser'@'%'");
// Create camselect user
$conn->query("CREATE USER IF NOT EXISTS '$camSelectUser'@'%' IDENTIFIED BY '$camSelectPassword'");
$conn->query("GRANT SELECT ON $dbName.* TO '$camSelectUser'@'%'");
// position table
$conn->query("
CREATE TABLE IF NOT EXISTS position (
id BIGINT PRIMARY KEY,
latitude INT,
longitude INT
)
");
// tag table
$conn->query("
CREATE TABLE IF NOT EXISTS tag (
id BIGINT,
k VARCHAR(100),
v VARCHAR(10000),
PRIMARY KEY (id, k),
CONSTRAINT fk_position FOREIGN KEY (id) REFERENCES `position`(id) ON DELETE CASCADE
)
");
$conn->query("CREATE INDEX IF NOT EXISTS LatLon ON position (latitude, longitude)");
// sync_state table
$conn->query("
CREATE TABLE IF NOT EXISTS sync_state (
k VARCHAR(100),
v VARCHAR(100)
)
");
$result = $conn -> query("SELECT * FROM sync_state WHERE k='sequenceNumber'");
$table_count = $result -> num_rows;
if ($table_count == 0){
$conn->query("INSERT INTO sync_state (k, v) VALUES ('sequenceNumber', '0');");
}
echo "Database, users, and tables created successfully.\n";
$result = $conn -> query("SELECT * FROM position limit 10");
$table_count = $result -> num_rows;
printf("Result set has %d rows.\n", $table_count);
if ($table_count == 0){
$location = "/opt/init/init.sql";
$commands = file_get_contents($location);
$conn->multi_query($commands);
echo "Inserted data.\n";
}
$conn->close();
?>

View file

@ -0,0 +1,291 @@
<?php
include "config.php";
$elementTypes = array();
$count = 0;
$countDelete = 0;
$countModifyDelete = 0;
$countModify = 0;
$countCreate = 0;
$mode = '';
$curNodeAttrs = null;
$curNodeTags = null;
$id = 0;
$latitude = 0;
$longitude = 0;
$mysqli = new mysqli(MYSQL_HOST, MYSQL_USER, MYSQL_PASSWORD, MYSQL_DB);
if($mysqli->connect_errno) {
echo "Error while connecting to DB : $mysqli->error \n" ;
exit(1);
}
$mysqli->autocommit(FALSE);
if (! ($deleteStmt = $mysqli->prepare("DELETE FROM position WHERE id=?"))) {
echo "Error while preparing delete position statement : " . $mysqli->error ;
exit(1);
}
$deleteStmt->bind_param('d', $id);
if (! ($deleteTagStmt = $mysqli->prepare("DELETE FROM tag WHERE id=?"))) {
echo "Error while preparing delete tag statement : " . $mysqli->error ;
exit(1);
}
$deleteTagStmt->bind_param('d', $id);
if (USE_STATISTICS) {
if (! ($deleteStatsStmt = $mysqli->prepare("DELETE FROM statistics WHERE id=?"))) {
echo "Error while preparing delete statistics statement : " . $mysqli->error ;
exit(1);
}
$deleteStatsStmt->bind_param('d', $id);
}
if (! ($insertStmt = $mysqli->prepare("INSERT INTO position (id, latitude, longitude) VALUES (?, ?, ?)"))) {
echo "Error while preparing insert position statement : " . $mysqli->error ;
exit(1);
}
$insertStmt->bind_param('dii', $id, $latitude, $longitude);
if (! ($insertTagStmt = $mysqli->prepare("INSERT INTO tag (id, k, v) VALUES (?, ?, ?)"))) {
echo "Error while preparing insert tag statement : " . $mysqli->error ;
exit(1);
}
$insertTagStmt->bind_param('dss', $id, $k, $v);
if (USE_STATISTICS) {
if (! ($insertStatsStmt = $mysqli->prepare("INSERT INTO statistics (id, ts, version) VALUES (?, ?, ?)"))) {
echo "Error while preparing insert statistics statement : " . $mysqli->error ;
exit(1);
}
$insertStatsStmt->bind_param('dsi', $id, $ts, $version);
}
function printDebug() {
global $elementTypes, $count, $countDelete, $countModifyDelete, $countModify, $countCreate;
echo "== $count ==============================\n";
foreach($elementTypes as $k => $v) {
echo "$k : $v\n";
}
echo "++++++ Surveillance nodes : ++++++\n";
echo "$countDelete deletions\n";
echo "$countModifyDelete modifications --> deletions\n";
echo "$countModify modifications\n";
echo "$countCreate creations\n";
}
function printDebugCurNode() {
global $curNodeAttrs, $curNodeTags, $mode;
echo "=============\n";
echo "$mode : " . $curNodeAttrs['id'] ." (". $curNodeAttrs['lat'] . " x " . $curNodeAttrs['lon'] . ") : " . $curNodeAttrs['user'] . "\n";
if (! empty($curNodeAttrs)) {
echo " => Attributes :\n";
foreach($curNodeAttrs as $k => $v) {
echo " $k : $v\n";
}
} else {
echo " => No attributes\n";
}
if (! empty($curNodeTags)) {
echo " => Tags :\n";
foreach($curNodeTags as $k => $v) {
echo " $k : $v\n";
}
} else {
echo " => No tags\n";
}
}
function startElement ($parser, $name, $attrs) {
global $elementTypes, $count, $mode, $curNodeAttrs, $curNodeTags;
$count++;
if (array_key_exists($name, $elementTypes)) {
$elementTypes[$name] += 1;
} else {
$elementTypes[$name] = 1;
}
if ($name == 'modify' || $name == 'delete' or $name == 'create') {
$mode = $name;
} else if ($name == 'node') {
$curNodeAttrs = $attrs;
$curNodeTags = array();
} else if ($name == 'tag') {
$curNodeTags[$attrs['k']] = $attrs['v'];
}
}
function endElement ($parser, $name) {
if (USE_STATISTICS) {
global $mode, $deleteStmt, $deleteTagStmt, $deleteStatsStmt, $insertStmt, $insertTagStmt, $insertStatsStmt, $selectStmt, $id, $latitude, $longitude, $k, $v, $ts, $version, $curNodeAttrs, $curNodeTags, $mysqli, $countDelete, $countModifyDelete, $countModify, $countCreate;
} else {
global $mode, $deleteStmt, $deleteTagStmt, $insertStmt, $insertTagStmt, $selectStmt, $id, $latitude, $longitude, $k, $v, $curNodeAttrs, $curNodeTags, $mysqli, $countDelete, $countModifyDelete, $countModify, $countCreate;
}
if ($name == 'modify' || $name == 'delete' or $name == 'create') {
$mode = '';
} else if ($name == 'node') {
if ($mode == 'delete') {
$id = $curNodeAttrs['id'];
if (USE_STATISTICS) {
if (! $deleteStatsStmt->execute()) {
echo "***** Error : Deleting statistics $id : ". $deleteStatsStmt->error . "\n";
}
}
if (! $deleteTagStmt->execute()) {
echo "***** Error : Deleting tags $id : ". $deleteTagStmt->error . "\n";
}
if (! $deleteStmt->execute()) {
echo "***** Error : Deleting $id : ". $deleteStmt->error . "\n";
}
if ($deleteStmt->affected_rows > 0) {
$countDelete++;
$mysqli->commit();
printDebugCurNode();
}
} else if ($mode == 'modify' || $mode == 'create') {
if (! empty($curNodeTags)
&& array_key_exists('man_made', $curNodeTags)
&& $curNodeTags['man_made'] == 'surveillance') {
printDebugCurNode();
$id = $curNodeAttrs['id'];
if ($mode == 'modify') {
$countModify++;
if (USE_STATISTICS) {
if (! $deleteStatsStmt->execute()) {
echo "***** Error : Deleting statistics $id for modification : ". $deleteStatsStmt->error . "\n";
}
}
if (! $deleteTagStmt->execute()) {
echo "***** Error : Deleting tags $id for modification : ". $deleteTagStmt->error . "\n";
}
if (! $deleteStmt->execute()) {
echo "***** Error : Deleting $id for modification : ". $deleteStmt->error . "\n";
}
} else {
$countCreate++;
}
$latitude = (int) ($curNodeAttrs['lat'] * 10000000);
$longitude = (int) ($curNodeAttrs['lon'] * 10000000);
if (! $insertStmt->execute()) {
echo "***** Error : inserting $id ($latitude x $longitude) : ". $insertStmt->error . "\n";
}
$k = 'lat';
$v = $curNodeAttrs['lat'];
if (! $insertTagStmt->execute()) {
echo "***** Error : inserting latitude $v for $id : ". $insertTagStmt->error . "\n";
}
$k = 'lon';
$v = $curNodeAttrs['lon'];
if (! $insertTagStmt->execute()) {
echo "***** Error : inserting longitude $v for $id : ". $insertTagStmt->error . "\n";
}
$k = 'userid';
$v = $curNodeAttrs['user'];
if (! $insertTagStmt->execute()) {
echo "***** Error : inserting user $v for $id : ". $insertTagStmt->error . "\n";
}
$k = 'version';
$v = $curNodeAttrs['version'];
if (! $insertTagStmt->execute()) {
echo "***** Error : inserting version $v for $id : ". $insertTagStmt->error . "\n";
}
$k = 'timestamp';
$v = $curNodeAttrs['timestamp'];
if (! $insertTagStmt->execute()) {
echo "***** Error : inserting timestamp $v for $id : ". $insertTagStmt->error . "\n";
}
foreach($curNodeTags as $k => $v) {
if (! $insertTagStmt->execute()) {
echo "***** Error : inserting tag $k => $v for $id : ". $insertTagStmt->error . "\n";
}
}
if (USE_STATISTICS) {
$ts = $curNodeAttrs['timestamp'];
$version = $curNodeAttrs['version'];
if (! $insertStatsStmt->execute()) {
echo "***** Error : inserting ts $ts, version $version for $id : ". $insertStatsStmt->error . "\n";
}
}
$mysqli->commit();
} else if ($mode == 'modify') {
// delete former surveillance nodes that were modified to non-surveillance nodes
$id = $curNodeAttrs['id'];
if (USE_STATISTICS) {
if (! $deleteStatsStmt->execute()) {
echo "***** Error : Deleting statistics $id for non-surveillance node : ". $deleteStatsStmt->error . "\n";
}
}
if (! $deleteTagStmt->execute()) {
echo "***** Error : Deleting tags $id for non-surveillance node : ". $deleteTagStmt->error . "\n";
}
if (! $deleteStmt->execute()) {
echo "***** Error : Deleting $id for non-surveillance node : ". $deleteStmt->error . "\n";
}
if ($deleteStmt->affected_rows > 0) {
$countModifyDelete++;
$mysqli->commit();
printDebugCurNode();
echo " ==> delete because modified to non-surveillance node\n";
}
}
}
$curNodeAttrs = null;
$curNodeTags = null;
}
}
$file="change_file.osc";
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false);
xml_set_element_handler($xml_parser, "startElement", "endElement");
if (!($fp = fopen($file, "r"))) {
die("could not open XML input");
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_parser, $data, feof($fp))) {
die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}
}
$sql="UPDATE sync_state SET v='" . $_SERVER['argv'][1] ."' WHERE k='sequenceNumber';";
$mysqli->query($sql);
$mysqli->commit();
printDebug();
$mysqli->close();
?>

View file

@ -0,0 +1,93 @@
#!/bin/bash
exedir=$(cd `dirname "$0"`; pwd)
REPLICATE_URL=`grep "REPLICATE_URL" "$exedir/config.php" | sed -e 's/.*http/http/' -e 's#...$##' `
if [ -e "/var/lock/update_camera" ]
then
# Maybe an other update is running
otherPid=$(cat "/var/lock/update_camera")
count=$(ps $otherPid | grep -c `basename "$0"`)
if [ $count -gt 0 ]
then
echo "$0 is running yet. Exiting." >&2
exit 1
fi
fi
# OK. We can update the database...
echo $$ > "/var/lock/update_camera"
exeDir=$(cd `dirname "$0"`; pwd);
cd "$exeDir"
if [ -e "state.txt" ]
then
rm "state.txt"
fi
#TODO get state from db
# Read the last update timestamp
# lastTimestamp=$(grep "^timestamp=" "lastState.txt" | cut -d'=' -f2-)
# lastSeqNum=$(grep "^sequenceNumber=" "lastState.txt" | cut -d'=' -f2-)
lastSeqNum=$(php get_sync_state.php)
curl -L "$REPLICATE_URL/state.txt" -o state.txt
newTimestamp=$(grep "^timestamp=" "state.txt" | cut -d'=' -f2-)
newSeqNum=$(grep "^sequenceNumber=" "state.txt" | cut -d'=' -f2-)
if [ $newSeqNum -eq $lastSeqNum ]
then
echo "No new file to be processed"
exit 1
fi
mkdir logs
curSeqNum=$lastSeqNum
while [ $curSeqNum -lt $newSeqNum ]
do
curSeqNum=$(( $curSeqNum + 1 ))
logFileName="logs/log.$curSeqNum"
if [ -e "change_file.osc" ]
then
rm "change_file.osc"
fi
if [ -e "change_file.osc.gz" ]
then
rm "change_file.osc.gz"
fi
echo `date "+%d/%m/%Y %H:%M"`" - Start processing sequence number $curSeqNum" > "$logFileName"
targetDirName=`echo "000000000$curSeqNum" | sed 's#.*\(...\)\(...\)\(...\)$#\1/\2/\3.osc.gz#'`
targetDirName="$REPLICATE_URL/$targetDirName"
curl -L "$targetDirName" -o change_file.osc.gz 2>&1 | tee -a $logFileName
if [ $? -gt 0 ]
then
echo "Error during recovery of $targetDirName" | tee -a $logFileName
exit 1
fi
gunzip change_file.osc.gz 2>&1 | tee -a $logFileName
if [ $? -gt 0 ]
then
echo "Error during decompression of $targetDirName" | tee -a $logFileName
exit 1
fi
php update_camera.php $curSeqNum 2>&1 | tee -a $logFileName
targetDirName=`echo "$targetDirName" | sed 's/.osc.gz$/.state.txt/'`
curl -L "$targetDirName" -o lastState.txt 2>&1 | tee -a $logFileName
echo `date "+%d/%m/%Y %H:%M"`" - Finish processing sequence number $curSeqNum" | tee -a "$logFileName"
done
rm "/var/lock/update_camera"

View file

@ -0,0 +1,4 @@
FROM quay.io/fedora/fedora-minimal:43
RUN microdnf install -y python-pip && microdnf clean all && pip install OSMPythonTools
COPY ./lookup_country.py /opt/

View file

@ -0,0 +1,7 @@
from OSMPythonTools.nominatim import Nominatim
nominatim = Nominatim()
heidelberg = nominatim.query(49.4093582, 8.694724, reverse=True, zoom=10)
print(heidelberg.address()['country_code'])

View file

@ -0,0 +1,12 @@
import xml.etree.cElementTree as ET
import gzip
import requests
r = requests.get('https://planet.openstreetmap.org/replication/minute/000/000/001.osc.gz')
data = gzip.decompress(r.content)
tree = ET.fromstring(data)
print(tree.findall("./."))

4
web/Containerfile Normal file
View file

@ -0,0 +1,4 @@
FROM docker.io/library/php:apache
RUN docker-php-ext-install mysqli bcmath
COPY ./www/* /var/www/html

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

View file

@ -0,0 +1,23 @@
Copyright (c) 2010-2021, Vladimir Agafonkin
Copyright (c) 2010-2011, CloudMade
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,32 @@
<img width="600" src="https://rawgit.com/Leaflet/Leaflet/master/src/images/logo.svg" alt="Leaflet" />
Leaflet is the leading open-source JavaScript library for **mobile-friendly interactive maps**.
Weighing just about 39 KB of gzipped JS plus 4 KB of gzipped CSS code, it has all the mapping [features][] most developers ever need.
Leaflet is designed with *simplicity*, *performance* and *usability* in mind.
It works efficiently across all major desktop and mobile platforms out of the box,
taking advantage of HTML5 and CSS3 on modern browsers while being accessible on older ones too.
It can be extended with a huge amount of [plugins][],
has a beautiful, easy to use and [well-documented][] API
and a simple, readable [source code][] that is a joy to [contribute][] to.
For more info, docs and tutorials, check out the [official website][].<br>
For **Leaflet downloads** (including the built master version), check out the [download page][].
We're happy to meet new contributors.
If you want to **get involved** with Leaflet development, check out the [contribution guide][contribute].
Let's make the best mapping library that will ever exist,
and push the limits of what's possible with online maps!
[![Build Status](https://travis-ci.org/Leaflet/Leaflet.svg?branch=master)](https://travis-ci.org/Leaflet/Leaflet)
[contributors]: https://github.com/Leaflet/Leaflet/graphs/contributors
[features]: http://leafletjs.com/#features
[plugins]: http://leafletjs.com/plugins.html
[well-documented]: http://leafletjs.com/reference.html "Leaflet API reference"
[source code]: https://github.com/Leaflet/Leaflet "Leaflet GitHub repository"
[hosted on GitHub]: http://github.com/Leaflet/Leaflet
[contribute]: https://github.com/Leaflet/Leaflet/blob/master/CONTRIBUTING.md "A guide to contributing to Leaflet"
[official website]: http://leafletjs.com
[download page]: http://leafletjs.com/download.html

File diff suppressed because it is too large Load diff

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