You've already forked Travel-Agent
feat: Added travel models, travel creation command, travels list command with pagination, set help message, improvements and fixes
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
# flake8: noqa
|
||||
|
||||
from app.models.base import Base
|
||||
import app.models.user
|
||||
import app.models.travel
|
||||
|
||||
Base.registry.configure()
|
||||
@@ -0,0 +1,5 @@
|
||||
from typing import Any
|
||||
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
Base: Any = declarative_base()
|
||||
@@ -0,0 +1,124 @@
|
||||
__all__ = ("Travel", "Location")
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.orm import relationship, validates
|
||||
|
||||
from app import session
|
||||
from app.models import Base
|
||||
from app.models.user import User
|
||||
|
||||
|
||||
association_table = sa.Table(
|
||||
"user_travel_association",
|
||||
Base.metadata,
|
||||
sa.Column("user_id", sa.BigInteger, sa.ForeignKey("users.telegram_id")),
|
||||
sa.Column("travel_id", sa.Integer, sa.ForeignKey("travels.id")),
|
||||
)
|
||||
|
||||
|
||||
class Travel(Base):
|
||||
__tablename__ = "travels"
|
||||
|
||||
id = sa.Column( # noqa: A003
|
||||
sa.Integer,
|
||||
unique=True,
|
||||
primary_key=True,
|
||||
nullable=False,
|
||||
autoincrement=True,
|
||||
index=True,
|
||||
)
|
||||
title = sa.Column(
|
||||
sa.String(50),
|
||||
nullable=False,
|
||||
unique=True,
|
||||
)
|
||||
description = sa.Column(
|
||||
sa.String(100),
|
||||
nullable=True,
|
||||
)
|
||||
|
||||
author_id = sa.Column(
|
||||
sa.BigInteger,
|
||||
sa.ForeignKey(User.telegram_id),
|
||||
nullable=False,
|
||||
)
|
||||
|
||||
users = relationship(
|
||||
User,
|
||||
secondary=association_table,
|
||||
backref="travels",
|
||||
)
|
||||
|
||||
locations = relationship("Location", backref="travel")
|
||||
notes = relationship("Note", backref="travel")
|
||||
|
||||
@validates("title")
|
||||
def validate_title(self, key, value):
|
||||
assert len(value) <= 30, "Title must be 30 characters or fewer."
|
||||
|
||||
if session.query(Travel).filter(Travel.title == value).first():
|
||||
raise AssertionError("This title is already taken.")
|
||||
|
||||
return value
|
||||
|
||||
@validates("description")
|
||||
def validate_description(self, key, value):
|
||||
if value is not None:
|
||||
assert (
|
||||
len(value) <= 100
|
||||
), "Description must be 100 characters or fewer."
|
||||
|
||||
return value
|
||||
|
||||
|
||||
class Location(Base):
|
||||
__tablename__ = "locations"
|
||||
|
||||
id = sa.Column( # noqa: A003
|
||||
sa.Integer,
|
||||
unique=True,
|
||||
primary_key=True,
|
||||
autoincrement=True,
|
||||
index=True,
|
||||
)
|
||||
name = sa.Column(sa.Text, nullable=False)
|
||||
date_start = sa.Column(sa.Date(), nullable=False)
|
||||
date_end = sa.Column(sa.Date(), nullable=False)
|
||||
|
||||
travel_id = sa.Column(
|
||||
sa.Integer,
|
||||
sa.ForeignKey("travels.id"),
|
||||
nullable=False,
|
||||
)
|
||||
|
||||
|
||||
class Note(Base):
|
||||
__tablename__ = "notes"
|
||||
|
||||
id = sa.Column( # noqa: A003
|
||||
sa.Integer,
|
||||
unique=True,
|
||||
primary_key=True,
|
||||
autoincrement=True,
|
||||
index=True,
|
||||
)
|
||||
|
||||
file_id = sa.Column(sa.Text, nullable=False)
|
||||
file_name = sa.Column(sa.Text, nullable=False)
|
||||
file_type = sa.Column(sa.Text, nullable=False)
|
||||
public: sa.Column[bool] = sa.Column(
|
||||
sa.Boolean(),
|
||||
nullable=False,
|
||||
default=False,
|
||||
)
|
||||
|
||||
author_id = sa.Column(
|
||||
sa.BigInteger,
|
||||
sa.ForeignKey(User.telegram_id),
|
||||
nullable=False,
|
||||
)
|
||||
travel_id = sa.Column(
|
||||
sa.Integer,
|
||||
sa.ForeignKey("travels.id"),
|
||||
nullable=False,
|
||||
)
|
||||
+8
-6
@@ -1,20 +1,16 @@
|
||||
__all__ = ("User",)
|
||||
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import validates
|
||||
from sqlalchemy.orm import relationship, validates
|
||||
|
||||
from app import session
|
||||
from app.models import Base
|
||||
from app.utils import geo
|
||||
from app.utils.db import utcnow
|
||||
|
||||
|
||||
Base: Any = declarative_base()
|
||||
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = "users"
|
||||
|
||||
@@ -38,6 +34,9 @@ class User(Base):
|
||||
server_default=utcnow(),
|
||||
)
|
||||
|
||||
notes = relationship("Note", backref="author")
|
||||
owned_travels = relationship("Travel", backref="author")
|
||||
|
||||
@validates("username")
|
||||
def validate_username(self, key, value):
|
||||
regex_pattern = re.compile(r"^[a-zA-Z0-9_]{5,20}$")
|
||||
@@ -98,6 +97,9 @@ class User(Base):
|
||||
|
||||
return normalized_value
|
||||
|
||||
def get_user_travels(self):
|
||||
return self.owned_travels + self.travels
|
||||
|
||||
def get_human_readable_datejoined(self):
|
||||
return self.date_joined.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user