/setup command implemented
This commit is contained in:
parent
35a8cd4b2b
commit
30b48c12f3
@ -2,7 +2,7 @@ from typing import List, Union
|
|||||||
|
|
||||||
from apscheduler.triggers.cron import CronTrigger
|
from apscheduler.triggers.cron import CronTrigger
|
||||||
from libbot.pyrogram.classes import PyroClient as LibPyroClient
|
from libbot.pyrogram.classes import PyroClient as LibPyroClient
|
||||||
from pymongo import ASCENDING, GEO2D
|
from pymongo import ASCENDING, GEOSPHERE, TEXT
|
||||||
from pyrogram.types import User
|
from pyrogram.types import User
|
||||||
|
|
||||||
from classes.location import Location
|
from classes.location import Location
|
||||||
@ -24,9 +24,10 @@ class PyroClient(LibPyroClient):
|
|||||||
[("id", ASCENDING)], name="location_id", unique=True
|
[("id", ASCENDING)], name="location_id", unique=True
|
||||||
)
|
)
|
||||||
await col_locations.create_index(
|
await col_locations.create_index(
|
||||||
[("location", GEO2D)],
|
[("location", GEOSPHERE)],
|
||||||
name="location_location",
|
name="location_location",
|
||||||
)
|
)
|
||||||
|
await col_locations.create_index([("name", TEXT)], name="location_name")
|
||||||
return await super().start(**kwargs)
|
return await super().start(**kwargs)
|
||||||
|
|
||||||
async def find_user(self, user: Union[int, User]) -> PyroUser:
|
async def find_user(self, user: Union[int, User]) -> PyroUser:
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
"port": 27017,
|
"port": 27017,
|
||||||
"name": "garbagebot"
|
"name": "garbagebot"
|
||||||
},
|
},
|
||||||
|
"search": {
|
||||||
|
"radius": 0.1
|
||||||
|
},
|
||||||
"reports": {
|
"reports": {
|
||||||
"chat_id": "owner"
|
"chat_id": "owner"
|
||||||
},
|
},
|
||||||
|
73
modules/search_name.py
Normal file
73
modules/search_name.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
from typing import Union
|
||||||
|
|
||||||
|
from convopyro import listen_message
|
||||||
|
from pykeyboard import ReplyButton, ReplyKeyboard
|
||||||
|
from pyrogram.types import ForceReply, Message, ReplyKeyboardRemove
|
||||||
|
|
||||||
|
from classes.location import Location
|
||||||
|
from classes.pyroclient import PyroClient
|
||||||
|
from modules.database import col_locations
|
||||||
|
|
||||||
|
|
||||||
|
async def search_name(app: PyroClient, message: Message) -> Union[Location, None]:
|
||||||
|
location: Union[Location, None] = None
|
||||||
|
|
||||||
|
await message.reply_text(
|
||||||
|
"Please, send me a location name. It should be the name used in your local authorities' garbage collection schedule. This usually is a name of the district or even the town itself.",
|
||||||
|
reply_markup=ForceReply(placeholder="Location name"),
|
||||||
|
)
|
||||||
|
|
||||||
|
while location is None:
|
||||||
|
answer = await listen_message(app, message.chat.id, 300)
|
||||||
|
|
||||||
|
if answer is None or answer.text == "/cancel":
|
||||||
|
await message.reply_text("Cancelled.", reply_markup=ReplyKeyboardRemove())
|
||||||
|
return
|
||||||
|
|
||||||
|
if answer.text is None:
|
||||||
|
await message.reply_text(
|
||||||
|
"Please, send the name of the location as a text. You can also abort this operation with /cancel command.",
|
||||||
|
reply_markup=ForceReply(placeholder="Location name"),
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
query = {"$text": {"$search": answer.text}}
|
||||||
|
|
||||||
|
locations = await col_locations.find(query).limit(6).to_list()
|
||||||
|
|
||||||
|
if len(locations) == 0:
|
||||||
|
await message.reply_text(
|
||||||
|
"Could not find any locations by this name. Try rephrasing it or make sure you use the same location language and name itself as it in written by your local authorities in garbage collection schedule. You can also abort this operation with /cancel command.",
|
||||||
|
reply_markup=ForceReply(placeholder="Location name"),
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
keyboard = ReplyKeyboard(resize_keyboard=True, row_width=2)
|
||||||
|
keyboard.add(*[ReplyButton(db_record["name"]) for db_record in locations])
|
||||||
|
|
||||||
|
await message.reply_text(
|
||||||
|
"Select the location using the keyboard", reply_markup=keyboard
|
||||||
|
)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
answer = await listen_message(app, message.chat.id, 300)
|
||||||
|
|
||||||
|
if answer is None or answer.text == "/cancel":
|
||||||
|
await message.reply_text(
|
||||||
|
"Cancelled.", reply_markup=ReplyKeyboardRemove()
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
for db_record in locations:
|
||||||
|
if answer.text == db_record["name"]:
|
||||||
|
location = Location(**db_record)
|
||||||
|
|
||||||
|
if answer.text is None or location is None:
|
||||||
|
await answer.reply_text(
|
||||||
|
"Please, select a valid location using keyboard provided. Use /cancel if you want to cancel this operation.",
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
return location
|
62
modules/search_nearby.py
Normal file
62
modules/search_nearby.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
from typing import Union
|
||||||
|
|
||||||
|
from bson.son import SON
|
||||||
|
from convopyro import listen_message
|
||||||
|
from pykeyboard import ReplyButton, ReplyKeyboard
|
||||||
|
from pyrogram.types import Message, ReplyKeyboardRemove
|
||||||
|
|
||||||
|
from classes.location import Location
|
||||||
|
from classes.pyroclient import PyroClient
|
||||||
|
from modules.database import col_locations
|
||||||
|
from modules.search_name import search_name
|
||||||
|
|
||||||
|
|
||||||
|
async def search_nearby(app: PyroClient, message: Message) -> Union[Location, None]:
|
||||||
|
query = {
|
||||||
|
"location": {
|
||||||
|
"$within": {
|
||||||
|
"$center": [
|
||||||
|
[message.location.longitude, message.location.latitude],
|
||||||
|
app.config["search"]["radius"],
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
locations = await col_locations.find(query).limit(6).to_list()
|
||||||
|
|
||||||
|
if len(locations) == 0:
|
||||||
|
await message.reply_text(
|
||||||
|
"Could not find any locations nearby. Let's try using the name search."
|
||||||
|
)
|
||||||
|
return await search_name(app, message)
|
||||||
|
|
||||||
|
keyboard = ReplyKeyboard(resize_keyboard=True, row_width=2)
|
||||||
|
keyboard.add(*[ReplyButton(db_record["name"]) for db_record in locations])
|
||||||
|
|
||||||
|
await message.reply_text(
|
||||||
|
"Select the location using the keyboard", reply_markup=keyboard
|
||||||
|
)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
answer = await listen_message(app, message.chat.id, 300)
|
||||||
|
location: Union[Location, None] = None
|
||||||
|
|
||||||
|
if answer is None or answer.text == "/cancel":
|
||||||
|
await message.reply_text("Cancelled.", reply_markup=ReplyKeyboardRemove())
|
||||||
|
return
|
||||||
|
|
||||||
|
for db_record in locations:
|
||||||
|
if answer.text == db_record["name"]:
|
||||||
|
location = Location(**db_record)
|
||||||
|
break
|
||||||
|
|
||||||
|
if answer.text is None or location is None:
|
||||||
|
await answer.reply_text(
|
||||||
|
"Please, select a valid location using keyboard provided. Use /cancel if you want to cancel this operation."
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
|
return location or await search_name(app, message)
|
@ -1,4 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from convopyro import listen_message
|
from convopyro import listen_message
|
||||||
from libbot import i18n
|
from libbot import i18n
|
||||||
@ -7,6 +8,8 @@ from pyrogram import filters
|
|||||||
from pyrogram.types import Message, ReplyKeyboardRemove
|
from pyrogram.types import Message, ReplyKeyboardRemove
|
||||||
|
|
||||||
from classes.pyroclient import PyroClient
|
from classes.pyroclient import PyroClient
|
||||||
|
from modules.search_name import search_name
|
||||||
|
from modules.search_nearby import search_nearby
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -17,88 +20,52 @@ logger = logging.getLogger(__name__)
|
|||||||
async def command_setup(app: PyroClient, message: Message):
|
async def command_setup(app: PyroClient, message: Message):
|
||||||
user = await app.find_user(message.from_user)
|
user = await app.find_user(message.from_user)
|
||||||
|
|
||||||
await message.reply_text(
|
keyboard_type = ReplyKeyboard(resize_keyboard=True, row_width=1)
|
||||||
"Holy... This one is still WIP...", reply_markup=ReplyKeyboardRemove()
|
keyboard_type.add(
|
||||||
|
ReplyButton("Search nearby locations", request_location=True),
|
||||||
|
ReplyButton("Search by location name"),
|
||||||
)
|
)
|
||||||
|
|
||||||
# # City selection
|
await message.reply_text(
|
||||||
# city_names = [city_iter.name for city_iter in await app.get_cities()]
|
"Let's begin configuration with the search for your location. Please, select whether you want to search among the locations near you or go straight to the search by location name.\n\nNote that the location you send to the bot will **NOT** be saved anywhere and is only used for location lookup in the database.",
|
||||||
# keyboard_cities = ReplyKeyboard(resize_keyboard=True, row_width=2)
|
reply_markup=keyboard_type,
|
||||||
# keyboard_cities.add(*[ReplyButton(name) for name in city_names])
|
)
|
||||||
|
|
||||||
# await message.reply_text(
|
while True:
|
||||||
# "Alright. Please, use the keyboard provided to choose your town.",
|
answer_type = await listen_message(app, message.chat.id, 300)
|
||||||
# reply_markup=keyboard_cities,
|
|
||||||
# )
|
|
||||||
|
|
||||||
# while True:
|
if answer_type is None or answer_type.text == "/cancel":
|
||||||
# answer_city = await listen_message(app, message.chat.id, 300)
|
await message.reply_text("Cancelled.", reply_markup=ReplyKeyboardRemove())
|
||||||
|
return
|
||||||
|
|
||||||
# if answer_city is None or answer_city.text == "/cancel":
|
if answer_type.location is None and answer_type.text not in [
|
||||||
# await message.reply_text("Cancelled.")
|
"Search by location name",
|
||||||
# return
|
]:
|
||||||
|
await answer_type.reply_text(
|
||||||
|
"Please, select a valid option using keyboard provided. Use /cancel if you want to cancel this operation."
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
# if answer_city.text not in city_names:
|
break
|
||||||
# await answer_city.reply_text(
|
|
||||||
# "Please, select a valid town using keyboard provided. Use /cancel if you want to cancel this operation."
|
|
||||||
# )
|
|
||||||
# continue
|
|
||||||
|
|
||||||
# break
|
location = (
|
||||||
|
await search_name(app, answer_type)
|
||||||
|
if answer_type.location is None
|
||||||
|
else await search_nearby(app, answer_type)
|
||||||
|
)
|
||||||
|
|
||||||
# # City recognition
|
if location is None:
|
||||||
# city = await app.find_city(name=answer_city.text)
|
await answer_type.reply_text(
|
||||||
|
"If you want try selecting the location again, use the /setup command.",
|
||||||
|
reply_markup=ReplyKeyboardRemove(),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
# # District selection
|
await user.update_location(location.id)
|
||||||
# district_names = [district_iter.name for district_iter in city.districts]
|
|
||||||
# keyboard_districts = ReplyKeyboard(resize_keyboard=True, row_width=2)
|
|
||||||
# keyboard_districts.add(*[ReplyButton(name) for name in district_names])
|
|
||||||
|
|
||||||
# await message.reply_text(
|
user_time = datetime(1970, 1, 1, user.time_hour, user.time_minute)
|
||||||
# "Alright. Please, use the keyboard provided to choose your district.",
|
|
||||||
# reply_markup=keyboard_districts,
|
|
||||||
# )
|
|
||||||
|
|
||||||
# while True:
|
await message.reply_text(
|
||||||
# answer_district = await listen_message(app, message.chat.id, 300)
|
f"You will now receive the notifications for **{location.name}** at {user_time.strftime(app._('time', 'formats', locale=user.locale))}, {user.offset} d. before collection.",
|
||||||
|
reply_markup=ReplyKeyboardRemove(),
|
||||||
# if answer_district is None or answer_district.text == "/cancel":
|
)
|
||||||
# await message.reply_text("Cancelled.")
|
|
||||||
# return
|
|
||||||
|
|
||||||
# if answer_district.text not in district_names:
|
|
||||||
# await answer_district.reply_text(
|
|
||||||
# "Please, select a valid district using keyboard provided. Use /cancel if you want to cancel this operation."
|
|
||||||
# )
|
|
||||||
# continue
|
|
||||||
|
|
||||||
# break
|
|
||||||
|
|
||||||
# # District recognition
|
|
||||||
# district_results = city.find_district(answer_district.text)
|
|
||||||
|
|
||||||
# if len(district_results) == 0:
|
|
||||||
# await answer_district.reply_text(
|
|
||||||
# "Something went wrong. Could not find this district in the database.",
|
|
||||||
# reply_markup=ReplyKeyboardRemove(),
|
|
||||||
# )
|
|
||||||
# return
|
|
||||||
|
|
||||||
# district = district_results[0]
|
|
||||||
|
|
||||||
# await user.update_city(city.id)
|
|
||||||
# await user.update_district(district.id)
|
|
||||||
|
|
||||||
# logger.info(
|
|
||||||
# "User %s has finished the location set up with city %s and district %s selected",
|
|
||||||
# user.id,
|
|
||||||
# city.id,
|
|
||||||
# district.id,
|
|
||||||
# )
|
|
||||||
|
|
||||||
# notice = "" if user.enabled else "Execute /toggle to enable notifications."
|
|
||||||
|
|
||||||
# await answer_district.reply_text(
|
|
||||||
# f"All set! You will now receive notification about garbage collection in district **{district.name}** of the town **{city.name}**. {notice}",
|
|
||||||
# reply_markup=ReplyKeyboardRemove(),
|
|
||||||
# )
|
|
||||||
|
Reference in New Issue
Block a user