""" OnlyLegs - Database models and functions for SQLAlchemy """ import os import platformdirs from sqlalchemy import ( create_engine, Column, Integer, String, Boolean, DateTime, ForeignKey, PickleType) from sqlalchemy.orm import declarative_base, relationship USER_DIR = platformdirs.user_config_dir('onlylegs') DB_PATH = os.path.join(USER_DIR, 'gallery.sqlite') # In the future, I want to add support for other databases # engine = create_engine('postgresql://username:password@host:port/database_name', echo=False) # engine = create_engine('mysql://username:password@host:port/database_name', echo=False) engine = create_engine(f'sqlite:///{DB_PATH}', echo=False) base = declarative_base() class Users (base): # pylint: disable=too-few-public-methods, C0103 """ User table Joins with post, groups, session and log """ __tablename__ = 'users' id = Column(Integer, primary_key=True) username = Column(String, unique=True, nullable=False) email = Column(String, unique=True, nullable=False) password = Column(String, nullable=False) created_at = Column(DateTime, nullable=False) posts = relationship('Posts', backref='users') groups = relationship('Groups', backref='users') session = relationship('Sessions', backref='users') log = relationship('Logs', backref='users') class Posts (base): # pylint: disable=too-few-public-methods, C0103 """ Post table Joins with group_junction """ __tablename__ = 'posts' id = Column(Integer, primary_key=True) author_id = Column(Integer, ForeignKey('users.id')) created_at = Column(DateTime, nullable=False) file_name = Column(String, unique=True, nullable=False) file_type = Column(String, nullable=False) image_exif = Column(PickleType, nullable=False) image_colours = Column(PickleType, nullable=False) post_description = Column(String, nullable=False) post_alt = Column(String, nullable=False) junction = relationship('GroupJunction', backref='posts') class Groups (base): # pylint: disable=too-few-public-methods, C0103 """ Group table Joins with group_junction """ __tablename__ = 'groups' id = Column(Integer, primary_key=True) name = Column(String, nullable=False) description = Column(String, nullable=False) author_id = Column(Integer, ForeignKey('users.id')) created_at = Column(DateTime, nullable=False) junction = relationship('GroupJunction', backref='groups') class GroupJunction (base): # pylint: disable=too-few-public-methods, C0103 """ Junction table for posts and groups Joins with posts and groups """ __tablename__ = 'group_junction' id = Column(Integer, primary_key=True) date_added = Column(DateTime, nullable=False) group_id = Column(Integer, ForeignKey('groups.id')) post_id = Column(Integer, ForeignKey('posts.id')) class Sessions (base): # pylint: disable=too-few-public-methods, C0103 """ Session table Joins with user """ __tablename__ = 'sessions' id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey('users.id')) session_uuid = Column(String, nullable=False) ip_address = Column(String, nullable=False) user_agent = Column(String, nullable=False) active = Column(Boolean, nullable=False) created_at = Column(DateTime, nullable=False) class Logs (base): # pylint: disable=too-few-public-methods, C0103 """ Log table Joins with user """ __tablename__ = 'logs' id = Column(Integer, primary_key=True) user_id = Column(Integer, ForeignKey('users.id')) ip_address = Column(String, nullable=False) code = Column(Integer, nullable=False) msg = Column(String, nullable=False) created_at = Column(DateTime, nullable=False) class Bans (base): # pylint: disable=too-few-public-methods, C0103 """ Bans table """ __tablename__ = 'bans' id = Column(Integer, primary_key=True) ip_address = Column(String, nullable=False) code = Column(Integer, nullable=False) msg = Column(String, nullable=False) created_at = Column(DateTime, nullable=False) # check if database file exists, if not create it if not os.path.isfile(DB_PATH): base.metadata.create_all(engine) print('Database created')