refactoring

main
Сергей Ванюшкин 2023-10-10 22:44:32 +03:00
parent 7d70c38fb8
commit 199eb0f3ae
13 changed files with 230 additions and 267 deletions

View File

@ -1,5 +1,6 @@
import os
import uuid
from datetime import datetime as dt
from dotenv import load_dotenv
@ -9,12 +10,16 @@ if os.path.exists(dotenv_path):
with open(dotenv_path, "a") as f:
if os.getenv("BRAND") is None:
br = input("Введите название блога: ")
f.writelines(f"BRAND={br}\n")
print("Генерирую SECRET_KEY...")
if os.getenv("SECRET_KEY") is None:
f.writelines(f"SECRET_KEY={uuid.uuid4().hex}\n")
print("_Ok_")
else:
print("SECRET_KEY уже установлен, прорускаю")
print("SECRET_KEY уже установлен, пропускаю")
print('Генерирую "Соль"...')
if os.getenv("SECURITY_PASSWORD_SALT") is None:
@ -27,9 +32,32 @@ with open(dotenv_path, "a") as f:
print("Настроки подключения к базе данных Posgresql:")
login = input("Введите логин пользователя бд: ")
passwd = input("Пароль: ")
db = input("Название бд (по умолчанию pyproger):") or "pyproger"
db = input("Название бд (по умолчанию pyprogerdb):") or "pyprogerdb"
ip = input("Адрес бд (по умолчанию localhost)") or "localhost"
port = input("Порт подключения: (по умолчанию 5432)") or "5432"
f.writelines(
f"SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://{login}:{passwd}@{ip}:{port}/{db}"
f"SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://{login}:{passwd}@{ip}:{port}/{db}\n"
)
if os.getenv("COPYRIGHT_YEAR") is None:
start_date = dt.utcnow().strftime("%Y")
f.writelines(f"COPYRIGHT_YEAR={start_date}\n")
if os.getenv("COPYRIGHT_NAME") is None:
name = input("Введите имя для для футера:")
f.writelines(f"COPYRIGHT_NAME={name}\n")
if os.getenv("COPYRIGHT_LINK") is None:
print("Введите ссылку для футера:")
print(
"email('something@somthing.else) или веб адрес полностью('http://anysite.any')"
)
link = input(">:")
if link.startswith("http"):
f.writelines(f"COPYRIGHT_LINK={link}\n")
else:
f.writelines(f"COPYRIGHT_LINK=mailto:{link}\n")
if os.getenv("COPYRIGHT_CITY") is None:
name = input("Введите свой город для для футера:")
f.writelines(f"COPYRIGHT_CITY={name}\n")

View File

@ -7,6 +7,7 @@ Create Date: ${create_date}
"""
from alembic import op
import sqlalchemy as sa
import flask_security
${imports if imports else ""}
# revision identifiers, used by Alembic.

View File

@ -1,34 +0,0 @@
"""empty message
Revision ID: 5e6d181b4b74
Revises: e24055e16b26
Create Date: 2023-10-04 08:46:50.473590
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '5e6d181b4b74'
down_revision = 'e24055e16b26'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('page', schema=None) as batch_op:
batch_op.add_column(sa.Column('update_datetime', sa.DateTime(), nullable=True))
batch_op.create_unique_constraint(None, ['id'])
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('page', schema=None) as batch_op:
batch_op.drop_constraint(None, type_='unique')
batch_op.drop_column('update_datetime')
# ### end Alembic commands ###

View File

@ -0,0 +1,126 @@
"""initial_migration
Revision ID: 68537cc1688c
Revises:
Create Date: 2023-10-10 22:17:40.476992
"""
from alembic import op
import sqlalchemy as sa
import flask_security
# revision identifiers, used by Alembic.
revision = '68537cc1688c'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('footer_icons',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=30), nullable=True),
sa.Column('bootstrap_ico', sa.String(length=20), nullable=True),
sa.Column('link', sa.String(length=100), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('id')
)
op.create_table('page',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=20), nullable=True),
sa.Column('slug', sa.String(length=50), nullable=False),
sa.Column('text', sa.Text(), nullable=True),
sa.Column('update_datetime', sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('id')
)
op.create_table('role',
sa.Column('name', sa.String(length=80), nullable=False),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('description', sa.String(length=255), nullable=True),
sa.Column('permissions', flask_security.datastore.AsaList(), nullable=True),
sa.Column('update_datetime', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
op.create_table('site_headers',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=20), nullable=True),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('content', sa.Text(), nullable=True),
sa.Column('enabled', sa.Boolean(), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('id')
)
op.create_table('tag',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('tag', sa.String(length=20), nullable=True),
sa.PrimaryKeyConstraint('id')
)
op.create_table('user',
sa.Column('first_name', sa.String(length=255), nullable=True),
sa.Column('last_name', sa.String(length=255), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('email', sa.String(length=255), nullable=False),
sa.Column('username', sa.String(length=255), nullable=True),
sa.Column('password', sa.String(length=255), nullable=False),
sa.Column('active', sa.Boolean(), nullable=False),
sa.Column('fs_uniquifier', sa.String(length=64), nullable=False),
sa.Column('confirmed_at', sa.DateTime(), nullable=True),
sa.Column('last_login_at', sa.DateTime(), nullable=True),
sa.Column('current_login_at', sa.DateTime(), nullable=True),
sa.Column('last_login_ip', sa.String(length=64), nullable=True),
sa.Column('current_login_ip', sa.String(length=64), nullable=True),
sa.Column('login_count', sa.Integer(), nullable=True),
sa.Column('tf_primary_method', sa.String(length=64), nullable=True),
sa.Column('tf_totp_secret', sa.String(length=255), nullable=True),
sa.Column('tf_phone_number', sa.String(length=128), nullable=True),
sa.Column('create_datetime', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.Column('update_datetime', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('email'),
sa.UniqueConstraint('fs_uniquifier')
)
op.create_table('post',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('author', sa.Integer(), nullable=True),
sa.Column('slug', sa.String(length=100), nullable=False),
sa.Column('title', sa.Text(), nullable=False),
sa.Column('description', sa.Text(), nullable=False),
sa.Column('published', sa.Boolean(), nullable=True),
sa.Column('create_datetime', sa.DateTime(), nullable=True),
sa.Column('update_datetime', sa.DateTime(), nullable=True),
sa.Column('text', sa.Text(), nullable=True),
sa.ForeignKeyConstraint(['author'], ['user.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('id')
)
op.create_table('roles_users',
sa.Column('user_id', sa.Integer(), nullable=True),
sa.Column('role_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['role_id'], ['role.id'], ),
sa.ForeignKeyConstraint(['user_id'], ['user.id'], )
)
op.create_table('tag_post',
sa.Column('tag_id', sa.Integer(), nullable=True),
sa.Column('post_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['post_id'], ['post.id'], ),
sa.ForeignKeyConstraint(['tag_id'], ['tag.id'], )
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('tag_post')
op.drop_table('roles_users')
op.drop_table('post')
op.drop_table('user')
op.drop_table('tag')
op.drop_table('site_headers')
op.drop_table('role')
op.drop_table('page')
op.drop_table('footer_icons')
# ### end Alembic commands ###

View File

@ -1,132 +0,0 @@
"""initial_migration
Revision ID: 8c415e462cb3
Revises:
Create Date: 2023-09-22 12:19:22.923813
"""
import flask_security
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "8c415e462cb3"
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"role",
sa.Column("name", sa.String(length=80), nullable=False),
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("description", sa.String(length=255), nullable=True),
sa.Column("permissions", flask_security.datastore.AsaList(), nullable=True),
sa.Column(
"update_datetime",
sa.DateTime(),
server_default=sa.text("now()"),
nullable=False,
),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("name"),
)
op.create_table(
"tag",
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
sa.Column("tag", sa.String(length=20), nullable=True),
sa.PrimaryKeyConstraint("id"),
)
op.create_table(
"user",
sa.Column("first_name", sa.String(length=255), nullable=True),
sa.Column("last_name", sa.String(length=255), nullable=True),
sa.Column("id", sa.Integer(), nullable=False),
sa.Column("email", sa.String(length=255), nullable=False),
sa.Column("username", sa.String(length=255), nullable=True),
sa.Column("password", sa.String(length=255), nullable=False),
sa.Column("active", sa.Boolean(), nullable=False),
sa.Column("fs_uniquifier", sa.String(length=64), nullable=False),
sa.Column("confirmed_at", sa.DateTime(), nullable=True),
sa.Column("last_login_at", sa.DateTime(), nullable=True),
sa.Column("current_login_at", sa.DateTime(), nullable=True),
sa.Column("last_login_ip", sa.String(length=64), nullable=True),
sa.Column("current_login_ip", sa.String(length=64), nullable=True),
sa.Column("login_count", sa.Integer(), nullable=True),
sa.Column("tf_primary_method", sa.String(length=64), nullable=True),
sa.Column("tf_totp_secret", sa.String(length=255), nullable=True),
sa.Column("tf_phone_number", sa.String(length=128), nullable=True),
sa.Column(
"create_datetime",
sa.DateTime(),
server_default=sa.text("now()"),
nullable=False,
),
sa.Column(
"update_datetime",
sa.DateTime(),
server_default=sa.text("now()"),
nullable=False,
),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("email"),
sa.UniqueConstraint("fs_uniquifier"),
)
op.create_table(
"post",
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
sa.Column("author", sa.Integer(), nullable=True),
sa.Column("slug", sa.String(length=100), nullable=False),
sa.Column("title", sa.Text(), nullable=False),
sa.Column("description", sa.Text(), nullable=False),
sa.Column("published", sa.Boolean(), nullable=True),
sa.Column("create_datetime", sa.DateTime(), nullable=True),
sa.Column("update_datetime", sa.DateTime(), nullable=True),
sa.Column("text", sa.Text(), nullable=True),
sa.ForeignKeyConstraint(
["author"],
["user.id"],
),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("id"),
)
op.create_table(
"roles_users",
sa.Column("user_id", sa.Integer(), nullable=True),
sa.Column("role_id", sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(
["role_id"],
["role.id"],
),
sa.ForeignKeyConstraint(
["user_id"],
["user.id"],
),
)
op.create_table(
"tag_post",
sa.Column("tag_id", sa.Integer(), nullable=True),
sa.Column("post_id", sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(
["post_id"],
["post.id"],
),
sa.ForeignKeyConstraint(
["tag_id"],
["tag.id"],
),
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table("tag_post")
op.drop_table("roles_users")
op.drop_table("post")
op.drop_table("user")
op.drop_table("tag")
op.drop_table("role")
# ### end Alembic commands ###

View File

@ -1,42 +0,0 @@
"""empty message
Revision ID: e24055e16b26
Revises: 8c415e462cb3
Create Date: 2023-10-02 09:30:10.566908
"""
import flask_security
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision = "e24055e16b26"
down_revision = "8c415e462cb3"
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"page",
sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
sa.Column("name", sa.String(length=20), nullable=True),
sa.Column("slug", sa.String(length=50), nullable=False),
sa.Column("text", sa.Text(), nullable=True),
sa.PrimaryKeyConstraint("id"),
sa.UniqueConstraint("id"),
)
with op.batch_alter_table("post", schema=None) as batch_op:
batch_op.create_unique_constraint(None, ["id"])
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table("post", schema=None) as batch_op:
batch_op.drop_constraint(None, type_="unique")
op.drop_table("page")
# ### end Alembic commands ###

View File

@ -1,36 +0,0 @@
"""empty message
Revision ID: ea0fde3014d7
Revises: 5e6d181b4b74
Create Date: 2023-10-07 14:32:08.410786
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'ea0fde3014d7'
down_revision = '5e6d181b4b74'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('site_headers',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('name', sa.String(length=20), nullable=True),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('content', sa.Text(), nullable=True),
sa.Column('enabled', sa.Boolean(), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('id')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('site_headers')
# ### end Alembic commands ###

View File

@ -112,3 +112,12 @@ class HeadersView(MyAdminView):
"name",
"description",
)
class FooterLinksView(MyAdminView):
column_labels = dict(
name="Название",
bootstrap_ico="Bootstrap код иконки",
link="Ссылка",
)
column_list = ("name",)

View File

@ -7,9 +7,12 @@ from flask_ckeditor import CKEditor
from flask_migrate import Migrate
from flask_security.core import Security
from pyproger.admin.views import FooterLinksView
from pyproger.dbase import Role, User, db, user_datastore
from pyproger.dbase.database import get_headers, get_menu_items
from pyproger.dbase.models import Page, Post, SiteHeaders, Tag
from pyproger.dbase.database import (get_footer_links, get_headers,
get_menu_items)
from pyproger.dbase.models import (FooterContactLinks, Page, Post, SiteHeaders,
Tag)
def create_app(test_config=None):
@ -23,6 +26,13 @@ def create_app(test_config=None):
app.config["SECRET_KEY"] = os.getenv("SECRET_KEY")
app.config["SECURITY_PASSWORD_SALT"] = os.getenv("SECURITY_PASSWORD_SALT")
app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv("SQLALCHEMY_DATABASE_URI")
app.config["MYCOPYRIGHT"] = {
"year": os.getenv("COPYRIGHT_YEAR"),
"name": os.getenv("COPYRIGHT_NAME"),
"link": os.getenv("COPYRIGHT_LINK"),
"city": os.getenv("COPYRIGHT_CITY"),
}
app.config["BRAND"] = os.getenv("BRAND")
else:
app.config.from_mapping(test_config)
@ -98,6 +108,14 @@ def create_app(test_config=None):
name="Включаемые в html заголовки",
)
)
admin.add_view(
FooterLinksView(
FooterContactLinks,
db.session,
category="Страницы",
name="Иконки-ссылки футера",
)
)
from pyproger.blog.blog import bp as bp_blog
from pyproger.cli.commands import bp_cli
@ -110,11 +128,27 @@ def create_app(test_config=None):
app.register_blueprint(bp_robots)
with app.app_context():
site_headers = get_headers()
try:
site_headers = get_headers()
except Exception as e:
print(e)
site_headers = None
app.config["SITE_HEADERS"] = site_headers
menu_items = get_menu_items()
try:
menu_items = get_menu_items()
except Exception as e:
print(e)
menu_items = None
app.config["MENU_ITEMS"] = menu_items
try:
links = get_footer_links()
except Exception as e:
print(e)
links = None
app.config["MYLINKS"] = links
@security.context_processor
def security_context_processor():
return dict(

View File

@ -1,20 +1,7 @@
import os
# Настройки блога
BRAND = "блог"
MYCOPYRIGHT = {
"year": "2023",
"name": "Иванов Иван",
"link": "http://yandex.ru",
"city": "г.Москва",
}
MYLINKS = (
{"icon": "fab fa-telegram", "link": "https://t.me"},
{"icon": "fab fa-vk", "link": "https://m.vk.com"},
{"icon": "fab fa-yandex", "link": "mailto:user@yandex.ru"},
{"icon": "fab fa-github", "link": "https://github.com"},
)
POSTS_ON_PAGE = 6
MYLIPOSTS_ON_PAGE = 6
# Тема оформления админ панели
FLASK_ADMIN_SWATCH = "slate"

View File

@ -1,5 +1,5 @@
from . import db
from .models import Page, Post, SiteHeaders, Tag, User
from .models import FooterContactLinks, Page, Post, SiteHeaders, Tag, User
def get_paginated_posts(page, per_page):
@ -72,3 +72,11 @@ def get_headers():
.all()
)
return headers
def get_footer_links():
links = db.session.query(
FooterContactLinks.link,
FooterContactLinks.bootstrap_ico,
).all()
return links

View File

@ -122,3 +122,17 @@ class SiteHeaders(db.Model):
description = Column(Text)
content = Column(Text)
enabled = Column(Boolean, default=False)
class FooterContactLinks(db.Model):
__tablename__ = "footer_icons"
id = Column(
Integer,
primary_key=True,
nullable=False,
unique=True,
autoincrement=True,
)
name = Column(String(30))
bootstrap_ico = Column(String(20))
link = Column(String(100))

View File

@ -71,7 +71,7 @@
<a class="btn btn-outline-light btn-floating m-2"
href="{{ l.link }}"
role="button"
><i class="{{ l.icon }}"></i
><i class="{{ l.bootstrap_ico }}"></i
></a>
{% endfor %}
</section>