diff --git a/dashmachine/site.db b/dashmachine/site.db new file mode 100644 index 0000000..3657cdf Binary files /dev/null and b/dashmachine/site.db differ diff --git a/dashmachine/update.py b/dashmachine/update.py new file mode 100644 index 0000000..9f9926a --- /dev/null +++ b/dashmachine/update.py @@ -0,0 +1,8 @@ +import os +import subprocess +from dashmachine.paths import root_folder + +migrate_fn = os.path.join(root_folder, 'manage_db.py db migrate') +upgrade_fn = os.path.join(root_folder, 'manage_db.py db upgrade') + +def update(): diff --git a/manage_db.py b/manage_db.py index 20c0153..126ec10 100755 --- a/manage_db.py +++ b/manage_db.py @@ -4,7 +4,7 @@ from flask_script import Manager from flask_migrate import Migrate, MigrateCommand from dashmachine import app, db -app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///dashmachine/site.db" +app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///dashmachine/user_data/site.db" migrate = Migrate(app, db) diff --git a/migrations/README b/migrations/README deleted file mode 100644 index 98e4f9c..0000000 --- a/migrations/README +++ /dev/null @@ -1 +0,0 @@ -Generic single-database configuration. \ No newline at end of file diff --git a/migrations/alembic.ini b/migrations/alembic.ini deleted file mode 100644 index f8ed480..0000000 --- a/migrations/alembic.ini +++ /dev/null @@ -1,45 +0,0 @@ -# A generic, single database configuration. - -[alembic] -# template used to generate migration files -# file_template = %%(rev)s_%%(slug)s - -# set to 'true' to run the environment during -# the 'revision' command, regardless of autogenerate -# revision_environment = false - - -# Logging configuration -[loggers] -keys = root,sqlalchemy,alembic - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = WARN -handlers = console -qualname = - -[logger_sqlalchemy] -level = WARN -handlers = -qualname = sqlalchemy.engine - -[logger_alembic] -level = INFO -handlers = -qualname = alembic - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(levelname)-5.5s [%(name)s] %(message)s -datefmt = %H:%M:%S diff --git a/migrations/env.py b/migrations/env.py deleted file mode 100644 index d766af8..0000000 --- a/migrations/env.py +++ /dev/null @@ -1,96 +0,0 @@ -from __future__ import with_statement - -import logging -from logging.config import fileConfig - -from sqlalchemy import engine_from_config -from sqlalchemy import pool - -from alembic import context - -# this is the Alembic Config object, which provides -# access to the values within the .ini file in use. -config = context.config - -# Interpret the config file for Python logging. -# This line sets up loggers basically. -fileConfig(config.config_file_name) -logger = logging.getLogger("alembic.env") - -# add your model's MetaData object here -# for 'autogenerate' support -# from myapp import mymodel -# target_metadata = mymodel.Base.metadata -from flask import current_app - -config.set_main_option( - "sqlalchemy.url", - current_app.config.get("SQLALCHEMY_DATABASE_URI").replace("%", "%%"), -) -target_metadata = current_app.extensions["migrate"].db.metadata - -# other values from the config, defined by the needs of env.py, -# can be acquired: -# my_important_option = config.get_main_option("my_important_option") -# ... etc. - - -def run_migrations_offline(): - """Run migrations in 'offline' mode. - - This configures the context with just a URL - and not an Engine, though an Engine is acceptable - here as well. By skipping the Engine creation - we don't even need a DBAPI to be available. - - Calls to context.execute() here emit the given string to the - script output. - - """ - url = config.get_main_option("sqlalchemy.url") - context.configure(url=url, target_metadata=target_metadata, literal_binds=True) - - with context.begin_transaction(): - context.run_migrations() - - -def run_migrations_online(): - """Run migrations in 'online' mode. - - In this scenario we need to create an Engine - and associate a connection with the context. - - """ - - # this callback is used to prevent an auto-migration from being generated - # when there are no changes to the schema - # reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html - def process_revision_directives(context, revision, directives): - if getattr(config.cmd_opts, "autogenerate", False): - script = directives[0] - if script.upgrade_ops.is_empty(): - directives[:] = [] - logger.info("No changes in schema detected.") - - connectable = engine_from_config( - config.get_section(config.config_ini_section), - prefix="sqlalchemy.", - poolclass=pool.NullPool, - ) - - with connectable.connect() as connection: - context.configure( - connection=connection, - target_metadata=target_metadata, - process_revision_directives=process_revision_directives, - **current_app.extensions["migrate"].configure_args - ) - - with context.begin_transaction(): - context.run_migrations() - - -if context.is_offline_mode(): - run_migrations_offline() -else: - run_migrations_online() diff --git a/migrations/script.py.mako b/migrations/script.py.mako deleted file mode 100644 index 2c01563..0000000 --- a/migrations/script.py.mako +++ /dev/null @@ -1,24 +0,0 @@ -"""${message} - -Revision ID: ${up_revision} -Revises: ${down_revision | comma,n} -Create Date: ${create_date} - -""" -from alembic import op -import sqlalchemy as sa -${imports if imports else ""} - -# revision identifiers, used by Alembic. -revision = ${repr(up_revision)} -down_revision = ${repr(down_revision)} -branch_labels = ${repr(branch_labels)} -depends_on = ${repr(depends_on)} - - -def upgrade(): - ${upgrades if upgrades else "pass"} - - -def downgrade(): - ${downgrades if downgrades else "pass"} diff --git a/migrations/versions/af72304ae017_.py b/migrations/versions/af72304ae017_.py new file mode 100644 index 0000000..87ccd03 --- /dev/null +++ b/migrations/versions/af72304ae017_.py @@ -0,0 +1,96 @@ +"""empty message + +Revision ID: af72304ae017 +Revises: +Create Date: 2020-01-30 21:09:14.404366 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = "af72304ae017" +down_revision = None +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "api_calls", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("name", sa.String(), nullable=True), + sa.Column("resource", sa.String(), nullable=True), + sa.Column("method", sa.String(), nullable=True), + sa.Column("payload", sa.String(), nullable=True), + sa.Column("authentication", sa.String(), nullable=True), + sa.Column("username", sa.String(), nullable=True), + sa.Column("password", sa.String(), nullable=True), + sa.Column("value_template", sa.String(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "apps", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("name", sa.String(), nullable=True), + sa.Column("prefix", sa.String(), nullable=True), + sa.Column("url", sa.String(), nullable=True), + sa.Column("icon", sa.String(), nullable=True), + sa.Column("sidebar_icon", sa.String(), nullable=True), + sa.Column("description", sa.String(), nullable=True), + sa.Column("open_in", sa.String(), nullable=True), + sa.Column("data_template", sa.String(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "files", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("name", sa.String(), nullable=True), + sa.Column("path", sa.String(), nullable=True), + sa.Column("external_path", sa.String(), nullable=True), + sa.Column("cache", sa.String(), nullable=True), + sa.Column("folder", sa.String(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "settings", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("theme", sa.String(), nullable=True), + sa.Column("accent", sa.String(), nullable=True), + sa.Column("background", sa.String(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "template_apps", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("name", sa.String(), nullable=True), + sa.Column("prefix", sa.String(), nullable=True), + sa.Column("url", sa.String(), nullable=True), + sa.Column("icon", sa.String(), nullable=True), + sa.Column("sidebar_icon", sa.String(), nullable=True), + sa.Column("description", sa.String(), nullable=True), + sa.Column("open_in", sa.String(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "user", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("username", sa.String(length=120), nullable=False), + sa.Column("password", sa.String(length=60), nullable=False), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("username"), + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table("user") + op.drop_table("template_apps") + op.drop_table("settings") + op.drop_table("files") + op.drop_table("apps") + op.drop_table("api_calls") + # ### end Alembic commands ### diff --git a/requirements.txt b/requirements.txt index 797e11d..c4f1ad6 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +alembic==1.3.3 amqp==2.5.1 aniso8601==7.0.0 APScheduler==3.6.1 @@ -16,7 +17,9 @@ Flask-Avatars==0.2.2 Flask-Bcrypt==0.7.1 Flask-Caching==1.8.0 Flask-Login==0.4.1 +Flask-Migrate==2.5.2 Flask-RESTful==0.3.7 +Flask-Script==2.0.6 Flask-SQLAlchemy==2.4.1 Flask-Toastr==0.5.2 Flask-WTF==0.14.2 @@ -29,6 +32,7 @@ itsdangerous==1.1.0 Jinja2==2.10.3 jsmin==2.2.2 kombu==4.6.7 +Mako==1.1.1 MarkupSafe==1.1.1 more-itertools==8.0.2 pathlib-mate==0.0.15 @@ -37,6 +41,7 @@ pycodestyle==2.5.0 pycparser==2.19 PyPDF2==1.26.0 python-dateutil==2.8.1 +python-editor==1.0.4 python-http-client==3.2.1 python-resize-image==1.1.19 pytz==2019.3