Aleksmorshen's picture
Update app.py
d5e50b4 verified
raw
history blame
13.5 kB
from flask import Flask, render_template_string, jsonify, request
import sqlite3
app = Flask(__name__)
# Инициализация базы данных SQLite3
def init_db():
conn = sqlite3.connect('markers.db')
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS markers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
description TEXT,
telegram_link TEXT,
latitude REAL NOT NULL,
longitude REAL NOT NULL
)''')
conn.commit()
conn.close()
# Получение всех меток из базы данных
def get_all_markers():
conn = sqlite3.connect('markers.db')
cursor = conn.cursor()
cursor.execute('SELECT id, name, description, telegram_link, latitude, longitude FROM markers')
markers = cursor.fetchall()
conn.close()
return markers
# Добавление новой метки в базу данных
def add_marker_to_db(name, description, telegram_link, latitude, longitude):
conn = sqlite3.connect('markers.db')
cursor = conn.cursor()
cursor.execute('INSERT INTO markers (name, description, telegram_link, latitude, longitude) VALUES (?, ?, ?, ?, ?)',
(name, description, telegram_link, latitude, longitude))
conn.commit()
marker_id = cursor.lastrowid
conn.close()
return marker_id
# Удаление метки из базы данных
def remove_marker_from_db(marker_id):
conn = sqlite3.connect('markers.db')
cursor = conn.cursor()
cursor.execute('DELETE FROM markers WHERE id = ?', (marker_id,))
conn.commit()
conn.close()
# HTML-шаблон с улучшенным дизайном
html_template = '''
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GeoGram</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css">
<style>
body {
font-family: Arial, sans-serif;
background-color: #f7f7f7;
margin: 0;
padding: 0;
}
#map {
height: 80vh;
width: 100%;
}
h1 {
text-align: center;
padding: 20px;
margin: 0;
background-color: #007BFF;
color: white;
font-size: 24px;
}
.leaflet-popup-content-wrapper {
background-color: #fff;
border-radius: 10px;
padding: 10px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
}
.leaflet-popup-content b {
color: #007BFF;
font-size: 18px;
display: block;
margin-bottom: 5px;
}
.leaflet-popup-content a {
color: #007BFF;
text-decoration: none;
}
.leaflet-popup-content a:hover {
text-decoration: underline;
}
.popup-form {
display: flex;
flex-direction: column;
width: 200px;
}
.popup-form input, .popup-form textarea {
padding: 5px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 14px;
}
.popup-form button {
background-color: #007BFF;
color: white;
border: none;
padding: 8px 12px;
border-radius: 5px;
cursor: pointer;
}
.popup-form button:hover {
background-color: #0056b3;
}
#search-input {
margin: 20px;
padding: 8px;
width: calc(100% - 40px);
border: 1px solid #ccc;
border-radius: 5px;
}
#search-button {
padding: 8px 12px;
background-color: #007BFF;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
#search-button:hover {
background-color: #0056b3;
}
#search-results {
margin: 20px;
}
</style>
</head>
<body>
<h1>GeoGram</h1>
<div>
<input type="text" id="search-input" placeholder="Поиск по названию или описанию" />
<button id="search-button">Поиск</button>
</div>
<div id="search-results"></div>
<div id="map"></div>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
<script>
const map = L.map('map').setView([55.75, 37.61], 13); // Начальное местоположение по умолчанию
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
}).addTo(map);
// Проверка поддержки геолокации и установка центра карты на текущее местоположение пользователя
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
const userLatitude = position.coords.latitude;
const userLongitude = position.coords.longitude;
map.setView([userLatitude, userLongitude], 13);
// Добавление маркера для местоположения пользователя
L.marker([userLatitude, userLongitude]).addTo(map)
.bindPopup('Вы находитесь здесь').openPopup();
}, function() {
alert('Не удалось получить ваше местоположение.');
});
} else {
alert('Ваш браузер не поддерживает геолокацию.');
}
// Загрузка существующих меток из базы данных
fetch('/get_markers')
.then(response => response.json())
.then(data => {
data.forEach(marker => {
const markerObj = L.marker([marker.latitude, marker.longitude]).addTo(map);
markerObj.bindPopup(`<b>${marker.name}</b><p>${marker.description}</p><a href="https://t.me/${marker.telegram_link}" target="_blank">Перейти в Telegram</a><br><button onclick="removeMarker(${marker.id})">Удалить</button>`);
});
});
// Функция для добавления метки
function addMarker(name, description, telegram_link, position) {
fetch('/add_marker', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: name,
description: description,
telegram_link: telegram_link,
position: [position.lat, position.lng]
})
})
.then(response => response.json())
.then(data => {
const markerObj = L.marker([data.latitude, data.longitude]).addTo(map);
markerObj.bindPopup(`<b>${data.name}</b><p>${data.description}</p><a href="https://t.me/${data.telegram_link}" target="_blank">Перейти в Telegram</a><br><button onclick="removeMarker(${data.id})">Удалить</button>`);
});
}
// Событие клика по карте для добавления формы
map.on('click', function(e) {
const popupContent = document.createElement('div');
popupContent.classList.add('popup-form');
const inputName = document.createElement('input');
inputName.type = 'text';
inputName.placeholder = 'Название метки';
const inputDescription = document.createElement('textarea');
inputDescription.placeholder = 'Описание метки';
const inputTelegram = document.createElement('input');
inputTelegram.type = 'text';
inputTelegram.placeholder = 'Имя пользователя Telegram (без https://t.me/)';
const button = document.createElement('button');
button.textContent = 'Добавить метку';
button.onclick = function() {
const markerName = inputName.value;
const markerDescription = inputDescription.value;
const markerTelegram = inputTelegram.value;
if (markerName && markerTelegram) {
addMarker(markerName, markerDescription, markerTelegram, e.latlng);
map.closePopup();
}
};
popupContent.appendChild(inputName);
popupContent.appendChild(inputDescription);
popupContent.appendChild(inputTelegram);
popupContent.appendChild(button);
const popup = L.popup()
.setLatLng(e.latlng)
.setContent(popupContent)
.openOn(map);
});
// Удаление метки
function removeMarker(id) {
fetch(`/remove_marker/${id}`, {
method: 'DELETE'
}).then(() => {
location.reload();
});
}
// Функция для поиска меток
function searchMarkers(query) {
fetch(`/search_markers?query=${encodeURIComponent(query)}`)
.then(response => response.json())
.then(data => {
const resultsDiv = document.getElementById('search-results');
resultsDiv.innerHTML = ''; // Очистить предыдущие результаты
if (data.length > 0) {
data.forEach(marker => {
const resultItem = document.createElement('div');
resultItem.innerHTML = `<b>${marker.name}</b>: ${marker.description} <button onclick="showMarker(${marker.id})">Показать на карте</button>`;
resultsDiv.appendChild(resultItem);
});
} else {
resultsDiv.innerHTML = '<p>Нет результатов</p>';
}
});
}
// Обработчик события для кнопки поиска
document.getElementById('search-button').onclick = function() {
const query = document.getElementById('search-input').value;
searchMarkers(query);
};
// Функция для показа метки на карте
function showMarker(markerId) {
fetch(`/get_markers`)
.then(response => response.json())
.then(data => {
const marker = data.find(m => m.id === markerId);
if (marker) {
map.setView([marker.latitude, marker.longitude], 13);
L.marker([marker.latitude, marker.longitude]).addTo(map)
.bindPopup(`<b>${marker.name}</b><p>${marker.description}</p><a href="https://t.me/${marker.telegram_link}" target="_blank">Перейти в Telegram</a>`);
}
});
}
</script>
</body>
</html>
'''
@app.route('/')
def index():
return render_template_string(html_template)
@app.route('/get_markers', methods=['GET'])
def get_markers():
markers = get_all_markers()
return jsonify([{
'id': marker[0],
'name': marker[1],
'description': marker[2],
'telegram_link': marker[3],
'latitude': marker[4],
'longitude': marker[5]
} for marker in markers])
@app.route('/add_marker', methods=['POST'])
def add_marker():
data = request.json
name = data['name']
description = data['description']
telegram_link = data['telegram_link']
latitude, longitude = data['position']
marker_id = add_marker_to_db(name, description, telegram_link, latitude, longitude)
return jsonify({
'id': marker_id,
'name': name,
'description': description,
'telegram_link': telegram_link,
'latitude': latitude,
'longitude': longitude
})
@app.route('/remove_marker/<int:marker_id>', methods=['DELETE'])
def remove_marker(marker_id):
remove_marker_from_db(marker_id)
return '', 204
@app.route('/search_markers', methods=['GET'])
def search_markers():
query = request.args.get('query', '')
conn = sqlite3.connect('markers.db')
cursor = conn.cursor()
cursor.execute('''SELECT id, name, description, telegram_link, latitude, longitude FROM markers
WHERE name LIKE ? OR description LIKE ?''',
(f'%{query}%', f'%{query}%'))
markers = cursor.fetchall()
conn.close()
return jsonify([{
'id': marker[0],
'name': marker[1],
'description': marker[2],
'telegram_link': marker[3],
'latitude': marker[4],
'longitude': marker[5]
} for marker in markers])
if __name__ == '__main__':
init_db()
app.run(debug=True, host='0.0.0.0', port=7860)