chore(cleanup): archive one-time migrations, secure telemetry endpoint, and purge temporary files

This commit is contained in:
Hamza-Ayed
2026-08-18 14:00:20 +03:00
parent cb384765fb
commit bab24892c7
13 changed files with 1927 additions and 102206 deletions
@@ -0,0 +1,28 @@
#!/bin/bash
set -e
DATA_DIR="/home/hamzadoctor/app/infrastructure/osm-data"
echo "Downloading Syria map data..."
curl -L -o "$DATA_DIR/syria-latest.osm.pbf" https://download.geofabrik.de/asia/syria-latest.osm.pbf
echo "Merging Syria and Jordan..."
# Backup original Jordan if not already backed up
if [ ! -f "$DATA_DIR/jordan-latest.orig.osm.pbf" ]; then
cp "$DATA_DIR/jordan-latest.osm.pbf" "$DATA_DIR/jordan-latest.orig.osm.pbf"
fi
# Use --overwrite flag and ensure .pbf extension is at the end
osmium merge "$DATA_DIR/jordan-latest.orig.osm.pbf" "$DATA_DIR/syria-latest.osm.pbf" -o "$DATA_DIR/levant-latest.osm.pbf" --overwrite
echo "Replacing data file for import..."
mv "$DATA_DIR/levant-latest.osm.pbf" "$DATA_DIR/jordan-latest.osm.pbf"
echo "Re-importing to database (this may take a few minutes)..."
cd /home/hamzadoctor/app
docker compose run --rm osm-import
echo "Restarting services..."
docker compose restart martin api
echo "✅ Success! Jordan and Syria are now merged and imported."
+73
View File
@@ -0,0 +1,73 @@
#!/usr/bin/env bash
set -e
# ==============================================================================
# Script: fix_exact_border.sh
# Purpose: Clean rogue lines and set exact straight border segment:
# From (36.839237, 32.311852) to (38.793024, 33.371104)
# ==============================================================================
echo "================================================================="
echo "🇯🇴 Applying Exact Jordan-Syria Border Fix..."
echo "================================================================="
if [ -f .env ]; then
export $(grep -v '^#' .env | xargs)
fi
DB_USER=${POSTGRES_USER:-postgres}
DB_NAME=${POSTGRES_DB:-gis}
docker exec -i map-db psql -U "$DB_USER" -d "$DB_NAME" << 'EOF'
BEGIN;
-- 1. Remove all dummy / experimental lines previously added
DELETE FROM planet_osm_line WHERE osm_id >= 900000;
DELETE FROM planet_osm_polygon WHERE osm_id >= 900000;
-- 2. Remove any rogue lines north of the border line in the desert area
-- (Bounding box covering the false upper lines in Syria)
DELETE FROM planet_osm_line
WHERE boundary = 'administrative'
AND admin_level IN ('2', '3', '4', '5')
AND ST_Intersects(
way,
ST_Transform(
ST_MakeEnvelope(36.80, 32.35, 38.85, 33.70, 4326),
3857
)
)
AND NOT ST_Intersects(
way,
ST_Transform(
ST_MakeEnvelope(35.5, 31.0, 36.80, 33.0, 4326),
3857
)
);
-- 3. Insert the EXACT official straight border segment from user coordinates:
-- Point A: (36.839237, 32.311852) -> Point B: (38.793024, 33.371104)
INSERT INTO planet_osm_line (osm_id, boundary, admin_level, name, way)
VALUES (
999555,
'administrative',
'2',
'Jordan - Syria International Border',
ST_Transform(
ST_Segmentize(
ST_GeomFromText('LINESTRING(36.839237 32.311852, 38.793024 33.371104)', 4326),
1000
),
3857
)
);
COMMIT;
EOF
echo "Restarting Martin..."
docker compose restart martin
echo "================================================================="
echo "✅ Exact border fixed and applied successfully!"
echo "================================================================="
@@ -0,0 +1,38 @@
#!/usr/bin/env bash
set -e
# ==============================================================================
# Script: import_official_boundaries.sh
# Purpose: Import and standardize Jordan Official International & Governorate Boundaries
# Source: UN geoBoundaries Official ADM0 (National) & ADM1 (12 Governorates)
# ==============================================================================
echo "================================================================="
echo "🇯🇴 Importing Official Jordan International & Governorate Boundaries..."
echo "================================================================="
if [ -f .env ]; then
export $(grep -v '^#' .env | xargs)
fi
DB_USER=${POSTGRES_USER:-postgres}
DB_NAME=${POSTGRES_DB:-gis}
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SQL_FILE="$SCRIPT_DIR/data/boundaries/import_official_jordan.sql"
if [ ! -f "$SQL_FILE" ]; then
echo "Generating SQL from official GeoJSON files..."
python3 "$SCRIPT_DIR/data/boundaries/generate_sql.py"
fi
echo "1. Inserting official Jordan National Boundary & 12 Governorates into PostGIS..."
docker exec -i map-db psql -U "$DB_USER" -d "$DB_NAME" < "$SQL_FILE"
echo "2. Restarting Martin Tile Server to apply updated boundary tiles..."
docker compose restart martin
echo "================================================================="
echo "✅ Official Jordan Boundaries applied successfully!"
echo "Refresh your browser at https://map-saas.intaleqapp.com/#compare"
echo "================================================================="
@@ -0,0 +1,55 @@
#!/bin/bash
set -e
# Configuration
CONTAINER_NAME="map-db"
DB_USER="postgres"
DB_NAME="map_saas"
CSV_FILE="infrastructure/docker/postgis/data_clean_syria.csv"
SQL_SCHEMA="infrastructure/docker/postgis/create_syria_table.sql"
# 1. Ensure the table exists
echo "Setting up Syria table..."
docker exec -i $CONTAINER_NAME psql -U $DB_USER -d $DB_NAME < $SQL_SCHEMA
# 2. Upload CSV to container for fast bulk loading
echo "Copying CSV to database container..."
docker cp $CSV_FILE $CONTAINER_NAME:/tmp/data_clean_syria.csv
# 3. Import data using a temporary table to map columns correctly
echo "Importing data into PostGIS..."
docker exec -i $CONTAINER_NAME psql -U $DB_USER -d $DB_NAME <<EOF
-- Create temporary table for CSV import
CREATE TEMP TABLE temp_syria_import (
search_query TEXT,
name TEXT,
rating TEXT,
reviews TEXT,
latitude DECIMAL,
longitude DECIMAL,
maps_url TEXT,
scraped_at TEXT
);
-- Copy from CSV (header row exists)
COPY temp_syria_import FROM '/tmp/data_clean_syria.csv' WITH (FORMAT csv, HEADER true, ENCODING 'UTF8');
-- Insert into main table
-- Mapping search_query -> neighbourhood
INSERT INTO places_syria (name, neighbourhood, latitude, longitude, created_at)
SELECT name, search_query, latitude, longitude,
CASE WHEN scraped_at IS NOT NULL AND scraped_at <> '' THEN scraped_at::timestamp ELSE CURRENT_TIMESTAMP END
FROM temp_syria_import;
-- Update PostGIS geometry column
UPDATE places_syria
SET location = ST_SetSRID(ST_MakePoint(longitude, latitude), 4326)
WHERE location IS NULL AND latitude IS NOT NULL AND longitude IS NOT NULL;
-- Clean up
DROP TABLE temp_syria_import;
EOF
echo "✅ Import completed successfully!"
echo "Data sample from places_syria:"
docker exec -i $CONTAINER_NAME psql -U $DB_USER -d $DB_NAME -c "SELECT name, neighbourhood, latitude, longitude FROM places_syria LIMIT 5;"
@@ -0,0 +1,55 @@
import re
def convert_mysql_to_pg(input_file, output_file):
print(f"Converting {input_file} to {output_file}...")
with open(input_file, 'r', encoding='utf-8') as f, open(output_file, 'w', encoding='utf-8') as out:
out.write("-- Converted PostGIS Migration Script for PostgreSQL (Compatibility Mode)\n")
out.write("SET statement_timeout = 0;\n")
out.write("SET client_encoding = 'UTF8';\n")
# Enable MySQL-style backslash escaping in strings
out.write("SET standard_conforming_strings = off;\n")
out.write("SET escape_string_warning = off;\n")
out.write("CREATE EXTENSION IF NOT EXISTS postgis;\n\n")
for line in f:
if line.startswith('--') or not line.strip() or line.startswith('/*') or line.startswith('SET ') or line.startswith('UNSET '):
continue
if "COMMIT;" in line or "START TRANSACTION;" in line:
continue
# 1. Standard Conversion (backticks to double quotes for identifiers)
# We must be careful not to replace backticks inside strings (though unlikely in these dumps)
line = line.replace('`', '"')
# 2. Cleanup column definitions
line = re.sub(r"CHARACTER SET \w+ COLLATE \w+", "", line)
if "CREATE TABLE" in line:
line = line.replace("int(11)", "integer")
line = line.replace("int NOT NULL", "integer NOT NULL")
line = line.replace("bigint(20)", "bigint")
line = line.replace("double NOT NULL", "double precision NOT NULL")
line = line.replace("POINT NOT NULL SRID 4326", "geometry(Point, 4326)")
line = line.replace("point NOT NULL", "geometry(Point, 4326)")
line = re.sub(r"ENGINE=InnoDB.*?;", ";", line)
# 3. Handle Hex data (NULL works best, triggers will fix it)
line = re.sub(r"0x[0-9a-fA-F]+", "NULL", line)
# Since standard_conforming_strings = off, we DON'T need to replace \' with ''
# Postgres will understand \' as a literal quote.
# We just need to ensure backslashes themselves are handled if they were double-escaped.
# Actually, with standard_conforming_strings = off, MySQL's escaping should work AS IS.
# But wait, my previous script changed \' to ''. Let's revert that and just clean Definitions.
# 4. Fix AUTO_INCREMENT
if "AUTO_INCREMENT" in line:
line = re.sub(r"integer NOT NULL AUTO_INCREMENT", "SERIAL PRIMARY KEY", line)
out.write(line)
print("Success!")
if __name__ == "__main__":
convert_mysql_to_pg('geocodeDB (1).sql', 'converted_data.sql')
@@ -0,0 +1,98 @@
import csv
import os
def parse_jordan_csv(csv_file):
print(f"Parsing {csv_file}...")
records = []
if not os.path.exists(csv_file):
print(f"CSV file {csv_file} not found!")
return []
with open(csv_file, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
try:
# Column names: الاسم,latitude,longitude,الفئة الرئيسية,المحافظة,الرابط المباشر,تاريخ الرصد
name_ar = row['الاسم'].strip()
lat = float(row['latitude'])
lng = float(row['longitude'])
category = row['الفئة الرئيسية'].strip()
city = row['المحافظة'].strip()
link = row['الرابط المباشر'].strip()
created_at = row['تاريخ الرصد'].strip()
records.append({
'name_ar': name_ar,
'name': name_ar, # Use Arabic name for both as no English name provided
'lat': lat,
'lng': lng,
'category': category,
'city': city,
'link': link,
'created_at': created_at,
'source': 'csv'
})
except Exception as e:
# print(f"Error parsing row: {e}")
continue
return records
def merge_and_deduplicate(csv_records):
final_records = []
seen_points = set()
new_added = 0
for r in csv_records:
if not r['name_ar']: continue
# Creating a key for de-duplication based on name and rounded coordinates
key = (r['name_ar'].lower().strip(), round(r['lat'], 5), round(r['lng'], 5))
if key not in seen_points:
final_records.append(r)
seen_points.add(key)
new_added += 1
print(f"CSV records parsed: {len(csv_records)}")
print(f"Unique records: {new_added}")
return final_records
def write_final_sql(merged_records, output_file):
print(f"Writing final SQL to {output_file}...")
with open(output_file, 'w', encoding='utf-8') as f:
f.write("-- Jordan Location Data Combined\n")
f.write("TRUNCATE TABLE places_jordan RESTART IDENTITY;\n\n")
batch_size = 500
for i in range(0, len(merged_records), batch_size):
batch = merged_records[i:i+batch_size]
f.write('INSERT INTO "places_jordan" (name, name_ar, latitude, longitude, category, city, link, created_at, location) VALUES\n')
values_list = []
for r in batch:
name = r['name'].replace("'", "''")
name_ar = r['name_ar'].replace("'", "''")
category = r['category'].replace("'", "''")
city = r['city'].replace("'", "''")
link = r['link'].replace("'", "''")
created_at = r['created_at']
lat = r['lat']
lng = r['lng']
# ST_SetSRID(ST_MakePoint(lon, lat), 4326)
val = f"('{name}', '{name_ar}', {lat}, {lng}, '{category}', '{city}', '{link}', '{created_at}', ST_SetSRID(ST_MakePoint({lng}, {lat}), 4326))"
values_list.append(val)
f.write(",\n".join(values_list))
f.write(";\n\n")
if __name__ == "__main__":
csv_file = 'infrastructure/docker/postgis/jordan_data.csv'
output_file = 'jordan_combined_final.sql'
# If running on server, adjust path if needed
if not os.path.exists(csv_file):
csv_file = 'jordan_data.csv'
csv_records = parse_jordan_csv(csv_file)
merged = merge_and_deduplicate(csv_records)
write_final_sql(merged, output_file)
print(f"Generation complete! File: {output_file}")
+102
View File
@@ -0,0 +1,102 @@
#!/usr/bin/env bash
set -e
# ==============================================================================
# Script: restore_osm_roads.sh
# Purpose: Restore all OSM roads for Jordan & Syria cleanly using osm2pgsql,
# then apply the exact border line without deleting any roads!
# ==============================================================================
echo "================================================================="
echo "🔄 Restoring OSM Road Network & Setting Official Jordan Border..."
echo "================================================================="
cd "$(dirname "$0")"
if [ -f .env ]; then
export $(grep -v '^#' .env | xargs)
fi
DB_USER=${POSTGRES_USER:-mapuser}
DB_NAME=${POSTGRES_DB:-mapdb}
DATA_DIR="./infrastructure/osm-data"
mkdir -p "$DATA_DIR"
# Download Jordan PBF if not present or corrupt
if [ ! -s "${DATA_DIR}/jordan-latest.osm.pbf" ]; then
echo "📥 Downloading Jordan OSM data..."
wget -q --show-progress -O "${DATA_DIR}/jordan-latest.osm.pbf" "https://download.geofabrik.de/asia/jordan-latest.osm.pbf"
fi
if [ ! -s "${DATA_DIR}/syria-latest.osm.pbf" ]; then
echo "📥 Downloading Syria OSM data..."
wget -q --show-progress -O "${DATA_DIR}/syria-latest.osm.pbf" "https://download.geofabrik.de/asia/syria-latest.osm.pbf"
fi
if [ ! -s "${DATA_DIR}/egypt-latest.osm.pbf" ]; then
echo "📥 Downloading Egypt OSM data..."
wget -q --show-progress -O "${DATA_DIR}/egypt-latest.osm.pbf" "https://download.geofabrik.de/africa/egypt-latest.osm.pbf" || true
fi
if [ ! -s "${DATA_DIR}/iraq-latest.osm.pbf" ]; then
echo "📥 Downloading Iraq OSM data..."
wget -q --show-progress -O "${DATA_DIR}/iraq-latest.osm.pbf" "https://download.geofabrik.de/asia/iraq-latest.osm.pbf" || true
fi
echo "🚀 Importing Jordan OSM roads into PostGIS..."
docker compose --profile import run --rm osm-import \
osm2pgsql --create --slim --cache 1000 \
--database "$DB_NAME" --host db --user "$DB_USER" \
/data/jordan-latest.osm.pbf
echo "🚀 Importing Syria OSM roads into PostGIS (--append)..."
docker compose --profile import run --rm osm-import \
osm2pgsql --append --slim --cache 1000 \
--database "$DB_NAME" --host db --user "$DB_USER" \
/data/syria-latest.osm.pbf
if [ -s "${DATA_DIR}/egypt-latest.osm.pbf" ]; then
echo "🚀 Importing Egypt OSM data (--append)..."
docker compose --profile import run --rm osm-import \
osm2pgsql --append --slim --cache 1000 \
--database "$DB_NAME" --host db --user "$DB_USER" \
/data/egypt-latest.osm.pbf || true
fi
if [ -s "${DATA_DIR}/iraq-latest.osm.pbf" ]; then
echo "🚀 Importing Iraq OSM data (--append)..."
docker compose --profile import run --rm osm-import \
osm2pgsql --append --slim --cache 1000 \
--database "$DB_NAME" --host db --user "$DB_USER" \
/data/iraq-latest.osm.pbf || true
fi
echo "📍 Applying exact straight Jordan-Syria border segment from user coordinates..."
docker exec -i map-db psql -U "$DB_USER" -d "$DB_NAME" << 'EOF'
-- Insert the official straight border line:
-- Point A: (36.839237, 32.311852) -> Point B: (38.793024, 33.371104)
DELETE FROM planet_osm_line WHERE name = 'Jordan - Syria Official Border';
INSERT INTO planet_osm_line (osm_id, boundary, admin_level, name, way)
VALUES (
-9999991,
'administrative',
'2',
'Jordan - Syria Official Border',
ST_Transform(
ST_Segmentize(
ST_GeomFromText('LINESTRING(36.839237 32.311852, 38.793024 33.371104)', 4326),
1000
),
3857
)
);
EOF
echo "🔄 Restarting Martin to refresh vector tiles..."
docker compose restart martin
echo "================================================================="
echo "✅ All OSM Roads restored and official border applied perfectly!"
echo "================================================================="
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
set -e
# ==============================================================================
# Script: revert_boundaries.sh
# Purpose: Completely remove custom inserted lines and restore clean original boundaries
# ==============================================================================
echo "================================================================="
echo "🔄 Reverting all boundary changes to original clean OSM state..."
echo "================================================================="
if [ -f .env ]; then
export $(grep -v '^#' .env | xargs)
fi
DB_USER=${POSTGRES_USER:-postgres}
DB_NAME=${POSTGRES_DB:-gis}
docker exec -i map-db psql -U "$DB_USER" -d "$DB_NAME" << 'EOF'
BEGIN;
-- 1. Remove all custom lines and polygons added
DELETE FROM planet_osm_line WHERE osm_id >= 999000;
DELETE FROM planet_osm_polygon WHERE osm_id >= 999000;
-- 2. Restore Jordan & Syria national boundary line directly from the relation polygons
INSERT INTO planet_osm_line (osm_id, boundary, admin_level, name, way)
SELECT
900001,
'administrative',
'2',
p.name,
ST_Boundary(p.way)
FROM planet_osm_polygon p
WHERE p.boundary = 'administrative'
AND p.admin_level = '2'
AND (p.name ILIKE '%Jordan%' OR p.name ILIKE '%الأردن%' OR p.name ILIKE '%Syria%' OR p.name ILIKE '%سوريا%')
ON CONFLICT DO NOTHING;
COMMIT;
EOF
echo "Restarting Martin..."
docker compose restart martin
echo "================================================================="
echo "✅ Reverted successfully to original clean map boundaries!"
echo "================================================================="
+69
View File
@@ -0,0 +1,69 @@
<?php
/**
* Real-time Driver Location Tracker (Configurable Days - Full Records)
* Used by Intaleq PHP Core to export driver tracks to Map SaaS.
*/
include_once("../../jwtconnect.php");
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
// 1. API Key Validation (Strict environment check)
$expected_api_key = getenv('LOCATION_SERVER_API_KEY');
function get_api_key()
{
$headers = getallheaders();
if (isset($headers['x-api-key']))
return $headers['x-api-key'];
if (isset($headers['X-API-KEY']))
return $headers['X-API-KEY'];
if (isset($_SERVER['HTTP_X_API_KEY']))
return $_SERVER['HTTP_X_API_KEY'];
return '';
}
$provided_api_key = get_api_key();
if (empty($expected_api_key) || $provided_api_key !== $expected_api_key) {
http_response_code(401);
echo json_encode(['error' => 'Unauthorized access: Invalid or missing API key']);
exit;
}
// 2. API Input (Optional days parameter, default 1, max 100)
$days = isset($_GET['days']) ? (int)$_GET['days'] : 1;
if ($days < 1) $days = 1;
if ($days > 100) $days = 100;
// 3. SQL Query with Parameterized Bound Values
$sql = "
SELECT *
FROM car_tracks
WHERE created_at >= NOW() - INTERVAL :days DAY
ORDER BY created_at DESC
";
try {
$stmt = $con->prepare($sql);
$stmt->bindValue(':days', $days, PDO::PARAM_INT);
$stmt->execute();
$records = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode([
'success' => true,
'total_records' => count($records),
'from' => date('Y-m-d H:i:s', strtotime("-$days days")),
'to' => date('Y-m-d H:i:s'),
'data' => $records
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode([
'error' => 'Database error',
'details' => $e->getMessage()
]);
}