From 4f3295a315db8eb1cf37ee445678370203935956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=ADITQ?= Date: Fri, 22 Mar 2024 12:47:57 +0300 Subject: [PATCH] feat: Added date joined to user --- app/callbacks/menu.py | 1 + app/callbacks/profile.py | 1 + app/handlers/profile_command.py | 1 + app/messages.py | 1 + ...model.py => 4914f00ae14a_added_user_model.py} | 16 ++++++++++++---- app/models/user.py | 10 ++++++++++ app/utils/db.py | 15 +++++++++++++++ 7 files changed, 41 insertions(+), 4 deletions(-) rename app/migrations/versions/{1ea8d34d6232_added_user_model.py => 4914f00ae14a_added_user_model.py} (75%) create mode 100644 app/utils/db.py diff --git a/app/callbacks/menu.py b/app/callbacks/menu.py index d485e58..21fbea8 100644 --- a/app/callbacks/menu.py +++ b/app/callbacks/menu.py @@ -29,6 +29,7 @@ async def profile_callback(callback: CallbackQuery) -> None: sex=user.sex.capitalize(), country=user.country, city=user.city, + date_joined=user.get_human_readable_datejoined(), ), reply_markup=get(), ) diff --git a/app/callbacks/profile.py b/app/callbacks/profile.py index 1b6f04d..f6d404a 100644 --- a/app/callbacks/profile.py +++ b/app/callbacks/profile.py @@ -211,6 +211,7 @@ async def profile_change_entered(message: Message, state: FSMContext) -> None: sex=user.sex.capitalize(), country=user.country, city=user.city, + date_joined=user.get_human_readable_datejoined(), ), message.chat.id, state_data["profile_message_id"], diff --git a/app/handlers/profile_command.py b/app/handlers/profile_command.py index 03a76b5..5b05b7d 100644 --- a/app/handlers/profile_command.py +++ b/app/handlers/profile_command.py @@ -28,6 +28,7 @@ async def command_profile_handler(message: Message) -> None: sex=user.sex.capitalize(), country=user.country, city=user.city, + date_joined=user.get_human_readable_datejoined(), ), reply_markup=get(), ) diff --git a/app/messages.py b/app/messages.py index 4adfdf2..6a1452f 100644 --- a/app/messages.py +++ b/app/messages.py @@ -27,6 +27,7 @@ PROFILE = ( "\tCountry: {country}\n" "\tCity: {city}\n" "\tBio: {bio}\n" + "\tDate joined: {date_joined}\n" ) NOT_SET = "Not set" EDIT_USERNAME = "Enter your username:\nAllowed characters: a-z, A-Z, 0-9, _\nLength: 5-20 characters" diff --git a/app/migrations/versions/1ea8d34d6232_added_user_model.py b/app/migrations/versions/4914f00ae14a_added_user_model.py similarity index 75% rename from app/migrations/versions/1ea8d34d6232_added_user_model.py rename to app/migrations/versions/4914f00ae14a_added_user_model.py index 06d4f95..57590bf 100644 --- a/app/migrations/versions/1ea8d34d6232_added_user_model.py +++ b/app/migrations/versions/4914f00ae14a_added_user_model.py @@ -1,8 +1,8 @@ """Added User model -Revision ID: 1ea8d34d6232 +Revision ID: 4914f00ae14a Revises: -Create Date: 2024-03-22 00:57:44.526995 +Create Date: 2024-03-22 12:23:37.993976 """ @@ -13,7 +13,7 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. -revision: str = '1ea8d34d6232' +revision: str = '4914f00ae14a' down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None @@ -23,13 +23,21 @@ def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### op.create_table( 'users', - sa.Column('telegram_id', sa.BigInteger(), nullable=False), + sa.Column( + 'telegram_id', sa.BigInteger(), autoincrement=False, nullable=False + ), sa.Column('username', sa.String(length=32), nullable=False), sa.Column('age', sa.SmallInteger(), nullable=False), sa.Column('bio', sa.String(length=100), nullable=True), sa.Column('sex', sa.String(length=6), nullable=True), sa.Column('country', sa.Text(), nullable=False), sa.Column('city', sa.Text(), nullable=False), + sa.Column( + 'date_joined', + sa.DateTime(timezone=True), + server_default=sa.text("TIMEZONE('utc', CURRENT_TIMESTAMP)"), + nullable=False, + ), sa.PrimaryKeyConstraint('telegram_id'), sa.UniqueConstraint('username'), ) diff --git a/app/models/user.py b/app/models/user.py index f4337d6..a5b27cd 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -9,6 +9,7 @@ from sqlalchemy.orm import validates from app import session from app.utils import geo +from app.utils.db import utcnow Base: Any = declarative_base() @@ -23,6 +24,7 @@ class User(Base): index=True, unique=True, nullable=False, + autoincrement=False, ) username = sa.Column(sa.String(32), nullable=False, unique=True) age = sa.Column(sa.SmallInteger, nullable=False) @@ -30,6 +32,11 @@ class User(Base): sex = sa.Column(sa.String(6), nullable=True) country = sa.Column(sa.Text, nullable=False) city = sa.Column(sa.Text, nullable=False) + date_joined = sa.Column( + sa.DateTime(timezone=True), + nullable=False, + server_default=utcnow(), + ) @validates("username") def validate_username(self, key, value): @@ -91,6 +98,9 @@ class User(Base): return normalized_value + def get_human_readable_datejoined(self): + return self.date_joined.strftime("%Y-%m-%d %H:%M:%S") + @classmethod def get_user_queryset_by_telegram_id(cls, telegram_id): return session.query(cls).filter(cls.telegram_id == telegram_id) diff --git a/app/utils/db.py b/app/utils/db.py new file mode 100644 index 0000000..567cf09 --- /dev/null +++ b/app/utils/db.py @@ -0,0 +1,15 @@ +__all__ = ("utcnow",) + +from sqlalchemy.ext.compiler import compiles +from sqlalchemy.sql import expression +from sqlalchemy.types import DateTime + + +class utcnow(expression.FunctionElement): # noqa: N801 + type = DateTime() # noqa: A003 + inherit_cache = True + + +@compiles(utcnow, "postgresql") +def pg_utcnow(element, compiler, **kw): + return "TIMEZONE('utc', CURRENT_TIMESTAMP)"