Skip to content

Commit fbebcb1

Browse files
committed
Change category button text
1 parent fa84525 commit fbebcb1

13 files changed

Lines changed: 872 additions & 1 deletion

File tree

python_flask_docker/tg_bot

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Environment variables
2+
.env
3+
4+
# Python
5+
__pycache__/
6+
venv/
7+
*.py[cod]
8+
*$py.class
9+
*.so
10+
.Python
11+
env/
12+
build/
13+
develop-eggs/
14+
dist/
15+
downloads/
16+
eggs/
17+
.eggs/
18+
lib/
19+
lib64/
20+
parts/
21+
sdist/
22+
var/
23+
*.egg-info/
24+
.installed.cfg
25+
*.egg
26+
27+
# Data files
28+
selected_objects.json
29+
30+
# Logs
31+
*.log
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Accessibility Mapping Telegram Bot
2+
3+
A Telegram bot designed to collect and share information about building accessibility features. The bot allows users to add new locations, specify their accessibility features, and view a map of accessible buildings.
4+
5+
## Features
6+
7+
- 📚 FAQ section with information about accessibility
8+
- 🗺️ Interactive map of accessible locations
9+
- ➕ Add new accessible buildings with detailed information
10+
- 📍 Share location data via GPS or manual coordinates
11+
- 📸 Upload photos of accessibility features
12+
- ✅ Select from multiple accessibility options for comprehensive mapping
13+
14+
## Getting Started
15+
16+
### Prerequisites
17+
18+
- Python 3.7+
19+
- Telegram Bot Token (obtained from [@BotFather](https://t.me/BotFather))
20+
21+
### Installation
22+
23+
1. Set up a virtual environment:
24+
```
25+
python -m venv venv
26+
```
27+
28+
2. Activate the virtual environment:
29+
- Windows: `venv\Scripts\activate`
30+
- macOS/Linux: `source venv/bin/activate`
31+
32+
3. Install dependencies:
33+
```
34+
pip install -r requirements.txt
35+
```
36+
37+
4. Create a `.env` file in the project root directory:
38+
```
39+
TELEGRAM_BOT_TOKEN=your_bot_token_here
40+
```
41+
42+
5. Run the bot:
43+
```
44+
python bot.py
45+
```
46+
47+
## Project Structure
48+
49+
```
50+
accessibility-telegram-bot/
51+
├── bot.py # Main entry point
52+
├── config.py # Configuration settings
53+
├── requirements.txt # Project dependencies
54+
├── .env # Environment variables (not in repository)
55+
├── data/
56+
│ ├── categories.py # Building categories and accessibility options
57+
│ └── storage.py # Functions for data persistence
58+
├── handlers/
59+
│ ├── callback_handlers.py # Handle inline button callbacks
60+
│ ├── command_handlers.py # Handle bot commands
61+
│ └── message_handlers.py # Handle text, photo, and location messages
62+
└── utils/
63+
└── helpers.py # Utility functions
64+
```
65+
66+
## Usage
67+
68+
1. Start the bot by sending `/start` command
69+
2. Use the main menu to navigate:
70+
- 📚 FAQ - Read about accessibility features and the bot
71+
- 🗺️ Accessibility Map - View an interactive map of accessible buildings
72+
- ➕ Add Object - Submit information about a new accessible building
73+
74+
3. When adding a new object:
75+
- Select the building category
76+
- Choose a specific object type
77+
- Share the location (via GPS or manual coordinates)
78+
- Select accessibility features present at the location
79+
- Upload a photo of the building or its accessibility features
80+
81+
## Data Storage
82+
83+
The bot stores submitted data in a JSON file (`selected_objects.json`). Each entry includes:
84+
- Building category and type
85+
- Location coordinates
86+
- Selected accessibility options
87+
- Photo file ID
88+
- Submission date
89+
90+
## Contributing
91+
92+
Contributions are welcome! Please feel free to submit a Pull Request.
93+
94+
## License
95+
96+
This project is licensed under the MIT License - see the LICENSE file for details.
97+
98+
## Acknowledgments
99+
100+
- Thanks to the python-telegram-bot team for their excellent library
101+
- Inspired by accessibility mapping initiatives worldwide

python_flask_docker/tg_bot/bot.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from telegram.ext import Application, CommandHandler, CallbackQueryHandler, MessageHandler, filters
2+
from config import TOKEN
3+
from handlers.command_handlers import start, handle_text_menu
4+
from handlers.callback_handlers import button_handler
5+
from handlers.message_handlers import location_handler, photo_handler, text_handler
6+
7+
def main():
8+
"""Main function to start the bot"""
9+
# Initialize the Application
10+
application = Application.builder().token(TOKEN).build()
11+
12+
# Add handlers
13+
application.add_handler(CommandHandler("start", start))
14+
application.add_handler(CallbackQueryHandler(button_handler))
15+
application.add_handler(MessageHandler(filters.LOCATION, location_handler))
16+
application.add_handler(MessageHandler(filters.PHOTO, photo_handler))
17+
18+
# Add handlers for text menu and coordinates input
19+
menu_filter = filters.TEXT & (
20+
filters.Regex(r'^📚 FAQ$') |
21+
filters.Regex(r'^🗺️ Мапа доступності$') |
22+
filters.Regex(r'^➕ Додати об\'єкт$')
23+
)
24+
application.add_handler(MessageHandler(menu_filter, handle_text_menu))
25+
26+
# This should be the last handler to catch all other text messages
27+
application.add_handler(MessageHandler(filters.TEXT & ~menu_filter, text_handler))
28+
29+
# Start the bot
30+
print("Bot started...")
31+
application.run_polling()
32+
33+
if __name__ == '__main__':
34+
main()
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import os
2+
import logging
3+
from dotenv import load_dotenv
4+
5+
# Load environment variables from .env file
6+
load_dotenv()
7+
8+
# Bot token obtained from BotFather via environment variable
9+
TOKEN = os.getenv('TELEGRAM_BOT_TOKEN')
10+
11+
# Optional fallback if environment variable isn't set (for development)
12+
if not TOKEN:
13+
# Only use this during development, never commit actual tokens
14+
TOKEN = ''
15+
logging.warning("No bot token found in environment variables! Using empty token.")
16+
17+
# Logging configuration
18+
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)
19+
logger = logging.getLogger(__name__)
20+
21+
# States for managing selection process
22+
STATE_WAITING_FOR_LOCATION = 1
23+
STATE_SELECTING_OPTIONS = 2
24+
STATE_WAITING_FOR_PHOTO = 3
25+
26+
# Dictionary to store current selection state for each user
27+
user_selections = {}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Categories and objects (with descriptions added)
2+
categories = {
3+
"Державні будівлі": {
4+
"objects": {
5+
"11": "Міські/обласні адміністрації",
6+
"12": "Центри надання адміністративних послуг",
7+
"13": "Відділення соціальних служб"
8+
},
9+
"description": "Будівлі державного та муніципального призначення"
10+
},
11+
"Комерційні об'єкти": {
12+
"objects": {
13+
"21": "Торгові центри",
14+
"22": "Супермаркети",
15+
"23": "Банківські відділення",
16+
"24": "Аптеки"
17+
},
18+
"description": "Будівлі, призначені для ведення бізнесу, продажу товарів та надання фінансових чи фармацевтичних послуг"
19+
},
20+
"Соціальна інфраструктура": {
21+
"objects": {
22+
"31": "Медичні заклади",
23+
"32": "Заклади освіти",
24+
"33": "Культурні об'єкти (музеї, театри, кінотеатри)",
25+
"34": "Парки та рекреаційні зони"
26+
},
27+
"description": "Об’єкти, що забезпечують базові потреби населення в освіті, охороні здоров’я, культурі та відпочинку"
28+
},
29+
"Транспортна інфраструктура": {
30+
"objects": {
31+
"41": "Залізничні/автовокзали",
32+
"42": "Станції метро",
33+
"43": "Зупинки громадського транспорту"
34+
},
35+
"description": "Місця, пов’язані з пересуванням людей і транспорту, що забезпечують доступність та мобільність населення"
36+
}
37+
}
38+
39+
# Options with descriptions
40+
options = {
41+
"1": "Пандус",
42+
"2": "Ліфт",
43+
"3": "Широкі двері",
44+
"4": "Доступний санвузол",
45+
"5": "Тактильна плитка",
46+
"6": "Звукові сигнали",
47+
"7": "Знаки Брайля",
48+
"8": "Контрастне маркування",
49+
"9": "Місця для паркування",
50+
"10": "Низькі пороги",
51+
"11": "Ручки зручної форми",
52+
"12": "Допоміжні поручні",
53+
"13": "Адаптовані інформаційні стенди",
54+
"14": "Тактильні карти приміщення",
55+
"15": "Аудіогід",
56+
"16": "Допомога персоналу",
57+
"17": "Спеціальні місця відпочинку",
58+
"18": "Підйомники",
59+
"19": "Індукційні петлі",
60+
"20": "Текстові описи для аудіоматеріалів",
61+
"21": "Сурдопереклад",
62+
"22": "Собаки-поводирі дозволені",
63+
"23": "Доступні місця для сидіння",
64+
"24": "Альтернативні входи",
65+
"25": "Достатнє освітлення"
66+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import json
2+
import os
3+
from config import logger
4+
5+
def save_to_json(user_id, selection, filename='selected_objects.json'):
6+
"""Save selected data to JSON file"""
7+
data = {}
8+
9+
# Try to read existing data if file exists
10+
if os.path.exists(filename):
11+
try:
12+
with open(filename, 'r') as file:
13+
file_content = file.read().strip()
14+
if file_content: # Check if file is not empty
15+
data = json.loads(file_content)
16+
# Ensure data is a dictionary
17+
if not isinstance(data, dict):
18+
logger.warning(f"Existing data is not a dictionary. Creating new.")
19+
data = {}
20+
except (json.JSONDecodeError, FileNotFoundError) as e:
21+
logger.error(f"Error reading JSON: {e}")
22+
data = {}
23+
24+
# Convert user_id to string for JSON compatibility
25+
user_id_str = str(user_id)
26+
27+
# Initialize user entry if not exists
28+
if user_id_str not in data:
29+
data[user_id_str] = []
30+
31+
# Add new selection
32+
data[user_id_str].append(selection)
33+
34+
# Save updated data
35+
try:
36+
with open(filename, 'w') as file:
37+
json.dump(data, file, indent=4)
38+
return True
39+
except Exception as e:
40+
logger.error(f"Error saving JSON: {e}")
41+
return False

0 commit comments

Comments
 (0)