Compare commits
6 Commits
9b35b4892a
...
9ae319cbb3
Author | SHA1 | Date | |
---|---|---|---|
9ae319cbb3
|
|||
b939772c85
|
|||
6253fb0917
|
|||
fd72d34e48
|
|||
48bb3cc4a3
|
|||
97141be93e
|
@@ -10,7 +10,7 @@ class CallbackLanguage:
|
||||
language: str
|
||||
|
||||
@classmethod
|
||||
def from_callback(cls, callback: CallbackQuery):
|
||||
def from_callback(cls, callback: CallbackQuery) -> "CallbackLanguage":
|
||||
"""Parse callback query and extract language data from it.
|
||||
|
||||
### Args:
|
||||
|
@@ -23,7 +23,7 @@ class GarbageEntry:
|
||||
date: datetime
|
||||
|
||||
@classmethod
|
||||
async def from_dict(cls, data: Mapping[str, Any]):
|
||||
async def from_dict(cls, data: Mapping[str, Any]) -> "GarbageEntry":
|
||||
"""Generate GarbageEntry object from the mapping provided
|
||||
|
||||
### Args:
|
||||
@@ -60,7 +60,7 @@ class GarbageEntry:
|
||||
)
|
||||
|
||||
@classmethod
|
||||
async def from_record(cls, data: Mapping[str, Any]):
|
||||
async def from_record(cls, data: Mapping[str, Any]) -> "GarbageEntry":
|
||||
locations = [
|
||||
await Location.get(location_id) for location_id in data["locations"]
|
||||
]
|
||||
|
@@ -28,7 +28,7 @@ class Location:
|
||||
timezone: Union[BaseTzInfo, DstTzInfo]
|
||||
|
||||
@classmethod
|
||||
async def get(cls, id: int):
|
||||
async def get(cls, id: int) -> "Location":
|
||||
db_entry = await col_locations.find_one({"id": id})
|
||||
|
||||
if db_entry is None:
|
||||
@@ -40,7 +40,7 @@ class Location:
|
||||
return cls(**db_entry)
|
||||
|
||||
@classmethod
|
||||
async def find(cls, name: str):
|
||||
async def find(cls, name: str) -> "Location":
|
||||
db_entry = await col_locations.find_one({"name": {"$regex": name}})
|
||||
|
||||
if db_entry is None:
|
||||
@@ -52,7 +52,7 @@ class Location:
|
||||
return cls(**db_entry)
|
||||
|
||||
@classmethod
|
||||
async def nearby(cls, lat: float, lon: float):
|
||||
async def nearby(cls, lat: float, lon: float) -> "Location":
|
||||
db_entry = await col_locations.find_one({"location": {"$near": [lon, lat]}})
|
||||
|
||||
if db_entry is None:
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Any, Union
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any, Mapping, Tuple, Union
|
||||
|
||||
import pytz
|
||||
from bson import ObjectId
|
||||
|
||||
from classes.location import Location
|
||||
@@ -45,7 +46,7 @@ class PyroUser:
|
||||
offset: int = 1,
|
||||
time_hour: int = 16,
|
||||
time_minute: int = 0,
|
||||
):
|
||||
) -> "PyroUser":
|
||||
db_entry = await col_users.find_one({"id": id})
|
||||
|
||||
if db_entry is None:
|
||||
@@ -73,7 +74,7 @@ class PyroUser:
|
||||
return cls(**db_entry)
|
||||
|
||||
@classmethod
|
||||
async def from_dict(cls, **kwargs):
|
||||
async def from_dict(cls, **kwargs) -> "PyroUser":
|
||||
if "location" in kwargs:
|
||||
try:
|
||||
kwargs["location"] = await Location.get(kwargs["location"]) # type: ignore
|
||||
@@ -81,46 +82,85 @@ class PyroUser:
|
||||
kwargs["location"] = None # type: ignore
|
||||
return cls(**kwargs)
|
||||
|
||||
async def update_locale(self, locale: Union[str, None]) -> None:
|
||||
async def update_locale(self, locale: Union[str, None]) -> Union[str, None]:
|
||||
"""Change user's locale stored in the database.
|
||||
|
||||
### Args:
|
||||
* locale (`Union[str, None]`): New locale to be set.
|
||||
"""
|
||||
|
||||
logger.debug("%s's locale has been set to %s", self.id, locale)
|
||||
|
||||
await col_users.update_one({"_id": self._id}, {"$set": {"locale": locale}})
|
||||
|
||||
self.locale = locale
|
||||
|
||||
async def update_state(self, enabled: bool = False) -> None:
|
||||
return self.locale
|
||||
|
||||
async def update_state(self, enabled: bool = False) -> bool:
|
||||
logger.debug("%s's state has been set to %s", self.id, enabled)
|
||||
|
||||
await col_users.update_one({"_id": self._id}, {"$set": {"enabled": enabled}})
|
||||
|
||||
self.enabled = enabled
|
||||
|
||||
async def update_location(self, location_id: int = 0) -> None:
|
||||
return self.enabled
|
||||
|
||||
async def update_location(self, location_id: int = 0) -> Location:
|
||||
logger.debug("%s's location has been set to %s", self.id, location_id)
|
||||
|
||||
await col_users.update_one(
|
||||
{"_id": self._id}, {"$set": {"location": location_id}}
|
||||
)
|
||||
self.location = await Location.get(location_id)
|
||||
|
||||
async def update_offset(self, offset: int = 1) -> None:
|
||||
location = await Location.get(location_id)
|
||||
|
||||
# Execute if timezones of old and new locations are different
|
||||
if self.location and (self.location.timezone.zone != location.timezone.zone):
|
||||
# Get UTC time for selected reminder time
|
||||
now_utc = datetime.now(pytz.utc).replace(
|
||||
hour=self.time_hour, minute=self.time_minute, second=0, microsecond=0
|
||||
)
|
||||
|
||||
# Get the time for the reminder time of old and new location
|
||||
local_old = now_utc.astimezone(self.location.timezone)
|
||||
local_new = (
|
||||
location.timezone.localize(local_old.replace(tzinfo=None))
|
||||
).astimezone(pytz.utc)
|
||||
|
||||
# Update the time to match the new timezone
|
||||
await self.update_time(hour=local_new.hour, minute=local_new.minute)
|
||||
|
||||
self.location = location
|
||||
|
||||
return self.location
|
||||
|
||||
async def update_offset(self, offset: int = 1) -> int:
|
||||
logger.debug("%s's offset has been set to %s", self.id, offset)
|
||||
|
||||
await col_users.update_one({"_id": self._id}, {"$set": {"offset": offset}})
|
||||
|
||||
self.offset = offset
|
||||
|
||||
async def update_time(self, hour: int = 16, minute: int = 0) -> None:
|
||||
return offset
|
||||
|
||||
async def update_time(self, hour: int = 16, minute: int = 0) -> Tuple[int, int]:
|
||||
logger.debug("%s's time has been set to %s h. %s m.", self.id, hour, minute)
|
||||
|
||||
await col_users.update_one(
|
||||
{"_id": self._id}, {"$set": {"time_hour": hour, "time_minute": minute}}
|
||||
)
|
||||
|
||||
self.time_hour = hour
|
||||
self.time_minute = minute
|
||||
|
||||
return self.time_hour, self.time_minute
|
||||
|
||||
async def delete(self) -> None:
|
||||
logger.debug("%s's data has been deleted", self.id)
|
||||
await col_users.delete_one({"_id": self._id})
|
||||
|
||||
async def checkout(self) -> Any:
|
||||
async def checkout(self) -> Mapping[str, Any]:
|
||||
logger.debug("%s's data has been checked out", self.id)
|
||||
db_entry = await col_users.find_one({"_id": self._id})
|
||||
|
||||
@@ -155,7 +195,7 @@ class PyroUser:
|
||||
logger.warning("Location %s does not have a timezone set", self.location.id)
|
||||
|
||||
return (
|
||||
datetime.now(self.location.timezone or timezone.utc) + timedelta(days=1)
|
||||
datetime.now(self.location.timezone or pytz.utc) + timedelta(days=1)
|
||||
).replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
|
||||
def get_reminder_time(self) -> datetime:
|
||||
@@ -180,12 +220,12 @@ class PyroUser:
|
||||
logger.warning("Location %s does not have a timezone set", self.location.id)
|
||||
|
||||
return (
|
||||
datetime.now(timezone.utc)
|
||||
datetime.now(pytz.utc)
|
||||
.replace(
|
||||
hour=self.time_hour,
|
||||
minute=self.time_minute,
|
||||
second=0,
|
||||
microsecond=0,
|
||||
)
|
||||
.astimezone(self.location.timezone or timezone.utc)
|
||||
.astimezone(self.location.timezone or pytz.utc)
|
||||
)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import logging
|
||||
from datetime import datetime, timezone
|
||||
from datetime import datetime
|
||||
|
||||
import pytz
|
||||
from bson import json_util
|
||||
from libbot.pyrogram.classes import PyroClient
|
||||
|
||||
@@ -14,7 +15,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def remind(app: PyroClient) -> None:
|
||||
utcnow = datetime.now(timezone.utc)
|
||||
utcnow = datetime.now(pytz.utc)
|
||||
|
||||
logger.debug("Performing reminder lookup for %s (UTCNOW)", utcnow)
|
||||
|
||||
@@ -42,13 +43,7 @@ async def remind(app: PyroClient) -> None:
|
||||
logger.warning("Skipping reminder for %s due to invalid location", user.id)
|
||||
continue
|
||||
|
||||
try:
|
||||
user_date = user.get_reminder_date()
|
||||
except AttributeError:
|
||||
logger.warning(
|
||||
"Skipping reminder for %s due to missing attributes", user.id
|
||||
)
|
||||
continue
|
||||
user_date = user.get_reminder_date().replace(tzinfo=None)
|
||||
|
||||
entries = await col_entries.find(
|
||||
{
|
||||
|
@@ -1,8 +1,7 @@
|
||||
from datetime import datetime
|
||||
from typing import Union
|
||||
|
||||
from pytz import UTC
|
||||
from pytz import timezone as pytz_timezone
|
||||
import pytz
|
||||
|
||||
|
||||
def to_utc(date: datetime, timezone: Union[str, None] = None) -> datetime:
|
||||
@@ -18,7 +17,9 @@ def to_utc(date: datetime, timezone: Union[str, None] = None) -> datetime:
|
||||
* `datetime`: Timezone unaware datetime in UTC with timezone's offset applied to it.
|
||||
"""
|
||||
timezone = "UTC" if timezone is None else timezone
|
||||
return pytz_timezone(timezone).localize(date).astimezone(UTC).replace(tzinfo=None)
|
||||
return (
|
||||
pytz.timezone(timezone).localize(date).astimezone(pytz.utc).replace(tzinfo=None)
|
||||
)
|
||||
|
||||
|
||||
def from_utc(date: datetime, timezone: Union[str, None] = None) -> datetime:
|
||||
@@ -35,8 +36,5 @@ def from_utc(date: datetime, timezone: Union[str, None] = None) -> datetime:
|
||||
"""
|
||||
timezone = "UTC" if timezone is None else timezone
|
||||
return (
|
||||
pytz_timezone("UTC")
|
||||
.localize(date)
|
||||
.astimezone(pytz_timezone(timezone))
|
||||
.replace(tzinfo=None)
|
||||
pytz.utc.localize(date).astimezone(pytz.timezone(timezone)).replace(tzinfo=None)
|
||||
)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import logging
|
||||
from datetime import datetime, timezone
|
||||
from datetime import datetime
|
||||
|
||||
import pytz
|
||||
from convopyro import listen_message
|
||||
from pyrogram import filters
|
||||
from pyrogram.types import ForceReply, Message, ReplyKeyboardRemove
|
||||
@@ -65,9 +66,9 @@ async def command_set_offset(app: PyroClient, message: Message):
|
||||
logger.info("User %s has set offset to %s", user.id, offset)
|
||||
|
||||
garbage_time = (
|
||||
datetime.now(timezone.utc)
|
||||
datetime.now(pytz.utc)
|
||||
.replace(hour=user.time_hour, minute=user.time_minute)
|
||||
.astimezone(user.location.timezone or timezone.utc)
|
||||
.astimezone(user.location.timezone or pytz.utc)
|
||||
)
|
||||
|
||||
await answer.reply_text(
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import logging
|
||||
from datetime import datetime, timezone
|
||||
from datetime import datetime
|
||||
|
||||
import pytz
|
||||
from convopyro import listen_message
|
||||
from pyrogram import filters
|
||||
from pyrogram.types import ForceReply, Message, ReplyKeyboardRemove
|
||||
@@ -54,34 +55,30 @@ async def command_set_time(app: PyroClient, message: Message):
|
||||
|
||||
break
|
||||
|
||||
now = datetime.now()
|
||||
# Time we got from the user
|
||||
parsed_time = datetime.strptime(answer.text, "%H:%M")
|
||||
|
||||
parsed_time = datetime.strptime(answer.text, "%H:%M").replace(
|
||||
year=now.year,
|
||||
month=now.month,
|
||||
day=now.day,
|
||||
second=0,
|
||||
microsecond=0,
|
||||
tzinfo=timezone.utc,
|
||||
# Datetime user means in their timezone
|
||||
user_time = datetime.now(user.location.timezone).replace(
|
||||
hour=parsed_time.hour, minute=parsed_time.minute, second=0, microsecond=0
|
||||
)
|
||||
|
||||
user_time = parsed_time.astimezone(user.location.timezone or timezone.utc)
|
||||
# Datetime in user's timezone moved to UTC timezone
|
||||
utc_time = user_time.astimezone(pytz.utc)
|
||||
|
||||
await user.update_time(hour=user_time.hour, minute=user_time.minute)
|
||||
await user.update_time(hour=utc_time.hour, minute=utc_time.minute)
|
||||
|
||||
logger.info(
|
||||
"User %s has selected notification time of %s (%s UTC)",
|
||||
user.id,
|
||||
parsed_time.strftime("%H:%M"),
|
||||
user_time.strftime("%H:%M"),
|
||||
utc_time.strftime("%H:%M"),
|
||||
)
|
||||
|
||||
garbage_time = parsed_time.strftime(app._("time", "formats", locale=user.locale))
|
||||
|
||||
await answer.reply_text(
|
||||
app._("set_time_finished", "messages", locale=user.locale).format(
|
||||
offset=user.offset,
|
||||
time=garbage_time,
|
||||
time=user_time.strftime(app._("time", "formats", locale=user.locale)),
|
||||
toggle_notice=(
|
||||
"" if user.enabled else app._("toggle", "messages", locale=user.locale)
|
||||
),
|
||||
|
@@ -72,12 +72,9 @@ async def command_setup(app: PyroClient, message: Message):
|
||||
|
||||
await user.update_location(location.id)
|
||||
|
||||
try:
|
||||
user_time = user.get_reminder_time().strftime(
|
||||
app._("time", "formats", locale=user.locale)
|
||||
)
|
||||
except AttributeError:
|
||||
user_time = "N/A"
|
||||
|
||||
await message.reply_text(
|
||||
app._("setup_finished", "messages", locale=user.locale).format(
|
||||
|
@@ -88,12 +88,9 @@ async def command_start(app: PyroClient, message: Message):
|
||||
|
||||
await user.update_location(location.id)
|
||||
|
||||
try:
|
||||
user_time = user.get_reminder_time().strftime(
|
||||
app._("time", "formats", locale=user.locale)
|
||||
)
|
||||
except AttributeError:
|
||||
user_time = "N/A"
|
||||
|
||||
await answer.reply_text(
|
||||
app._("start_selection_yes", "messages", locale=user.locale).format(
|
||||
|
@@ -1,5 +1,6 @@
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import pytz
|
||||
from pyrogram import filters
|
||||
from pyrogram.types import Message
|
||||
|
||||
@@ -23,11 +24,11 @@ async def command_upcoming(app: PyroClient, message: Message):
|
||||
|
||||
date_min = (
|
||||
datetime.now(user.location.timezone).replace(second=0, microsecond=0)
|
||||
).replace(tzinfo=timezone.utc)
|
||||
).replace(tzinfo=pytz.utc)
|
||||
date_max = (
|
||||
datetime.now(user.location.timezone).replace(second=0, microsecond=0)
|
||||
+ timedelta(days=30)
|
||||
).replace(tzinfo=timezone.utc)
|
||||
).replace(tzinfo=pytz.utc)
|
||||
|
||||
entries = [
|
||||
await GarbageEntry.from_record(entry)
|
||||
|
Reference in New Issue
Block a user