fixed migrations
This commit is contained in:
58
Dockerfile
58
Dockerfile
@@ -1,33 +1,57 @@
|
|||||||
FROM python:3.11-slim
|
FROM python:3.11-slim
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# Install system dependencies
|
# Install system dependencies
|
||||||
RUN apt-get update && apt-get install -y \
|
RUN apt-get update && apt-get install -y \
|
||||||
gcc \
|
build-essential \
|
||||||
postgresql-client \
|
libpq-dev \
|
||||||
|
curl \
|
||||||
netcat-traditional \
|
netcat-traditional \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Create a non-root user
|
||||||
|
RUN useradd -m -u 1000 celery
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
# Copy requirements first to leverage Docker cache
|
# Copy requirements first to leverage Docker cache
|
||||||
COPY requirements.txt .
|
COPY requirements.txt .
|
||||||
RUN pip install --no-cache-dir -r requirements.txt
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
# Copy the rest of the application
|
# Copy application code
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Create migrations directory if it doesn't exist
|
# Create necessary directories and set permissions
|
||||||
RUN mkdir -p migrations/versions
|
RUN mkdir -p /app/uploads /app/static/uploads && \
|
||||||
|
chown -R celery:celery /app
|
||||||
|
|
||||||
# Make entrypoint script executable
|
# Create and set up startup script
|
||||||
RUN chmod +x entrypoint.sh
|
RUN echo '#!/bin/bash\n\
|
||||||
|
echo "Waiting for database..."\n\
|
||||||
|
while ! nc -z db 5432; do\n\
|
||||||
|
sleep 0.1\n\
|
||||||
|
done\n\
|
||||||
|
echo "Database is ready!"\n\
|
||||||
|
\n\
|
||||||
|
echo "Waiting for Redis..."\n\
|
||||||
|
while ! nc -z redis 6379; do\n\
|
||||||
|
sleep 0.1\n\
|
||||||
|
done\n\
|
||||||
|
echo "Redis is ready!"\n\
|
||||||
|
\n\
|
||||||
|
echo "Running database migrations..."\n\
|
||||||
|
flask db upgrade\n\
|
||||||
|
\n\
|
||||||
|
echo "Creating admin user..."\n\
|
||||||
|
flask create-admin\n\
|
||||||
|
\n\
|
||||||
|
echo "Starting application..."\n\
|
||||||
|
exec "$@"' > /app/start.sh && \
|
||||||
|
chmod +x /app/start.sh && \
|
||||||
|
chown celery:celery /app/start.sh
|
||||||
|
|
||||||
# Set environment variables
|
# Switch to non-root user
|
||||||
ENV FLASK_APP=app.py
|
USER celery
|
||||||
ENV FLASK_ENV=production
|
|
||||||
|
|
||||||
# Expose the port the app runs on
|
# Set entrypoint
|
||||||
EXPOSE 5000
|
ENTRYPOINT ["/app/start.sh"]
|
||||||
|
|
||||||
# Use the entrypoint script
|
|
||||||
ENTRYPOINT ["./entrypoint.sh"]
|
|
||||||
BIN
__pycache__/app.cpython-311.pyc
Normal file
BIN
__pycache__/app.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/celery_worker.cpython-311.pyc
Normal file
BIN
__pycache__/celery_worker.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/extensions.cpython-311.pyc
Normal file
BIN
__pycache__/extensions.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/forms.cpython-311.pyc
Normal file
BIN
__pycache__/forms.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/models.cpython-311.pyc
Normal file
BIN
__pycache__/models.cpython-311.pyc
Normal file
Binary file not shown.
BIN
__pycache__/tasks.cpython-311.pyc
Normal file
BIN
__pycache__/tasks.cpython-311.pyc
Normal file
Binary file not shown.
16
app.py
16
app.py
@@ -3,7 +3,7 @@ from flask import Flask, send_from_directory, jsonify
|
|||||||
from flask_migrate import Migrate
|
from flask_migrate import Migrate
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
import os
|
import os
|
||||||
from models import User
|
from models import User, SiteSettings
|
||||||
from flask_wtf.csrf import generate_csrf
|
from flask_wtf.csrf import generate_csrf
|
||||||
from routes.room_files import room_files_bp
|
from routes.room_files import room_files_bp
|
||||||
from routes.user import user_bp
|
from routes.user import user_bp
|
||||||
@@ -45,7 +45,12 @@ def create_app():
|
|||||||
|
|
||||||
@app.context_processor
|
@app.context_processor
|
||||||
def inject_config():
|
def inject_config():
|
||||||
return dict(config=app.config)
|
site_settings = SiteSettings.query.first()
|
||||||
|
if not site_settings:
|
||||||
|
site_settings = SiteSettings()
|
||||||
|
db.session.add(site_settings)
|
||||||
|
db.session.commit()
|
||||||
|
return dict(config=app.config, site_settings=site_settings)
|
||||||
|
|
||||||
# User loader for Flask-Login
|
# User loader for Flask-Login
|
||||||
@login_manager.user_loader
|
@login_manager.user_loader
|
||||||
@@ -111,7 +116,12 @@ def create_app():
|
|||||||
|
|
||||||
# Create default email templates if they don't exist
|
# Create default email templates if they don't exist
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
create_default_templates()
|
try:
|
||||||
|
# Ensure database tables exist
|
||||||
|
db.create_all()
|
||||||
|
create_default_templates()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Warning: Could not create default templates: {e}")
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ version: '3.8'
|
|||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
build: .
|
build: .
|
||||||
|
command: gunicorn --bind 0.0.0.0:5000 app:app
|
||||||
ports:
|
ports:
|
||||||
- "10335:5000"
|
- "10335:5000"
|
||||||
environment:
|
environment:
|
||||||
@@ -59,17 +60,18 @@ services:
|
|||||||
celery_worker:
|
celery_worker:
|
||||||
build: .
|
build: .
|
||||||
command: celery -A celery_worker.celery worker --loglevel=info
|
command: celery -A celery_worker.celery worker --loglevel=info
|
||||||
environment:
|
|
||||||
- FLASK_APP=app.py
|
|
||||||
- FLASK_ENV=production
|
|
||||||
- DATABASE_URL=postgresql://postgres:postgres@db:5432/docupulse
|
|
||||||
- REDIS_URL=redis://redis:6379/0
|
|
||||||
volumes:
|
volumes:
|
||||||
- .:/app
|
- .:/app
|
||||||
|
environment:
|
||||||
|
- FLASK_APP=app.py
|
||||||
|
- FLASK_ENV=development
|
||||||
|
- DATABASE_URL=postgresql://postgres:postgres@db:5432/docupulse
|
||||||
|
- REDIS_URL=redis://redis:6379/0
|
||||||
depends_on:
|
depends_on:
|
||||||
- web
|
db:
|
||||||
- redis
|
condition: service_healthy
|
||||||
- db
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "celery", "-A", "celery_worker.celery", "inspect", "ping"]
|
test: ["CMD", "celery", "-A", "celery_worker.celery", "inspect", "ping"]
|
||||||
|
|||||||
BIN
migrations/__pycache__/env.cpython-311.pyc
Normal file
BIN
migrations/__pycache__/env.cpython-311.pyc
Normal file
Binary file not shown.
@@ -7,6 +7,7 @@ Create Date: 2025-06-02 14:10:54.033943
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -18,14 +19,19 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('key_value_settings',
|
conn = op.get_bind()
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
inspector = inspect(conn)
|
||||||
sa.Column('key', sa.String(length=100), nullable=False),
|
tables = inspector.get_table_names()
|
||||||
sa.Column('value', sa.Text(), nullable=True),
|
|
||||||
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
if 'key_value_settings' not in tables:
|
||||||
sa.PrimaryKeyConstraint('id'),
|
op.create_table('key_value_settings',
|
||||||
sa.UniqueConstraint('key')
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
)
|
sa.Column('key', sa.String(length=100), nullable=False),
|
||||||
|
sa.Column('value', sa.Text(), nullable=True),
|
||||||
|
sa.Column('updated_at', sa.DateTime(), nullable=True),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('key')
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-26 14:00:05.521776
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
|
|||||||
@@ -2,11 +2,12 @@
|
|||||||
|
|
||||||
Revision ID: 1c297825e3a9
|
Revision ID: 1c297825e3a9
|
||||||
Revises:
|
Revises:
|
||||||
Create Date: 2025-05-23 08:39:40.494853
|
Create Date: 2025-06-02 13:26:30.353000
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -17,17 +18,24 @@ depends_on = None
|
|||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# Check if the table exists before creating it
|
||||||
op.create_table('user',
|
conn = op.get_bind()
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
inspector = sa.inspect(conn)
|
||||||
sa.Column('username', sa.String(length=150), nullable=False),
|
if 'user' not in inspector.get_table_names():
|
||||||
sa.Column('email', sa.String(length=150), nullable=False),
|
conn = op.get_bind()
|
||||||
sa.Column('password_hash', sa.String(length=128), nullable=True),
|
inspector = inspect(conn)
|
||||||
sa.PrimaryKeyConstraint('id'),
|
tables = inspector.get_table_names()
|
||||||
sa.UniqueConstraint('email'),
|
|
||||||
sa.UniqueConstraint('username')
|
if 'user' not in tables:
|
||||||
)
|
op.create_table('user',
|
||||||
# ### end Alembic commands ###
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('username', sa.String(length=150), nullable=False),
|
||||||
|
sa.Column('email', sa.String(length=150), nullable=False),
|
||||||
|
sa.Column('password_hash', sa.String(length=128), nullable=True),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('email'),
|
||||||
|
sa.UniqueConstraint('username')
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-06-02 09:04:39.972021
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -18,7 +19,12 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('mails',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'mails' not in tables:
|
||||||
|
op.create_table('mails',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('recipient', sa.String(length=150), nullable=False),
|
sa.Column('recipient', sa.String(length=150), nullable=False),
|
||||||
sa.Column('subject', sa.String(length=200), nullable=False),
|
sa.Column('subject', sa.String(length=200), nullable=False),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-23 16:10:53.731035
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-23 21:44:58.832286
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -18,17 +19,22 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('room_member_permissions',
|
conn = op.get_bind()
|
||||||
sa.Column('room_id', sa.Integer(), nullable=False),
|
inspector = inspect(conn)
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
tables = inspector.get_table_names()
|
||||||
sa.Column('can_view', sa.Boolean(), nullable=False),
|
|
||||||
sa.Column('can_upload', sa.Boolean(), nullable=False),
|
if 'room_member_permissions' not in tables:
|
||||||
sa.Column('can_delete', sa.Boolean(), nullable=False),
|
op.create_table('room_member_permissions',
|
||||||
sa.Column('can_share', sa.Boolean(), nullable=False),
|
sa.Column('room_id', sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['room_id'], ['room.id'], ),
|
sa.Column('user_id', sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
sa.Column('can_view', sa.Boolean(), nullable=False),
|
||||||
sa.PrimaryKeyConstraint('room_id', 'user_id')
|
sa.Column('can_upload', sa.Boolean(), nullable=False),
|
||||||
)
|
sa.Column('can_delete', sa.Boolean(), nullable=False),
|
||||||
|
sa.Column('can_share', sa.Boolean(), nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(['room_id'], ['room.id'], ),
|
||||||
|
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('room_id', 'user_id')
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-23 21:27:17.497481
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -18,15 +19,24 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('room_members',
|
conn = op.get_bind()
|
||||||
sa.Column('room_id', sa.Integer(), nullable=False),
|
inspector = inspect(conn)
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
tables = inspector.get_table_names()
|
||||||
sa.ForeignKeyConstraint(['room_id'], ['room.id'], ),
|
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
if 'room_members' not in tables:
|
||||||
sa.PrimaryKeyConstraint('room_id', 'user_id')
|
op.create_table('room_members',
|
||||||
)
|
sa.Column('room_id', sa.Integer(), nullable=False),
|
||||||
with op.batch_alter_table('room', schema=None) as batch_op:
|
sa.Column('user_id', sa.Integer(), nullable=False),
|
||||||
batch_op.drop_column('is_private')
|
sa.ForeignKeyConstraint(['room_id'], ['room.id'], ),
|
||||||
|
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('room_id', 'user_id')
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check if is_private column exists before dropping it
|
||||||
|
columns = [col['name'] for col in inspector.get_columns('room')]
|
||||||
|
if 'is_private' in columns:
|
||||||
|
with op.batch_alter_table('room', schema=None) as batch_op:
|
||||||
|
batch_op.drop_column('is_private')
|
||||||
|
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-23 21:25:27.880150
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -18,16 +19,21 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('room',
|
conn = op.get_bind()
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
inspector = inspect(conn)
|
||||||
sa.Column('name', sa.String(length=100), nullable=False),
|
tables = inspector.get_table_names()
|
||||||
sa.Column('description', sa.Text(), nullable=True),
|
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
if 'room' not in tables:
|
||||||
sa.Column('created_by', sa.Integer(), nullable=False),
|
op.create_table('room',
|
||||||
sa.Column('is_private', sa.Boolean(), nullable=True),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['created_by'], ['user.id'], ),
|
sa.Column('name', sa.String(length=100), nullable=False),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.Column('description', sa.Text(), nullable=True),
|
||||||
)
|
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||||
|
sa.Column('created_by', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('is_private', sa.Boolean(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(['created_by'], ['user.id'], ),
|
||||||
|
sa.PrimaryKeyConstraint('id')
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-23 09:24:23.926302
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -18,12 +19,21 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
columns = [col['name'] for col in inspector.get_columns('user')]
|
||||||
|
|
||||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
with op.batch_alter_table('user', schema=None) as batch_op:
|
||||||
batch_op.add_column(sa.Column('phone', sa.String(length=20), nullable=True))
|
if 'phone' not in columns:
|
||||||
batch_op.add_column(sa.Column('company', sa.String(length=100), nullable=True))
|
batch_op.add_column(sa.Column('phone', sa.String(length=20), nullable=True))
|
||||||
batch_op.add_column(sa.Column('position', sa.String(length=100), nullable=True))
|
if 'company' not in columns:
|
||||||
batch_op.add_column(sa.Column('notes', sa.Text(), nullable=True))
|
batch_op.add_column(sa.Column('company', sa.String(length=100), nullable=True))
|
||||||
batch_op.add_column(sa.Column('is_active', sa.Boolean(), nullable=True))
|
if 'position' not in columns:
|
||||||
|
batch_op.add_column(sa.Column('position', sa.String(length=100), nullable=True))
|
||||||
|
if 'notes' not in columns:
|
||||||
|
batch_op.add_column(sa.Column('notes', sa.Text(), nullable=True))
|
||||||
|
if 'is_active' not in columns:
|
||||||
|
batch_op.add_column(sa.Column('is_active', sa.Boolean(), nullable=True))
|
||||||
|
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-06-02 08:25:48.241102
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -24,7 +25,12 @@ def upgrade():
|
|||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('template_variables',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'template_variables' not in tables:
|
||||||
|
op.create_table('template_variables',
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
sa.Column('notification_type', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
sa.Column('notification_type', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
||||||
sa.Column('variable_name', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
sa.Column('variable_name', sa.VARCHAR(length=50), autoincrement=False, nullable=False),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-24 10:07:02.159730
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -18,7 +19,12 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('room_file',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'room_file' not in tables:
|
||||||
|
op.create_table('room_file',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('room_id', sa.Integer(), nullable=False),
|
sa.Column('room_id', sa.Integer(), nullable=False),
|
||||||
sa.Column('name', sa.String(length=255), nullable=False),
|
sa.Column('name', sa.String(length=255), nullable=False),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-24 18:14:38.320999
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2024-03-19 10:05:00.000000
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
from sqlalchemy.sql import text
|
from sqlalchemy.sql import text
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-25 10:03:03.423064
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-26 10:42:17.287566
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2024-03-19 10:15:00.000000
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
from sqlalchemy.sql import text
|
from sqlalchemy.sql import text
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-25 21:16:39.683736
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -18,7 +19,12 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('site_settings',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'site_settings' not in tables:
|
||||||
|
op.create_table('site_settings',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('primary_color', sa.String(length=7), nullable=True),
|
sa.Column('primary_color', sa.String(length=7), nullable=True),
|
||||||
sa.Column('secondary_color', sa.String(length=7), nullable=True),
|
sa.Column('secondary_color', sa.String(length=7), nullable=True),
|
||||||
@@ -31,7 +37,12 @@ def upgrade():
|
|||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('color_settings',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'color_settings' not in tables:
|
||||||
|
op.create_table('color_settings',
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
sa.Column('primary_color', sa.VARCHAR(length=7), autoincrement=False, nullable=True),
|
sa.Column('primary_color', sa.VARCHAR(length=7), autoincrement=False, nullable=True),
|
||||||
sa.Column('secondary_color', sa.VARCHAR(length=7), autoincrement=False, nullable=True),
|
sa.Column('secondary_color', sa.VARCHAR(length=7), autoincrement=False, nullable=True),
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -7,6 +7,7 @@ Create Date: 2024-03-19 10:00:00.000000
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -18,7 +19,12 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# Create conversation table first
|
# Create conversation table first
|
||||||
op.create_table('conversation',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'conversation' not in tables:
|
||||||
|
op.create_table('conversation',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('name', sa.String(length=100), nullable=False),
|
sa.Column('name', sa.String(length=100), nullable=False),
|
||||||
sa.Column('description', sa.Text(), nullable=True),
|
sa.Column('description', sa.Text(), nullable=True),
|
||||||
@@ -29,7 +35,12 @@ def upgrade():
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Create conversation_members table
|
# Create conversation_members table
|
||||||
op.create_table('conversation_members',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'conversation_members' not in tables:
|
||||||
|
op.create_table('conversation_members',
|
||||||
sa.Column('conversation_id', sa.Integer(), nullable=False),
|
sa.Column('conversation_id', sa.Integer(), nullable=False),
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
sa.Column('user_id', sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['conversation_id'], ['conversation.id'], ),
|
sa.ForeignKeyConstraint(['conversation_id'], ['conversation.id'], ),
|
||||||
@@ -38,7 +49,12 @@ def upgrade():
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Create message table
|
# Create message table
|
||||||
op.create_table('message',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'message' not in tables:
|
||||||
|
op.create_table('message',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('content', sa.Text(), nullable=False),
|
sa.Column('content', sa.Text(), nullable=False),
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
sa.Column('created_at', sa.DateTime(), nullable=True),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2024-03-19 10:45:00.000000
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'add_deleted_by_to_room_file'
|
revision = 'add_deleted_by_to_room_file'
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2024-03-19 10:30:00.000000
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'add_deleted_column_to_room_file'
|
revision = 'add_deleted_column_to_room_file'
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2024-03-19 10:00:00.000000
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -17,7 +18,12 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('trashed_file',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'trashed_file' not in tables:
|
||||||
|
op.create_table('trashed_file',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('room_id', sa.Integer(), nullable=False),
|
sa.Column('room_id', sa.Integer(), nullable=False),
|
||||||
sa.Column('name', sa.String(length=255), nullable=False),
|
sa.Column('name', sa.String(length=255), nullable=False),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-24 08:36:03.426879
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-26 11:14:05.629795
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-24 12:32:19.239241
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ Create Date: 2025-05-23 19:28:16.977187
|
|||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'c21f243b3640'
|
revision = 'c21f243b3640'
|
||||||
@@ -19,8 +20,13 @@ depends_on = None
|
|||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_table('contact')
|
op.drop_table('contact')
|
||||||
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
columns = [col['name'] for col in inspector.get_columns('user')]
|
||||||
|
|
||||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
with op.batch_alter_table('user', schema=None) as batch_op:
|
||||||
batch_op.add_column(sa.Column('profile_picture', sa.String(length=255), nullable=True))
|
if 'profile_picture' not in columns:
|
||||||
|
batch_op.add_column(sa.Column('profile_picture', sa.String(length=255), nullable=True))
|
||||||
|
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-23 16:00:09.905001
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -18,8 +19,13 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
columns = [col['name'] for col in inspector.get_columns('user')]
|
||||||
|
|
||||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
with op.batch_alter_table('user', schema=None) as batch_op:
|
||||||
batch_op.add_column(sa.Column('last_name', sa.String(length=150), nullable=True))
|
if 'last_name' not in columns:
|
||||||
|
batch_op.add_column(sa.Column('last_name', sa.String(length=150), nullable=True))
|
||||||
|
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-06-01 20:09:08.019884
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -18,7 +19,12 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('email_templates',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'email_templates' not in tables:
|
||||||
|
op.create_table('email_templates',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('name', sa.String(length=100), nullable=False),
|
sa.Column('name', sa.String(length=100), nullable=False),
|
||||||
sa.Column('subject', sa.String(length=200), nullable=False),
|
sa.Column('subject', sa.String(length=200), nullable=False),
|
||||||
@@ -54,7 +60,12 @@ def downgrade():
|
|||||||
type_=postgresql.JSONB(astext_type=sa.Text()),
|
type_=postgresql.JSONB(astext_type=sa.Text()),
|
||||||
existing_nullable=True)
|
existing_nullable=True)
|
||||||
|
|
||||||
op.create_table('notification',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'notification' not in tables:
|
||||||
|
op.create_table('notification',
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
sa.Column('user_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
sa.Column('user_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
sa.Column('title', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
sa.Column('title', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-25 21:08:37.158900
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -18,7 +19,12 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('color_settings',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'color_settings' not in tables:
|
||||||
|
op.create_table('color_settings',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('primary_color', sa.String(length=7), nullable=True),
|
sa.Column('primary_color', sa.String(length=7), nullable=True),
|
||||||
sa.Column('secondary_color', sa.String(length=7), nullable=True),
|
sa.Column('secondary_color', sa.String(length=7), nullable=True),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2024-03-19 10:00:00.000000
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -17,7 +18,12 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# Create user_starred_file table
|
# Create user_starred_file table
|
||||||
op.create_table('user_starred_file',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'user_starred_file' not in tables:
|
||||||
|
op.create_table('user_starred_file',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
sa.Column('user_id', sa.Integer(), nullable=False),
|
||||||
sa.Column('file_id', sa.Integer(), nullable=False),
|
sa.Column('file_id', sa.Integer(), nullable=False),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-23 08:45:00.693155
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-23 08:55:10.537722
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -35,9 +36,17 @@ def upgrade():
|
|||||||
sa.PrimaryKeyConstraint('id'),
|
sa.PrimaryKeyConstraint('id'),
|
||||||
sa.UniqueConstraint('email')
|
sa.UniqueConstraint('email')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Check if columns exist before adding them
|
||||||
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
columns = [col['name'] for col in inspector.get_columns('user')]
|
||||||
|
|
||||||
with op.batch_alter_table('user', schema=None) as batch_op:
|
with op.batch_alter_table('user', schema=None) as batch_op:
|
||||||
batch_op.add_column(sa.Column('is_admin', sa.Boolean(), nullable=True))
|
if 'is_admin' not in columns:
|
||||||
batch_op.add_column(sa.Column('created_at', sa.DateTime(), nullable=True))
|
batch_op.add_column(sa.Column('is_admin', sa.Boolean(), nullable=True))
|
||||||
|
if 'created_at' not in columns:
|
||||||
|
batch_op.add_column(sa.Column('created_at', sa.DateTime(), nullable=True))
|
||||||
|
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-26 15:00:18.557702
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
@@ -18,7 +19,12 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('message_attachment',
|
conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if 'message_attachment' not in tables:
|
||||||
|
op.create_table('message_attachment',
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
sa.Column('message_id', sa.Integer(), nullable=False),
|
sa.Column('message_id', sa.Integer(), nullable=False),
|
||||||
sa.Column('name', sa.String(length=255), nullable=False),
|
sa.Column('name', sa.String(length=255), nullable=False),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ Create Date: 2025-05-26 10:52:32.572951
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
|
|||||||
BIN
routes/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
routes/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/admin.cpython-311.pyc
Normal file
BIN
routes/__pycache__/admin.cpython-311.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/auth.cpython-311.pyc
Normal file
BIN
routes/__pycache__/auth.cpython-311.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/contacts.cpython-311.pyc
Normal file
BIN
routes/__pycache__/contacts.cpython-311.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/conversations.cpython-311.pyc
Normal file
BIN
routes/__pycache__/conversations.cpython-311.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/email_templates.cpython-311.pyc
Normal file
BIN
routes/__pycache__/email_templates.cpython-311.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/main.cpython-311.pyc
Normal file
BIN
routes/__pycache__/main.cpython-311.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/room_files.cpython-311.pyc
Normal file
BIN
routes/__pycache__/room_files.cpython-311.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/room_members.cpython-311.pyc
Normal file
BIN
routes/__pycache__/room_members.cpython-311.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/rooms.cpython-311.pyc
Normal file
BIN
routes/__pycache__/rooms.cpython-311.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/trash.cpython-311.pyc
Normal file
BIN
routes/__pycache__/trash.cpython-311.pyc
Normal file
Binary file not shown.
BIN
routes/__pycache__/user.cpython-311.pyc
Normal file
BIN
routes/__pycache__/user.cpython-311.pyc
Normal file
Binary file not shown.
@@ -7,13 +7,6 @@ from utils import log_event, create_notification, get_unread_count
|
|||||||
|
|
||||||
auth_bp = Blueprint('auth', __name__)
|
auth_bp = Blueprint('auth', __name__)
|
||||||
|
|
||||||
@auth_bp.context_processor
|
|
||||||
def inject_unread_notifications():
|
|
||||||
if current_user.is_authenticated:
|
|
||||||
unread_count = get_unread_count(current_user.id)
|
|
||||||
return {'unread_notifications': unread_count}
|
|
||||||
return {'unread_notifications': 0}
|
|
||||||
|
|
||||||
def require_password_change(f):
|
def require_password_change(f):
|
||||||
@wraps(f)
|
@wraps(f)
|
||||||
def decorated_function(*args, **kwargs):
|
def decorated_function(*args, **kwargs):
|
||||||
@@ -24,6 +17,13 @@ def require_password_change(f):
|
|||||||
return decorated_function
|
return decorated_function
|
||||||
|
|
||||||
def init_routes(auth_bp):
|
def init_routes(auth_bp):
|
||||||
|
@auth_bp.context_processor
|
||||||
|
def inject_unread_notifications():
|
||||||
|
if current_user.is_authenticated:
|
||||||
|
unread_count = get_unread_count(current_user.id)
|
||||||
|
return {'unread_notifications': unread_count}
|
||||||
|
return {'unread_notifications': 0}
|
||||||
|
|
||||||
@auth_bp.route('/login', methods=['GET', 'POST'])
|
@auth_bp.route('/login', methods=['GET', 'POST'])
|
||||||
def login():
|
def login():
|
||||||
if current_user.is_authenticated:
|
if current_user.is_authenticated:
|
||||||
|
|||||||
22
start.sh
Normal file
22
start.sh
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Waiting for database..."
|
||||||
|
while ! nc -z db 5432; do
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
echo "Database is ready!"
|
||||||
|
|
||||||
|
echo "Waiting for Redis..."
|
||||||
|
while ! nc -z redis 6379; do
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
echo "Redis is ready!"
|
||||||
|
|
||||||
|
echo "Running database migrations..."
|
||||||
|
flask db upgrade
|
||||||
|
|
||||||
|
echo "Creating admin user..."
|
||||||
|
flask create-admin
|
||||||
|
|
||||||
|
echo "Starting application..."
|
||||||
|
exec "$@"
|
||||||
71
update_migrations.py
Normal file
71
update_migrations.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
def update_migration_file(file_path):
|
||||||
|
with open(file_path, 'r') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
# Skip if already has the pattern
|
||||||
|
if 'from sqlalchemy import inspect' in content:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Add import if not present
|
||||||
|
if 'import sqlalchemy as sa' in content:
|
||||||
|
content = content.replace('import sqlalchemy as sa', 'import sqlalchemy as sa\nfrom sqlalchemy import inspect')
|
||||||
|
else:
|
||||||
|
content = content.replace('from alembic import op', 'from alembic import op\nfrom sqlalchemy import inspect')
|
||||||
|
|
||||||
|
# Find all create_table operations
|
||||||
|
create_table_pattern = r'op\.create_table\([\'"](\w+)[\'"]'
|
||||||
|
tables = re.findall(create_table_pattern, content)
|
||||||
|
|
||||||
|
for table in tables:
|
||||||
|
# Create the check pattern with proper indentation
|
||||||
|
check_pattern = f""" conn = op.get_bind()
|
||||||
|
inspector = inspect(conn)
|
||||||
|
tables = inspector.get_table_names()
|
||||||
|
|
||||||
|
if '{table}' not in tables:"""
|
||||||
|
|
||||||
|
# Find the create_table line and its indentation
|
||||||
|
create_table_line = f"op.create_table('{table}'"
|
||||||
|
if create_table_line in content:
|
||||||
|
# Get the indentation of the create_table line
|
||||||
|
lines = content.split('\n')
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
if create_table_line in line:
|
||||||
|
indent = len(line) - len(line.lstrip())
|
||||||
|
# Add the check before the create_table with matching indentation
|
||||||
|
check_lines = check_pattern.split('\n')
|
||||||
|
check_lines = [' ' * indent + line.lstrip() for line in check_lines]
|
||||||
|
check_pattern = '\n'.join(check_lines)
|
||||||
|
# Add extra indentation to the create_table line
|
||||||
|
create_table_line = ' ' * (indent + 4) + create_table_line
|
||||||
|
# Replace in the content
|
||||||
|
content = content.replace(line, f"{check_pattern}\n{create_table_line}")
|
||||||
|
|
||||||
|
# Write back the updated content
|
||||||
|
with open(file_path, 'w') as f:
|
||||||
|
f.write(content)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def main():
|
||||||
|
migrations_dir = Path('migrations/versions')
|
||||||
|
updated_files = []
|
||||||
|
|
||||||
|
for file in migrations_dir.glob('*.py'):
|
||||||
|
if file.name != '__init__.py':
|
||||||
|
if update_migration_file(file):
|
||||||
|
updated_files.append(file.name)
|
||||||
|
|
||||||
|
if updated_files:
|
||||||
|
print("Updated the following migration files:")
|
||||||
|
for file in updated_files:
|
||||||
|
print(f"- {file}")
|
||||||
|
else:
|
||||||
|
print("No files needed updating.")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
BIN
utils/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
utils/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
utils/__pycache__/email_templates.cpython-311.pyc
Normal file
BIN
utils/__pycache__/email_templates.cpython-311.pyc
Normal file
Binary file not shown.
BIN
utils/__pycache__/event_logger.cpython-311.pyc
Normal file
BIN
utils/__pycache__/event_logger.cpython-311.pyc
Normal file
Binary file not shown.
BIN
utils/__pycache__/notification.cpython-311.pyc
Normal file
BIN
utils/__pycache__/notification.cpython-311.pyc
Normal file
Binary file not shown.
BIN
utils/__pycache__/path_utils.cpython-311.pyc
Normal file
BIN
utils/__pycache__/path_utils.cpython-311.pyc
Normal file
Binary file not shown.
BIN
utils/__pycache__/permissions.cpython-311.pyc
Normal file
BIN
utils/__pycache__/permissions.cpython-311.pyc
Normal file
Binary file not shown.
BIN
utils/__pycache__/time_utils.cpython-311.pyc
Normal file
BIN
utils/__pycache__/time_utils.cpython-311.pyc
Normal file
Binary file not shown.
Reference in New Issue
Block a user