mirror of
https://github.com/lucaspalomodevelop/eventcally.git
synced 2026-03-13 00:07:22 +00:00
parent
d63f340384
commit
273b3fb072
14
.flake8
Normal file
14
.flake8
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
[flake8]
|
||||||
|
extend-ignore = E501, E203
|
||||||
|
exclude =
|
||||||
|
.git,
|
||||||
|
.github,
|
||||||
|
.pytest_cache,
|
||||||
|
.vscode,
|
||||||
|
__pycache__,
|
||||||
|
doc,
|
||||||
|
env,
|
||||||
|
tmp
|
||||||
|
per-file-ignores =
|
||||||
|
__init__.py: F401, E402
|
||||||
|
migrations/*: F401, E402
|
||||||
12
.github/workflows/lint.yml
vendored
Normal file
12
.github/workflows/lint.yml
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
name: Lint
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
- uses: psf/black@stable
|
||||||
|
- uses: TrueBrain/actions-flake8@v1.4.1
|
||||||
10
.pre-commit-config.yaml
Normal file
10
.pre-commit-config.yaml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
repos:
|
||||||
|
- repo: https://github.com/psf/black
|
||||||
|
rev: stable
|
||||||
|
hooks:
|
||||||
|
- id: black
|
||||||
|
language_version: python3.7
|
||||||
|
- repo: https://gitlab.com/pycqa/flake8
|
||||||
|
rev: 3.8.4
|
||||||
|
hooks:
|
||||||
|
- id: flake8
|
||||||
@ -15,4 +15,6 @@ before_script:
|
|||||||
- psql -c 'create database gsevpt_tests;' -U postgres
|
- psql -c 'create database gsevpt_tests;' -U postgres
|
||||||
- psql -c 'create extension postgis;' -U postgres -d gsevpt_tests
|
- psql -c 'create extension postgis;' -U postgres -d gsevpt_tests
|
||||||
script:
|
script:
|
||||||
- pytest
|
- pytest --cov=project
|
||||||
|
after_success:
|
||||||
|
— coveralls
|
||||||
|
|||||||
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@ -1,3 +1,7 @@
|
|||||||
{
|
{
|
||||||
"python.pythonPath": "/Users/daniel/Projects/gsevpt/env/bin/python3"
|
"python.pythonPath": "/Users/daniel/Projects/gsevpt/env/bin/python3",
|
||||||
|
"python.formatting.provider": "black",
|
||||||
|
"python.linting.enabled": true,
|
||||||
|
"python.linting.pylintEnabled": false,
|
||||||
|
"python.linting.flake8Enabled": true
|
||||||
}
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
[](https://travis-ci.com/DanielGrams/gsevpt)
|
|
||||||
|
|
||||||
# Goslar Event Prototype
|
# Goslar Event Prototype
|
||||||
|
|
||||||
|
[](https://travis-ci.com/DanielGrams/gsevpt) [](https://coveralls.io/github/DanielGrams/gsevpt?branch=master) [](https://github.com/psf/black)
|
||||||
|
|
||||||
Website prototype using Python, Flask and Postgres running on Heroku.
|
Website prototype using Python, Flask and Postgres running on Heroku.
|
||||||
|
|
||||||
## Automatic Deployment
|
## Automatic Deployment
|
||||||
@ -67,4 +67,4 @@ Create `.env` file in the root directory or pass as environment variables.
|
|||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
[Development](doc/development.md)
|
[Development](doc/development.md)
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
from project import app
|
from project import app # noqa: F401
|
||||||
|
|||||||
@ -15,6 +15,12 @@ psql -c 'create extension postgis;' -d gsevpt_tests -U postgres
|
|||||||
pytest
|
pytest
|
||||||
```
|
```
|
||||||
|
|
||||||
|
With coverage:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
pytest --cov-report=html --cov=project
|
||||||
|
```
|
||||||
|
|
||||||
## Database
|
## Database
|
||||||
|
|
||||||
### Create new revision
|
### Create new revision
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
from flask_script import Manager, Command
|
from flask_script import Manager
|
||||||
from flask_migrate import Migrate, MigrateCommand
|
from flask_migrate import Migrate, MigrateCommand
|
||||||
from project import app, db
|
from project import app, db
|
||||||
|
|
||||||
migrate = Migrate(app, db)
|
migrate = Migrate(app, db)
|
||||||
manager = Manager(app)
|
manager = Manager(app)
|
||||||
|
|
||||||
manager.add_command('db', MigrateCommand)
|
manager.add_command("db", MigrateCommand)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
manager.run()
|
manager.run()
|
||||||
|
|||||||
@ -15,17 +15,19 @@ config = context.config
|
|||||||
# Interpret the config file for Python logging.
|
# Interpret the config file for Python logging.
|
||||||
# This line sets up loggers basically.
|
# This line sets up loggers basically.
|
||||||
fileConfig(config.config_file_name)
|
fileConfig(config.config_file_name)
|
||||||
logger = logging.getLogger('alembic.env')
|
logger = logging.getLogger("alembic.env")
|
||||||
|
|
||||||
# add your model's MetaData object here
|
# add your model's MetaData object here
|
||||||
# for 'autogenerate' support
|
# for 'autogenerate' support
|
||||||
# from myapp import mymodel
|
# from myapp import mymodel
|
||||||
# target_metadata = mymodel.Base.metadata
|
# target_metadata = mymodel.Base.metadata
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
|
||||||
config.set_main_option(
|
config.set_main_option(
|
||||||
'sqlalchemy.url',
|
"sqlalchemy.url",
|
||||||
str(current_app.extensions['migrate'].db.engine.url).replace('%', '%%'))
|
str(current_app.extensions["migrate"].db.engine.url).replace("%", "%%"),
|
||||||
target_metadata = current_app.extensions['migrate'].db.metadata
|
)
|
||||||
|
target_metadata = current_app.extensions["migrate"].db.metadata
|
||||||
|
|
||||||
# other values from the config, defined by the needs of env.py,
|
# other values from the config, defined by the needs of env.py,
|
||||||
# can be acquired:
|
# can be acquired:
|
||||||
@ -46,9 +48,7 @@ def run_migrations_offline():
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
url = config.get_main_option("sqlalchemy.url")
|
url = config.get_main_option("sqlalchemy.url")
|
||||||
context.configure(
|
context.configure(url=url, target_metadata=target_metadata, literal_binds=True)
|
||||||
url=url, target_metadata=target_metadata, literal_binds=True
|
|
||||||
)
|
|
||||||
|
|
||||||
with context.begin_transaction():
|
with context.begin_transaction():
|
||||||
context.run_migrations()
|
context.run_migrations()
|
||||||
@ -66,15 +66,15 @@ def run_migrations_online():
|
|||||||
# when there are no changes to the schema
|
# when there are no changes to the schema
|
||||||
# reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
|
# reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
|
||||||
def process_revision_directives(context, revision, directives):
|
def process_revision_directives(context, revision, directives):
|
||||||
if getattr(config.cmd_opts, 'autogenerate', False):
|
if getattr(config.cmd_opts, "autogenerate", False):
|
||||||
script = directives[0]
|
script = directives[0]
|
||||||
if script.upgrade_ops.is_empty():
|
if script.upgrade_ops.is_empty():
|
||||||
directives[:] = []
|
directives[:] = []
|
||||||
logger.info('No changes in schema detected.')
|
logger.info("No changes in schema detected.")
|
||||||
|
|
||||||
connectable = engine_from_config(
|
connectable = engine_from_config(
|
||||||
config.get_section(config.config_ini_section),
|
config.get_section(config.config_ini_section),
|
||||||
prefix='sqlalchemy.',
|
prefix="sqlalchemy.",
|
||||||
poolclass=pool.NullPool,
|
poolclass=pool.NullPool,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -83,7 +83,7 @@ def run_migrations_online():
|
|||||||
connection=connection,
|
connection=connection,
|
||||||
target_metadata=target_metadata,
|
target_metadata=target_metadata,
|
||||||
process_revision_directives=process_revision_directives,
|
process_revision_directives=process_revision_directives,
|
||||||
**current_app.extensions['migrate'].configure_args
|
**current_app.extensions["migrate"].configure_args
|
||||||
)
|
)
|
||||||
|
|
||||||
with context.begin_transaction():
|
with context.begin_transaction():
|
||||||
|
|||||||
@ -12,31 +12,50 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '00daa8c472ba'
|
revision = "00daa8c472ba"
|
||||||
down_revision = '50337ecd23db'
|
down_revision = "50337ecd23db"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
#op.drop_table('spatial_ref_sys')
|
# op.drop_table('spatial_ref_sys')
|
||||||
op.drop_constraint('eventsuggestion_event_id_fkey', 'eventsuggestion', type_='foreignkey')
|
op.drop_constraint(
|
||||||
op.create_foreign_key(None, 'eventsuggestion', 'event', ['event_id'], ['id'], ondelete='SET NULL')
|
"eventsuggestion_event_id_fkey", "eventsuggestion", type_="foreignkey"
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
None, "eventsuggestion", "event", ["event_id"], ["id"], ondelete="SET NULL"
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_constraint(None, 'eventsuggestion', type_='foreignkey')
|
op.drop_constraint(None, "eventsuggestion", type_="foreignkey")
|
||||||
op.create_foreign_key('eventsuggestion_event_id_fkey', 'eventsuggestion', 'event', ['event_id'], ['id'])
|
op.create_foreign_key(
|
||||||
op.create_table('spatial_ref_sys',
|
"eventsuggestion_event_id_fkey",
|
||||||
sa.Column('srid', sa.INTEGER(), autoincrement=False, nullable=False),
|
"eventsuggestion",
|
||||||
sa.Column('auth_name', sa.VARCHAR(length=256), autoincrement=False, nullable=True),
|
"event",
|
||||||
sa.Column('auth_srid', sa.INTEGER(), autoincrement=False, nullable=True),
|
["event_id"],
|
||||||
sa.Column('srtext', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
["id"],
|
||||||
sa.Column('proj4text', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
)
|
||||||
sa.CheckConstraint('(srid > 0) AND (srid <= 998999)', name='spatial_ref_sys_srid_check'),
|
op.create_table(
|
||||||
sa.PrimaryKeyConstraint('srid', name='spatial_ref_sys_pkey')
|
"spatial_ref_sys",
|
||||||
|
sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
|
sa.Column(
|
||||||
|
"auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column(
|
||||||
|
"srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.CheckConstraint(
|
||||||
|
"(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,68 +12,117 @@ from project import dbtypes
|
|||||||
from project.models import EventRejectionReason, EventReviewStatus
|
from project.models import EventRejectionReason, EventReviewStatus
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '021f602d9965'
|
revision = "021f602d9965"
|
||||||
down_revision = '92f37474ad62'
|
down_revision = "92f37474ad62"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('eventsuggestion',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"eventsuggestion",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('name', sa.Unicode(length=255), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('start', sa.DateTime(timezone=True), nullable=False),
|
sa.Column("name", sa.Unicode(length=255), nullable=False),
|
||||||
sa.Column('description', sa.UnicodeText(), nullable=True),
|
sa.Column("start", sa.DateTime(timezone=True), nullable=False),
|
||||||
sa.Column('external_link', sa.String(length=255), nullable=True),
|
sa.Column("description", sa.UnicodeText(), nullable=True),
|
||||||
sa.Column('review_status', dbtypes.IntegerEnum(EventReviewStatus), nullable=True),
|
sa.Column("external_link", sa.String(length=255), nullable=True),
|
||||||
sa.Column('rejection_resaon', dbtypes.IntegerEnum(EventRejectionReason), nullable=True),
|
sa.Column(
|
||||||
sa.Column('contact_name', sa.Unicode(length=255), nullable=False),
|
"review_status", dbtypes.IntegerEnum(EventReviewStatus), nullable=True
|
||||||
sa.Column('contact_email', sa.Unicode(length=255), nullable=True),
|
),
|
||||||
sa.Column('contact_phone', sa.Unicode(length=255), nullable=True),
|
sa.Column(
|
||||||
sa.Column('admin_unit_id', sa.Integer(), nullable=False),
|
"rejection_resaon", dbtypes.IntegerEnum(EventRejectionReason), nullable=True
|
||||||
sa.Column('event_place_id', sa.Integer(), nullable=True),
|
),
|
||||||
sa.Column('event_place_text', sa.Unicode(length=255), nullable=True),
|
sa.Column("contact_name", sa.Unicode(length=255), nullable=False),
|
||||||
sa.Column('organizer_id', sa.Integer(), nullable=True),
|
sa.Column("contact_email", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('organizer_text', sa.Unicode(length=255), nullable=True),
|
sa.Column("contact_phone", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('photo_id', sa.Integer(), nullable=True),
|
sa.Column("admin_unit_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
sa.Column("event_place_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], ),
|
sa.Column("event_place_text", sa.Unicode(length=255), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
sa.Column("organizer_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['event_place_id'], ['eventplace.id'], ),
|
sa.Column("organizer_text", sa.Unicode(length=255), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['organizer_id'], ['eventorganizer.id'], ),
|
sa.Column("photo_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['photo_id'], ['image.id'], ),
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.ForeignKeyConstraint(
|
||||||
|
["admin_unit_id"],
|
||||||
|
["adminunit.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["event_place_id"],
|
||||||
|
["eventplace.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["organizer_id"],
|
||||||
|
["eventorganizer.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["photo_id"],
|
||||||
|
["image.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
#op.drop_table('spatial_ref_sys')
|
# op.drop_table('spatial_ref_sys')
|
||||||
op.drop_constraint('event_contact_id_fkey', 'event', type_='foreignkey')
|
op.drop_constraint("event_contact_id_fkey", "event", type_="foreignkey")
|
||||||
op.drop_column('event', 'review_status')
|
op.drop_column("event", "review_status")
|
||||||
op.drop_column('event', 'rejection_resaon')
|
op.drop_column("event", "rejection_resaon")
|
||||||
op.drop_column('event', 'contact_id')
|
op.drop_column("event", "contact_id")
|
||||||
op.drop_column('eventcontact', 'email')
|
op.drop_column("eventcontact", "email")
|
||||||
op.drop_column('eventcontact', 'name')
|
op.drop_column("eventcontact", "name")
|
||||||
op.drop_column('eventcontact', 'phone')
|
op.drop_column("eventcontact", "phone")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('eventcontact', sa.Column('phone', sa.VARCHAR(length=255), autoincrement=False, nullable=True))
|
op.add_column(
|
||||||
op.add_column('eventcontact', sa.Column('name', sa.VARCHAR(length=255), autoincrement=False, nullable=False))
|
"eventcontact",
|
||||||
op.add_column('eventcontact', sa.Column('email', sa.VARCHAR(length=255), autoincrement=False, nullable=True))
|
sa.Column("phone", sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||||
op.add_column('event', sa.Column('contact_id', sa.INTEGER(), autoincrement=False, nullable=True))
|
|
||||||
op.add_column('event', sa.Column('rejection_resaon', sa.INTEGER(), autoincrement=False, nullable=True))
|
|
||||||
op.add_column('event', sa.Column('review_status', sa.INTEGER(), autoincrement=False, nullable=True))
|
|
||||||
op.create_foreign_key('event_contact_id_fkey', 'event', 'eventcontact', ['contact_id'], ['id'])
|
|
||||||
op.create_table('spatial_ref_sys',
|
|
||||||
sa.Column('srid', sa.INTEGER(), autoincrement=False, nullable=False),
|
|
||||||
sa.Column('auth_name', sa.VARCHAR(length=256), autoincrement=False, nullable=True),
|
|
||||||
sa.Column('auth_srid', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
||||||
sa.Column('srtext', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
|
||||||
sa.Column('proj4text', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
|
||||||
sa.CheckConstraint('(srid > 0) AND (srid <= 998999)', name='spatial_ref_sys_srid_check'),
|
|
||||||
sa.PrimaryKeyConstraint('srid', name='spatial_ref_sys_pkey')
|
|
||||||
)
|
)
|
||||||
op.drop_table('eventsuggestion')
|
op.add_column(
|
||||||
|
"eventcontact",
|
||||||
|
sa.Column("name", sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"eventcontact",
|
||||||
|
sa.Column("email", sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"event",
|
||||||
|
sa.Column("contact_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"event",
|
||||||
|
sa.Column("rejection_resaon", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"event",
|
||||||
|
sa.Column("review_status", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
)
|
||||||
|
op.create_foreign_key(
|
||||||
|
"event_contact_id_fkey", "event", "eventcontact", ["contact_id"], ["id"]
|
||||||
|
)
|
||||||
|
op.create_table(
|
||||||
|
"spatial_ref_sys",
|
||||||
|
sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
|
sa.Column(
|
||||||
|
"auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column(
|
||||||
|
"srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.CheckConstraint(
|
||||||
|
"(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
|
||||||
|
)
|
||||||
|
op.drop_table("eventsuggestion")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -8,14 +8,12 @@ Create Date: 2020-10-02 09:29:12.932229
|
|||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from sqlalchemy.sql import text
|
from sqlalchemy.sql import text
|
||||||
import sqlalchemy_utils
|
|
||||||
from project import dbtypes
|
|
||||||
from geoalchemy2.types import Geometry
|
from geoalchemy2.types import Geometry
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '091deace5f08'
|
revision = "091deace5f08"
|
||||||
down_revision = '6b7016f73688'
|
down_revision = "6b7016f73688"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
@ -26,21 +24,39 @@ def upgrade():
|
|||||||
bind.execute(text("create extension if not exists postgis;"))
|
bind.execute(text("create extension if not exists postgis;"))
|
||||||
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
#op.drop_table('spatial_ref_sys')
|
# op.drop_table('spatial_ref_sys')
|
||||||
op.add_column('location', sa.Column('coordinate', Geometry(geometry_type='POINT', from_text='ST_GeomFromEWKT', name='geometry'), nullable=True))
|
op.add_column(
|
||||||
|
"location",
|
||||||
|
sa.Column(
|
||||||
|
"coordinate",
|
||||||
|
Geometry(
|
||||||
|
geometry_type="POINT", from_text="ST_GeomFromEWKT", name="geometry"
|
||||||
|
),
|
||||||
|
nullable=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('location', 'coordinate')
|
op.drop_column("location", "coordinate")
|
||||||
op.create_table('spatial_ref_sys',
|
op.create_table(
|
||||||
sa.Column('srid', sa.INTEGER(), autoincrement=False, nullable=False),
|
"spatial_ref_sys",
|
||||||
sa.Column('auth_name', sa.VARCHAR(length=256), autoincrement=False, nullable=True),
|
sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
sa.Column('auth_srid', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.Column(
|
||||||
sa.Column('srtext', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
"auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
|
||||||
sa.Column('proj4text', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
),
|
||||||
sa.CheckConstraint('(srid > 0) AND (srid <= 998999)', name='spatial_ref_sys_srid_check'),
|
sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.PrimaryKeyConstraint('srid', name='spatial_ref_sys_pkey')
|
sa.Column(
|
||||||
|
"srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.CheckConstraint(
|
||||||
|
"(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,35 +12,48 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '0a282a331e35'
|
revision = "0a282a331e35"
|
||||||
down_revision = 'da63ba1d58b1'
|
down_revision = "da63ba1d58b1"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
#op.drop_table('spatial_ref_sys')
|
# op.drop_table('spatial_ref_sys')
|
||||||
op.add_column('event', sa.Column('booked_up', sa.Boolean(), nullable=True))
|
op.add_column("event", sa.Column("booked_up", sa.Boolean(), nullable=True))
|
||||||
op.add_column('event', sa.Column('expected_participants', sa.Integer(), nullable=True))
|
op.add_column(
|
||||||
op.add_column('event', sa.Column('price_info', sa.UnicodeText(), nullable=True))
|
"event", sa.Column("expected_participants", sa.Integer(), nullable=True)
|
||||||
op.add_column('event', sa.Column('registration_required', sa.Boolean(), nullable=True))
|
)
|
||||||
|
op.add_column("event", sa.Column("price_info", sa.UnicodeText(), nullable=True))
|
||||||
|
op.add_column(
|
||||||
|
"event", sa.Column("registration_required", sa.Boolean(), nullable=True)
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('event', 'registration_required')
|
op.drop_column("event", "registration_required")
|
||||||
op.drop_column('event', 'price_info')
|
op.drop_column("event", "price_info")
|
||||||
op.drop_column('event', 'expected_participants')
|
op.drop_column("event", "expected_participants")
|
||||||
op.drop_column('event', 'booked_up')
|
op.drop_column("event", "booked_up")
|
||||||
op.create_table('spatial_ref_sys',
|
op.create_table(
|
||||||
sa.Column('srid', sa.INTEGER(), autoincrement=False, nullable=False),
|
"spatial_ref_sys",
|
||||||
sa.Column('auth_name', sa.VARCHAR(length=256), autoincrement=False, nullable=True),
|
sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
sa.Column('auth_srid', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.Column(
|
||||||
sa.Column('srtext', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
"auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
|
||||||
sa.Column('proj4text', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
),
|
||||||
sa.CheckConstraint('(srid > 0) AND (srid <= 998999)', name='spatial_ref_sys_srid_check'),
|
sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.PrimaryKeyConstraint('srid', name='spatial_ref_sys_pkey')
|
sa.Column(
|
||||||
|
"srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.CheckConstraint(
|
||||||
|
"(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -8,39 +8,70 @@ Create Date: 2020-11-08 16:14:01.866196
|
|||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
import sqlalchemy_utils
|
import sqlalchemy_utils
|
||||||
from project import dbtypes
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '27da3ceea723'
|
revision = "27da3ceea723"
|
||||||
down_revision = '00daa8c472ba'
|
down_revision = "00daa8c472ba"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
#op.drop_table('spatial_ref_sys')
|
# op.drop_table('spatial_ref_sys')
|
||||||
op.add_column('adminunit', sa.Column('widget_background_color', sqlalchemy_utils.types.color.ColorType(length=20), nullable=True))
|
op.add_column(
|
||||||
op.add_column('adminunit', sa.Column('widget_font', sa.Unicode(length=255), nullable=True))
|
"adminunit",
|
||||||
op.add_column('adminunit', sa.Column('widget_link_color', sqlalchemy_utils.types.color.ColorType(length=20), nullable=True))
|
sa.Column(
|
||||||
op.add_column('adminunit', sa.Column('widget_primary_color', sqlalchemy_utils.types.color.ColorType(length=20), nullable=True))
|
"widget_background_color",
|
||||||
|
sqlalchemy_utils.types.color.ColorType(length=20),
|
||||||
|
nullable=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"adminunit", sa.Column("widget_font", sa.Unicode(length=255), nullable=True)
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"adminunit",
|
||||||
|
sa.Column(
|
||||||
|
"widget_link_color",
|
||||||
|
sqlalchemy_utils.types.color.ColorType(length=20),
|
||||||
|
nullable=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"adminunit",
|
||||||
|
sa.Column(
|
||||||
|
"widget_primary_color",
|
||||||
|
sqlalchemy_utils.types.color.ColorType(length=20),
|
||||||
|
nullable=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('adminunit', 'widget_primary_color')
|
op.drop_column("adminunit", "widget_primary_color")
|
||||||
op.drop_column('adminunit', 'widget_link_color')
|
op.drop_column("adminunit", "widget_link_color")
|
||||||
op.drop_column('adminunit', 'widget_font')
|
op.drop_column("adminunit", "widget_font")
|
||||||
op.drop_column('adminunit', 'widget_background_color')
|
op.drop_column("adminunit", "widget_background_color")
|
||||||
op.create_table('spatial_ref_sys',
|
op.create_table(
|
||||||
sa.Column('srid', sa.INTEGER(), autoincrement=False, nullable=False),
|
"spatial_ref_sys",
|
||||||
sa.Column('auth_name', sa.VARCHAR(length=256), autoincrement=False, nullable=True),
|
sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
sa.Column('auth_srid', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.Column(
|
||||||
sa.Column('srtext', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
"auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
|
||||||
sa.Column('proj4text', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
),
|
||||||
sa.CheckConstraint('(srid > 0) AND (srid <= 998999)', name='spatial_ref_sys_srid_check'),
|
sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.PrimaryKeyConstraint('srid', name='spatial_ref_sys_pkey')
|
sa.Column(
|
||||||
|
"srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.CheckConstraint(
|
||||||
|
"(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -13,49 +13,65 @@ from project import dbtypes
|
|||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '3c5b34fd1156'
|
revision = "3c5b34fd1156"
|
||||||
down_revision = '27da3ceea723'
|
down_revision = "27da3ceea723"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
class Event(Base):
|
class Event(Base):
|
||||||
__tablename__ = 'event'
|
__tablename__ = "event"
|
||||||
id = sa.Column(sa.Integer(), primary_key=True)
|
id = sa.Column(sa.Integer(), primary_key=True)
|
||||||
category_id = sa.Column(sa.Integer, sa.ForeignKey('eventcategory.id'), nullable=False)
|
category_id = sa.Column(
|
||||||
category = orm.relationship('EventCategory', uselist=False)
|
sa.Integer, sa.ForeignKey("eventcategory.id"), nullable=False
|
||||||
categories = orm.relationship('EventCategory', secondary='event_eventcategories')
|
)
|
||||||
|
category = orm.relationship("EventCategory", uselist=False)
|
||||||
|
categories = orm.relationship("EventCategory", secondary="event_eventcategories")
|
||||||
|
|
||||||
|
|
||||||
class EventEventCategories(Base):
|
class EventEventCategories(Base):
|
||||||
__tablename__ = 'event_eventcategories'
|
__tablename__ = "event_eventcategories"
|
||||||
id = sa.Column(sa.Integer(), primary_key=True)
|
id = sa.Column(sa.Integer(), primary_key=True)
|
||||||
event_id = sa.Column(sa.Integer, sa.ForeignKey('event.id'), nullable=False)
|
event_id = sa.Column(sa.Integer, sa.ForeignKey("event.id"), nullable=False)
|
||||||
category_id = sa.Column(sa.Integer, sa.ForeignKey('eventcategory.id'), nullable=False)
|
category_id = sa.Column(
|
||||||
|
sa.Integer, sa.ForeignKey("eventcategory.id"), nullable=False
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class EventCategory(Base):
|
class EventCategory(Base):
|
||||||
__tablename__ = 'eventcategory'
|
__tablename__ = "eventcategory"
|
||||||
id = sa.Column(sa.Integer(), primary_key=True)
|
id = sa.Column(sa.Integer(), primary_key=True)
|
||||||
name = sa.Column(sa.Unicode(255), nullable=False, unique=True)
|
name = sa.Column(sa.Unicode(255), nullable=False, unique=True)
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('event_eventcategories',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"event_eventcategories",
|
||||||
sa.Column('event_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('category_id', sa.Integer(), nullable=False),
|
sa.Column("event_id", sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['category_id'], ['eventcategory.id'], ),
|
sa.Column("category_id", sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['event_id'], ['event.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.PrimaryKeyConstraint('id')
|
["category_id"],
|
||||||
|
["eventcategory.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["event_id"],
|
||||||
|
["event.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
|
|
||||||
migrate_category_to_categories()
|
migrate_category_to_categories()
|
||||||
|
|
||||||
#op.drop_table('spatial_ref_sys')
|
# op.drop_table('spatial_ref_sys')
|
||||||
op.drop_constraint('event_category_id_fkey', 'event', type_='foreignkey')
|
op.drop_constraint("event_category_id_fkey", "event", type_="foreignkey")
|
||||||
op.drop_column('event', 'category_id')
|
op.drop_column("event", "category_id")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def migrate_category_to_categories():
|
def migrate_category_to_categories():
|
||||||
bind = op.get_bind()
|
bind = op.get_bind()
|
||||||
session = orm.Session(bind=bind)
|
session = orm.Session(bind=bind)
|
||||||
@ -65,18 +81,33 @@ def migrate_category_to_categories():
|
|||||||
|
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('event', sa.Column('category_id', sa.INTEGER(), autoincrement=False, nullable=False))
|
op.add_column(
|
||||||
op.create_foreign_key('event_category_id_fkey', 'event', 'eventcategory', ['category_id'], ['id'])
|
"event",
|
||||||
op.create_table('spatial_ref_sys',
|
sa.Column("category_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
sa.Column('srid', sa.INTEGER(), autoincrement=False, nullable=False),
|
|
||||||
sa.Column('auth_name', sa.VARCHAR(length=256), autoincrement=False, nullable=True),
|
|
||||||
sa.Column('auth_srid', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
||||||
sa.Column('srtext', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
|
||||||
sa.Column('proj4text', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
|
||||||
sa.CheckConstraint('(srid > 0) AND (srid <= 998999)', name='spatial_ref_sys_srid_check'),
|
|
||||||
sa.PrimaryKeyConstraint('srid', name='spatial_ref_sys_pkey')
|
|
||||||
)
|
)
|
||||||
op.drop_table('event_eventcategories')
|
op.create_foreign_key(
|
||||||
|
"event_category_id_fkey", "event", "eventcategory", ["category_id"], ["id"]
|
||||||
|
)
|
||||||
|
op.create_table(
|
||||||
|
"spatial_ref_sys",
|
||||||
|
sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
|
sa.Column(
|
||||||
|
"auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column(
|
||||||
|
"srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.CheckConstraint(
|
||||||
|
"(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
|
||||||
|
)
|
||||||
|
op.drop_table("event_eventcategories")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,21 +12,23 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '41512b20e07c'
|
revision = "41512b20e07c"
|
||||||
down_revision = 'fd7794ece0b3'
|
down_revision = "fd7794ece0b3"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_constraint('event_event_place_id_fkey', 'event', type_='foreignkey')
|
op.drop_constraint("event_event_place_id_fkey", "event", type_="foreignkey")
|
||||||
op.create_foreign_key(None, 'event', 'eventplace', ['event_place_id'], ['id'])
|
op.create_foreign_key(None, "event", "eventplace", ["event_place_id"], ["id"])
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_constraint(None, 'event', type_='foreignkey')
|
op.drop_constraint(None, "event", type_="foreignkey")
|
||||||
op.create_foreign_key('event_event_place_id_fkey', 'event', 'place', ['event_place_id'], ['id'])
|
op.create_foreign_key(
|
||||||
|
"event_event_place_id_fkey", "event", "place", ["event_place_id"], ["id"]
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,25 +12,26 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '4e913af88c33'
|
revision = "4e913af88c33"
|
||||||
down_revision = '67216b6cf293'
|
down_revision = "67216b6cf293"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('analytics',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"analytics",
|
||||||
sa.Column('key', sa.Unicode(length=255), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('value', sa.UnicodeText(), nullable=True),
|
sa.Column("key", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
sa.Column("value", sa.UnicodeText(), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_table('analytics')
|
op.drop_table("analytics")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,31 +12,40 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '50337ecd23db'
|
revision = "50337ecd23db"
|
||||||
down_revision = '6be822396123'
|
down_revision = "6be822396123"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
#op.drop_table('spatial_ref_sys')
|
# op.drop_table('spatial_ref_sys')
|
||||||
op.add_column('eventsuggestion', sa.Column('event_id', sa.Integer(), nullable=True))
|
op.add_column("eventsuggestion", sa.Column("event_id", sa.Integer(), nullable=True))
|
||||||
op.create_foreign_key(None, 'eventsuggestion', 'event', ['event_id'], ['id'])
|
op.create_foreign_key(None, "eventsuggestion", "event", ["event_id"], ["id"])
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_constraint(None, 'eventsuggestion', type_='foreignkey')
|
op.drop_constraint(None, "eventsuggestion", type_="foreignkey")
|
||||||
op.drop_column('eventsuggestion', 'event_id')
|
op.drop_column("eventsuggestion", "event_id")
|
||||||
op.create_table('spatial_ref_sys',
|
op.create_table(
|
||||||
sa.Column('srid', sa.INTEGER(), autoincrement=False, nullable=False),
|
"spatial_ref_sys",
|
||||||
sa.Column('auth_name', sa.VARCHAR(length=256), autoincrement=False, nullable=True),
|
sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
sa.Column('auth_srid', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.Column(
|
||||||
sa.Column('srtext', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
"auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
|
||||||
sa.Column('proj4text', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
),
|
||||||
sa.CheckConstraint('(srid > 0) AND (srid <= 998999)', name='spatial_ref_sys_srid_check'),
|
sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.PrimaryKeyConstraint('srid', name='spatial_ref_sys_pkey')
|
sa.Column(
|
||||||
|
"srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.CheckConstraint(
|
||||||
|
"(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -7,26 +7,26 @@ Create Date: 2020-09-29 15:38:44.033998
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
import sqlalchemy_utils
|
|
||||||
from project import dbtypes
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '51c47c7f0bdb'
|
revision = "51c47c7f0bdb"
|
||||||
down_revision = '7afc40e11791'
|
down_revision = "7afc40e11791"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('featuredevent', sa.Column('admin_unit_id', sa.Integer(), nullable=False))
|
op.add_column(
|
||||||
op.create_foreign_key(None, 'featuredevent', 'adminunit', ['admin_unit_id'], ['id'])
|
"featuredevent", sa.Column("admin_unit_id", sa.Integer(), nullable=False)
|
||||||
|
)
|
||||||
|
op.create_foreign_key(None, "featuredevent", "adminunit", ["admin_unit_id"], ["id"])
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_constraint(None, 'featuredevent', type_='foreignkey')
|
op.drop_constraint(None, "featuredevent", type_="foreignkey")
|
||||||
op.drop_column('featuredevent', 'admin_unit_id')
|
op.drop_column("featuredevent", "admin_unit_id")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -7,26 +7,26 @@ Create Date: 2020-07-13 19:01:04.770613
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
import sqlalchemy_utils
|
|
||||||
from project import dbtypes
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '5c8457f2eac1'
|
revision = "5c8457f2eac1"
|
||||||
down_revision = 'ed6bb2084bbd'
|
down_revision = "ed6bb2084bbd"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('event', sa.Column('end', sa.DateTime(timezone=True), nullable=True))
|
op.add_column("event", sa.Column("end", sa.DateTime(timezone=True), nullable=True))
|
||||||
op.add_column('event', sa.Column('start', sa.DateTime(timezone=True), nullable=True))
|
op.add_column(
|
||||||
|
"event", sa.Column("start", sa.DateTime(timezone=True), nullable=True)
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('event', 'start')
|
op.drop_column("event", "start")
|
||||||
op.drop_column('event', 'end')
|
op.drop_column("event", "end")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,29 +12,36 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '62e071b0da50'
|
revision = "62e071b0da50"
|
||||||
down_revision = 'dcd0b71650b0'
|
down_revision = "dcd0b71650b0"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.alter_column('eventorganizer', 'name',
|
op.alter_column(
|
||||||
existing_type=sa.VARCHAR(length=255),
|
"eventorganizer", "name", existing_type=sa.VARCHAR(length=255), nullable=False
|
||||||
nullable=False)
|
)
|
||||||
op.create_unique_constraint(None, 'eventorganizer', ['name', 'admin_unit_id'])
|
op.create_unique_constraint(None, "eventorganizer", ["name", "admin_unit_id"])
|
||||||
op.drop_column('eventorganizer', 'org_name')
|
op.drop_column("eventorganizer", "org_name")
|
||||||
op.create_unique_constraint(None, 'eventplace', ['name', 'organizer_id', 'admin_unit_id'])
|
op.create_unique_constraint(
|
||||||
|
None, "eventplace", ["name", "organizer_id", "admin_unit_id"]
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_constraint(None, 'eventplace', type_='unique')
|
op.drop_constraint(None, "eventplace", type_="unique")
|
||||||
op.add_column('eventorganizer', sa.Column('org_name', sa.VARCHAR(length=255), autoincrement=False, nullable=True))
|
op.add_column(
|
||||||
op.drop_constraint(None, 'eventorganizer', type_='unique')
|
"eventorganizer",
|
||||||
op.alter_column('eventorganizer', 'name',
|
sa.Column(
|
||||||
existing_type=sa.VARCHAR(length=255),
|
"org_name", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||||
nullable=True)
|
),
|
||||||
|
)
|
||||||
|
op.drop_constraint(None, "eventorganizer", type_="unique")
|
||||||
|
op.alter_column(
|
||||||
|
"eventorganizer", "name", existing_type=sa.VARCHAR(length=255), nullable=True
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -7,29 +7,40 @@ Create Date: 2020-08-01 15:43:11.377833
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
import sqlalchemy_utils
|
|
||||||
from project import dbtypes
|
from project import dbtypes
|
||||||
from project.models import EventRejectionReason, EventReviewStatus
|
from project.models import EventRejectionReason, EventReviewStatus
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '67216b6cf293'
|
revision = "67216b6cf293"
|
||||||
down_revision = 'a336ac384c64'
|
down_revision = "a336ac384c64"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('event', sa.Column('rejection_resaon', dbtypes.IntegerEnum(EventRejectionReason), nullable=True))
|
op.add_column(
|
||||||
op.add_column('event', sa.Column('review_status', dbtypes.IntegerEnum(EventReviewStatus), nullable=True))
|
"event",
|
||||||
op.drop_column('event', 'verified')
|
sa.Column(
|
||||||
|
"rejection_resaon", dbtypes.IntegerEnum(EventRejectionReason), nullable=True
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"event",
|
||||||
|
sa.Column(
|
||||||
|
"review_status", dbtypes.IntegerEnum(EventReviewStatus), nullable=True
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.drop_column("event", "verified")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('event', sa.Column('verified', sa.BOOLEAN(), autoincrement=False, nullable=True))
|
op.add_column(
|
||||||
op.drop_column('event', 'review_status')
|
"event", sa.Column("verified", sa.BOOLEAN(), autoincrement=False, nullable=True)
|
||||||
op.drop_column('event', 'rejection_resaon')
|
)
|
||||||
|
op.drop_column("event", "review_status")
|
||||||
|
op.drop_column("event", "rejection_resaon")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,31 +12,37 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '699c4f6a7fe8'
|
revision = "699c4f6a7fe8"
|
||||||
down_revision = 'b1c05324cc13'
|
down_revision = "b1c05324cc13"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('eventorganizer', sa.Column('admin_unit_id', sa.Integer(), nullable=True))
|
op.add_column(
|
||||||
op.create_foreign_key(None, 'eventorganizer', 'adminunit', ['admin_unit_id'], ['id'])
|
"eventorganizer", sa.Column("admin_unit_id", sa.Integer(), nullable=True)
|
||||||
op.add_column('eventplace', sa.Column('admin_unit_id', sa.Integer(), nullable=True))
|
)
|
||||||
op.add_column('eventplace', sa.Column('organizer_id', sa.Integer(), nullable=True))
|
op.create_foreign_key(
|
||||||
op.add_column('eventplace', sa.Column('public', sa.Boolean(), nullable=True))
|
None, "eventorganizer", "adminunit", ["admin_unit_id"], ["id"]
|
||||||
op.create_foreign_key(None, 'eventplace', 'eventorganizer', ['organizer_id'], ['id'])
|
)
|
||||||
op.create_foreign_key(None, 'eventplace', 'adminunit', ['admin_unit_id'], ['id'])
|
op.add_column("eventplace", sa.Column("admin_unit_id", sa.Integer(), nullable=True))
|
||||||
|
op.add_column("eventplace", sa.Column("organizer_id", sa.Integer(), nullable=True))
|
||||||
|
op.add_column("eventplace", sa.Column("public", sa.Boolean(), nullable=True))
|
||||||
|
op.create_foreign_key(
|
||||||
|
None, "eventplace", "eventorganizer", ["organizer_id"], ["id"]
|
||||||
|
)
|
||||||
|
op.create_foreign_key(None, "eventplace", "adminunit", ["admin_unit_id"], ["id"])
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_constraint(None, 'eventplace', type_='foreignkey')
|
op.drop_constraint(None, "eventplace", type_="foreignkey")
|
||||||
op.drop_constraint(None, 'eventplace', type_='foreignkey')
|
op.drop_constraint(None, "eventplace", type_="foreignkey")
|
||||||
op.drop_column('eventplace', 'public')
|
op.drop_column("eventplace", "public")
|
||||||
op.drop_column('eventplace', 'organizer_id')
|
op.drop_column("eventplace", "organizer_id")
|
||||||
op.drop_column('eventplace', 'admin_unit_id')
|
op.drop_column("eventplace", "admin_unit_id")
|
||||||
op.drop_constraint(None, 'eventorganizer', type_='foreignkey')
|
op.drop_constraint(None, "eventorganizer", type_="foreignkey")
|
||||||
op.drop_column('eventorganizer', 'admin_unit_id')
|
op.drop_column("eventorganizer", "admin_unit_id")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,169 +12,321 @@ from project import dbtypes
|
|||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '6b7016f73688'
|
revision = "6b7016f73688"
|
||||||
down_revision = 'a75bd9c8ad3a'
|
down_revision = "a75bd9c8ad3a"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_constraint('event_place_id_fkey', 'event', type_='foreignkey')
|
op.drop_constraint("event_place_id_fkey", "event", type_="foreignkey")
|
||||||
op.drop_constraint('event_host_id_fkey', 'event', type_='foreignkey')
|
op.drop_constraint("event_host_id_fkey", "event", type_="foreignkey")
|
||||||
op.drop_column('event', 'host_id')
|
op.drop_column("event", "host_id")
|
||||||
op.drop_column('event', 'place_id')
|
op.drop_column("event", "place_id")
|
||||||
op.drop_table('eventsuggestiondate')
|
op.drop_table("eventsuggestiondate")
|
||||||
op.drop_table('place')
|
op.drop_table("place")
|
||||||
op.drop_table('org_or_adminunit')
|
op.drop_table("org_or_adminunit")
|
||||||
op.drop_table('actor')
|
op.drop_table("actor")
|
||||||
op.drop_table('adminunitorgroles_organizations')
|
op.drop_table("adminunitorgroles_organizations")
|
||||||
op.drop_table('adminunitorgrole')
|
op.drop_table("adminunitorgrole")
|
||||||
op.drop_table('adminunitorg')
|
op.drop_table("adminunitorg")
|
||||||
op.drop_table('orgmemberroles_members')
|
op.drop_table("orgmemberroles_members")
|
||||||
op.drop_table('orgmember')
|
op.drop_table("orgmember")
|
||||||
op.drop_table('organization')
|
op.drop_table("organization")
|
||||||
op.drop_table('eventsuggestion')
|
op.drop_table("eventsuggestion")
|
||||||
op.drop_table('orgmemberrole')
|
op.drop_table("orgmemberrole")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('event', sa.Column('place_id', sa.INTEGER(), autoincrement=False, nullable=True))
|
op.add_column(
|
||||||
op.add_column('event', sa.Column('host_id', sa.INTEGER(), autoincrement=False, nullable=True))
|
"event", sa.Column("place_id", sa.INTEGER(), autoincrement=False, nullable=True)
|
||||||
op.create_foreign_key('event_host_id_fkey', 'event', 'org_or_adminunit', ['host_id'], ['id'])
|
|
||||||
op.create_foreign_key('event_place_id_fkey', 'event', 'place', ['place_id'], ['id'])
|
|
||||||
op.create_table('orgmemberroles_members',
|
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
|
||||||
sa.Column('member_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
||||||
sa.Column('role_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['member_id'], ['orgmember.id'], name='orgmemberroles_members_member_id_fkey'),
|
|
||||||
sa.ForeignKeyConstraint(['role_id'], ['orgmemberrole.id'], name='orgmemberroles_members_role_id_fkey'),
|
|
||||||
sa.PrimaryKeyConstraint('id', name='orgmemberroles_members_pkey')
|
|
||||||
)
|
)
|
||||||
op.create_table('orgmemberrole',
|
op.add_column(
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
"event", sa.Column("host_id", sa.INTEGER(), autoincrement=False, nullable=True)
|
||||||
sa.Column('name', sa.VARCHAR(length=80), autoincrement=False, nullable=True),
|
|
||||||
sa.Column('description', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
|
||||||
sa.Column('permissions', sa.TEXT(), autoincrement=False, nullable=True),
|
|
||||||
sa.PrimaryKeyConstraint('id', name='orgmemberrole_pkey'),
|
|
||||||
sa.UniqueConstraint('name', name='orgmemberrole_name_key')
|
|
||||||
)
|
)
|
||||||
op.create_table('eventsuggestion',
|
op.create_foreign_key(
|
||||||
sa.Column('created_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
"event_host_id_fkey", "event", "org_or_adminunit", ["host_id"], ["id"]
|
||||||
sa.Column('id', sa.INTEGER(), server_default=sa.text("nextval('eventsuggestion_id_seq'::regclass)"), autoincrement=True, nullable=False),
|
|
||||||
sa.Column('admin_unit_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
|
||||||
sa.Column('host_name', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
|
||||||
sa.Column('event_name', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
|
||||||
sa.Column('description', sa.TEXT(), autoincrement=False, nullable=False),
|
|
||||||
sa.Column('place_name', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
|
||||||
sa.Column('place_street', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
|
||||||
sa.Column('place_postalCode', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
|
||||||
sa.Column('place_city', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
|
||||||
sa.Column('contact_name', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
|
||||||
sa.Column('contact_email', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
|
||||||
sa.Column('external_link', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
|
||||||
sa.Column('created_by_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], name='eventsuggestion_admin_unit_id_fkey'),
|
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], name='eventsuggestion_created_by_id_fkey'),
|
|
||||||
sa.PrimaryKeyConstraint('id', name='eventsuggestion_pkey'),
|
|
||||||
postgresql_ignore_search_path=False
|
|
||||||
)
|
)
|
||||||
op.create_table('orgmember',
|
op.create_foreign_key("event_place_id_fkey", "event", "place", ["place_id"], ["id"])
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
op.create_table(
|
||||||
sa.Column('organization_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
"orgmemberroles_members",
|
||||||
sa.Column('user_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], name='orgmember_organization_id_fkey'),
|
sa.Column("member_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], name='orgmember_user_id_fkey'),
|
sa.Column("role_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id', name='orgmember_pkey')
|
sa.ForeignKeyConstraint(
|
||||||
|
["member_id"],
|
||||||
|
["orgmember.id"],
|
||||||
|
name="orgmemberroles_members_member_id_fkey",
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["role_id"],
|
||||||
|
["orgmemberrole.id"],
|
||||||
|
name="orgmemberroles_members_role_id_fkey",
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id", name="orgmemberroles_members_pkey"),
|
||||||
)
|
)
|
||||||
op.create_table('adminunitorg',
|
op.create_table(
|
||||||
sa.Column('id', sa.INTEGER(), server_default=sa.text("nextval('adminunitorg_id_seq'::regclass)"), autoincrement=True, nullable=False),
|
"orgmemberrole",
|
||||||
sa.Column('admin_unit_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
sa.Column('organization_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
sa.Column("name", sa.VARCHAR(length=80), autoincrement=False, nullable=True),
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], name='adminunitorg_admin_unit_id_fkey'),
|
sa.Column(
|
||||||
sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], name='adminunitorg_organization_id_fkey'),
|
"description", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||||
sa.PrimaryKeyConstraint('id', name='adminunitorg_pkey'),
|
),
|
||||||
postgresql_ignore_search_path=False
|
sa.Column("permissions", sa.TEXT(), autoincrement=False, nullable=True),
|
||||||
|
sa.PrimaryKeyConstraint("id", name="orgmemberrole_pkey"),
|
||||||
|
sa.UniqueConstraint("name", name="orgmemberrole_name_key"),
|
||||||
)
|
)
|
||||||
op.create_table('adminunitorgroles_organizations',
|
op.create_table(
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
"eventsuggestion",
|
||||||
sa.Column('admin_unit_org_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.Column(
|
||||||
sa.Column('role_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
"created_at", postgresql.TIMESTAMP(), autoincrement=False, nullable=True
|
||||||
sa.ForeignKeyConstraint(['admin_unit_org_id'], ['adminunitorg.id'], name='adminunitorgroles_organizations_admin_unit_org_id_fkey'),
|
),
|
||||||
sa.ForeignKeyConstraint(['role_id'], ['adminunitorgrole.id'], name='adminunitorgroles_organizations_role_id_fkey'),
|
sa.Column(
|
||||||
sa.PrimaryKeyConstraint('id', name='adminunitorgroles_organizations_pkey')
|
"id",
|
||||||
|
sa.INTEGER(),
|
||||||
|
server_default=sa.text("nextval('eventsuggestion_id_seq'::regclass)"),
|
||||||
|
autoincrement=True,
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
sa.Column("admin_unit_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
|
sa.Column(
|
||||||
|
"host_name", sa.VARCHAR(length=255), autoincrement=False, nullable=False
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"event_name", sa.VARCHAR(length=255), autoincrement=False, nullable=False
|
||||||
|
),
|
||||||
|
sa.Column("description", sa.TEXT(), autoincrement=False, nullable=False),
|
||||||
|
sa.Column(
|
||||||
|
"place_name", sa.VARCHAR(length=255), autoincrement=False, nullable=False
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"place_street", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"place_postalCode",
|
||||||
|
sa.VARCHAR(length=255),
|
||||||
|
autoincrement=False,
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"place_city", sa.VARCHAR(length=255), autoincrement=False, nullable=False
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"contact_name", sa.VARCHAR(length=255), autoincrement=False, nullable=False
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"contact_email", sa.VARCHAR(length=255), autoincrement=False, nullable=False
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"external_link", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column("created_by_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["admin_unit_id"],
|
||||||
|
["adminunit.id"],
|
||||||
|
name="eventsuggestion_admin_unit_id_fkey",
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"], ["user.id"], name="eventsuggestion_created_by_id_fkey"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id", name="eventsuggestion_pkey"),
|
||||||
|
postgresql_ignore_search_path=False,
|
||||||
)
|
)
|
||||||
op.create_table('organization',
|
op.create_table(
|
||||||
sa.Column('created_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
"orgmember",
|
||||||
sa.Column('id', sa.INTEGER(), server_default=sa.text("nextval('organization_id_seq'::regclass)"), autoincrement=True, nullable=False),
|
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
sa.Column('name', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
sa.Column("organization_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
sa.Column('legal_name', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
sa.Column("user_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
sa.Column('location_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.ForeignKeyConstraint(
|
||||||
sa.Column('logo_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
["organization_id"],
|
||||||
sa.Column('url', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
["organization.id"],
|
||||||
sa.Column('created_by_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
name="orgmember_organization_id_fkey",
|
||||||
sa.Column('email', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
),
|
||||||
sa.Column('phone', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
sa.ForeignKeyConstraint(
|
||||||
sa.Column('fax', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
["user_id"], ["user.id"], name="orgmember_user_id_fkey"
|
||||||
sa.Column('short_name', sa.VARCHAR(length=100), autoincrement=False, nullable=True),
|
),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], name='organization_created_by_id_fkey'),
|
sa.PrimaryKeyConstraint("id", name="orgmember_pkey"),
|
||||||
sa.ForeignKeyConstraint(['location_id'], ['location.id'], name='organization_location_id_fkey'),
|
|
||||||
sa.ForeignKeyConstraint(['logo_id'], ['image.id'], name='organization_logo_id_fkey'),
|
|
||||||
sa.PrimaryKeyConstraint('id', name='organization_pkey'),
|
|
||||||
sa.UniqueConstraint('name', name='organization_name_key'),
|
|
||||||
sa.UniqueConstraint('short_name', name='organization_short_name_key'),
|
|
||||||
postgresql_ignore_search_path=False
|
|
||||||
)
|
)
|
||||||
op.create_table('adminunitorgrole',
|
op.create_table(
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
"adminunitorg",
|
||||||
sa.Column('name', sa.VARCHAR(length=80), autoincrement=False, nullable=True),
|
sa.Column(
|
||||||
sa.Column('description', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
"id",
|
||||||
sa.Column('permissions', sa.TEXT(), autoincrement=False, nullable=True),
|
sa.INTEGER(),
|
||||||
sa.PrimaryKeyConstraint('id', name='adminunitorgrole_pkey'),
|
server_default=sa.text("nextval('adminunitorg_id_seq'::regclass)"),
|
||||||
sa.UniqueConstraint('name', name='adminunitorgrole_name_key')
|
autoincrement=True,
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
sa.Column("admin_unit_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
|
sa.Column("organization_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["admin_unit_id"], ["adminunit.id"], name="adminunitorg_admin_unit_id_fkey"
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["organization_id"],
|
||||||
|
["organization.id"],
|
||||||
|
name="adminunitorg_organization_id_fkey",
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id", name="adminunitorg_pkey"),
|
||||||
|
postgresql_ignore_search_path=False,
|
||||||
)
|
)
|
||||||
op.create_table('actor',
|
op.create_table(
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
"adminunitorgroles_organizations",
|
||||||
sa.Column('user_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
sa.Column('organization_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.Column(
|
||||||
sa.Column('admin_unit_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
"admin_unit_org_id", sa.INTEGER(), autoincrement=False, nullable=True
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], name='actor_admin_unit_id_fkey'),
|
),
|
||||||
sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], name='actor_organization_id_fkey'),
|
sa.Column("role_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], name='actor_user_id_fkey'),
|
sa.ForeignKeyConstraint(
|
||||||
sa.PrimaryKeyConstraint('id', name='actor_pkey'),
|
["admin_unit_org_id"],
|
||||||
sa.UniqueConstraint('user_id', 'organization_id', 'admin_unit_id', name='actor_user_id_organization_id_admin_unit_id_key')
|
["adminunitorg.id"],
|
||||||
|
name="adminunitorgroles_organizations_admin_unit_org_id_fkey",
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["role_id"],
|
||||||
|
["adminunitorgrole.id"],
|
||||||
|
name="adminunitorgroles_organizations_role_id_fkey",
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id", name="adminunitorgroles_organizations_pkey"),
|
||||||
)
|
)
|
||||||
op.create_table('org_or_adminunit',
|
op.create_table(
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
"organization",
|
||||||
sa.Column('organization_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.Column(
|
||||||
sa.Column('admin_unit_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
"created_at", postgresql.TIMESTAMP(), autoincrement=False, nullable=True
|
||||||
sa.CheckConstraint('NOT ((organization_id IS NULL) AND (admin_unit_id IS NULL))', name='org_or_adminunit_check'),
|
),
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], name='org_or_adminunit_admin_unit_id_fkey'),
|
sa.Column(
|
||||||
sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], name='org_or_adminunit_organization_id_fkey'),
|
"id",
|
||||||
sa.PrimaryKeyConstraint('id', name='org_or_adminunit_pkey'),
|
sa.INTEGER(),
|
||||||
sa.UniqueConstraint('organization_id', 'admin_unit_id', name='org_or_adminunit_organization_id_admin_unit_id_key')
|
server_default=sa.text("nextval('organization_id_seq'::regclass)"),
|
||||||
|
autoincrement=True,
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
sa.Column("name", sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||||
|
sa.Column(
|
||||||
|
"legal_name", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column("location_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("logo_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("url", sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("created_by_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("email", sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("phone", sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("fax", sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||||
|
sa.Column(
|
||||||
|
"short_name", sa.VARCHAR(length=100), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"], ["user.id"], name="organization_created_by_id_fkey"
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["location_id"], ["location.id"], name="organization_location_id_fkey"
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["logo_id"], ["image.id"], name="organization_logo_id_fkey"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id", name="organization_pkey"),
|
||||||
|
sa.UniqueConstraint("name", name="organization_name_key"),
|
||||||
|
sa.UniqueConstraint("short_name", name="organization_short_name_key"),
|
||||||
|
postgresql_ignore_search_path=False,
|
||||||
)
|
)
|
||||||
op.create_table('place',
|
op.create_table(
|
||||||
sa.Column('created_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
"adminunitorgrole",
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
sa.Column('name', sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
sa.Column("name", sa.VARCHAR(length=80), autoincrement=False, nullable=True),
|
||||||
sa.Column('location_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.Column(
|
||||||
sa.Column('photo_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
"description", sa.VARCHAR(length=255), autoincrement=False, nullable=True
|
||||||
sa.Column('url', sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
),
|
||||||
sa.Column('description', sa.TEXT(), autoincrement=False, nullable=True),
|
sa.Column("permissions", sa.TEXT(), autoincrement=False, nullable=True),
|
||||||
sa.Column('created_by_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.PrimaryKeyConstraint("id", name="adminunitorgrole_pkey"),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], name='place_created_by_id_fkey'),
|
sa.UniqueConstraint("name", name="adminunitorgrole_name_key"),
|
||||||
sa.ForeignKeyConstraint(['location_id'], ['location.id'], name='place_location_id_fkey'),
|
|
||||||
sa.ForeignKeyConstraint(['photo_id'], ['image.id'], name='place_photo_id_fkey'),
|
|
||||||
sa.PrimaryKeyConstraint('id', name='place_pkey')
|
|
||||||
)
|
)
|
||||||
op.create_table('eventsuggestiondate',
|
op.create_table(
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
"actor",
|
||||||
sa.Column('event_suggestion_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
sa.Column('start', postgresql.TIMESTAMP(timezone=True), autoincrement=False, nullable=False),
|
sa.Column("user_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
sa.ForeignKeyConstraint(['event_suggestion_id'], ['eventsuggestion.id'], name='eventsuggestiondate_event_suggestion_id_fkey'),
|
sa.Column("organization_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id', name='eventsuggestiondate_pkey')
|
sa.Column("admin_unit_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["admin_unit_id"], ["adminunit.id"], name="actor_admin_unit_id_fkey"
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["organization_id"], ["organization.id"], name="actor_organization_id_fkey"
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(["user_id"], ["user.id"], name="actor_user_id_fkey"),
|
||||||
|
sa.PrimaryKeyConstraint("id", name="actor_pkey"),
|
||||||
|
sa.UniqueConstraint(
|
||||||
|
"user_id",
|
||||||
|
"organization_id",
|
||||||
|
"admin_unit_id",
|
||||||
|
name="actor_user_id_organization_id_admin_unit_id_key",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.create_table(
|
||||||
|
"org_or_adminunit",
|
||||||
|
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
|
sa.Column("organization_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("admin_unit_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.CheckConstraint(
|
||||||
|
"NOT ((organization_id IS NULL) AND (admin_unit_id IS NULL))",
|
||||||
|
name="org_or_adminunit_check",
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["admin_unit_id"],
|
||||||
|
["adminunit.id"],
|
||||||
|
name="org_or_adminunit_admin_unit_id_fkey",
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["organization_id"],
|
||||||
|
["organization.id"],
|
||||||
|
name="org_or_adminunit_organization_id_fkey",
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id", name="org_or_adminunit_pkey"),
|
||||||
|
sa.UniqueConstraint(
|
||||||
|
"organization_id",
|
||||||
|
"admin_unit_id",
|
||||||
|
name="org_or_adminunit_organization_id_admin_unit_id_key",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.create_table(
|
||||||
|
"place",
|
||||||
|
sa.Column(
|
||||||
|
"created_at", postgresql.TIMESTAMP(), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
|
sa.Column("name", sa.VARCHAR(length=255), autoincrement=False, nullable=False),
|
||||||
|
sa.Column("location_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("photo_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("url", sa.VARCHAR(length=255), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("description", sa.TEXT(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column("created_by_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"], ["user.id"], name="place_created_by_id_fkey"
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["location_id"], ["location.id"], name="place_location_id_fkey"
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(["photo_id"], ["image.id"], name="place_photo_id_fkey"),
|
||||||
|
sa.PrimaryKeyConstraint("id", name="place_pkey"),
|
||||||
|
)
|
||||||
|
op.create_table(
|
||||||
|
"eventsuggestiondate",
|
||||||
|
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
|
sa.Column(
|
||||||
|
"event_suggestion_id", sa.INTEGER(), autoincrement=False, nullable=False
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"start",
|
||||||
|
postgresql.TIMESTAMP(timezone=True),
|
||||||
|
autoincrement=False,
|
||||||
|
nullable=False,
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["event_suggestion_id"],
|
||||||
|
["eventsuggestion.id"],
|
||||||
|
name="eventsuggestiondate_event_suggestion_id_fkey",
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id", name="eventsuggestiondate_pkey"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,37 +12,54 @@ from project import dbtypes
|
|||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '6be822396123'
|
revision = "6be822396123"
|
||||||
down_revision = '021f602d9965'
|
down_revision = "021f602d9965"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
#op.drop_table('spatial_ref_sys')
|
# op.drop_table('spatial_ref_sys')
|
||||||
op.drop_table('eventcontact')
|
op.drop_table("eventcontact")
|
||||||
op.add_column('eventsuggestion', sa.Column('contact_email_notice', sa.Boolean(), nullable=True))
|
op.add_column(
|
||||||
|
"eventsuggestion",
|
||||||
|
sa.Column("contact_email_notice", sa.Boolean(), nullable=True),
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('eventsuggestion', 'contact_email_notice')
|
op.drop_column("eventsuggestion", "contact_email_notice")
|
||||||
op.create_table('eventcontact',
|
op.create_table(
|
||||||
sa.Column('created_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
"eventcontact",
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
sa.Column(
|
||||||
sa.Column('created_by_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
"created_at", postgresql.TIMESTAMP(), autoincrement=False, nullable=True
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], name='eventcontact_created_by_id_fkey'),
|
),
|
||||||
sa.PrimaryKeyConstraint('id', name='eventcontact_pkey')
|
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
|
sa.Column("created_by_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"], ["user.id"], name="eventcontact_created_by_id_fkey"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id", name="eventcontact_pkey"),
|
||||||
)
|
)
|
||||||
op.create_table('spatial_ref_sys',
|
op.create_table(
|
||||||
sa.Column('srid', sa.INTEGER(), autoincrement=False, nullable=False),
|
"spatial_ref_sys",
|
||||||
sa.Column('auth_name', sa.VARCHAR(length=256), autoincrement=False, nullable=True),
|
sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
sa.Column('auth_srid', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.Column(
|
||||||
sa.Column('srtext', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
"auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
|
||||||
sa.Column('proj4text', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
),
|
||||||
sa.CheckConstraint('(srid > 0) AND (srid <= 998999)', name='spatial_ref_sys_srid_check'),
|
sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.PrimaryKeyConstraint('srid', name='spatial_ref_sys_pkey')
|
sa.Column(
|
||||||
|
"srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.CheckConstraint(
|
||||||
|
"(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -11,35 +11,43 @@ import sqlalchemy_utils
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '75c07cb9cfe3'
|
revision = "75c07cb9cfe3"
|
||||||
down_revision = 'abf0f671ba27'
|
down_revision = "abf0f671ba27"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('adminunit', sa.Column('email', sa.Unicode(length=255), nullable=True))
|
op.add_column(
|
||||||
op.add_column('adminunit', sa.Column('location_id', sa.Integer(), nullable=True))
|
"adminunit", sa.Column("email", sa.Unicode(length=255), nullable=True)
|
||||||
op.add_column('adminunit', sa.Column('logo_id', sa.Integer(), nullable=True))
|
)
|
||||||
op.add_column('adminunit', sa.Column('phone', sa.Unicode(length=255), nullable=True))
|
op.add_column("adminunit", sa.Column("location_id", sa.Integer(), nullable=True))
|
||||||
op.add_column('adminunit', sa.Column('url', sa.String(length=255), nullable=True))
|
op.add_column("adminunit", sa.Column("logo_id", sa.Integer(), nullable=True))
|
||||||
op.create_foreign_key(None, 'adminunit', 'image', ['logo_id'], ['id'])
|
op.add_column(
|
||||||
op.create_foreign_key(None, 'adminunit', 'location', ['location_id'], ['id'])
|
"adminunit", sa.Column("phone", sa.Unicode(length=255), nullable=True)
|
||||||
op.add_column('organization', sa.Column('email', sa.Unicode(length=255), nullable=True))
|
)
|
||||||
op.add_column('organization', sa.Column('phone', sa.Unicode(length=255), nullable=True))
|
op.add_column("adminunit", sa.Column("url", sa.String(length=255), nullable=True))
|
||||||
|
op.create_foreign_key(None, "adminunit", "image", ["logo_id"], ["id"])
|
||||||
|
op.create_foreign_key(None, "adminunit", "location", ["location_id"], ["id"])
|
||||||
|
op.add_column(
|
||||||
|
"organization", sa.Column("email", sa.Unicode(length=255), nullable=True)
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"organization", sa.Column("phone", sa.Unicode(length=255), nullable=True)
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('organization', 'phone')
|
op.drop_column("organization", "phone")
|
||||||
op.drop_column('organization', 'email')
|
op.drop_column("organization", "email")
|
||||||
op.drop_constraint(None, 'adminunit', type_='foreignkey')
|
op.drop_constraint(None, "adminunit", type_="foreignkey")
|
||||||
op.drop_constraint(None, 'adminunit', type_='foreignkey')
|
op.drop_constraint(None, "adminunit", type_="foreignkey")
|
||||||
op.drop_column('adminunit', 'url')
|
op.drop_column("adminunit", "url")
|
||||||
op.drop_column('adminunit', 'phone')
|
op.drop_column("adminunit", "phone")
|
||||||
op.drop_column('adminunit', 'logo_id')
|
op.drop_column("adminunit", "logo_id")
|
||||||
op.drop_column('adminunit', 'location_id')
|
op.drop_column("adminunit", "location_id")
|
||||||
op.drop_column('adminunit', 'email')
|
op.drop_column("adminunit", "email")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -7,38 +7,52 @@ Create Date: 2020-09-28 10:38:46.424791
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
import sqlalchemy_utils
|
|
||||||
from project import dbtypes
|
from project import dbtypes
|
||||||
from project.models import FeaturedEventRejectionReason, FeaturedEventReviewStatus
|
from project.models import FeaturedEventRejectionReason, FeaturedEventReviewStatus
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '7afc40e11791'
|
revision = "7afc40e11791"
|
||||||
down_revision = 'a8c662c46047'
|
down_revision = "a8c662c46047"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('featuredevent',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"featuredevent",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('event_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('review_status', dbtypes.IntegerEnum(FeaturedEventReviewStatus), nullable=True),
|
sa.Column("event_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('rejection_resaon', dbtypes.IntegerEnum(FeaturedEventRejectionReason), nullable=True),
|
sa.Column(
|
||||||
sa.Column('rating', sa.Integer(), nullable=True),
|
"review_status",
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
dbtypes.IntegerEnum(FeaturedEventReviewStatus),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
nullable=True,
|
||||||
sa.ForeignKeyConstraint(['event_id'], ['event.id'], ),
|
),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.Column(
|
||||||
|
"rejection_resaon",
|
||||||
|
dbtypes.IntegerEnum(FeaturedEventRejectionReason),
|
||||||
|
nullable=True,
|
||||||
|
),
|
||||||
|
sa.Column("rating", sa.Integer(), nullable=True),
|
||||||
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["event_id"],
|
||||||
|
["event.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.add_column('event', sa.Column('rating', sa.Integer(), nullable=True))
|
op.add_column("event", sa.Column("rating", sa.Integer(), nullable=True))
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('event', 'rating')
|
op.drop_column("event", "rating")
|
||||||
op.drop_table('featuredevent')
|
op.drop_table("featuredevent")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,27 +12,31 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '8f4df40a36f3'
|
revision = "8f4df40a36f3"
|
||||||
down_revision = 'f71c86333bfb'
|
down_revision = "f71c86333bfb"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('adminunitmemberinvitation',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"adminunitmemberinvitation",
|
||||||
sa.Column('admin_unit_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('email', sa.String(length=255), nullable=True),
|
sa.Column("admin_unit_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('roles', sa.UnicodeText(), nullable=True),
|
sa.Column("email", sa.String(length=255), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], ),
|
sa.Column("roles", sa.UnicodeText(), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.ForeignKeyConstraint(
|
||||||
sa.UniqueConstraint('email', 'admin_unit_id')
|
["admin_unit_id"],
|
||||||
|
["adminunit.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("email", "admin_unit_id"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_table('adminunitmemberinvitation')
|
op.drop_table("adminunitmemberinvitation")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -7,41 +7,65 @@ Create Date: 2020-10-18 13:06:47.639083
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
import sqlalchemy_utils
|
|
||||||
from project import dbtypes
|
|
||||||
from project.models import EventRejectionReason, EventReviewStatus
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '92f37474ad62'
|
revision = "92f37474ad62"
|
||||||
down_revision = '0a282a331e35'
|
down_revision = "0a282a331e35"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
#op.drop_table('spatial_ref_sys')
|
# op.drop_table('spatial_ref_sys')
|
||||||
op.drop_constraint('eventplace_name_organizer_id_admin_unit_id_key', 'eventplace', type_='unique')
|
op.drop_constraint(
|
||||||
op.drop_constraint('eventplace_organizer_id_fkey', 'eventplace', type_='foreignkey')
|
"eventplace_name_organizer_id_admin_unit_id_key", "eventplace", type_="unique"
|
||||||
op.drop_column('eventplace', 'public')
|
)
|
||||||
op.drop_column('eventplace', 'organizer_id')
|
op.drop_constraint("eventplace_organizer_id_fkey", "eventplace", type_="foreignkey")
|
||||||
|
op.drop_column("eventplace", "public")
|
||||||
|
op.drop_column("eventplace", "organizer_id")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('eventplace', sa.Column('organizer_id', sa.INTEGER(), autoincrement=False, nullable=True))
|
op.add_column(
|
||||||
op.add_column('eventplace', sa.Column('public', sa.BOOLEAN(), autoincrement=False, nullable=True))
|
"eventplace",
|
||||||
op.create_foreign_key('eventplace_organizer_id_fkey', 'eventplace', 'eventorganizer', ['organizer_id'], ['id'])
|
sa.Column("organizer_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
op.create_unique_constraint('eventplace_name_organizer_id_admin_unit_id_key', 'eventplace', ['name', 'organizer_id', 'admin_unit_id'])
|
)
|
||||||
op.create_table('spatial_ref_sys',
|
op.add_column(
|
||||||
sa.Column('srid', sa.INTEGER(), autoincrement=False, nullable=False),
|
"eventplace",
|
||||||
sa.Column('auth_name', sa.VARCHAR(length=256), autoincrement=False, nullable=True),
|
sa.Column("public", sa.BOOLEAN(), autoincrement=False, nullable=True),
|
||||||
sa.Column('auth_srid', sa.INTEGER(), autoincrement=False, nullable=True),
|
)
|
||||||
sa.Column('srtext', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
op.create_foreign_key(
|
||||||
sa.Column('proj4text', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
"eventplace_organizer_id_fkey",
|
||||||
sa.CheckConstraint('(srid > 0) AND (srid <= 998999)', name='spatial_ref_sys_srid_check'),
|
"eventplace",
|
||||||
sa.PrimaryKeyConstraint('srid', name='spatial_ref_sys_pkey')
|
"eventorganizer",
|
||||||
|
["organizer_id"],
|
||||||
|
["id"],
|
||||||
|
)
|
||||||
|
op.create_unique_constraint(
|
||||||
|
"eventplace_name_organizer_id_admin_unit_id_key",
|
||||||
|
"eventplace",
|
||||||
|
["name", "organizer_id", "admin_unit_id"],
|
||||||
|
)
|
||||||
|
op.create_table(
|
||||||
|
"spatial_ref_sys",
|
||||||
|
sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
|
sa.Column(
|
||||||
|
"auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
|
sa.Column(
|
||||||
|
"srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.CheckConstraint(
|
||||||
|
"(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,48 +12,44 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '975c22ae802b'
|
revision = "975c22ae802b"
|
||||||
down_revision = '5c8457f2eac1'
|
down_revision = "5c8457f2eac1"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('eventorganizer',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"eventorganizer",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('name', sa.Unicode(length=255), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('org_name', sa.Unicode(length=255), nullable=True),
|
sa.Column("name", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('url', sa.String(length=255), nullable=True),
|
sa.Column("org_name", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('email', sa.Unicode(length=255), nullable=True),
|
sa.Column("url", sa.String(length=255), nullable=True),
|
||||||
sa.Column('phone', sa.Unicode(length=255), nullable=True),
|
sa.Column("email", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
sa.Column("phone", sa.Unicode(length=255), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.add_column('event', sa.Column('organizer_id', sa.Integer(), nullable=True))
|
op.add_column("event", sa.Column("organizer_id", sa.Integer(), nullable=True))
|
||||||
op.alter_column('event', 'host_id',
|
op.alter_column("event", "host_id", existing_type=sa.INTEGER(), nullable=True)
|
||||||
existing_type=sa.INTEGER(),
|
op.alter_column("event", "place_id", existing_type=sa.INTEGER(), nullable=True)
|
||||||
nullable=True)
|
op.create_foreign_key(None, "event", "eventorganizer", ["organizer_id"], ["id"])
|
||||||
op.alter_column('event', 'place_id',
|
op.drop_constraint("place_name_key", "place", type_="unique")
|
||||||
existing_type=sa.INTEGER(),
|
|
||||||
nullable=True)
|
|
||||||
op.create_foreign_key(None, 'event', 'eventorganizer', ['organizer_id'], ['id'])
|
|
||||||
op.drop_constraint('place_name_key', 'place', type_='unique')
|
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_unique_constraint('place_name_key', 'place', ['name'])
|
op.create_unique_constraint("place_name_key", "place", ["name"])
|
||||||
op.drop_constraint(None, 'event', type_='foreignkey')
|
op.drop_constraint(None, "event", type_="foreignkey")
|
||||||
op.alter_column('event', 'place_id',
|
op.alter_column("event", "place_id", existing_type=sa.INTEGER(), nullable=False)
|
||||||
existing_type=sa.INTEGER(),
|
op.alter_column("event", "host_id", existing_type=sa.INTEGER(), nullable=False)
|
||||||
nullable=False)
|
op.drop_column("event", "organizer_id")
|
||||||
op.alter_column('event', 'host_id',
|
op.drop_table("eventorganizer")
|
||||||
existing_type=sa.INTEGER(),
|
|
||||||
nullable=False)
|
|
||||||
op.drop_column('event', 'organizer_id')
|
|
||||||
op.drop_table('eventorganizer')
|
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,32 +12,36 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'a336ac384c64'
|
revision = "a336ac384c64"
|
||||||
down_revision = '62e071b0da50'
|
down_revision = "62e071b0da50"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('eventcontact',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"eventcontact",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('name', sa.Unicode(length=255), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('email', sa.Unicode(length=255), nullable=True),
|
sa.Column("name", sa.Unicode(length=255), nullable=False),
|
||||||
sa.Column('phone', sa.Unicode(length=255), nullable=True),
|
sa.Column("email", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
sa.Column("phone", sa.Unicode(length=255), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.add_column('event', sa.Column('contact_id', sa.Integer(), nullable=True))
|
op.add_column("event", sa.Column("contact_id", sa.Integer(), nullable=True))
|
||||||
op.create_foreign_key(None, 'event', 'eventcontact', ['contact_id'], ['id'])
|
op.create_foreign_key(None, "event", "eventcontact", ["contact_id"], ["id"])
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_constraint(None, 'event', type_='foreignkey')
|
op.drop_constraint(None, "event", type_="foreignkey")
|
||||||
op.drop_column('event', 'contact_id')
|
op.drop_column("event", "contact_id")
|
||||||
op.drop_table('eventcontact')
|
op.drop_table("eventcontact")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -7,65 +7,104 @@ Create Date: 2020-09-29 16:53:02.520125
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
import sqlalchemy_utils
|
|
||||||
from project import dbtypes
|
from project import dbtypes
|
||||||
from sqlalchemy.dialects import postgresql
|
from sqlalchemy.dialects import postgresql
|
||||||
from project.models import EventReferenceRequestRejectionReason, EventReferenceRequestReviewStatus
|
from project.models import (
|
||||||
|
EventReferenceRequestRejectionReason,
|
||||||
|
EventReferenceRequestReviewStatus,
|
||||||
|
)
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'a75bd9c8ad3a'
|
revision = "a75bd9c8ad3a"
|
||||||
down_revision = '51c47c7f0bdb'
|
down_revision = "51c47c7f0bdb"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('eventreference',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"eventreference",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('event_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('admin_unit_id', sa.Integer(), nullable=False),
|
sa.Column("event_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('rating', sa.Integer(), nullable=True),
|
sa.Column("admin_unit_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
sa.Column("rating", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], ),
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.ForeignKeyConstraint(['event_id'], ['event.id'], ),
|
["admin_unit_id"],
|
||||||
sa.PrimaryKeyConstraint('id')
|
["adminunit.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["event_id"],
|
||||||
|
["event.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.create_table('eventreferencerequest',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"eventreferencerequest",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('event_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('admin_unit_id', sa.Integer(), nullable=False),
|
sa.Column("event_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('review_status', dbtypes.IntegerEnum(EventReferenceRequestReviewStatus), nullable=True),
|
sa.Column("admin_unit_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('rejection_reason', dbtypes.IntegerEnum(EventReferenceRequestRejectionReason), nullable=True),
|
sa.Column(
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
"review_status",
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], ),
|
dbtypes.IntegerEnum(EventReferenceRequestReviewStatus),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
nullable=True,
|
||||||
sa.ForeignKeyConstraint(['event_id'], ['event.id'], ),
|
),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.Column(
|
||||||
|
"rejection_reason",
|
||||||
|
dbtypes.IntegerEnum(EventReferenceRequestRejectionReason),
|
||||||
|
nullable=True,
|
||||||
|
),
|
||||||
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["admin_unit_id"],
|
||||||
|
["adminunit.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["event_id"],
|
||||||
|
["event.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.drop_table('featuredevent')
|
op.drop_table("featuredevent")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('featuredevent',
|
op.create_table(
|
||||||
sa.Column('created_at', postgresql.TIMESTAMP(), autoincrement=False, nullable=True),
|
"featuredevent",
|
||||||
sa.Column('id', sa.INTEGER(), autoincrement=True, nullable=False),
|
sa.Column(
|
||||||
sa.Column('event_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
"created_at", postgresql.TIMESTAMP(), autoincrement=False, nullable=True
|
||||||
sa.Column('review_status', sa.INTEGER(), autoincrement=False, nullable=True),
|
),
|
||||||
sa.Column('rejection_resaon', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False),
|
||||||
sa.Column('rating', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.Column("event_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
sa.Column('created_by_id', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.Column("review_status", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.Column('admin_unit_id', sa.INTEGER(), autoincrement=False, nullable=False),
|
sa.Column("rejection_resaon", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], name='featuredevent_admin_unit_id_fkey'),
|
sa.Column("rating", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], name='featuredevent_created_by_id_fkey'),
|
sa.Column("created_by_id", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.ForeignKeyConstraint(['event_id'], ['event.id'], name='featuredevent_event_id_fkey'),
|
sa.Column("admin_unit_id", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
sa.PrimaryKeyConstraint('id', name='featuredevent_pkey')
|
sa.ForeignKeyConstraint(
|
||||||
|
["admin_unit_id"], ["adminunit.id"], name="featuredevent_admin_unit_id_fkey"
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"], ["user.id"], name="featuredevent_created_by_id_fkey"
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["event_id"], ["event.id"], name="featuredevent_event_id_fkey"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id", name="featuredevent_pkey"),
|
||||||
)
|
)
|
||||||
op.drop_table('eventreferencerequest')
|
op.drop_table("eventreferencerequest")
|
||||||
op.drop_table('eventreference')
|
op.drop_table("eventreference")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,21 +12,23 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'a8c662c46047'
|
revision = "a8c662c46047"
|
||||||
down_revision = '8f4df40a36f3'
|
down_revision = "8f4df40a36f3"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('adminunitmemberrole', sa.Column('title', sa.Unicode(length=255), nullable=True))
|
op.add_column(
|
||||||
op.add_column('role', sa.Column('title', sa.Unicode(length=255), nullable=True))
|
"adminunitmemberrole", sa.Column("title", sa.Unicode(length=255), nullable=True)
|
||||||
|
)
|
||||||
|
op.add_column("role", sa.Column("title", sa.Unicode(length=255), nullable=True))
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('role', 'title')
|
op.drop_column("role", "title")
|
||||||
op.drop_column('adminunitmemberrole', 'title')
|
op.drop_column("adminunitmemberrole", "title")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -11,29 +11,33 @@ import sqlalchemy_utils
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'abf0f671ba27'
|
revision = "abf0f671ba27"
|
||||||
down_revision = 'bbad7e33a780'
|
down_revision = "bbad7e33a780"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('flask_dance_oauth',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"flask_dance_oauth",
|
||||||
sa.Column('provider', sa.String(length=50), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=False),
|
sa.Column("provider", sa.String(length=50), nullable=False),
|
||||||
sa.Column('token', sqlalchemy_utils.types.json.JSONType(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=False),
|
||||||
sa.Column('provider_user_id', sa.String(length=256), nullable=False),
|
sa.Column("token", sqlalchemy_utils.types.json.JSONType(), nullable=False),
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
sa.Column("provider_user_id", sa.String(length=256), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
sa.Column("user_id", sa.Integer(), nullable=False),
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.ForeignKeyConstraint(
|
||||||
sa.UniqueConstraint('provider_user_id')
|
["user_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("provider_user_id"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_table('flask_dance_oauth')
|
op.drop_table("flask_dance_oauth")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,23 +12,27 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'b128cc637447'
|
revision = "b128cc637447"
|
||||||
down_revision = '41512b20e07c'
|
down_revision = "41512b20e07c"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('adminunit', sa.Column('fax', sa.Unicode(length=255), nullable=True))
|
op.add_column("adminunit", sa.Column("fax", sa.Unicode(length=255), nullable=True))
|
||||||
op.add_column('eventorganizer', sa.Column('fax', sa.Unicode(length=255), nullable=True))
|
op.add_column(
|
||||||
op.add_column('organization', sa.Column('fax', sa.Unicode(length=255), nullable=True))
|
"eventorganizer", sa.Column("fax", sa.Unicode(length=255), nullable=True)
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"organization", sa.Column("fax", sa.Unicode(length=255), nullable=True)
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('organization', 'fax')
|
op.drop_column("organization", "fax")
|
||||||
op.drop_column('eventorganizer', 'fax')
|
op.drop_column("eventorganizer", "fax")
|
||||||
op.drop_column('adminunit', 'fax')
|
op.drop_column("adminunit", "fax")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,21 +12,21 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'b1c05324cc13'
|
revision = "b1c05324cc13"
|
||||||
down_revision = 'cce1284874fa'
|
down_revision = "cce1284874fa"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_unique_constraint(None, 'adminunit', ['short_name'])
|
op.create_unique_constraint(None, "adminunit", ["short_name"])
|
||||||
op.create_unique_constraint(None, 'organization', ['short_name'])
|
op.create_unique_constraint(None, "organization", ["short_name"])
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_constraint(None, 'organization', type_='unique')
|
op.drop_constraint(None, "organization", type_="unique")
|
||||||
op.drop_constraint(None, 'adminunit', type_='unique')
|
op.drop_constraint(None, "adminunit", type_="unique")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
"""empty message
|
"""empty message
|
||||||
|
|
||||||
Revision ID: bbad7e33a780
|
Revision ID: bbad7e33a780
|
||||||
Revises:
|
Revises:
|
||||||
Create Date: 2020-06-24 21:17:25.548159
|
Create Date: 2020-06-24 21:17:25.548159
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -10,7 +10,7 @@ import sqlalchemy as sa
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'bbad7e33a780'
|
revision = "bbad7e33a780"
|
||||||
down_revision = None
|
down_revision = None
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
@ -18,282 +18,420 @@ depends_on = None
|
|||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('adminunitmemberrole',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"adminunitmemberrole",
|
||||||
sa.Column('name', sa.String(length=80), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('description', sa.String(length=255), nullable=True),
|
sa.Column("name", sa.String(length=80), nullable=True),
|
||||||
sa.Column('permissions', sa.UnicodeText(), nullable=True),
|
sa.Column("description", sa.String(length=255), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.Column("permissions", sa.UnicodeText(), nullable=True),
|
||||||
sa.UniqueConstraint('name')
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("name"),
|
||||||
)
|
)
|
||||||
op.create_table('adminunitorgrole',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"adminunitorgrole",
|
||||||
sa.Column('name', sa.String(length=80), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('description', sa.String(length=255), nullable=True),
|
sa.Column("name", sa.String(length=80), nullable=True),
|
||||||
sa.Column('permissions', sa.UnicodeText(), nullable=True),
|
sa.Column("description", sa.String(length=255), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.Column("permissions", sa.UnicodeText(), nullable=True),
|
||||||
sa.UniqueConstraint('name')
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("name"),
|
||||||
)
|
)
|
||||||
op.create_table('eventcategory',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"eventcategory",
|
||||||
sa.Column('name', sa.Unicode(length=255), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.Column("name", sa.Unicode(length=255), nullable=False),
|
||||||
sa.UniqueConstraint('name')
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("name"),
|
||||||
)
|
)
|
||||||
op.create_table('orgmemberrole',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"orgmemberrole",
|
||||||
sa.Column('name', sa.String(length=80), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('description', sa.String(length=255), nullable=True),
|
sa.Column("name", sa.String(length=80), nullable=True),
|
||||||
sa.Column('permissions', sa.UnicodeText(), nullable=True),
|
sa.Column("description", sa.String(length=255), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.Column("permissions", sa.UnicodeText(), nullable=True),
|
||||||
sa.UniqueConstraint('name')
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("name"),
|
||||||
)
|
)
|
||||||
op.create_table('role',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"role",
|
||||||
sa.Column('name', sa.String(length=80), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('description', sa.String(length=255), nullable=True),
|
sa.Column("name", sa.String(length=80), nullable=True),
|
||||||
sa.Column('permissions', sa.UnicodeText(), nullable=True),
|
sa.Column("description", sa.String(length=255), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.Column("permissions", sa.UnicodeText(), nullable=True),
|
||||||
sa.UniqueConstraint('name')
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("name"),
|
||||||
)
|
)
|
||||||
op.create_table('user',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"user",
|
||||||
sa.Column('email', sa.String(length=255), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('username', sa.String(length=255), nullable=True),
|
sa.Column("email", sa.String(length=255), nullable=True),
|
||||||
sa.Column('password', sa.String(length=255), nullable=True),
|
sa.Column("username", sa.String(length=255), nullable=True),
|
||||||
sa.Column('last_login_at', sa.DateTime(), nullable=True),
|
sa.Column("password", sa.String(length=255), nullable=True),
|
||||||
sa.Column('current_login_at', sa.DateTime(), nullable=True),
|
sa.Column("last_login_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('last_login_ip', sa.String(length=100), nullable=True),
|
sa.Column("current_login_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('current_login_ip', sa.String(length=100), nullable=True),
|
sa.Column("last_login_ip", sa.String(length=100), nullable=True),
|
||||||
sa.Column('login_count', sa.Integer(), nullable=True),
|
sa.Column("current_login_ip", sa.String(length=100), nullable=True),
|
||||||
sa.Column('active', sa.Boolean(), nullable=True),
|
sa.Column("login_count", sa.Integer(), nullable=True),
|
||||||
sa.Column('fs_uniquifier', sa.String(length=255), nullable=True),
|
sa.Column("active", sa.Boolean(), nullable=True),
|
||||||
sa.Column('confirmed_at', sa.DateTime(), nullable=True),
|
sa.Column("fs_uniquifier", sa.String(length=255), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.Column("confirmed_at", sa.DateTime(), nullable=True),
|
||||||
sa.UniqueConstraint('email')
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("email"),
|
||||||
)
|
)
|
||||||
op.create_table('adminunit',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"adminunit",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('name', sa.Unicode(length=255), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
sa.Column("name", sa.Unicode(length=255), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id'),
|
sa.ForeignKeyConstraint(
|
||||||
sa.UniqueConstraint('name')
|
["created_by_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("name"),
|
||||||
)
|
)
|
||||||
op.create_table('image',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"image",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('data', sa.LargeBinary(), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('encoding_format', sa.String(length=80), nullable=True),
|
sa.Column("data", sa.LargeBinary(), nullable=True),
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
sa.Column("encoding_format", sa.String(length=80), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.create_table('location',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"location",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('street', sa.Unicode(length=255), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('postalCode', sa.Unicode(length=255), nullable=True),
|
sa.Column("street", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('city', sa.Unicode(length=255), nullable=True),
|
sa.Column("postalCode", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('state', sa.Unicode(length=255), nullable=True),
|
sa.Column("city", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('country', sa.Unicode(length=255), nullable=True),
|
sa.Column("state", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('latitude', sa.Numeric(precision=18, scale=16), nullable=True),
|
sa.Column("country", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('longitude', sa.Numeric(precision=19, scale=16), nullable=True),
|
sa.Column("latitude", sa.Numeric(precision=18, scale=16), nullable=True),
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
sa.Column("longitude", sa.Numeric(precision=19, scale=16), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.create_table('roles_users',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"roles_users",
|
||||||
sa.Column('user_id', sa.Integer(), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('role_id', sa.Integer(), nullable=True),
|
sa.Column("user_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['role_id'], ['role.id'], ),
|
sa.Column("role_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.PrimaryKeyConstraint('id')
|
["role_id"],
|
||||||
|
["role.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["user_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.create_table('adminunitmember',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"adminunitmember",
|
||||||
sa.Column('admin_unit_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
sa.Column("admin_unit_id", sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], ),
|
sa.Column("user_id", sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.PrimaryKeyConstraint('id')
|
["admin_unit_id"],
|
||||||
|
["adminunit.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["user_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.create_table('eventsuggestion',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"eventsuggestion",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('admin_unit_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('host_name', sa.Unicode(length=255), nullable=False),
|
sa.Column("admin_unit_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('event_name', sa.Unicode(length=255), nullable=False),
|
sa.Column("host_name", sa.Unicode(length=255), nullable=False),
|
||||||
sa.Column('description', sa.UnicodeText(), nullable=False),
|
sa.Column("event_name", sa.Unicode(length=255), nullable=False),
|
||||||
sa.Column('place_name', sa.Unicode(length=255), nullable=False),
|
sa.Column("description", sa.UnicodeText(), nullable=False),
|
||||||
sa.Column('place_street', sa.Unicode(length=255), nullable=True),
|
sa.Column("place_name", sa.Unicode(length=255), nullable=False),
|
||||||
sa.Column('place_postalCode', sa.Unicode(length=255), nullable=False),
|
sa.Column("place_street", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('place_city', sa.Unicode(length=255), nullable=False),
|
sa.Column("place_postalCode", sa.Unicode(length=255), nullable=False),
|
||||||
sa.Column('contact_name', sa.Unicode(length=255), nullable=False),
|
sa.Column("place_city", sa.Unicode(length=255), nullable=False),
|
||||||
sa.Column('contact_email', sa.Unicode(length=255), nullable=False),
|
sa.Column("contact_name", sa.Unicode(length=255), nullable=False),
|
||||||
sa.Column('external_link', sa.String(length=255), nullable=True),
|
sa.Column("contact_email", sa.Unicode(length=255), nullable=False),
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
sa.Column("external_link", sa.String(length=255), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], ),
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.PrimaryKeyConstraint('id')
|
["admin_unit_id"],
|
||||||
|
["adminunit.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.create_table('organization',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"organization",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('name', sa.Unicode(length=255), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('legal_name', sa.Unicode(length=255), nullable=True),
|
sa.Column("name", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('location_id', sa.Integer(), nullable=True),
|
sa.Column("legal_name", sa.Unicode(length=255), nullable=True),
|
||||||
sa.Column('logo_id', sa.Integer(), nullable=True),
|
sa.Column("location_id", sa.Integer(), nullable=True),
|
||||||
sa.Column('url', sa.String(length=255), nullable=True),
|
sa.Column("logo_id", sa.Integer(), nullable=True),
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
sa.Column("url", sa.String(length=255), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['location_id'], ['location.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.ForeignKeyConstraint(['logo_id'], ['image.id'], ),
|
["created_by_id"],
|
||||||
sa.PrimaryKeyConstraint('id'),
|
["user.id"],
|
||||||
sa.UniqueConstraint('name')
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["location_id"],
|
||||||
|
["location.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["logo_id"],
|
||||||
|
["image.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("name"),
|
||||||
)
|
)
|
||||||
op.create_table('place',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"place",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('name', sa.Unicode(length=255), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('location_id', sa.Integer(), nullable=True),
|
sa.Column("name", sa.Unicode(length=255), nullable=False),
|
||||||
sa.Column('photo_id', sa.Integer(), nullable=True),
|
sa.Column("location_id", sa.Integer(), nullable=True),
|
||||||
sa.Column('url', sa.String(length=255), nullable=True),
|
sa.Column("photo_id", sa.Integer(), nullable=True),
|
||||||
sa.Column('description', sa.UnicodeText(), nullable=True),
|
sa.Column("url", sa.String(length=255), nullable=True),
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
sa.Column("description", sa.UnicodeText(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['location_id'], ['location.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.ForeignKeyConstraint(['photo_id'], ['image.id'], ),
|
["created_by_id"],
|
||||||
sa.PrimaryKeyConstraint('id'),
|
["user.id"],
|
||||||
sa.UniqueConstraint('name')
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["location_id"],
|
||||||
|
["location.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["photo_id"],
|
||||||
|
["image.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("name"),
|
||||||
)
|
)
|
||||||
op.create_table('actor',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"actor",
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('organization_id', sa.Integer(), nullable=True),
|
sa.Column("user_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('admin_unit_id', sa.Integer(), nullable=True),
|
sa.Column("organization_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], ),
|
sa.Column("admin_unit_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
["admin_unit_id"],
|
||||||
sa.PrimaryKeyConstraint('id'),
|
["adminunit.id"],
|
||||||
sa.UniqueConstraint('user_id', 'organization_id', 'admin_unit_id')
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["organization_id"],
|
||||||
|
["organization.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["user_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("user_id", "organization_id", "admin_unit_id"),
|
||||||
)
|
)
|
||||||
op.create_table('adminunitmemberroles_members',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"adminunitmemberroles_members",
|
||||||
sa.Column('member_id', sa.Integer(), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('role_id', sa.Integer(), nullable=True),
|
sa.Column("member_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['member_id'], ['adminunitmember.id'], ),
|
sa.Column("role_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['role_id'], ['adminunitmemberrole.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.PrimaryKeyConstraint('id')
|
["member_id"],
|
||||||
|
["adminunitmember.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["role_id"],
|
||||||
|
["adminunitmemberrole.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.create_table('adminunitorg',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"adminunitorg",
|
||||||
sa.Column('admin_unit_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('organization_id', sa.Integer(), nullable=False),
|
sa.Column("admin_unit_id", sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], ),
|
sa.Column("organization_id", sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.PrimaryKeyConstraint('id')
|
["admin_unit_id"],
|
||||||
|
["adminunit.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["organization_id"],
|
||||||
|
["organization.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.create_table('eventsuggestiondate',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"eventsuggestiondate",
|
||||||
sa.Column('event_suggestion_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('start', sa.DateTime(timezone=True), nullable=False),
|
sa.Column("event_suggestion_id", sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['event_suggestion_id'], ['eventsuggestion.id'], ),
|
sa.Column("start", sa.DateTime(timezone=True), nullable=False),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.ForeignKeyConstraint(
|
||||||
|
["event_suggestion_id"],
|
||||||
|
["eventsuggestion.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.create_table('org_or_adminunit',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"org_or_adminunit",
|
||||||
sa.Column('organization_id', sa.Integer(), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('admin_unit_id', sa.Integer(), nullable=True),
|
sa.Column("organization_id", sa.Integer(), nullable=True),
|
||||||
sa.CheckConstraint('NOT(organization_id IS NULL AND admin_unit_id IS NULL)'),
|
sa.Column("admin_unit_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], ),
|
sa.CheckConstraint("NOT(organization_id IS NULL AND admin_unit_id IS NULL)"),
|
||||||
sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.PrimaryKeyConstraint('id'),
|
["admin_unit_id"],
|
||||||
sa.UniqueConstraint('organization_id', 'admin_unit_id')
|
["adminunit.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["organization_id"],
|
||||||
|
["organization.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
|
sa.UniqueConstraint("organization_id", "admin_unit_id"),
|
||||||
)
|
)
|
||||||
op.create_table('orgmember',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"orgmember",
|
||||||
sa.Column('organization_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('user_id', sa.Integer(), nullable=False),
|
sa.Column("organization_id", sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['organization_id'], ['organization.id'], ),
|
sa.Column("user_id", sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['user_id'], ['user.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.PrimaryKeyConstraint('id')
|
["organization_id"],
|
||||||
|
["organization.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["user_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.create_table('adminunitorgroles_organizations',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"adminunitorgroles_organizations",
|
||||||
sa.Column('admin_unit_org_id', sa.Integer(), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('role_id', sa.Integer(), nullable=True),
|
sa.Column("admin_unit_org_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['admin_unit_org_id'], ['adminunitorg.id'], ),
|
sa.Column("role_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['role_id'], ['adminunitorgrole.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.PrimaryKeyConstraint('id')
|
["admin_unit_org_id"],
|
||||||
|
["adminunitorg.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["role_id"],
|
||||||
|
["adminunitorgrole.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.create_table('event',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"event",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('admin_unit_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('host_id', sa.Integer(), nullable=False),
|
sa.Column("admin_unit_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('place_id', sa.Integer(), nullable=False),
|
sa.Column("host_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('name', sa.Unicode(length=255), nullable=False),
|
sa.Column("place_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('description', sa.UnicodeText(), nullable=False),
|
sa.Column("name", sa.Unicode(length=255), nullable=False),
|
||||||
sa.Column('external_link', sa.String(length=255), nullable=True),
|
sa.Column("description", sa.UnicodeText(), nullable=False),
|
||||||
sa.Column('ticket_link', sa.String(length=255), nullable=True),
|
sa.Column("external_link", sa.String(length=255), nullable=True),
|
||||||
sa.Column('verified', sa.Boolean(), nullable=True),
|
sa.Column("ticket_link", sa.String(length=255), nullable=True),
|
||||||
sa.Column('photo_id', sa.Integer(), nullable=True),
|
sa.Column("verified", sa.Boolean(), nullable=True),
|
||||||
sa.Column('category_id', sa.Integer(), nullable=False),
|
sa.Column("photo_id", sa.Integer(), nullable=True),
|
||||||
sa.Column('recurrence_rule', sa.UnicodeText(), nullable=True),
|
sa.Column("category_id", sa.Integer(), nullable=False),
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
sa.Column("recurrence_rule", sa.UnicodeText(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['admin_unit_id'], ['adminunit.id'], ),
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['category_id'], ['eventcategory.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
["admin_unit_id"],
|
||||||
sa.ForeignKeyConstraint(['host_id'], ['org_or_adminunit.id'], ),
|
["adminunit.id"],
|
||||||
sa.ForeignKeyConstraint(['photo_id'], ['image.id'], ),
|
),
|
||||||
sa.ForeignKeyConstraint(['place_id'], ['place.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.PrimaryKeyConstraint('id')
|
["category_id"],
|
||||||
|
["eventcategory.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["created_by_id"],
|
||||||
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["host_id"],
|
||||||
|
["org_or_adminunit.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["photo_id"],
|
||||||
|
["image.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["place_id"],
|
||||||
|
["place.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.create_table('orgmemberroles_members',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"orgmemberroles_members",
|
||||||
sa.Column('member_id', sa.Integer(), nullable=True),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('role_id', sa.Integer(), nullable=True),
|
sa.Column("member_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['member_id'], ['orgmember.id'], ),
|
sa.Column("role_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['role_id'], ['orgmemberrole.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.PrimaryKeyConstraint('id')
|
["member_id"],
|
||||||
|
["orgmember.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["role_id"],
|
||||||
|
["orgmemberrole.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.create_table('eventdate',
|
op.create_table(
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
"eventdate",
|
||||||
sa.Column('event_id', sa.Integer(), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('start', sa.DateTime(timezone=True), nullable=False),
|
sa.Column("event_id", sa.Integer(), nullable=False),
|
||||||
sa.ForeignKeyConstraint(['event_id'], ['event.id'], ),
|
sa.Column("start", sa.DateTime(timezone=True), nullable=False),
|
||||||
sa.PrimaryKeyConstraint('id')
|
sa.ForeignKeyConstraint(
|
||||||
|
["event_id"],
|
||||||
|
["event.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_table('eventdate')
|
op.drop_table("eventdate")
|
||||||
op.drop_table('orgmemberroles_members')
|
op.drop_table("orgmemberroles_members")
|
||||||
op.drop_table('event')
|
op.drop_table("event")
|
||||||
op.drop_table('adminunitorgroles_organizations')
|
op.drop_table("adminunitorgroles_organizations")
|
||||||
op.drop_table('orgmember')
|
op.drop_table("orgmember")
|
||||||
op.drop_table('org_or_adminunit')
|
op.drop_table("org_or_adminunit")
|
||||||
op.drop_table('eventsuggestiondate')
|
op.drop_table("eventsuggestiondate")
|
||||||
op.drop_table('adminunitorg')
|
op.drop_table("adminunitorg")
|
||||||
op.drop_table('adminunitmemberroles_members')
|
op.drop_table("adminunitmemberroles_members")
|
||||||
op.drop_table('actor')
|
op.drop_table("actor")
|
||||||
op.drop_table('place')
|
op.drop_table("place")
|
||||||
op.drop_table('organization')
|
op.drop_table("organization")
|
||||||
op.drop_table('eventsuggestion')
|
op.drop_table("eventsuggestion")
|
||||||
op.drop_table('adminunitmember')
|
op.drop_table("adminunitmember")
|
||||||
op.drop_table('roles_users')
|
op.drop_table("roles_users")
|
||||||
op.drop_table('location')
|
op.drop_table("location")
|
||||||
op.drop_table('image')
|
op.drop_table("image")
|
||||||
op.drop_table('adminunit')
|
op.drop_table("adminunit")
|
||||||
op.drop_table('user')
|
op.drop_table("user")
|
||||||
op.drop_table('role')
|
op.drop_table("role")
|
||||||
op.drop_table('orgmemberrole')
|
op.drop_table("orgmemberrole")
|
||||||
op.drop_table('eventcategory')
|
op.drop_table("eventcategory")
|
||||||
op.drop_table('adminunitorgrole')
|
op.drop_table("adminunitorgrole")
|
||||||
op.drop_table('adminunitmemberrole')
|
op.drop_table("adminunitmemberrole")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,21 +12,25 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'cce1284874fa'
|
revision = "cce1284874fa"
|
||||||
down_revision = 'b128cc637447'
|
down_revision = "b128cc637447"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('adminunit', sa.Column('short_name', sa.Unicode(length=100), nullable=True))
|
op.add_column(
|
||||||
op.add_column('organization', sa.Column('short_name', sa.Unicode(length=100), nullable=True))
|
"adminunit", sa.Column("short_name", sa.Unicode(length=100), nullable=True)
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"organization", sa.Column("short_name", sa.Unicode(length=100), nullable=True)
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('organization', 'short_name')
|
op.drop_column("organization", "short_name")
|
||||||
op.drop_column('adminunit', 'short_name')
|
op.drop_column("adminunit", "short_name")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,29 +12,40 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'da63ba1d58b1'
|
revision = "da63ba1d58b1"
|
||||||
down_revision = '091deace5f08'
|
down_revision = "091deace5f08"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
#op.drop_table('spatial_ref_sys')
|
# op.drop_table('spatial_ref_sys')
|
||||||
op.add_column('image', sa.Column('copyright_text', sa.Unicode(length=255), nullable=True))
|
op.add_column(
|
||||||
|
"image", sa.Column("copyright_text", sa.Unicode(length=255), nullable=True)
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('image', 'copyright_text')
|
op.drop_column("image", "copyright_text")
|
||||||
op.create_table('spatial_ref_sys',
|
op.create_table(
|
||||||
sa.Column('srid', sa.INTEGER(), autoincrement=False, nullable=False),
|
"spatial_ref_sys",
|
||||||
sa.Column('auth_name', sa.VARCHAR(length=256), autoincrement=False, nullable=True),
|
sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
|
||||||
sa.Column('auth_srid', sa.INTEGER(), autoincrement=False, nullable=True),
|
sa.Column(
|
||||||
sa.Column('srtext', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
"auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
|
||||||
sa.Column('proj4text', sa.VARCHAR(length=2048), autoincrement=False, nullable=True),
|
),
|
||||||
sa.CheckConstraint('(srid > 0) AND (srid <= 998999)', name='spatial_ref_sys_srid_check'),
|
sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
|
||||||
sa.PrimaryKeyConstraint('srid', name='spatial_ref_sys_pkey')
|
sa.Column(
|
||||||
|
"srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.Column(
|
||||||
|
"proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
|
||||||
|
),
|
||||||
|
sa.CheckConstraint(
|
||||||
|
"(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
|
||||||
)
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,25 +12,27 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'dcd0b71650b0'
|
revision = "dcd0b71650b0"
|
||||||
down_revision = '699c4f6a7fe8'
|
down_revision = "699c4f6a7fe8"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('eventorganizer', sa.Column('location_id', sa.Integer(), nullable=True))
|
op.add_column(
|
||||||
op.add_column('eventorganizer', sa.Column('logo_id', sa.Integer(), nullable=True))
|
"eventorganizer", sa.Column("location_id", sa.Integer(), nullable=True)
|
||||||
op.create_foreign_key(None, 'eventorganizer', 'image', ['logo_id'], ['id'])
|
)
|
||||||
op.create_foreign_key(None, 'eventorganizer', 'location', ['location_id'], ['id'])
|
op.add_column("eventorganizer", sa.Column("logo_id", sa.Integer(), nullable=True))
|
||||||
|
op.create_foreign_key(None, "eventorganizer", "image", ["logo_id"], ["id"])
|
||||||
|
op.create_foreign_key(None, "eventorganizer", "location", ["location_id"], ["id"])
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_constraint(None, 'eventorganizer', type_='foreignkey')
|
op.drop_constraint(None, "eventorganizer", type_="foreignkey")
|
||||||
op.drop_constraint(None, 'eventorganizer', type_='foreignkey')
|
op.drop_constraint(None, "eventorganizer", type_="foreignkey")
|
||||||
op.drop_column('eventorganizer', 'logo_id')
|
op.drop_column("eventorganizer", "logo_id")
|
||||||
op.drop_column('eventorganizer', 'location_id')
|
op.drop_column("eventorganizer", "location_id")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -7,26 +7,29 @@ Create Date: 2020-07-08 08:53:44.373606
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
import sqlalchemy_utils
|
|
||||||
from project import dbtypes
|
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'ed6bb2084bbd'
|
revision = "ed6bb2084bbd"
|
||||||
down_revision = 'f1bc3fa623c7'
|
down_revision = "f1bc3fa623c7"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('event', sa.Column('previous_start_date', sa.DateTime(timezone=True), nullable=True))
|
op.add_column(
|
||||||
op.add_column('eventdate', sa.Column('end', sa.DateTime(timezone=True), nullable=True))
|
"event",
|
||||||
|
sa.Column("previous_start_date", sa.DateTime(timezone=True), nullable=True),
|
||||||
|
)
|
||||||
|
op.add_column(
|
||||||
|
"eventdate", sa.Column("end", sa.DateTime(timezone=True), nullable=True)
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('eventdate', 'end')
|
op.drop_column("eventdate", "end")
|
||||||
op.drop_column('event', 'previous_start_date')
|
op.drop_column("event", "previous_start_date")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -7,38 +7,53 @@ Create Date: 2020-07-07 15:49:58.653888
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
import sqlalchemy_utils
|
|
||||||
from project import dbtypes
|
from project import dbtypes
|
||||||
from project.models import EventTargetGroupOrigin, EventAttendanceMode, EventStatus
|
from project.models import EventTargetGroupOrigin, EventAttendanceMode, EventStatus
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'f1bc3fa623c7'
|
revision = "f1bc3fa623c7"
|
||||||
down_revision = '75c07cb9cfe3'
|
down_revision = "75c07cb9cfe3"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('event', sa.Column('accessible_for_free', sa.Boolean(), nullable=True))
|
op.add_column(
|
||||||
op.add_column('event', sa.Column('age_from', sa.Integer(), nullable=True))
|
"event", sa.Column("accessible_for_free", sa.Boolean(), nullable=True)
|
||||||
op.add_column('event', sa.Column('age_to', sa.Integer(), nullable=True))
|
)
|
||||||
op.add_column('event', sa.Column('attendance_mode', dbtypes.IntegerEnum(EventAttendanceMode), nullable=True))
|
op.add_column("event", sa.Column("age_from", sa.Integer(), nullable=True))
|
||||||
op.add_column('event', sa.Column('kid_friendly', sa.Boolean(), nullable=True))
|
op.add_column("event", sa.Column("age_to", sa.Integer(), nullable=True))
|
||||||
op.add_column('event', sa.Column('status', dbtypes.IntegerEnum(EventStatus), nullable=True))
|
op.add_column(
|
||||||
op.add_column('event', sa.Column('tags', sa.UnicodeText(), nullable=True))
|
"event",
|
||||||
op.add_column('event', sa.Column('target_group_origin', dbtypes.IntegerEnum(EventTargetGroupOrigin), nullable=True))
|
sa.Column(
|
||||||
|
"attendance_mode", dbtypes.IntegerEnum(EventAttendanceMode), nullable=True
|
||||||
|
),
|
||||||
|
)
|
||||||
|
op.add_column("event", sa.Column("kid_friendly", sa.Boolean(), nullable=True))
|
||||||
|
op.add_column(
|
||||||
|
"event", sa.Column("status", dbtypes.IntegerEnum(EventStatus), nullable=True)
|
||||||
|
)
|
||||||
|
op.add_column("event", sa.Column("tags", sa.UnicodeText(), nullable=True))
|
||||||
|
op.add_column(
|
||||||
|
"event",
|
||||||
|
sa.Column(
|
||||||
|
"target_group_origin",
|
||||||
|
dbtypes.IntegerEnum(EventTargetGroupOrigin),
|
||||||
|
nullable=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_column('event', 'target_group_origin')
|
op.drop_column("event", "target_group_origin")
|
||||||
op.drop_column('event', 'tags')
|
op.drop_column("event", "tags")
|
||||||
op.drop_column('event', 'status')
|
op.drop_column("event", "status")
|
||||||
op.drop_column('event', 'kid_friendly')
|
op.drop_column("event", "kid_friendly")
|
||||||
op.drop_column('event', 'attendance_mode')
|
op.drop_column("event", "attendance_mode")
|
||||||
op.drop_column('event', 'age_to')
|
op.drop_column("event", "age_to")
|
||||||
op.drop_column('event', 'age_from')
|
op.drop_column("event", "age_from")
|
||||||
op.drop_column('event', 'accessible_for_free')
|
op.drop_column("event", "accessible_for_free")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,23 +12,29 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'f71c86333bfb'
|
revision = "f71c86333bfb"
|
||||||
down_revision = '4e913af88c33'
|
down_revision = "4e913af88c33"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('analytics', sa.Column('value1', sa.Unicode(length=255), nullable=True))
|
op.add_column(
|
||||||
op.add_column('analytics', sa.Column('value2', sa.Unicode(length=255), nullable=True))
|
"analytics", sa.Column("value1", sa.Unicode(length=255), nullable=True)
|
||||||
op.drop_column('analytics', 'value')
|
)
|
||||||
|
op.add_column(
|
||||||
|
"analytics", sa.Column("value2", sa.Unicode(length=255), nullable=True)
|
||||||
|
)
|
||||||
|
op.drop_column("analytics", "value")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.add_column('analytics', sa.Column('value', sa.TEXT(), autoincrement=False, nullable=True))
|
op.add_column(
|
||||||
op.drop_column('analytics', 'value2')
|
"analytics", sa.Column("value", sa.TEXT(), autoincrement=False, nullable=True)
|
||||||
op.drop_column('analytics', 'value1')
|
)
|
||||||
|
op.drop_column("analytics", "value2")
|
||||||
|
op.drop_column("analytics", "value1")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -12,36 +12,46 @@ from project import dbtypes
|
|||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = 'fd7794ece0b3'
|
revision = "fd7794ece0b3"
|
||||||
down_revision = '975c22ae802b'
|
down_revision = "975c22ae802b"
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
def upgrade():
|
def upgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.create_table('eventplace',
|
op.create_table(
|
||||||
sa.Column('created_at', sa.DateTime(), nullable=True),
|
"eventplace",
|
||||||
sa.Column('id', sa.Integer(), nullable=False),
|
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||||
sa.Column('name', sa.Unicode(length=255), nullable=False),
|
sa.Column("id", sa.Integer(), nullable=False),
|
||||||
sa.Column('location_id', sa.Integer(), nullable=True),
|
sa.Column("name", sa.Unicode(length=255), nullable=False),
|
||||||
sa.Column('photo_id', sa.Integer(), nullable=True),
|
sa.Column("location_id", sa.Integer(), nullable=True),
|
||||||
sa.Column('url', sa.String(length=255), nullable=True),
|
sa.Column("photo_id", sa.Integer(), nullable=True),
|
||||||
sa.Column('description', sa.UnicodeText(), nullable=True),
|
sa.Column("url", sa.String(length=255), nullable=True),
|
||||||
sa.Column('created_by_id', sa.Integer(), nullable=True),
|
sa.Column("description", sa.UnicodeText(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['created_by_id'], ['user.id'], ),
|
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||||
sa.ForeignKeyConstraint(['location_id'], ['location.id'], ),
|
sa.ForeignKeyConstraint(
|
||||||
sa.ForeignKeyConstraint(['photo_id'], ['image.id'], ),
|
["created_by_id"],
|
||||||
sa.PrimaryKeyConstraint('id')
|
["user.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["location_id"],
|
||||||
|
["location.id"],
|
||||||
|
),
|
||||||
|
sa.ForeignKeyConstraint(
|
||||||
|
["photo_id"],
|
||||||
|
["image.id"],
|
||||||
|
),
|
||||||
|
sa.PrimaryKeyConstraint("id"),
|
||||||
)
|
)
|
||||||
op.add_column('event', sa.Column('event_place_id', sa.Integer(), nullable=True))
|
op.add_column("event", sa.Column("event_place_id", sa.Integer(), nullable=True))
|
||||||
op.create_foreign_key(None, 'event', 'place', ['event_place_id'], ['id'])
|
op.create_foreign_key(None, "event", "place", ["event_place_id"], ["id"])
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|
||||||
|
|
||||||
def downgrade():
|
def downgrade():
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
# ### commands auto generated by Alembic - please adjust! ###
|
||||||
op.drop_constraint(None, 'event', type_='foreignkey')
|
op.drop_constraint(None, "event", type_="foreignkey")
|
||||||
op.drop_column('event', 'event_place_id')
|
op.drop_column("event", "event_place_id")
|
||||||
op.drop_table('eventplace')
|
op.drop_table("eventplace")
|
||||||
# ### end Alembic commands ###
|
# ### end Alembic commands ###
|
||||||
|
|||||||
@ -1,46 +1,45 @@
|
|||||||
import os
|
import os
|
||||||
from base64 import b64decode
|
from flask import Flask
|
||||||
from flask import jsonify, Flask, render_template, request, url_for, redirect, abort, flash, current_app
|
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
from sqlalchemy.orm import joinedload
|
from flask_security import (
|
||||||
from sqlalchemy.sql import asc, func
|
Security,
|
||||||
from sqlalchemy import and_, or_, not_, event
|
SQLAlchemySessionUserDatastore,
|
||||||
from flask_security import Security, current_user, auth_required, roles_required, SQLAlchemySessionUserDatastore
|
)
|
||||||
from flask_security.utils import FsPermNeed
|
from flask_babelex import Babel
|
||||||
from flask_babelex import Babel, gettext, lazy_gettext, format_datetime, to_user_timezone
|
|
||||||
from flask_principal import Permission
|
|
||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
import pytz
|
|
||||||
import json
|
|
||||||
from flask_qrcode import QRcode
|
from flask_qrcode import QRcode
|
||||||
from flask_mail import Mail, Message, email_dispatched
|
from flask_mail import Mail, email_dispatched
|
||||||
|
|
||||||
# Create app
|
# Create app
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ['DATABASE_URL']
|
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ["DATABASE_URL"]
|
||||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
||||||
app.config['SECURITY_CONFIRMABLE'] = False
|
app.config["SECURITY_CONFIRMABLE"] = False
|
||||||
app.config['SECURITY_TRACKABLE'] = True
|
app.config["SECURITY_TRACKABLE"] = True
|
||||||
app.config['SECURITY_REGISTERABLE'] = True
|
app.config["SECURITY_REGISTERABLE"] = True
|
||||||
app.config['SECURITY_SEND_REGISTER_EMAIL'] = False
|
app.config["SECURITY_SEND_REGISTER_EMAIL"] = False
|
||||||
app.config['SECURITY_RECOVERABLE'] = True
|
app.config["SECURITY_RECOVERABLE"] = True
|
||||||
app.config['SECURITY_CHANGEABLE'] = True
|
app.config["SECURITY_CHANGEABLE"] = True
|
||||||
app.config['SECURITY_EMAIL_SENDER'] = os.getenv("MAIL_DEFAULT_SENDER")
|
app.config["SECURITY_EMAIL_SENDER"] = os.getenv("MAIL_DEFAULT_SENDER")
|
||||||
app.config['LANGUAGES'] = ['en', 'de']
|
app.config["LANGUAGES"] = ["en", "de"]
|
||||||
app.config['GOOGLE_OAUTH_CLIENT_ID'] = os.getenv('GOOGLE_OAUTH_CLIENT_ID')
|
app.config["GOOGLE_OAUTH_CLIENT_ID"] = os.getenv("GOOGLE_OAUTH_CLIENT_ID")
|
||||||
app.config['GOOGLE_OAUTH_CLIENT_SECRET'] = os.getenv('GOOGLE_OAUTH_CLIENT_SECRET')
|
app.config["GOOGLE_OAUTH_CLIENT_SECRET"] = os.getenv("GOOGLE_OAUTH_CLIENT_SECRET")
|
||||||
app.config['OAUTHLIB_INSECURE_TRANSPORT'] = True
|
app.config["OAUTHLIB_INSECURE_TRANSPORT"] = True
|
||||||
app.config['OAUTHLIB_RELAX_TOKEN_SCOPE'] = True
|
app.config["OAUTHLIB_RELAX_TOKEN_SCOPE"] = True
|
||||||
|
|
||||||
# Generate a nice key using secrets.token_urlsafe()
|
# Generate a nice key using secrets.token_urlsafe()
|
||||||
app.config['SECRET_KEY'] = os.environ.get("SECRET_KEY", 'pf9Wkove4IKEAXvy-cQkeDPhv9Cb3Ag-wyJILbq_dFw')
|
app.config["SECRET_KEY"] = os.environ.get(
|
||||||
|
"SECRET_KEY", "pf9Wkove4IKEAXvy-cQkeDPhv9Cb3Ag-wyJILbq_dFw"
|
||||||
|
)
|
||||||
# Bcrypt is set as default SECURITY_PASSWORD_HASH, which requires a salt
|
# Bcrypt is set as default SECURITY_PASSWORD_HASH, which requires a salt
|
||||||
# Generate a good salt using: secrets.SystemRandom().getrandbits(128)
|
# Generate a good salt using: secrets.SystemRandom().getrandbits(128)
|
||||||
app.config['SECURITY_PASSWORD_SALT'] = os.environ.get("SECURITY_PASSWORD_SALT", '146585145368132386173505678016728509634')
|
app.config["SECURITY_PASSWORD_SALT"] = os.environ.get(
|
||||||
|
"SECURITY_PASSWORD_SALT", "146585145368132386173505678016728509634"
|
||||||
|
)
|
||||||
|
|
||||||
# i18n
|
# i18n
|
||||||
app.config['BABEL_DEFAULT_LOCALE'] = 'de'
|
app.config["BABEL_DEFAULT_LOCALE"] = "de"
|
||||||
app.config['BABEL_DEFAULT_TIMEZONE'] = 'Europe/Berlin'
|
app.config["BABEL_DEFAULT_TIMEZONE"] = "Europe/Berlin"
|
||||||
babel = Babel(app)
|
babel = Babel(app)
|
||||||
|
|
||||||
# cors
|
# cors
|
||||||
@ -50,24 +49,26 @@ cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
|
|||||||
mail_server = os.getenv("MAIL_SERVER")
|
mail_server = os.getenv("MAIL_SERVER")
|
||||||
|
|
||||||
if mail_server is None:
|
if mail_server is None:
|
||||||
app.config['MAIL_SUPPRESS_SEND'] = True
|
app.config["MAIL_SUPPRESS_SEND"] = True
|
||||||
app.config['MAIL_DEFAULT_SENDER'] = 'test@oveda.de'
|
app.config["MAIL_DEFAULT_SENDER"] = "test@oveda.de"
|
||||||
else:
|
else:
|
||||||
app.config['MAIL_SUPPRESS_SEND'] = False
|
app.config["MAIL_SUPPRESS_SEND"] = False
|
||||||
app.config['MAIL_SERVER'] = mail_server
|
app.config["MAIL_SERVER"] = mail_server
|
||||||
app.config['MAIL_PORT'] = os.getenv("MAIL_PORT")
|
app.config["MAIL_PORT"] = os.getenv("MAIL_PORT")
|
||||||
app.config['MAIL_USE_TLS'] = os.getenv("MAIL_USE_TLS", True)
|
app.config["MAIL_USE_TLS"] = os.getenv("MAIL_USE_TLS", True)
|
||||||
app.config['MAIL_USE_SSL'] = os.getenv("MAIL_USE_SSL", False)
|
app.config["MAIL_USE_SSL"] = os.getenv("MAIL_USE_SSL", False)
|
||||||
app.config['MAIL_USERNAME'] = os.getenv("MAIL_USERNAME")
|
app.config["MAIL_USERNAME"] = os.getenv("MAIL_USERNAME")
|
||||||
app.config['MAIL_PASSWORD'] = os.getenv("MAIL_PASSWORD")
|
app.config["MAIL_PASSWORD"] = os.getenv("MAIL_PASSWORD")
|
||||||
app.config['MAIL_DEFAULT_SENDER'] = os.getenv("MAIL_DEFAULT_SENDER")
|
app.config["MAIL_DEFAULT_SENDER"] = os.getenv("MAIL_DEFAULT_SENDER")
|
||||||
|
|
||||||
mail = Mail(app)
|
mail = Mail(app)
|
||||||
|
|
||||||
if app.config['MAIL_SUPPRESS_SEND']:
|
if app.config["MAIL_SUPPRESS_SEND"]:
|
||||||
|
|
||||||
def log_message(message, app):
|
def log_message(message, app):
|
||||||
print(message.subject)
|
print(message.subject)
|
||||||
print(message.body)
|
print(message.body)
|
||||||
|
|
||||||
email_dispatched.connect(log_message)
|
email_dispatched.connect(log_message)
|
||||||
|
|
||||||
# Create db
|
# Create db
|
||||||
@ -78,20 +79,23 @@ QRcode(app)
|
|||||||
|
|
||||||
# JSON
|
# JSON
|
||||||
from project.jsonld import DateTimeEncoder
|
from project.jsonld import DateTimeEncoder
|
||||||
|
|
||||||
app.json_encoder = DateTimeEncoder
|
app.json_encoder = DateTimeEncoder
|
||||||
|
|
||||||
# Setup Flask-Security
|
# Setup Flask-Security
|
||||||
from project.models import User, Role
|
from project.models import User, Role
|
||||||
|
|
||||||
user_datastore = SQLAlchemySessionUserDatastore(db.session, User, Role)
|
user_datastore = SQLAlchemySessionUserDatastore(db.session, User, Role)
|
||||||
security = Security(app, user_datastore)
|
security = Security(app, user_datastore)
|
||||||
|
|
||||||
# OAuth
|
# OAuth
|
||||||
from project.oauth import blueprint
|
from project.oauth import blueprint
|
||||||
|
|
||||||
app.register_blueprint(blueprint, url_prefix="/login")
|
app.register_blueprint(blueprint, url_prefix="/login")
|
||||||
|
|
||||||
from project.i10n import *
|
from project import i10n
|
||||||
from project.jinja_filters import *
|
from project import jinja_filters
|
||||||
from project.init_data import *
|
from project import init_data
|
||||||
|
|
||||||
# Routes
|
# Routes
|
||||||
from project.views import (
|
from project.views import (
|
||||||
@ -113,8 +117,8 @@ from project.views import (
|
|||||||
reference_request_review,
|
reference_request_review,
|
||||||
root,
|
root,
|
||||||
user,
|
user,
|
||||||
widget
|
widget,
|
||||||
)
|
)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
app.run()
|
app.run()
|
||||||
|
|||||||
@ -4,23 +4,29 @@ from flask_security.utils import FsPermNeed
|
|||||||
from flask_principal import Permission
|
from flask_principal import Permission
|
||||||
from project.models import AdminUnitMember, AdminUnit
|
from project.models import AdminUnitMember, AdminUnit
|
||||||
|
|
||||||
|
|
||||||
def has_current_user_permission(permission):
|
def has_current_user_permission(permission):
|
||||||
user_perm = Permission(FsPermNeed(permission))
|
user_perm = Permission(FsPermNeed(permission))
|
||||||
return user_perm.can()
|
return user_perm.can()
|
||||||
|
|
||||||
|
|
||||||
def has_admin_unit_member_permission(admin_unit_member, permission):
|
def has_admin_unit_member_permission(admin_unit_member, permission):
|
||||||
for role in admin_unit_member.roles:
|
for role in admin_unit_member.roles:
|
||||||
if permission in role.get_permissions():
|
if permission in role.get_permissions():
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def has_current_user_member_permission_for_admin_unit(admin_unit_id, permission):
|
def has_current_user_member_permission_for_admin_unit(admin_unit_id, permission):
|
||||||
admin_unit_member = AdminUnitMember.query.filter_by(admin_unit_id=admin_unit_id, user_id=current_user.id).first()
|
admin_unit_member = AdminUnitMember.query.filter_by(
|
||||||
|
admin_unit_id=admin_unit_id, user_id=current_user.id
|
||||||
|
).first()
|
||||||
if admin_unit_member is not None:
|
if admin_unit_member is not None:
|
||||||
if has_admin_unit_member_permission(admin_unit_member, permission):
|
if has_admin_unit_member_permission(admin_unit_member, permission):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def has_current_user_permission_for_admin_unit(admin_unit, permission):
|
def has_current_user_permission_for_admin_unit(admin_unit, permission):
|
||||||
if not current_user.is_authenticated:
|
if not current_user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
@ -33,40 +39,54 @@ def has_current_user_permission_for_admin_unit(admin_unit, permission):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def has_access(admin_unit, permission):
|
def has_access(admin_unit, permission):
|
||||||
return has_current_user_permission_for_admin_unit(admin_unit, permission)
|
return has_current_user_permission_for_admin_unit(admin_unit, permission)
|
||||||
|
|
||||||
|
|
||||||
def access_or_401(admin_unit, permission):
|
def access_or_401(admin_unit, permission):
|
||||||
if not has_access(admin_unit, permission):
|
if not has_access(admin_unit, permission):
|
||||||
abort(401)
|
abort(401)
|
||||||
|
|
||||||
|
|
||||||
def can_list_admin_unit_members(admin_unit):
|
def can_list_admin_unit_members(admin_unit):
|
||||||
return has_current_user_permission_for_admin_unit(admin_unit, 'admin_unit.members:read')
|
return has_current_user_permission_for_admin_unit(
|
||||||
|
admin_unit, "admin_unit.members:read"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def can_create_event(admin_unit):
|
def can_create_event(admin_unit):
|
||||||
return has_current_user_permission_for_admin_unit(admin_unit, 'event:create')
|
return has_current_user_permission_for_admin_unit(admin_unit, "event:create")
|
||||||
|
|
||||||
|
|
||||||
def can_update_event(event):
|
def can_update_event(event):
|
||||||
return has_current_user_permission_for_admin_unit(event.admin_unit, 'event:update')
|
return has_current_user_permission_for_admin_unit(event.admin_unit, "event:update")
|
||||||
|
|
||||||
|
|
||||||
def can_delete_event(event):
|
def can_delete_event(event):
|
||||||
return has_current_user_permission_for_admin_unit(event.admin_unit, 'event:delete')
|
return has_current_user_permission_for_admin_unit(event.admin_unit, "event:delete")
|
||||||
|
|
||||||
|
|
||||||
def can_reference_event(event):
|
def can_reference_event(event):
|
||||||
return len(get_admin_units_for_event_reference(event)) > 0
|
return len(get_admin_units_for_event_reference(event)) > 0
|
||||||
|
|
||||||
|
|
||||||
def can_update_organizer(organizer):
|
def can_update_organizer(organizer):
|
||||||
return get_admin_unit_for_manage(organizer.admin_unit_id) is not None
|
return get_admin_unit_for_manage(organizer.admin_unit_id) is not None
|
||||||
|
|
||||||
|
|
||||||
def can_create_admin_unit():
|
def can_create_admin_unit():
|
||||||
return current_user.is_authenticated
|
return current_user.is_authenticated
|
||||||
|
|
||||||
|
|
||||||
def can_verify_event_for_admin_unit(admin_unit):
|
def can_verify_event_for_admin_unit(admin_unit):
|
||||||
return has_current_user_permission_for_admin_unit(admin_unit, 'event:verify')
|
return has_current_user_permission_for_admin_unit(admin_unit, "event:verify")
|
||||||
|
|
||||||
|
|
||||||
def can_verify_event(event):
|
def can_verify_event(event):
|
||||||
return can_verify_event_for_admin_unit(event.admin_unit)
|
return can_verify_event_for_admin_unit(event.admin_unit)
|
||||||
|
|
||||||
|
|
||||||
def get_admin_units_with_current_user_permission(permission):
|
def get_admin_units_with_current_user_permission(permission):
|
||||||
result = list()
|
result = list()
|
||||||
|
|
||||||
@ -77,41 +97,48 @@ def get_admin_units_with_current_user_permission(permission):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_admin_units_for_event_reference(event):
|
def get_admin_units_for_event_reference(event):
|
||||||
result = list()
|
result = list()
|
||||||
|
|
||||||
admin_units = get_admin_units_with_current_user_permission('event:reference')
|
admin_units = get_admin_units_with_current_user_permission("event:reference")
|
||||||
for admin_unit in admin_units:
|
for admin_unit in admin_units:
|
||||||
if admin_unit.id != event.admin_unit_id:
|
if admin_unit.id != event.admin_unit_id:
|
||||||
result.append(admin_unit)
|
result.append(admin_unit)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def admin_units_the_current_user_is_member_of():
|
def admin_units_the_current_user_is_member_of():
|
||||||
result = list()
|
result = list()
|
||||||
|
|
||||||
if current_user.is_authenticated:
|
if current_user.is_authenticated:
|
||||||
admin_unit_members = AdminUnitMember.query.filter_by(user_id=current_user.id).all()
|
admin_unit_members = AdminUnitMember.query.filter_by(
|
||||||
|
user_id=current_user.id
|
||||||
|
).all()
|
||||||
for admin_unit_member in admin_unit_members:
|
for admin_unit_member in admin_unit_members:
|
||||||
result.append(admin_unit_member.adminunit)
|
result.append(admin_unit_member.adminunit)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_admin_units_for_manage():
|
def get_admin_units_for_manage():
|
||||||
# Global admin
|
# Global admin
|
||||||
if current_user.has_role('admin'):
|
if current_user.has_role("admin"):
|
||||||
return AdminUnit.query.all()
|
return AdminUnit.query.all()
|
||||||
|
|
||||||
return admin_units_the_current_user_is_member_of()
|
return admin_units_the_current_user_is_member_of()
|
||||||
|
|
||||||
|
|
||||||
def get_admin_unit_for_manage(admin_unit_id):
|
def get_admin_unit_for_manage(admin_unit_id):
|
||||||
admin_units = get_admin_units_for_manage()
|
admin_units = get_admin_units_for_manage()
|
||||||
return next((au for au in admin_units if au.id == admin_unit_id), None)
|
return next((au for au in admin_units if au.id == admin_unit_id), None)
|
||||||
|
|
||||||
|
|
||||||
def get_admin_unit_for_manage_or_404(admin_unit_id):
|
def get_admin_unit_for_manage_or_404(admin_unit_id):
|
||||||
admin_unit = get_admin_unit_for_manage(admin_unit_id)
|
admin_unit = get_admin_unit_for_manage(admin_unit_id)
|
||||||
|
|
||||||
if not admin_unit:
|
if not admin_unit:
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
return admin_unit
|
return admin_unit
|
||||||
|
|||||||
@ -1,41 +1,58 @@
|
|||||||
import pytz
|
import pytz
|
||||||
from dateutil import rrule
|
from dateutil.rrule import rrulestr
|
||||||
from dateutil.rrule import rrulestr, rruleset, rrule
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
berlin_tz = pytz.timezone('Europe/Berlin')
|
berlin_tz = pytz.timezone("Europe/Berlin")
|
||||||
now = datetime.now(tz=berlin_tz)
|
now = datetime.now(tz=berlin_tz)
|
||||||
today = datetime(now.year, now.month, now.day, tzinfo=now.tzinfo)
|
today = datetime(now.year, now.month, now.day, tzinfo=now.tzinfo)
|
||||||
|
|
||||||
def create_berlin_date(year, month, day, hour, minute = 0):
|
|
||||||
|
def create_berlin_date(year, month, day, hour, minute=0):
|
||||||
return berlin_tz.localize(datetime(year, month, day, hour=hour, minute=minute))
|
return berlin_tz.localize(datetime(year, month, day, hour=hour, minute=minute))
|
||||||
|
|
||||||
|
|
||||||
def date_add_time(date, hour=0, minute=0, second=0, tzinfo=None):
|
def date_add_time(date, hour=0, minute=0, second=0, tzinfo=None):
|
||||||
return datetime(date.year, date.month, date.day, hour=hour, minute=minute, second=second, tzinfo=tzinfo)
|
return datetime(
|
||||||
|
date.year,
|
||||||
|
date.month,
|
||||||
|
date.day,
|
||||||
|
hour=hour,
|
||||||
|
minute=minute,
|
||||||
|
second=second,
|
||||||
|
tzinfo=tzinfo,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def date_set_end_of_day(date):
|
def date_set_end_of_day(date):
|
||||||
return date_add_time(date, hour=23, minute=59, second=59)
|
return date_add_time(date, hour=23, minute=59, second=59)
|
||||||
|
|
||||||
|
|
||||||
def form_input_to_date(date_str, hour=0, minute=0, second=0):
|
def form_input_to_date(date_str, hour=0, minute=0, second=0):
|
||||||
date = datetime.strptime(date_str, "%Y-%m-%d")
|
date = datetime.strptime(date_str, "%Y-%m-%d")
|
||||||
date_time = date_add_time(date, hour=hour, minute=minute, second=second)
|
date_time = date_add_time(date, hour=hour, minute=minute, second=second)
|
||||||
return berlin_tz.localize(date_time)
|
return berlin_tz.localize(date_time)
|
||||||
|
|
||||||
|
|
||||||
def form_input_from_date(date):
|
def form_input_from_date(date):
|
||||||
return date.strftime("%Y-%m-%d")
|
return date.strftime("%Y-%m-%d")
|
||||||
|
|
||||||
|
|
||||||
def dates_from_recurrence_rule(start, recurrence_rule):
|
def dates_from_recurrence_rule(start, recurrence_rule):
|
||||||
result = list()
|
result = list()
|
||||||
|
|
||||||
adv_recurrence_rule = recurrence_rule.replace('T000000', 'T235959')
|
adv_recurrence_rule = recurrence_rule.replace("T000000", "T235959")
|
||||||
start_wo_tz = start.replace(tzinfo=None)
|
start_wo_tz = start.replace(tzinfo=None)
|
||||||
rule_set = rrulestr(adv_recurrence_rule, forceset=True, dtstart=start_wo_tz)
|
rule_set = rrulestr(adv_recurrence_rule, forceset=True, dtstart=start_wo_tz)
|
||||||
|
|
||||||
start_date = start_wo_tz
|
start_date = start_wo_tz
|
||||||
end_date = start_date + relativedelta(years=1)
|
end_date = start_date + relativedelta(years=1)
|
||||||
start_date_begin_of_day = datetime(start_date.year, start_date.month, start_date.day)
|
start_date_begin_of_day = datetime(
|
||||||
end_date_end_of_day = datetime(end_date.year, end_date.month, end_date.day, hour=23, minute=59, second=59)
|
start_date.year, start_date.month, start_date.day
|
||||||
|
)
|
||||||
|
end_date_end_of_day = datetime(
|
||||||
|
end_date.year, end_date.month, end_date.day, hour=23, minute=59, second=59
|
||||||
|
)
|
||||||
|
|
||||||
for rule_date in rule_set.between(start_date_begin_of_day, end_date_end_of_day):
|
for rule_date in rule_set.between(start_date_begin_of_day, end_date_end_of_day):
|
||||||
rule_data_w_tz = berlin_tz.localize(rule_date)
|
rule_data_w_tz = berlin_tz.localize(rule_date)
|
||||||
@ -43,7 +60,9 @@ def dates_from_recurrence_rule(start, recurrence_rule):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
BATCH_DELTA = 3 # How many batches to show before + after current batch
|
|
||||||
|
BATCH_DELTA = 3 # How many batches to show before + after current batch
|
||||||
|
|
||||||
|
|
||||||
def calculate_occurrences(start_date, date_format, rrule_str, start, batch_size):
|
def calculate_occurrences(start_date, date_format, rrule_str, start, batch_size):
|
||||||
# TODO: Return error on failure
|
# TODO: Return error on failure
|
||||||
@ -53,9 +72,9 @@ def calculate_occurrences(start_date, date_format, rrule_str, start, batch_size)
|
|||||||
iterator = iter(rule)
|
iterator = iter(rule)
|
||||||
|
|
||||||
cur_batch = start // batch_size
|
cur_batch = start // batch_size
|
||||||
start = cur_batch * batch_size # Avoid stupid start-values
|
start = cur_batch * batch_size # Avoid stupid start-values
|
||||||
|
|
||||||
if hasattr(rule, '_exdate'):
|
if hasattr(rule, "_exdate"):
|
||||||
exdates = sorted(rule._exdate)
|
exdates = sorted(rule._exdate)
|
||||||
else:
|
else:
|
||||||
exdates = []
|
exdates = []
|
||||||
@ -79,13 +98,17 @@ def calculate_occurrences(start_date, date_format, rrule_str, start, batch_size)
|
|||||||
else:
|
else:
|
||||||
# include them
|
# include them
|
||||||
exdate = exdates.pop(0)
|
exdate = exdates.pop(0)
|
||||||
occurrences.append({'date': exdate.strftime('%Y%m%dT%H%M%S'),
|
occurrences.append(
|
||||||
'formattedDate': exdate.strftime(date_format),
|
{
|
||||||
'type': 'exdate',})
|
"date": exdate.strftime("%Y%m%dT%H%M%S"),
|
||||||
|
"formattedDate": exdate.strftime(date_format),
|
||||||
|
"type": "exdate",
|
||||||
|
}
|
||||||
|
)
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
if i >= batch_size + start:
|
if i >= batch_size + start:
|
||||||
break # We are done!
|
break # We are done!
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
if i <= start:
|
if i <= start:
|
||||||
@ -93,24 +116,32 @@ def calculate_occurrences(start_date, date_format, rrule_str, start, batch_size)
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Add it to the results
|
# Add it to the results
|
||||||
if date in getattr(rule, '_rdate', []):
|
if date in getattr(rule, "_rdate", []):
|
||||||
occurrence_type = 'rdate'
|
occurrence_type = "rdate"
|
||||||
elif date == start_date:
|
elif date == start_date:
|
||||||
occurrence_type = 'start'
|
occurrence_type = "start"
|
||||||
else:
|
else:
|
||||||
occurrence_type = 'rrule'
|
occurrence_type = "rrule"
|
||||||
occurrences.append({'date': date.strftime('%Y%m%dT%H%M%S'),
|
occurrences.append(
|
||||||
'formattedDate': date.strftime(date_format),
|
{
|
||||||
'type': occurrence_type,})
|
"date": date.strftime("%Y%m%dT%H%M%S"),
|
||||||
|
"formattedDate": date.strftime(date_format),
|
||||||
|
"type": occurrence_type,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
while exdates:
|
while exdates:
|
||||||
# There are exdates that are after the end of the recurrence.
|
# There are exdates that are after the end of the recurrence.
|
||||||
# Excluding the last dates make no sense, as you can change the
|
# Excluding the last dates make no sense, as you can change the
|
||||||
# range instead, but we need to support it anyway.
|
# range instead, but we need to support it anyway.
|
||||||
exdate = exdates.pop(0)
|
exdate = exdates.pop(0)
|
||||||
occurrences.append({'date': exdate.strftime('%Y%m%dT%H%M%S'),
|
occurrences.append(
|
||||||
'formattedDate': exdate.strftime(date_format),
|
{
|
||||||
'type': 'exdate',})
|
"date": exdate.strftime("%Y%m%dT%H%M%S"),
|
||||||
|
"formattedDate": exdate.strftime(date_format),
|
||||||
|
"type": "exdate",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
# Calculate no of occurrences, but only to a max of three times
|
# Calculate no of occurrences, but only to a max of three times
|
||||||
# the batch size. This will support infinite recurrence in a
|
# the batch size. This will support infinite recurrence in a
|
||||||
@ -132,18 +163,21 @@ def calculate_occurrences(start_date, date_format, rrule_str, start, batch_size)
|
|||||||
# Total number of occurrences:
|
# Total number of occurrences:
|
||||||
num_occurrences += batch_size + start
|
num_occurrences += batch_size + start
|
||||||
|
|
||||||
max_batch = (num_occurrences - 1)//batch_size
|
max_batch = (num_occurrences - 1) // batch_size
|
||||||
if last_batch > max_batch:
|
if last_batch > max_batch:
|
||||||
last_batch = max_batch
|
last_batch = max_batch
|
||||||
first_batch = max(0, max_batch - (BATCH_DELTA * 2))
|
first_batch = max(0, max_batch - (BATCH_DELTA * 2))
|
||||||
|
|
||||||
batches = [((x * batch_size) + 1, (x + 1) * batch_size) for x in range(first_batch, last_batch + 1)]
|
batches = [
|
||||||
batch_data = {'start': start,
|
((x * batch_size) + 1, (x + 1) * batch_size)
|
||||||
'end': num_occurrences,
|
for x in range(first_batch, last_batch + 1)
|
||||||
'batch_size': batch_size,
|
]
|
||||||
'batches': batches,
|
batch_data = {
|
||||||
'currentBatch': cur_batch - first_batch,
|
"start": start,
|
||||||
}
|
"end": num_occurrences,
|
||||||
|
"batch_size": batch_size,
|
||||||
return {'occurrences': occurrences, 'batch': batch_data}
|
"batches": batches,
|
||||||
|
"currentBatch": cur_batch - first_batch,
|
||||||
|
}
|
||||||
|
|
||||||
|
return {"occurrences": occurrences, "batch": batch_data}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
from sqlalchemy.types import TypeDecorator
|
from sqlalchemy.types import TypeDecorator
|
||||||
from sqlalchemy import Integer
|
from sqlalchemy import Integer
|
||||||
|
|
||||||
|
|
||||||
class IntegerEnum(TypeDecorator):
|
class IntegerEnum(TypeDecorator):
|
||||||
impl = Integer
|
impl = Integer
|
||||||
|
|
||||||
def __init__(self, enumtype, *args, **kwargs):
|
def __init__(self, enumtype, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self._enumtype = enumtype
|
self._enumtype = enumtype
|
||||||
|
|||||||
@ -1,49 +1,90 @@
|
|||||||
from flask_babelex import lazy_gettext
|
from flask_babelex import lazy_gettext
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_wtf.file import FileField, FileAllowed
|
from wtforms import (
|
||||||
from wtforms import StringField, SubmitField, DecimalField, TextAreaField, FormField, SelectField
|
StringField,
|
||||||
|
SubmitField,
|
||||||
|
DecimalField,
|
||||||
|
FormField,
|
||||||
|
)
|
||||||
from wtforms.fields.html5 import EmailField, TelField, URLField
|
from wtforms.fields.html5 import EmailField, TelField, URLField
|
||||||
from wtforms.validators import DataRequired, Optional, Regexp
|
from wtforms.validators import DataRequired, Optional, Regexp
|
||||||
from wtforms.widgets.html5 import ColorInput
|
from wtforms.widgets.html5 import ColorInput
|
||||||
import decimal
|
|
||||||
from project.models import Location, Image
|
from project.models import Location, Image
|
||||||
from project.forms.common import FileImageForm
|
from project.forms.common import FileImageForm
|
||||||
|
|
||||||
|
|
||||||
class AdminUnitLocationForm(FlaskForm):
|
class AdminUnitLocationForm(FlaskForm):
|
||||||
street = StringField(lazy_gettext('Street'), validators=[Optional()])
|
street = StringField(lazy_gettext("Street"), validators=[Optional()])
|
||||||
postalCode = StringField(lazy_gettext('Postal code'), validators=[DataRequired()])
|
postalCode = StringField(lazy_gettext("Postal code"), validators=[DataRequired()])
|
||||||
city = StringField(lazy_gettext('City'), validators=[DataRequired()])
|
city = StringField(lazy_gettext("City"), validators=[DataRequired()])
|
||||||
state = StringField(lazy_gettext('State'), validators=[Optional()])
|
state = StringField(lazy_gettext("State"), validators=[Optional()])
|
||||||
latitude = DecimalField(lazy_gettext('Latitude'), places=16, validators=[Optional()])
|
latitude = DecimalField(
|
||||||
longitude = DecimalField(lazy_gettext('Longitude'), places=16, validators=[Optional()])
|
lazy_gettext("Latitude"), places=16, validators=[Optional()]
|
||||||
|
)
|
||||||
|
longitude = DecimalField(
|
||||||
|
lazy_gettext("Longitude"), places=16, validators=[Optional()]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class BaseAdminUnitForm(FlaskForm):
|
class BaseAdminUnitForm(FlaskForm):
|
||||||
name = StringField(lazy_gettext('Name'), validators=[DataRequired()])
|
name = StringField(lazy_gettext("Name"), validators=[DataRequired()])
|
||||||
short_name = StringField(lazy_gettext('Short name'), description=lazy_gettext('The short name is used to create a unique identifier for your events'), validators=[DataRequired(), Regexp('^\w+$', message=lazy_gettext("Short name must contain only letters numbers or underscore"))])
|
short_name = StringField(
|
||||||
url = URLField(lazy_gettext('Link URL'), validators=[Optional()])
|
lazy_gettext("Short name"),
|
||||||
email = EmailField(lazy_gettext('Email'), validators=[Optional()])
|
description=lazy_gettext(
|
||||||
phone = TelField(lazy_gettext('Phone'), validators=[Optional()])
|
"The short name is used to create a unique identifier for your events"
|
||||||
fax = TelField(lazy_gettext('Fax'), validators=[Optional()])
|
),
|
||||||
logo = FormField(FileImageForm, lazy_gettext('Logo'), default=lambda: Image())
|
validators=[
|
||||||
|
DataRequired(),
|
||||||
|
Regexp(
|
||||||
|
r"^\w+$",
|
||||||
|
message=lazy_gettext(
|
||||||
|
"Short name must contain only letters numbers or underscore"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
url = URLField(lazy_gettext("Link URL"), validators=[Optional()])
|
||||||
|
email = EmailField(lazy_gettext("Email"), validators=[Optional()])
|
||||||
|
phone = TelField(lazy_gettext("Phone"), validators=[Optional()])
|
||||||
|
fax = TelField(lazy_gettext("Fax"), validators=[Optional()])
|
||||||
|
logo = FormField(FileImageForm, lazy_gettext("Logo"), default=lambda: Image())
|
||||||
location = FormField(AdminUnitLocationForm, default=lambda: Location())
|
location = FormField(AdminUnitLocationForm, default=lambda: Location())
|
||||||
|
|
||||||
def populate_obj(self, obj):
|
def populate_obj(self, obj):
|
||||||
for name, field in self._fields.items():
|
for name, field in self._fields.items():
|
||||||
if name == 'location' and not obj.location:
|
if name == "location" and not obj.location:
|
||||||
obj.location = Location()
|
obj.location = Location()
|
||||||
elif name == 'logo' and not obj.logo:
|
elif name == "logo" and not obj.logo:
|
||||||
obj.logo = Image()
|
obj.logo = Image()
|
||||||
field.populate_obj(obj, name)
|
field.populate_obj(obj, name)
|
||||||
|
|
||||||
|
|
||||||
class CreateAdminUnitForm(BaseAdminUnitForm):
|
class CreateAdminUnitForm(BaseAdminUnitForm):
|
||||||
submit = SubmitField(lazy_gettext("Create admin unit"))
|
submit = SubmitField(lazy_gettext("Create admin unit"))
|
||||||
|
|
||||||
|
|
||||||
class UpdateAdminUnitForm(BaseAdminUnitForm):
|
class UpdateAdminUnitForm(BaseAdminUnitForm):
|
||||||
submit = SubmitField(lazy_gettext("Update settings"))
|
submit = SubmitField(lazy_gettext("Update settings"))
|
||||||
|
|
||||||
|
|
||||||
class UpdateAdminUnitWidgetForm(FlaskForm):
|
class UpdateAdminUnitWidgetForm(FlaskForm):
|
||||||
widget_font = StringField(lazy_gettext('Font'), validators=[Optional()])
|
widget_font = StringField(lazy_gettext("Font"), validators=[Optional()])
|
||||||
widget_background_color = StringField(lazy_gettext('Background Color'), default='#ffffff', widget=ColorInput(), validators=[Optional()])
|
widget_background_color = StringField(
|
||||||
widget_primary_color = StringField(lazy_gettext('Primary Color'), default='#007bff', widget=ColorInput(), validators=[Optional()])
|
lazy_gettext("Background Color"),
|
||||||
widget_link_color = StringField(lazy_gettext('Link Color'), default='#007bff', widget=ColorInput(), validators=[Optional()])
|
default="#ffffff",
|
||||||
submit = SubmitField(lazy_gettext("Update settings"))
|
widget=ColorInput(),
|
||||||
|
validators=[Optional()],
|
||||||
|
)
|
||||||
|
widget_primary_color = StringField(
|
||||||
|
lazy_gettext("Primary Color"),
|
||||||
|
default="#007bff",
|
||||||
|
widget=ColorInput(),
|
||||||
|
validators=[Optional()],
|
||||||
|
)
|
||||||
|
widget_link_color = StringField(
|
||||||
|
lazy_gettext("Link Color"),
|
||||||
|
default="#007bff",
|
||||||
|
widget=ColorInput(),
|
||||||
|
validators=[Optional()],
|
||||||
|
)
|
||||||
|
submit = SubmitField(lazy_gettext("Update settings"))
|
||||||
|
|||||||
@ -1,31 +1,32 @@
|
|||||||
from flask_babelex import lazy_gettext
|
from flask_babelex import lazy_gettext
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_wtf.file import FileField, FileAllowed
|
from wtforms import SubmitField
|
||||||
from wtforms import StringField, SubmitField, DecimalField, TextAreaField, FormField, SelectField
|
from wtforms.fields.html5 import EmailField
|
||||||
from wtforms.fields.html5 import EmailField, TelField
|
from wtforms.validators import DataRequired
|
||||||
from wtforms.validators import DataRequired, Optional, Regexp
|
|
||||||
import decimal
|
|
||||||
from project.models import Location
|
|
||||||
from project.forms.widgets import MultiCheckboxField
|
from project.forms.widgets import MultiCheckboxField
|
||||||
|
|
||||||
|
|
||||||
class InviteAdminUnitMemberForm(FlaskForm):
|
class InviteAdminUnitMemberForm(FlaskForm):
|
||||||
email = EmailField(lazy_gettext('Email'), validators=[DataRequired()])
|
email = EmailField(lazy_gettext("Email"), validators=[DataRequired()])
|
||||||
roles = MultiCheckboxField(lazy_gettext('Roles'))
|
roles = MultiCheckboxField(lazy_gettext("Roles"))
|
||||||
submit = SubmitField(lazy_gettext("Invite"))
|
submit = SubmitField(lazy_gettext("Invite"))
|
||||||
|
|
||||||
|
|
||||||
class NegotiateAdminUnitMemberInvitationForm(FlaskForm):
|
class NegotiateAdminUnitMemberInvitationForm(FlaskForm):
|
||||||
accept = SubmitField(lazy_gettext("Accept"))
|
accept = SubmitField(lazy_gettext("Accept"))
|
||||||
decline = SubmitField(lazy_gettext("Decline"))
|
decline = SubmitField(lazy_gettext("Decline"))
|
||||||
|
|
||||||
|
|
||||||
class DeleteAdminUnitInvitationForm(FlaskForm):
|
class DeleteAdminUnitInvitationForm(FlaskForm):
|
||||||
submit = SubmitField(lazy_gettext("Delete invitation"))
|
submit = SubmitField(lazy_gettext("Delete invitation"))
|
||||||
email = EmailField(lazy_gettext('Email'), validators=[DataRequired()])
|
email = EmailField(lazy_gettext("Email"), validators=[DataRequired()])
|
||||||
|
|
||||||
|
|
||||||
class DeleteAdminUnitMemberForm(FlaskForm):
|
class DeleteAdminUnitMemberForm(FlaskForm):
|
||||||
submit = SubmitField(lazy_gettext("Delete member"))
|
submit = SubmitField(lazy_gettext("Delete member"))
|
||||||
email = EmailField(lazy_gettext('Email'), validators=[DataRequired()])
|
email = EmailField(lazy_gettext("Email"), validators=[DataRequired()])
|
||||||
|
|
||||||
|
|
||||||
class UpdateAdminUnitMemberForm(FlaskForm):
|
class UpdateAdminUnitMemberForm(FlaskForm):
|
||||||
roles = MultiCheckboxField(lazy_gettext('Roles'))
|
roles = MultiCheckboxField(lazy_gettext("Roles"))
|
||||||
submit = SubmitField(lazy_gettext("Update member"))
|
submit = SubmitField(lazy_gettext("Update member"))
|
||||||
|
|
||||||
|
|||||||
@ -2,16 +2,25 @@ from flask_babelex import lazy_gettext
|
|||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_wtf.file import FileField, FileAllowed
|
from flask_wtf.file import FileField, FileAllowed
|
||||||
from wtforms import StringField, BooleanField, HiddenField
|
from wtforms import StringField, BooleanField, HiddenField
|
||||||
from wtforms.validators import DataRequired, Optional
|
from wtforms.validators import Optional
|
||||||
import re
|
import re
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
|
|
||||||
class BaseImageForm(FlaskForm):
|
class BaseImageForm(FlaskForm):
|
||||||
copyright_text = StringField(lazy_gettext('Copyright text'), validators=[Optional()])
|
copyright_text = StringField(
|
||||||
|
lazy_gettext("Copyright text"), validators=[Optional()]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FileImageForm(BaseImageForm):
|
class FileImageForm(BaseImageForm):
|
||||||
image_file = FileField(lazy_gettext('File'), validators=[FileAllowed(['jpg', 'jpeg', 'png'], lazy_gettext('Images only!'))])
|
image_file = FileField(
|
||||||
delete_flag = BooleanField(lazy_gettext('Delete image'), default=False, validators=[Optional()])
|
lazy_gettext("File"),
|
||||||
|
validators=[FileAllowed(["jpg", "jpeg", "png"], lazy_gettext("Images only!"))],
|
||||||
|
)
|
||||||
|
delete_flag = BooleanField(
|
||||||
|
lazy_gettext("Delete image"), default=False, validators=[Optional()]
|
||||||
|
)
|
||||||
|
|
||||||
def populate_obj(self, obj):
|
def populate_obj(self, obj):
|
||||||
super(BaseImageForm, self).populate_obj(obj)
|
super(BaseImageForm, self).populate_obj(obj)
|
||||||
@ -24,6 +33,7 @@ class FileImageForm(BaseImageForm):
|
|||||||
obj.data = None
|
obj.data = None
|
||||||
obj.encoding_format = None
|
obj.encoding_format = None
|
||||||
|
|
||||||
|
|
||||||
class Base64ImageForm(BaseImageForm):
|
class Base64ImageForm(BaseImageForm):
|
||||||
image_base64 = HiddenField()
|
image_base64 = HiddenField()
|
||||||
|
|
||||||
@ -31,8 +41,10 @@ class Base64ImageForm(BaseImageForm):
|
|||||||
super(BaseImageForm, self).process(formdata, obj, data, **kwargs)
|
super(BaseImageForm, self).process(formdata, obj, data, **kwargs)
|
||||||
|
|
||||||
if self.image_base64.data is None and obj and obj.data:
|
if self.image_base64.data is None and obj and obj.data:
|
||||||
base64_str = base64.b64encode(obj.data).decode('utf-8')
|
base64_str = base64.b64encode(obj.data).decode("utf-8")
|
||||||
self.image_base64.data = 'data:{};base64,{}'.format(obj.encoding_format, base64_str)
|
self.image_base64.data = "data:{};base64,{}".format(
|
||||||
|
obj.encoding_format, base64_str
|
||||||
|
)
|
||||||
|
|
||||||
def populate_obj(self, obj):
|
def populate_obj(self, obj):
|
||||||
super(BaseImageForm, self).populate_obj(obj)
|
super(BaseImageForm, self).populate_obj(obj)
|
||||||
@ -49,35 +61,36 @@ class Base64ImageForm(BaseImageForm):
|
|||||||
obj.data = None
|
obj.data = None
|
||||||
obj.encoding_format = None
|
obj.encoding_format = None
|
||||||
|
|
||||||
|
|
||||||
event_rating_choices = [
|
event_rating_choices = [
|
||||||
(0,lazy_gettext('0 (Little relevant)')),
|
(0, lazy_gettext("0 (Little relevant)")),
|
||||||
(10,'1'),
|
(10, "1"),
|
||||||
(20,'2'),
|
(20, "2"),
|
||||||
(30,'3'),
|
(30, "3"),
|
||||||
(40,'4'),
|
(40, "4"),
|
||||||
(50,'5'),
|
(50, "5"),
|
||||||
(60,'6'),
|
(60, "6"),
|
||||||
(70,'7'),
|
(70, "7"),
|
||||||
(80,'8'),
|
(80, "8"),
|
||||||
(90,'9'),
|
(90, "9"),
|
||||||
(100,lazy_gettext('10 (Highlight)'))
|
(100, lazy_gettext("10 (Highlight)")),
|
||||||
]
|
]
|
||||||
|
|
||||||
weekday_choices = [
|
weekday_choices = [
|
||||||
(1,lazy_gettext('Monday')),
|
(1, lazy_gettext("Monday")),
|
||||||
(2,lazy_gettext('Tueday')),
|
(2, lazy_gettext("Tueday")),
|
||||||
(3,lazy_gettext('Wednesday')),
|
(3, lazy_gettext("Wednesday")),
|
||||||
(4,lazy_gettext('Thursday')),
|
(4, lazy_gettext("Thursday")),
|
||||||
(5,lazy_gettext('Friday')),
|
(5, lazy_gettext("Friday")),
|
||||||
(6,lazy_gettext('Saturday')),
|
(6, lazy_gettext("Saturday")),
|
||||||
(0,lazy_gettext('Sunday'))
|
(0, lazy_gettext("Sunday")),
|
||||||
]
|
]
|
||||||
|
|
||||||
distance_choices = [
|
distance_choices = [
|
||||||
(500,lazy_gettext('500 m')),
|
(500, lazy_gettext("500 m")),
|
||||||
(5000,lazy_gettext('5 km')),
|
(5000, lazy_gettext("5 km")),
|
||||||
(10000,lazy_gettext('10 km')),
|
(10000, lazy_gettext("10 km")),
|
||||||
(25000,lazy_gettext('20 km')),
|
(25000, lazy_gettext("20 km")),
|
||||||
(50000,lazy_gettext('50 km')),
|
(50000, lazy_gettext("50 km")),
|
||||||
(100000,lazy_gettext('100 km'))
|
(100000, lazy_gettext("100 km")),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,100 +1,183 @@
|
|||||||
from flask import request
|
from flask import request
|
||||||
from flask_babelex import lazy_gettext, gettext
|
from flask_babelex import lazy_gettext, gettext
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_wtf.file import FileField, FileAllowed
|
from wtforms import (
|
||||||
from wtforms import SelectMultipleField, FieldList, RadioField, DateTimeField, StringField, SubmitField, TextAreaField, SelectField, BooleanField, IntegerField, FormField
|
SelectMultipleField,
|
||||||
from wtforms.fields.html5 import DateTimeLocalField, EmailField, URLField
|
RadioField,
|
||||||
|
StringField,
|
||||||
|
SubmitField,
|
||||||
|
TextAreaField,
|
||||||
|
SelectField,
|
||||||
|
BooleanField,
|
||||||
|
IntegerField,
|
||||||
|
FormField,
|
||||||
|
)
|
||||||
|
from wtforms.fields.html5 import EmailField, URLField
|
||||||
from wtforms.validators import DataRequired, Optional
|
from wtforms.validators import DataRequired, Optional
|
||||||
from wtforms.widgets import html_params, HTMLString
|
from project.models import (
|
||||||
from project.models import EventPlace, EventTargetGroupOrigin, EventAttendanceMode, EventStatus, Location, EventOrganizer, EventRejectionReason, EventReviewStatus, Image
|
EventPlace,
|
||||||
|
EventTargetGroupOrigin,
|
||||||
|
EventAttendanceMode,
|
||||||
|
EventStatus,
|
||||||
|
Location,
|
||||||
|
EventOrganizer,
|
||||||
|
Image,
|
||||||
|
)
|
||||||
from project.forms.common import event_rating_choices, Base64ImageForm
|
from project.forms.common import event_rating_choices, Base64ImageForm
|
||||||
from project.forms.widgets import CustomDateTimeField, CustomDateField
|
from project.forms.widgets import CustomDateTimeField, CustomDateField
|
||||||
|
|
||||||
|
|
||||||
class EventPlaceLocationForm(FlaskForm):
|
class EventPlaceLocationForm(FlaskForm):
|
||||||
street = StringField(lazy_gettext('Street'), validators=[Optional()])
|
street = StringField(lazy_gettext("Street"), validators=[Optional()])
|
||||||
postalCode = StringField(lazy_gettext('Postal code'), validators=[Optional()])
|
postalCode = StringField(lazy_gettext("Postal code"), validators=[Optional()])
|
||||||
city = StringField(lazy_gettext('City'), validators=[Optional()])
|
city = StringField(lazy_gettext("City"), validators=[Optional()])
|
||||||
|
|
||||||
|
|
||||||
class EventPlaceForm(FlaskForm):
|
class EventPlaceForm(FlaskForm):
|
||||||
name = StringField(lazy_gettext('Name'), validators=[Optional()])
|
name = StringField(lazy_gettext("Name"), validators=[Optional()])
|
||||||
location = FormField(EventPlaceLocationForm, default=lambda: Location())
|
location = FormField(EventPlaceLocationForm, default=lambda: Location())
|
||||||
|
|
||||||
def populate_obj(self, obj):
|
def populate_obj(self, obj):
|
||||||
for name, field in self._fields.items():
|
for name, field in self._fields.items():
|
||||||
if name == 'location' and not obj.location:
|
if name == "location" and not obj.location:
|
||||||
obj.location = Location()
|
obj.location = Location()
|
||||||
field.populate_obj(obj, name)
|
field.populate_obj(obj, name)
|
||||||
|
|
||||||
|
|
||||||
class OrganizerForm(EventPlaceForm):
|
class OrganizerForm(EventPlaceForm):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class EventOrganizerForm(FlaskForm):
|
class EventOrganizerForm(FlaskForm):
|
||||||
name = StringField(lazy_gettext('Organizator'), validators=[Optional()])
|
name = StringField(lazy_gettext("Organizator"), validators=[Optional()])
|
||||||
url = URLField(lazy_gettext('Link URL'), validators=[Optional()])
|
url = URLField(lazy_gettext("Link URL"), validators=[Optional()])
|
||||||
email = EmailField(lazy_gettext('Email'), validators=[Optional()])
|
email = EmailField(lazy_gettext("Email"), validators=[Optional()])
|
||||||
phone = StringField(lazy_gettext('Phone'), validators=[Optional()])
|
phone = StringField(lazy_gettext("Phone"), validators=[Optional()])
|
||||||
fax = StringField(lazy_gettext('Fax'), validators=[Optional()])
|
fax = StringField(lazy_gettext("Fax"), validators=[Optional()])
|
||||||
|
|
||||||
|
|
||||||
class BaseEventForm(FlaskForm):
|
class BaseEventForm(FlaskForm):
|
||||||
name = StringField(lazy_gettext('Name'), validators=[DataRequired()])
|
name = StringField(lazy_gettext("Name"), validators=[DataRequired()])
|
||||||
external_link = URLField(lazy_gettext('Link URL'), validators=[Optional()])
|
external_link = URLField(lazy_gettext("Link URL"), validators=[Optional()])
|
||||||
ticket_link = StringField(lazy_gettext('Ticket Link URL'), validators=[Optional()])
|
ticket_link = StringField(lazy_gettext("Ticket Link URL"), validators=[Optional()])
|
||||||
description = TextAreaField(lazy_gettext('Description'), validators=[DataRequired()])
|
description = TextAreaField(
|
||||||
recurrence_rule = TextAreaField(lazy_gettext('Recurrence rule'), validators=[Optional()])
|
lazy_gettext("Description"), validators=[DataRequired()]
|
||||||
start = CustomDateTimeField(lazy_gettext('Start'), validators=[DataRequired()])
|
)
|
||||||
end = CustomDateTimeField(lazy_gettext('End'), validators=[Optional()])
|
recurrence_rule = TextAreaField(
|
||||||
previous_start_date = CustomDateTimeField(lazy_gettext('Previous start date'), validators=[Optional()])
|
lazy_gettext("Recurrence rule"), validators=[Optional()]
|
||||||
tags = StringField(lazy_gettext('Tags'), validators=[Optional()])
|
)
|
||||||
category_ids = SelectMultipleField(lazy_gettext('Categories'), validators=[DataRequired()], coerce=int)
|
start = CustomDateTimeField(lazy_gettext("Start"), validators=[DataRequired()])
|
||||||
|
end = CustomDateTimeField(lazy_gettext("End"), validators=[Optional()])
|
||||||
|
previous_start_date = CustomDateTimeField(
|
||||||
|
lazy_gettext("Previous start date"), validators=[Optional()]
|
||||||
|
)
|
||||||
|
tags = StringField(lazy_gettext("Tags"), validators=[Optional()])
|
||||||
|
category_ids = SelectMultipleField(
|
||||||
|
lazy_gettext("Categories"), validators=[DataRequired()], coerce=int
|
||||||
|
)
|
||||||
|
|
||||||
kid_friendly = BooleanField(lazy_gettext('Kid friendly'), validators=[Optional()])
|
kid_friendly = BooleanField(lazy_gettext("Kid friendly"), validators=[Optional()])
|
||||||
accessible_for_free = BooleanField(lazy_gettext('Accessible for free'), validators=[Optional()])
|
accessible_for_free = BooleanField(
|
||||||
age_from = IntegerField(lazy_gettext('Typical Age from'), validators=[Optional()])
|
lazy_gettext("Accessible for free"), validators=[Optional()]
|
||||||
age_to = IntegerField(lazy_gettext('Typical Age to'), validators=[Optional()])
|
)
|
||||||
registration_required = BooleanField(lazy_gettext('Registration required'), validators=[Optional()])
|
age_from = IntegerField(lazy_gettext("Typical Age from"), validators=[Optional()])
|
||||||
booked_up = BooleanField(lazy_gettext('Booked up'), validators=[Optional()])
|
age_to = IntegerField(lazy_gettext("Typical Age to"), validators=[Optional()])
|
||||||
expected_participants = IntegerField(lazy_gettext('Expected number of participants'), validators=[Optional()])
|
registration_required = BooleanField(
|
||||||
price_info = TextAreaField(lazy_gettext('Price info'), validators=[Optional()])
|
lazy_gettext("Registration required"), validators=[Optional()]
|
||||||
|
)
|
||||||
|
booked_up = BooleanField(lazy_gettext("Booked up"), validators=[Optional()])
|
||||||
|
expected_participants = IntegerField(
|
||||||
|
lazy_gettext("Expected number of participants"), validators=[Optional()]
|
||||||
|
)
|
||||||
|
price_info = TextAreaField(lazy_gettext("Price info"), validators=[Optional()])
|
||||||
|
|
||||||
target_group_origin = SelectField(lazy_gettext('Target group origin'), coerce=int, choices=[
|
target_group_origin = SelectField(
|
||||||
(int(EventTargetGroupOrigin.both), lazy_gettext('EventTargetGroupOrigin.both')),
|
lazy_gettext("Target group origin"),
|
||||||
(int(EventTargetGroupOrigin.tourist), lazy_gettext('EventTargetGroupOrigin.tourist')),
|
coerce=int,
|
||||||
(int(EventTargetGroupOrigin.resident), lazy_gettext('EventTargetGroupOrigin.resident'))])
|
choices=[
|
||||||
|
(
|
||||||
|
int(EventTargetGroupOrigin.both),
|
||||||
|
lazy_gettext("EventTargetGroupOrigin.both"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
int(EventTargetGroupOrigin.tourist),
|
||||||
|
lazy_gettext("EventTargetGroupOrigin.tourist"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
int(EventTargetGroupOrigin.resident),
|
||||||
|
lazy_gettext("EventTargetGroupOrigin.resident"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
attendance_mode = SelectField(lazy_gettext('Attendance mode'), coerce=int, choices=[
|
attendance_mode = SelectField(
|
||||||
(int(EventAttendanceMode.offline), lazy_gettext('EventAttendanceMode.offline')),
|
lazy_gettext("Attendance mode"),
|
||||||
(int(EventAttendanceMode.online), lazy_gettext('EventAttendanceMode.online')),
|
coerce=int,
|
||||||
(int(EventAttendanceMode.mixed), lazy_gettext('EventAttendanceMode.mixed'))])
|
choices=[
|
||||||
|
(
|
||||||
|
int(EventAttendanceMode.offline),
|
||||||
|
lazy_gettext("EventAttendanceMode.offline"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
int(EventAttendanceMode.online),
|
||||||
|
lazy_gettext("EventAttendanceMode.online"),
|
||||||
|
),
|
||||||
|
(int(EventAttendanceMode.mixed), lazy_gettext("EventAttendanceMode.mixed")),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
photo = FormField(Base64ImageForm, lazy_gettext("Photo"), default=lambda: Image())
|
||||||
|
rating = SelectField(
|
||||||
|
lazy_gettext("Rating"), default=50, coerce=int, choices=event_rating_choices
|
||||||
|
)
|
||||||
|
|
||||||
photo = FormField(Base64ImageForm, lazy_gettext('Photo'), default=lambda: Image())
|
|
||||||
rating = SelectField(lazy_gettext('Rating'), default=50, coerce=int, choices=event_rating_choices)
|
|
||||||
|
|
||||||
class CreateEventForm(BaseEventForm):
|
class CreateEventForm(BaseEventForm):
|
||||||
event_place_choice = RadioField(lazy_gettext('Place'), choices=[(1,lazy_gettext('Select existing place')), (2,lazy_gettext('Enter new place'))], default=1, coerce=int)
|
event_place_choice = RadioField(
|
||||||
event_place_id = SelectField(lazy_gettext('Place'), validators=[Optional()], coerce=int)
|
lazy_gettext("Place"),
|
||||||
|
choices=[
|
||||||
|
(1, lazy_gettext("Select existing place")),
|
||||||
|
(2, lazy_gettext("Enter new place")),
|
||||||
|
],
|
||||||
|
default=1,
|
||||||
|
coerce=int,
|
||||||
|
)
|
||||||
|
event_place_id = SelectField(
|
||||||
|
lazy_gettext("Place"), validators=[Optional()], coerce=int
|
||||||
|
)
|
||||||
new_event_place = FormField(EventPlaceForm, default=lambda: EventPlace())
|
new_event_place = FormField(EventPlaceForm, default=lambda: EventPlace())
|
||||||
|
|
||||||
organizer_choice = RadioField(lazy_gettext('Organizer'), choices=[(1,lazy_gettext('Select existing organizer')), (2,lazy_gettext('Enter new organizer'))], default=1, coerce=int)
|
organizer_choice = RadioField(
|
||||||
organizer_id = SelectField(lazy_gettext('Organizer'), validators=[Optional()], coerce=int)
|
lazy_gettext("Organizer"),
|
||||||
|
choices=[
|
||||||
|
(1, lazy_gettext("Select existing organizer")),
|
||||||
|
(2, lazy_gettext("Enter new organizer")),
|
||||||
|
],
|
||||||
|
default=1,
|
||||||
|
coerce=int,
|
||||||
|
)
|
||||||
|
organizer_id = SelectField(
|
||||||
|
lazy_gettext("Organizer"), validators=[Optional()], coerce=int
|
||||||
|
)
|
||||||
new_organizer = FormField(OrganizerForm, default=lambda: EventOrganizer())
|
new_organizer = FormField(OrganizerForm, default=lambda: EventOrganizer())
|
||||||
|
|
||||||
submit = SubmitField(lazy_gettext("Create event"))
|
submit = SubmitField(lazy_gettext("Create event"))
|
||||||
|
|
||||||
def populate_obj(self, obj):
|
def populate_obj(self, obj):
|
||||||
for name, field in self._fields.items():
|
for name, field in self._fields.items():
|
||||||
if name == 'new_event_place':
|
if name == "new_event_place":
|
||||||
if self.event_place_choice.data != 2:
|
if self.event_place_choice.data != 2:
|
||||||
continue
|
continue
|
||||||
if not obj.event_place:
|
if not obj.event_place:
|
||||||
obj.event_place = EventPlace()
|
obj.event_place = EventPlace()
|
||||||
field.populate_obj(obj, 'event_place')
|
field.populate_obj(obj, "event_place")
|
||||||
elif name == 'new_organizer':
|
elif name == "new_organizer":
|
||||||
if self.organizer_choice.data != 2:
|
if self.organizer_choice.data != 2:
|
||||||
continue
|
continue
|
||||||
if not obj.organizer:
|
if not obj.organizer:
|
||||||
obj.organizer = EventOrganizer()
|
obj.organizer = EventOrganizer()
|
||||||
field.populate_obj(obj, 'organizer')
|
field.populate_obj(obj, "organizer")
|
||||||
elif name == 'photo' and not obj.photo:
|
elif name == "photo" and not obj.photo:
|
||||||
obj.photo = Image()
|
obj.photo = Image()
|
||||||
field.populate_obj(obj, name)
|
field.populate_obj(obj, name)
|
||||||
|
|
||||||
@ -102,50 +185,67 @@ class CreateEventForm(BaseEventForm):
|
|||||||
if not super(BaseEventForm, self).validate():
|
if not super(BaseEventForm, self).validate():
|
||||||
return False
|
return False
|
||||||
if self.event_place_id.data == 0 and not self.new_event_place.form.name.data:
|
if self.event_place_id.data == 0 and not self.new_event_place.form.name.data:
|
||||||
msg = gettext('Select existing place or enter new place')
|
msg = gettext("Select existing place or enter new place")
|
||||||
self.event_place_id.errors.append(msg)
|
self.event_place_id.errors.append(msg)
|
||||||
self.new_event_place.form.name.errors.append(msg)
|
self.new_event_place.form.name.errors.append(msg)
|
||||||
return False
|
return False
|
||||||
if self.organizer_id.data == 0 and not self.new_organizer.form.name.data:
|
if self.organizer_id.data == 0 and not self.new_organizer.form.name.data:
|
||||||
msg = gettext('Select existing organizer or enter new organizer')
|
msg = gettext("Select existing organizer or enter new organizer")
|
||||||
self.organizer_id.errors.append(msg)
|
self.organizer_id.errors.append(msg)
|
||||||
self.new_organizer.form.name.errors.append(msg)
|
self.new_organizer.form.name.errors.append(msg)
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class UpdateEventForm(BaseEventForm):
|
|
||||||
event_place_id = SelectField(lazy_gettext('Place'), validators=[DataRequired()], coerce=int)
|
|
||||||
organizer_id = SelectField(lazy_gettext('Organizer'), validators=[DataRequired()], coerce=int)
|
|
||||||
|
|
||||||
status = SelectField(lazy_gettext('Status'), coerce=int, choices=[
|
class UpdateEventForm(BaseEventForm):
|
||||||
(int(EventStatus.scheduled), lazy_gettext('EventStatus.scheduled')),
|
event_place_id = SelectField(
|
||||||
(int(EventStatus.cancelled), lazy_gettext('EventStatus.cancelled')),
|
lazy_gettext("Place"), validators=[DataRequired()], coerce=int
|
||||||
(int(EventStatus.movedOnline), lazy_gettext('EventStatus.movedOnline')),
|
)
|
||||||
(int(EventStatus.postponed), lazy_gettext('EventStatus.postponed')),
|
organizer_id = SelectField(
|
||||||
(int(EventStatus.rescheduled), lazy_gettext('EventStatus.rescheduled'))])
|
lazy_gettext("Organizer"), validators=[DataRequired()], coerce=int
|
||||||
|
)
|
||||||
|
|
||||||
|
status = SelectField(
|
||||||
|
lazy_gettext("Status"),
|
||||||
|
coerce=int,
|
||||||
|
choices=[
|
||||||
|
(int(EventStatus.scheduled), lazy_gettext("EventStatus.scheduled")),
|
||||||
|
(int(EventStatus.cancelled), lazy_gettext("EventStatus.cancelled")),
|
||||||
|
(int(EventStatus.movedOnline), lazy_gettext("EventStatus.movedOnline")),
|
||||||
|
(int(EventStatus.postponed), lazy_gettext("EventStatus.postponed")),
|
||||||
|
(int(EventStatus.rescheduled), lazy_gettext("EventStatus.rescheduled")),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
submit = SubmitField(lazy_gettext("Update event"))
|
submit = SubmitField(lazy_gettext("Update event"))
|
||||||
|
|
||||||
def populate_obj(self, obj):
|
def populate_obj(self, obj):
|
||||||
for name, field in self._fields.items():
|
for name, field in self._fields.items():
|
||||||
if name == 'photo' and not obj.photo:
|
if name == "photo" and not obj.photo:
|
||||||
obj.photo = Image()
|
obj.photo = Image()
|
||||||
field.populate_obj(obj, name)
|
field.populate_obj(obj, name)
|
||||||
|
|
||||||
|
|
||||||
class DeleteEventForm(FlaskForm):
|
class DeleteEventForm(FlaskForm):
|
||||||
submit = SubmitField(lazy_gettext("Delete event"))
|
submit = SubmitField(lazy_gettext("Delete event"))
|
||||||
name = StringField(lazy_gettext('Name'), validators=[DataRequired()])
|
name = StringField(lazy_gettext("Name"), validators=[DataRequired()])
|
||||||
|
|
||||||
|
|
||||||
class FindEventForm(FlaskForm):
|
class FindEventForm(FlaskForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
csrf = False
|
csrf = False
|
||||||
date_from = CustomDateField(lazy_gettext('From'), validators=[Optional()])
|
|
||||||
date_to = CustomDateField(lazy_gettext('to'), validators=[Optional()])
|
date_from = CustomDateField(lazy_gettext("From"), validators=[Optional()])
|
||||||
keyword = StringField(lazy_gettext('Keyword'), validators=[Optional()])
|
date_to = CustomDateField(lazy_gettext("to"), validators=[Optional()])
|
||||||
category_id = SelectField(lazy_gettext('Category'), validators=[Optional()], coerce=int)
|
keyword = StringField(lazy_gettext("Keyword"), validators=[Optional()])
|
||||||
organizer_id = SelectField(lazy_gettext('Organizer'), validators=[Optional()], coerce=int)
|
category_id = SelectField(
|
||||||
|
lazy_gettext("Category"), validators=[Optional()], coerce=int
|
||||||
|
)
|
||||||
|
organizer_id = SelectField(
|
||||||
|
lazy_gettext("Organizer"), validators=[Optional()], coerce=int
|
||||||
|
)
|
||||||
|
|
||||||
submit = SubmitField(lazy_gettext("Find events"))
|
submit = SubmitField(lazy_gettext("Find events"))
|
||||||
|
|
||||||
def is_submitted(self):
|
def is_submitted(self):
|
||||||
return 'submit' in request.args
|
return "submit" in request.args
|
||||||
|
|||||||
@ -1,28 +1,37 @@
|
|||||||
from flask import request
|
from flask import request
|
||||||
from flask_babelex import lazy_gettext, gettext
|
from flask_babelex import lazy_gettext
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_wtf.file import FileField, FileAllowed
|
from wtforms import (
|
||||||
from wtforms import HiddenField, SelectMultipleField, FieldList, RadioField, DateTimeField, StringField, SubmitField, TextAreaField, SelectField, BooleanField, IntegerField, FormField
|
HiddenField,
|
||||||
from wtforms.fields.html5 import DateTimeLocalField, EmailField
|
StringField,
|
||||||
from wtforms.validators import DataRequired, Optional
|
SubmitField,
|
||||||
from wtforms.widgets import html_params, HTMLString
|
SelectField,
|
||||||
from project.models import EventPlace, EventTargetGroupOrigin, EventAttendanceMode, EventStatus, Location, EventOrganizer, EventRejectionReason, EventReviewStatus
|
)
|
||||||
from project.forms.common import event_rating_choices, weekday_choices, distance_choices
|
from wtforms.validators import Optional
|
||||||
from project.forms.widgets import CustomDateField, MultiCheckboxField
|
from project.forms.common import distance_choices
|
||||||
|
from project.forms.widgets import CustomDateField
|
||||||
|
|
||||||
|
|
||||||
class FindEventDateForm(FlaskForm):
|
class FindEventDateForm(FlaskForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
csrf = False
|
csrf = False
|
||||||
|
|
||||||
date_from = CustomDateField(lazy_gettext('From'), validators=[Optional()])
|
date_from = CustomDateField(lazy_gettext("From"), validators=[Optional()])
|
||||||
date_to = CustomDateField(lazy_gettext('to'), validators=[Optional()])
|
date_to = CustomDateField(lazy_gettext("to"), validators=[Optional()])
|
||||||
keyword = StringField(lazy_gettext('Keyword'), validators=[Optional()])
|
keyword = StringField(lazy_gettext("Keyword"), validators=[Optional()])
|
||||||
category_id = SelectField(lazy_gettext('Category'), validators=[Optional()], coerce=int)
|
category_id = SelectField(
|
||||||
|
lazy_gettext("Category"), validators=[Optional()], coerce=int
|
||||||
|
)
|
||||||
coordinate = HiddenField(validators=[Optional()])
|
coordinate = HiddenField(validators=[Optional()])
|
||||||
location = StringField(lazy_gettext('Location'), validators=[Optional()])
|
location = StringField(lazy_gettext("Location"), validators=[Optional()])
|
||||||
distance = SelectField(lazy_gettext('Distance'), validators=[Optional()], coerce=int, choices=distance_choices)
|
distance = SelectField(
|
||||||
|
lazy_gettext("Distance"),
|
||||||
|
validators=[Optional()],
|
||||||
|
coerce=int,
|
||||||
|
choices=distance_choices,
|
||||||
|
)
|
||||||
|
|
||||||
submit = SubmitField(lazy_gettext("Find"))
|
submit = SubmitField(lazy_gettext("Find"))
|
||||||
|
|
||||||
def is_submitted(self):
|
def is_submitted(self):
|
||||||
return 'submit' in request.args
|
return "submit" in request.args
|
||||||
|
|||||||
@ -1,48 +1,62 @@
|
|||||||
from flask_babelex import lazy_gettext, gettext
|
from flask_babelex import lazy_gettext
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_wtf.file import FileField, FileAllowed
|
from wtforms import (
|
||||||
from wtforms import DecimalField, RadioField, DateTimeField, StringField, SubmitField, TextAreaField, SelectField, BooleanField, IntegerField, FormField
|
DecimalField,
|
||||||
from wtforms.fields.html5 import DateTimeLocalField, EmailField, URLField
|
StringField,
|
||||||
|
SubmitField,
|
||||||
|
TextAreaField,
|
||||||
|
FormField,
|
||||||
|
)
|
||||||
|
from wtforms.fields.html5 import URLField
|
||||||
from wtforms.validators import DataRequired, Optional
|
from wtforms.validators import DataRequired, Optional
|
||||||
from wtforms.widgets import html_params, HTMLString
|
|
||||||
import decimal
|
|
||||||
from project.models import Location, Image
|
from project.models import Location, Image
|
||||||
from project.forms.common import FileImageForm
|
from project.forms.common import FileImageForm
|
||||||
|
|
||||||
|
|
||||||
class EventPlaceLocationForm(FlaskForm):
|
class EventPlaceLocationForm(FlaskForm):
|
||||||
street = StringField(lazy_gettext('Street'), validators=[Optional()])
|
street = StringField(lazy_gettext("Street"), validators=[Optional()])
|
||||||
postalCode = StringField(lazy_gettext('Postal code'), validators=[Optional()])
|
postalCode = StringField(lazy_gettext("Postal code"), validators=[Optional()])
|
||||||
city = StringField(lazy_gettext('City'), validators=[Optional()])
|
city = StringField(lazy_gettext("City"), validators=[Optional()])
|
||||||
state = StringField(lazy_gettext('State'), validators=[Optional()])
|
state = StringField(lazy_gettext("State"), validators=[Optional()])
|
||||||
latitude = DecimalField(lazy_gettext('Latitude'), places=16, validators=[Optional()])
|
latitude = DecimalField(
|
||||||
longitude = DecimalField(lazy_gettext('Longitude'), places=16, validators=[Optional()])
|
lazy_gettext("Latitude"), places=16, validators=[Optional()]
|
||||||
|
)
|
||||||
|
longitude = DecimalField(
|
||||||
|
lazy_gettext("Longitude"), places=16, validators=[Optional()]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class BaseEventPlaceForm(FlaskForm):
|
class BaseEventPlaceForm(FlaskForm):
|
||||||
name = StringField(lazy_gettext('Name'), validators=[DataRequired()])
|
name = StringField(lazy_gettext("Name"), validators=[DataRequired()])
|
||||||
url = URLField(lazy_gettext('Link URL'), validators=[Optional()])
|
url = URLField(lazy_gettext("Link URL"), validators=[Optional()])
|
||||||
photo = FormField(FileImageForm, lazy_gettext('Photo'), default=lambda: Image())
|
photo = FormField(FileImageForm, lazy_gettext("Photo"), default=lambda: Image())
|
||||||
description = TextAreaField(lazy_gettext('Description'), validators=[Optional()])
|
description = TextAreaField(lazy_gettext("Description"), validators=[Optional()])
|
||||||
location = FormField(EventPlaceLocationForm)
|
location = FormField(EventPlaceLocationForm)
|
||||||
|
|
||||||
def populate_obj(self, obj):
|
def populate_obj(self, obj):
|
||||||
for name, field in self._fields.items():
|
for name, field in self._fields.items():
|
||||||
if name == 'location' and not obj.location:
|
if name == "location" and not obj.location:
|
||||||
obj.location = Location()
|
obj.location = Location()
|
||||||
elif name == 'photo' and not obj.photo:
|
elif name == "photo" and not obj.photo:
|
||||||
obj.photo = Image()
|
obj.photo = Image()
|
||||||
field.populate_obj(obj, name)
|
field.populate_obj(obj, name)
|
||||||
|
|
||||||
|
|
||||||
class CreateEventPlaceForm(BaseEventPlaceForm):
|
class CreateEventPlaceForm(BaseEventPlaceForm):
|
||||||
submit = SubmitField(lazy_gettext("Create place"))
|
submit = SubmitField(lazy_gettext("Create place"))
|
||||||
|
|
||||||
|
|
||||||
class UpdateEventPlaceForm(BaseEventPlaceForm):
|
class UpdateEventPlaceForm(BaseEventPlaceForm):
|
||||||
submit = SubmitField(lazy_gettext("Update place"))
|
submit = SubmitField(lazy_gettext("Update place"))
|
||||||
|
|
||||||
|
|
||||||
class DeleteEventPlaceForm(FlaskForm):
|
class DeleteEventPlaceForm(FlaskForm):
|
||||||
submit = SubmitField(lazy_gettext("Delete place"))
|
submit = SubmitField(lazy_gettext("Delete place"))
|
||||||
name = StringField(lazy_gettext('Name'), validators=[DataRequired()])
|
name = StringField(lazy_gettext("Name"), validators=[DataRequired()])
|
||||||
|
|
||||||
|
|
||||||
class FindEventPlaceForm(FlaskForm):
|
class FindEventPlaceForm(FlaskForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
csrf = False
|
csrf = False
|
||||||
|
|
||||||
submit = SubmitField(lazy_gettext("Find places"))
|
submit = SubmitField(lazy_gettext("Find places"))
|
||||||
|
|||||||
@ -1,52 +1,135 @@
|
|||||||
from flask import request
|
from flask_babelex import lazy_gettext
|
||||||
from flask_babelex import lazy_gettext, gettext
|
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_wtf.file import FileField, FileAllowed
|
from wtforms import (
|
||||||
from wtforms import FieldList, RadioField, DateTimeField, StringField, SubmitField, TextAreaField, SelectField, BooleanField, IntegerField, FormField
|
StringField,
|
||||||
from wtforms.fields.html5 import DateTimeLocalField, EmailField, TelField, URLField
|
SubmitField,
|
||||||
|
TextAreaField,
|
||||||
|
SelectField,
|
||||||
|
BooleanField,
|
||||||
|
FormField,
|
||||||
|
)
|
||||||
|
from wtforms.fields.html5 import EmailField, TelField, URLField
|
||||||
from wtforms.validators import DataRequired, Optional
|
from wtforms.validators import DataRequired, Optional
|
||||||
from wtforms.widgets import html_params, HTMLString
|
from project.models import (
|
||||||
from project.models import EventSuggestion, EventPlace, EventTargetGroupOrigin, EventAttendanceMode, EventStatus, Location, EventOrganizer, EventRejectionReason, EventReviewStatus, Image
|
EventRejectionReason,
|
||||||
from project.forms.common import event_rating_choices, Base64ImageForm
|
Image,
|
||||||
from project.forms.widgets import CustomDateTimeField, CustomDateField, TagSelectField
|
)
|
||||||
from project.forms.common import event_rating_choices
|
from project.forms.common import Base64ImageForm
|
||||||
|
from project.forms.widgets import CustomDateTimeField, TagSelectField
|
||||||
|
|
||||||
|
|
||||||
class CreateEventSuggestionForm(FlaskForm):
|
class CreateEventSuggestionForm(FlaskForm):
|
||||||
name = StringField(lazy_gettext('Name'), validators=[DataRequired()], description=lazy_gettext('Enter a short, meaningful name for the event.'))
|
name = StringField(
|
||||||
start = CustomDateTimeField(lazy_gettext('Start'), validators=[DataRequired()], description=lazy_gettext('Indicate when the event will take place.'))
|
lazy_gettext("Name"),
|
||||||
description = TextAreaField(lazy_gettext('Description'), validators=[Optional()], description=lazy_gettext('Add an optional description of the event.'))
|
validators=[DataRequired()],
|
||||||
external_link = URLField(lazy_gettext('Link URL'), validators=[Optional()], description=lazy_gettext('Add an optional link. That can make the review easier.'))
|
description=lazy_gettext("Enter a short, meaningful name for the event."),
|
||||||
|
)
|
||||||
|
start = CustomDateTimeField(
|
||||||
|
lazy_gettext("Start"),
|
||||||
|
validators=[DataRequired()],
|
||||||
|
description=lazy_gettext("Indicate when the event will take place."),
|
||||||
|
)
|
||||||
|
description = TextAreaField(
|
||||||
|
lazy_gettext("Description"),
|
||||||
|
validators=[Optional()],
|
||||||
|
description=lazy_gettext("Add an optional description of the event."),
|
||||||
|
)
|
||||||
|
external_link = URLField(
|
||||||
|
lazy_gettext("Link URL"),
|
||||||
|
validators=[Optional()],
|
||||||
|
description=lazy_gettext(
|
||||||
|
"Add an optional link. That can make the review easier."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
contact_name = StringField(lazy_gettext('Name'), validators=[DataRequired()], description=lazy_gettext('Please enter your name for the review.'))
|
contact_name = StringField(
|
||||||
contact_phone = TelField(lazy_gettext('Phone'), validators=[Optional()], description=lazy_gettext('Please enter your phone number or email address for the review.'))
|
lazy_gettext("Name"),
|
||||||
contact_email = EmailField(lazy_gettext('Email'), validators=[Optional()], description=lazy_gettext('Please enter your email address or phone number for the review.'))
|
validators=[DataRequired()],
|
||||||
contact_email_notice = BooleanField(lazy_gettext('I would like to be notified by email after the review'), validators=[Optional()])
|
description=lazy_gettext("Please enter your name for the review."),
|
||||||
|
)
|
||||||
|
contact_phone = TelField(
|
||||||
|
lazy_gettext("Phone"),
|
||||||
|
validators=[Optional()],
|
||||||
|
description=lazy_gettext(
|
||||||
|
"Please enter your phone number or email address for the review."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
contact_email = EmailField(
|
||||||
|
lazy_gettext("Email"),
|
||||||
|
validators=[Optional()],
|
||||||
|
description=lazy_gettext(
|
||||||
|
"Please enter your email address or phone number for the review."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
contact_email_notice = BooleanField(
|
||||||
|
lazy_gettext("I would like to be notified by email after the review"),
|
||||||
|
validators=[Optional()],
|
||||||
|
)
|
||||||
|
|
||||||
event_place_id = TagSelectField(lazy_gettext('Place'), validators=[DataRequired()], description=lazy_gettext('Choose where the event takes place. If the venue is not yet in the list, just enter it.'))
|
event_place_id = TagSelectField(
|
||||||
organizer_id = TagSelectField(lazy_gettext('Organizer'), validators=[DataRequired()], description=lazy_gettext('Select the organizer. If the organizer is not yet on the list, just enter it.'))
|
lazy_gettext("Place"),
|
||||||
photo = FormField(Base64ImageForm, lazy_gettext('Photo'), default=lambda: Image(), description=lazy_gettext('We recommend uploading a photo for the event. It looks a lot more, but of course it works without it.'))
|
validators=[DataRequired()],
|
||||||
accept_tos = BooleanField(lazy_gettext('I confirm that I have clarified all information (text, images, etc.) that I upload into the system with regard to their rights of use and declare that they may be passed on.'), validators=[DataRequired()])
|
description=lazy_gettext(
|
||||||
|
"Choose where the event takes place. If the venue is not yet in the list, just enter it."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
organizer_id = TagSelectField(
|
||||||
|
lazy_gettext("Organizer"),
|
||||||
|
validators=[DataRequired()],
|
||||||
|
description=lazy_gettext(
|
||||||
|
"Select the organizer. If the organizer is not yet on the list, just enter it."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
photo = FormField(
|
||||||
|
Base64ImageForm,
|
||||||
|
lazy_gettext("Photo"),
|
||||||
|
default=lambda: Image(),
|
||||||
|
description=lazy_gettext(
|
||||||
|
"We recommend uploading a photo for the event. It looks a lot more, but of course it works without it."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
accept_tos = BooleanField(
|
||||||
|
lazy_gettext(
|
||||||
|
"I confirm that I have clarified all information (text, images, etc.) that I upload into the system with regard to their rights of use and declare that they may be passed on."
|
||||||
|
),
|
||||||
|
validators=[DataRequired()],
|
||||||
|
)
|
||||||
|
|
||||||
submit = SubmitField(lazy_gettext("Create event suggestion"))
|
submit = SubmitField(lazy_gettext("Create event suggestion"))
|
||||||
|
|
||||||
def populate_obj(self, obj):
|
def populate_obj(self, obj):
|
||||||
for name, field in self._fields.items():
|
for name, field in self._fields.items():
|
||||||
if name == 'photo' and not obj.photo:
|
if name == "photo" and not obj.photo:
|
||||||
obj.photo = Image()
|
obj.photo = Image()
|
||||||
if name == 'event_place_id' and self.event_place_id.is_free_text():
|
if name == "event_place_id" and self.event_place_id.is_free_text():
|
||||||
obj.event_place_text = self.event_place_id.data
|
obj.event_place_text = self.event_place_id.data
|
||||||
obj.event_place_id = None
|
obj.event_place_id = None
|
||||||
elif name == 'organizer_id' and self.organizer_id.is_free_text():
|
elif name == "organizer_id" and self.organizer_id.is_free_text():
|
||||||
obj.organizer_text = self.organizer_id.data
|
obj.organizer_text = self.organizer_id.data
|
||||||
obj.organizer_id = None
|
obj.organizer_id = None
|
||||||
else:
|
else:
|
||||||
field.populate_obj(obj, name)
|
field.populate_obj(obj, name)
|
||||||
|
|
||||||
|
|
||||||
class RejectEventSuggestionForm(FlaskForm):
|
class RejectEventSuggestionForm(FlaskForm):
|
||||||
rejection_resaon = SelectField(lazy_gettext('Rejection reason'), coerce=int, choices=[
|
rejection_resaon = SelectField(
|
||||||
(0, ''),
|
lazy_gettext("Rejection reason"),
|
||||||
(int(EventRejectionReason.duplicate), lazy_gettext('EventRejectionReason.duplicate')),
|
coerce=int,
|
||||||
(int(EventRejectionReason.untrustworthy), lazy_gettext('EventRejectionReason.untrustworthy')),
|
choices=[
|
||||||
(int(EventRejectionReason.illegal), lazy_gettext('EventRejectionReason.illegal'))])
|
(0, ""),
|
||||||
|
(
|
||||||
|
int(EventRejectionReason.duplicate),
|
||||||
|
lazy_gettext("EventRejectionReason.duplicate"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
int(EventRejectionReason.untrustworthy),
|
||||||
|
lazy_gettext("EventRejectionReason.untrustworthy"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
int(EventRejectionReason.illegal),
|
||||||
|
lazy_gettext("EventRejectionReason.illegal"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
submit = SubmitField(lazy_gettext("Reject event suggestion"))
|
submit = SubmitField(lazy_gettext("Reject event suggestion"))
|
||||||
|
|||||||
@ -1,44 +1,56 @@
|
|||||||
from flask_babelex import lazy_gettext
|
from flask_babelex import lazy_gettext
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_wtf.file import FileField, FileAllowed
|
from wtforms import (
|
||||||
from wtforms import StringField, SubmitField, DecimalField, TextAreaField, FormField, SelectField
|
StringField,
|
||||||
|
SubmitField,
|
||||||
|
DecimalField,
|
||||||
|
FormField,
|
||||||
|
)
|
||||||
from wtforms.fields.html5 import EmailField, TelField, URLField
|
from wtforms.fields.html5 import EmailField, TelField, URLField
|
||||||
from wtforms.validators import DataRequired, Optional, Regexp
|
from wtforms.validators import DataRequired, Optional
|
||||||
import decimal
|
|
||||||
from project.models import Location, Image
|
from project.models import Location, Image
|
||||||
from project.forms.common import FileImageForm
|
from project.forms.common import FileImageForm
|
||||||
|
|
||||||
|
|
||||||
class OrganizerLocationForm(FlaskForm):
|
class OrganizerLocationForm(FlaskForm):
|
||||||
street = StringField(lazy_gettext('Street'), validators=[Optional()])
|
street = StringField(lazy_gettext("Street"), validators=[Optional()])
|
||||||
postalCode = StringField(lazy_gettext('Postal code'), validators=[Optional()])
|
postalCode = StringField(lazy_gettext("Postal code"), validators=[Optional()])
|
||||||
city = StringField(lazy_gettext('City'), validators=[Optional()])
|
city = StringField(lazy_gettext("City"), validators=[Optional()])
|
||||||
state = StringField(lazy_gettext('State'), validators=[Optional()])
|
state = StringField(lazy_gettext("State"), validators=[Optional()])
|
||||||
latitude = DecimalField(lazy_gettext('Latitude'), places=16, validators=[Optional()])
|
latitude = DecimalField(
|
||||||
longitude = DecimalField(lazy_gettext('Longitude'), places=16, validators=[Optional()])
|
lazy_gettext("Latitude"), places=16, validators=[Optional()]
|
||||||
|
)
|
||||||
|
longitude = DecimalField(
|
||||||
|
lazy_gettext("Longitude"), places=16, validators=[Optional()]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class BaseOrganizerForm(FlaskForm):
|
class BaseOrganizerForm(FlaskForm):
|
||||||
name = StringField(lazy_gettext('Name'), validators=[DataRequired()])
|
name = StringField(lazy_gettext("Name"), validators=[DataRequired()])
|
||||||
url = URLField(lazy_gettext('Link URL'), validators=[Optional()])
|
url = URLField(lazy_gettext("Link URL"), validators=[Optional()])
|
||||||
email = EmailField(lazy_gettext('Email'), validators=[Optional()])
|
email = EmailField(lazy_gettext("Email"), validators=[Optional()])
|
||||||
phone = TelField(lazy_gettext('Phone'), validators=[Optional()])
|
phone = TelField(lazy_gettext("Phone"), validators=[Optional()])
|
||||||
fax = TelField(lazy_gettext('Fax'), validators=[Optional()])
|
fax = TelField(lazy_gettext("Fax"), validators=[Optional()])
|
||||||
logo = FormField(FileImageForm, lazy_gettext('Logo'), default=lambda: Image())
|
logo = FormField(FileImageForm, lazy_gettext("Logo"), default=lambda: Image())
|
||||||
location = FormField(OrganizerLocationForm)
|
location = FormField(OrganizerLocationForm)
|
||||||
|
|
||||||
def populate_obj(self, obj):
|
def populate_obj(self, obj):
|
||||||
for name, field in self._fields.items():
|
for name, field in self._fields.items():
|
||||||
if name == 'location' and not obj.location:
|
if name == "location" and not obj.location:
|
||||||
obj.location = Location()
|
obj.location = Location()
|
||||||
elif name == 'logo' and not obj.logo:
|
elif name == "logo" and not obj.logo:
|
||||||
obj.logo = Image()
|
obj.logo = Image()
|
||||||
field.populate_obj(obj, name)
|
field.populate_obj(obj, name)
|
||||||
|
|
||||||
|
|
||||||
class CreateOrganizerForm(BaseOrganizerForm):
|
class CreateOrganizerForm(BaseOrganizerForm):
|
||||||
submit = SubmitField(lazy_gettext("Create organizer"))
|
submit = SubmitField(lazy_gettext("Create organizer"))
|
||||||
|
|
||||||
|
|
||||||
class UpdateOrganizerForm(BaseOrganizerForm):
|
class UpdateOrganizerForm(BaseOrganizerForm):
|
||||||
submit = SubmitField(lazy_gettext("Update organizer"))
|
submit = SubmitField(lazy_gettext("Update organizer"))
|
||||||
|
|
||||||
|
|
||||||
class DeleteOrganizerForm(FlaskForm):
|
class DeleteOrganizerForm(FlaskForm):
|
||||||
submit = SubmitField(lazy_gettext("Delete organizer"))
|
submit = SubmitField(lazy_gettext("Delete organizer"))
|
||||||
name = StringField(lazy_gettext('Name'), validators=[DataRequired()])
|
name = StringField(lazy_gettext("Name"), validators=[DataRequired()])
|
||||||
|
|||||||
@ -1,28 +1,37 @@
|
|||||||
from flask import request
|
from flask import request
|
||||||
from flask_babelex import lazy_gettext, gettext
|
from flask_babelex import lazy_gettext
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_wtf.file import FileField, FileAllowed
|
from wtforms import HiddenField, StringField, SubmitField, SelectField
|
||||||
from wtforms import HiddenField, SelectMultipleField, FieldList, RadioField, DateTimeField, StringField, SubmitField, TextAreaField, SelectField, BooleanField, IntegerField, FormField
|
from wtforms.validators import Optional
|
||||||
from wtforms.fields.html5 import DateTimeLocalField, EmailField
|
from project.forms.common import weekday_choices, distance_choices
|
||||||
from wtforms.validators import DataRequired, Optional
|
|
||||||
from wtforms.widgets import html_params, HTMLString
|
|
||||||
from project.models import EventPlace, EventTargetGroupOrigin, EventAttendanceMode, EventStatus, Location, EventOrganizer, EventRejectionReason, EventReviewStatus
|
|
||||||
from project.forms.common import event_rating_choices, weekday_choices, distance_choices
|
|
||||||
from project.forms.widgets import CustomDateField, MultiCheckboxField
|
from project.forms.widgets import CustomDateField, MultiCheckboxField
|
||||||
|
|
||||||
|
|
||||||
class PlaningForm(FlaskForm):
|
class PlaningForm(FlaskForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
csrf = False
|
csrf = False
|
||||||
|
|
||||||
date_from = CustomDateField(lazy_gettext('From'), validators=[Optional()])
|
date_from = CustomDateField(lazy_gettext("From"), validators=[Optional()])
|
||||||
date_to = CustomDateField(lazy_gettext('to'), validators=[Optional()])
|
date_to = CustomDateField(lazy_gettext("to"), validators=[Optional()])
|
||||||
category_id = SelectField(lazy_gettext('Category'), validators=[Optional()], coerce=int)
|
category_id = SelectField(
|
||||||
|
lazy_gettext("Category"), validators=[Optional()], coerce=int
|
||||||
|
)
|
||||||
coordinate = HiddenField(validators=[Optional()])
|
coordinate = HiddenField(validators=[Optional()])
|
||||||
location = StringField(lazy_gettext('Location'), validators=[Optional()])
|
location = StringField(lazy_gettext("Location"), validators=[Optional()])
|
||||||
distance = SelectField(lazy_gettext('Distance'), validators=[Optional()], coerce=int, choices=distance_choices)
|
distance = SelectField(
|
||||||
weekday = MultiCheckboxField(lazy_gettext('Weekdays'), validators=[Optional()], coerce=int, choices=weekday_choices)
|
lazy_gettext("Distance"),
|
||||||
|
validators=[Optional()],
|
||||||
|
coerce=int,
|
||||||
|
choices=distance_choices,
|
||||||
|
)
|
||||||
|
weekday = MultiCheckboxField(
|
||||||
|
lazy_gettext("Weekdays"),
|
||||||
|
validators=[Optional()],
|
||||||
|
coerce=int,
|
||||||
|
choices=weekday_choices,
|
||||||
|
)
|
||||||
|
|
||||||
submit = SubmitField(lazy_gettext("Find"))
|
submit = SubmitField(lazy_gettext("Find"))
|
||||||
|
|
||||||
def is_submitted(self):
|
def is_submitted(self):
|
||||||
return 'submit' in request.args
|
return "submit" in request.args
|
||||||
|
|||||||
@ -1,18 +1,27 @@
|
|||||||
from flask_babelex import lazy_gettext, gettext
|
from flask_babelex import lazy_gettext
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from wtforms import SelectField, StringField, SubmitField
|
from wtforms import SelectField, StringField, SubmitField
|
||||||
from wtforms.validators import DataRequired
|
from wtforms.validators import DataRequired
|
||||||
from project.forms.common import event_rating_choices
|
from project.forms.common import event_rating_choices
|
||||||
|
|
||||||
|
|
||||||
class CreateEventReferenceForm(FlaskForm):
|
class CreateEventReferenceForm(FlaskForm):
|
||||||
admin_unit_id = SelectField(lazy_gettext('Admin unit'), validators=[DataRequired()], coerce=int)
|
admin_unit_id = SelectField(
|
||||||
rating = SelectField(lazy_gettext('Rating'), default=50, coerce=int, choices=event_rating_choices)
|
lazy_gettext("Admin unit"), validators=[DataRequired()], coerce=int
|
||||||
|
)
|
||||||
|
rating = SelectField(
|
||||||
|
lazy_gettext("Rating"), default=50, coerce=int, choices=event_rating_choices
|
||||||
|
)
|
||||||
submit = SubmitField(lazy_gettext("Save reference"))
|
submit = SubmitField(lazy_gettext("Save reference"))
|
||||||
|
|
||||||
|
|
||||||
class UpdateEventReferenceForm(FlaskForm):
|
class UpdateEventReferenceForm(FlaskForm):
|
||||||
rating = SelectField(lazy_gettext('Rating'), default=50, coerce=int, choices=event_rating_choices)
|
rating = SelectField(
|
||||||
|
lazy_gettext("Rating"), default=50, coerce=int, choices=event_rating_choices
|
||||||
|
)
|
||||||
submit = SubmitField(lazy_gettext("Update reference"))
|
submit = SubmitField(lazy_gettext("Update reference"))
|
||||||
|
|
||||||
|
|
||||||
class DeleteReferenceForm(FlaskForm):
|
class DeleteReferenceForm(FlaskForm):
|
||||||
submit = SubmitField(lazy_gettext("Delete reference"))
|
submit = SubmitField(lazy_gettext("Delete reference"))
|
||||||
name = StringField(lazy_gettext('Name'), validators=[DataRequired()])
|
name = StringField(lazy_gettext("Name"), validators=[DataRequired()])
|
||||||
|
|||||||
@ -1,30 +1,71 @@
|
|||||||
from flask_babelex import lazy_gettext, gettext
|
from flask_babelex import lazy_gettext
|
||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from wtforms import SelectField, StringField, SubmitField
|
from wtforms import SelectField, StringField, SubmitField
|
||||||
from wtforms.validators import DataRequired
|
from wtforms.validators import DataRequired
|
||||||
from project.forms.common import event_rating_choices
|
from project.forms.common import event_rating_choices
|
||||||
from project.models import EventReferenceRequestRejectionReason, EventReferenceRequestReviewStatus
|
from project.models import (
|
||||||
|
EventReferenceRequestRejectionReason,
|
||||||
|
EventReferenceRequestReviewStatus,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CreateEventReferenceRequestForm(FlaskForm):
|
class CreateEventReferenceRequestForm(FlaskForm):
|
||||||
admin_unit_id = SelectField(lazy_gettext('Admin unit'), validators=[DataRequired()], coerce=int)
|
admin_unit_id = SelectField(
|
||||||
|
lazy_gettext("Admin unit"), validators=[DataRequired()], coerce=int
|
||||||
|
)
|
||||||
submit = SubmitField(lazy_gettext("Save request"))
|
submit = SubmitField(lazy_gettext("Save request"))
|
||||||
|
|
||||||
|
|
||||||
class DeleteReferenceRequestForm(FlaskForm):
|
class DeleteReferenceRequestForm(FlaskForm):
|
||||||
submit = SubmitField(lazy_gettext("Delete request"))
|
submit = SubmitField(lazy_gettext("Delete request"))
|
||||||
name = StringField(lazy_gettext('Name'), validators=[DataRequired()])
|
name = StringField(lazy_gettext("Name"), validators=[DataRequired()])
|
||||||
|
|
||||||
|
|
||||||
class ReferenceRequestReviewForm(FlaskForm):
|
class ReferenceRequestReviewForm(FlaskForm):
|
||||||
review_status = SelectField(lazy_gettext('Review status'), coerce=int, choices=[
|
review_status = SelectField(
|
||||||
(int(EventReferenceRequestReviewStatus.inbox), lazy_gettext('EventReferenceRequestReviewStatus.inbox')),
|
lazy_gettext("Review status"),
|
||||||
(int(EventReferenceRequestReviewStatus.verified), lazy_gettext('EventReferenceRequestReviewStatus.verified')),
|
coerce=int,
|
||||||
(int(EventReferenceRequestReviewStatus.rejected), lazy_gettext('EventReferenceRequestReviewStatus.rejected'))])
|
choices=[
|
||||||
|
(
|
||||||
|
int(EventReferenceRequestReviewStatus.inbox),
|
||||||
|
lazy_gettext("EventReferenceRequestReviewStatus.inbox"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
int(EventReferenceRequestReviewStatus.verified),
|
||||||
|
lazy_gettext("EventReferenceRequestReviewStatus.verified"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
int(EventReferenceRequestReviewStatus.rejected),
|
||||||
|
lazy_gettext("EventReferenceRequestReviewStatus.rejected"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
rejection_reason = SelectField(lazy_gettext('Rejection reason'), coerce=int, choices=[
|
rejection_reason = SelectField(
|
||||||
(0, ''),
|
lazy_gettext("Rejection reason"),
|
||||||
(int(EventReferenceRequestRejectionReason.duplicate), lazy_gettext('EventReferenceRequestRejectionReason.duplicate')),
|
coerce=int,
|
||||||
(int(EventReferenceRequestRejectionReason.untrustworthy), lazy_gettext('EventReferenceRequestRejectionReason.untrustworthy')),
|
choices=[
|
||||||
(int(EventReferenceRequestRejectionReason.irrelevant), lazy_gettext('EventReferenceRequestRejectionReason.irrelevant')),
|
(0, ""),
|
||||||
(int(EventReferenceRequestRejectionReason.illegal), lazy_gettext('EventReferenceRequestRejectionReason.illegal'))])
|
(
|
||||||
|
int(EventReferenceRequestRejectionReason.duplicate),
|
||||||
|
lazy_gettext("EventReferenceRequestRejectionReason.duplicate"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
int(EventReferenceRequestRejectionReason.untrustworthy),
|
||||||
|
lazy_gettext("EventReferenceRequestRejectionReason.untrustworthy"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
int(EventReferenceRequestRejectionReason.irrelevant),
|
||||||
|
lazy_gettext("EventReferenceRequestRejectionReason.irrelevant"),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
int(EventReferenceRequestRejectionReason.illegal),
|
||||||
|
lazy_gettext("EventReferenceRequestRejectionReason.illegal"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
rating = SelectField(lazy_gettext('Rating'), default=50, coerce=int, choices=event_rating_choices)
|
rating = SelectField(
|
||||||
submit = SubmitField(lazy_gettext("Save review"))
|
lazy_gettext("Rating"), default=50, coerce=int, choices=event_rating_choices
|
||||||
|
)
|
||||||
|
submit = SubmitField(lazy_gettext("Save review"))
|
||||||
|
|||||||
@ -1,15 +1,16 @@
|
|||||||
from wtforms import DateTimeField, SelectMultipleField, SelectField
|
from wtforms import DateTimeField, SelectMultipleField, SelectField
|
||||||
from wtforms.widgets import html_params, HTMLString, ListWidget, CheckboxInput
|
from wtforms.widgets import html_params, HTMLString, ListWidget, CheckboxInput
|
||||||
from wtforms.validators import StopValidation
|
from wtforms.validators import StopValidation
|
||||||
import pytz
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from flask_babelex import to_user_timezone, gettext
|
from flask_babelex import to_user_timezone, gettext
|
||||||
from project.dateutils import berlin_tz
|
from project.dateutils import berlin_tz
|
||||||
|
|
||||||
|
|
||||||
class MultiCheckboxField(SelectMultipleField):
|
class MultiCheckboxField(SelectMultipleField):
|
||||||
widget = ListWidget(prefix_label=False)
|
widget = ListWidget(prefix_label=False)
|
||||||
option_widget = CheckboxInput()
|
option_widget = CheckboxInput()
|
||||||
|
|
||||||
|
|
||||||
def create_option_string(count, value):
|
def create_option_string(count, value):
|
||||||
result = ""
|
result = ""
|
||||||
for i in range(count):
|
for i in range(count):
|
||||||
@ -17,10 +18,11 @@ def create_option_string(count, value):
|
|||||||
result = result + '<option value="%02d"%s>%02d</option>' % (i, selected, i)
|
result = result + '<option value="%02d"%s>%02d</option>' % (i, selected, i)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class CustomDateTimeWidget:
|
class CustomDateTimeWidget:
|
||||||
def __call__(self, field, **kwargs):
|
def __call__(self, field, **kwargs):
|
||||||
id = kwargs.pop('id', field.id)
|
id = kwargs.pop("id", field.id)
|
||||||
date = ''
|
date = ""
|
||||||
hour = minute = 0
|
hour = minute = 0
|
||||||
if field.data:
|
if field.data:
|
||||||
date_value = to_user_timezone(field.data)
|
date_value = to_user_timezone(field.data)
|
||||||
@ -28,12 +30,24 @@ class CustomDateTimeWidget:
|
|||||||
hour = date_value.hour
|
hour = date_value.hour
|
||||||
minute = date_value.minute
|
minute = date_value.minute
|
||||||
|
|
||||||
date_params = html_params(name=field.name, id=id, value=date, required=field.flags.required, **kwargs)
|
date_params = html_params(
|
||||||
time_hour_params = html_params(name=field.name, id=id + '-hour', **kwargs)
|
name=field.name, id=id, value=date, required=field.flags.required, **kwargs
|
||||||
time_minute_params = html_params(name=field.name, id=id + '-minute', **kwargs)
|
)
|
||||||
clear_button_id = id + '-clear-button'
|
time_hour_params = html_params(name=field.name, id=id + "-hour", **kwargs)
|
||||||
|
time_minute_params = html_params(name=field.name, id=id + "-minute", **kwargs)
|
||||||
|
clear_button_id = id + "-clear-button"
|
||||||
|
|
||||||
|
return HTMLString(
|
||||||
|
'<div class="input-group-prepend mt-1"><input type="text" class="datepicker" {}/><button class="btn btn-outline-secondary" type="button" id="{}"><i class="fa fa-times"></i></button></div><div class="mx-2"></div><div class="input-group-append mt-1"><select {}>{}</select><span class="input-group-text">:</span><select {}>{}</select></div>'.format(
|
||||||
|
date_params,
|
||||||
|
clear_button_id,
|
||||||
|
time_hour_params,
|
||||||
|
create_option_string(24, hour),
|
||||||
|
time_minute_params,
|
||||||
|
create_option_string(60, minute),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return HTMLString('<div class="input-group-prepend mt-1"><input type="text" class="datepicker" {}/><button class="btn btn-outline-secondary" type="button" id="{}"><i class="fa fa-times"></i></button></div><div class="mx-2"></div><div class="input-group-append mt-1"><select {}>{}</select><span class="input-group-text">:</span><select {}>{}</select></div>'.format(date_params, clear_button_id, time_hour_params, create_option_string(24, hour), time_minute_params, create_option_string(60, minute)))
|
|
||||||
|
|
||||||
class CustomDateTimeField(DateTimeField):
|
class CustomDateTimeField(DateTimeField):
|
||||||
widget = CustomDateTimeWidget()
|
widget = CustomDateTimeWidget()
|
||||||
@ -47,15 +61,20 @@ class CustomDateTimeField(DateTimeField):
|
|||||||
return
|
return
|
||||||
|
|
||||||
date = datetime.strptime(date_str, "%Y-%m-%d")
|
date = datetime.strptime(date_str, "%Y-%m-%d")
|
||||||
date_time = datetime(date.year, date.month, date.day, int(hour_str), int(minute_str))
|
date_time = datetime(
|
||||||
|
date.year, date.month, date.day, int(hour_str), int(minute_str)
|
||||||
|
)
|
||||||
self.data = berlin_tz.localize(date_time)
|
self.data = berlin_tz.localize(date_time)
|
||||||
except:
|
except Exception:
|
||||||
raise ValueError('Not a valid datetime value. Looking for YYYY-MM-DD HH:mm.')
|
raise ValueError(
|
||||||
|
"Not a valid datetime value. Looking for YYYY-MM-DD HH:mm."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CustomDateWidget:
|
class CustomDateWidget:
|
||||||
def __call__(self, field, **kwargs):
|
def __call__(self, field, **kwargs):
|
||||||
id = kwargs.pop('id', field.id)
|
id = kwargs.pop("id", field.id)
|
||||||
date = ''
|
date = ""
|
||||||
if field.data:
|
if field.data:
|
||||||
date_value = to_user_timezone(field.data)
|
date_value = to_user_timezone(field.data)
|
||||||
date = date_value.strftime("%Y-%m-%d")
|
date = date_value.strftime("%Y-%m-%d")
|
||||||
@ -63,6 +82,7 @@ class CustomDateWidget:
|
|||||||
date_params = html_params(name=field.name, id=id, value=date, **kwargs)
|
date_params = html_params(name=field.name, id=id, value=date, **kwargs)
|
||||||
return HTMLString('<input type="text" {}/>'.format(date_params))
|
return HTMLString('<input type="text" {}/>'.format(date_params))
|
||||||
|
|
||||||
|
|
||||||
class CustomDateField(DateTimeField):
|
class CustomDateField(DateTimeField):
|
||||||
widget = CustomDateWidget()
|
widget = CustomDateWidget()
|
||||||
|
|
||||||
@ -76,8 +96,9 @@ class CustomDateField(DateTimeField):
|
|||||||
|
|
||||||
date = datetime.strptime(date_str, "%Y-%m-%d")
|
date = datetime.strptime(date_str, "%Y-%m-%d")
|
||||||
self.data = berlin_tz.localize(date)
|
self.data = berlin_tz.localize(date)
|
||||||
except:
|
except Exception:
|
||||||
raise ValueError('Not a valid date value. Looking for YYYY-MM-DD.')
|
raise ValueError("Not a valid date value. Looking for YYYY-MM-DD.")
|
||||||
|
|
||||||
|
|
||||||
def try_to_int(value):
|
def try_to_int(value):
|
||||||
if isinstance(value, int):
|
if isinstance(value, int):
|
||||||
@ -91,15 +112,25 @@ def try_to_int(value):
|
|||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
class TagSelectField(SelectField):
|
|
||||||
|
|
||||||
def __init__(self, label=None, validators=None, coerce=try_to_int, choices=None, validate_choice=True, **kwargs):
|
class TagSelectField(SelectField):
|
||||||
super(TagSelectField, self).__init__(label, validators, coerce, choices, validate_choice, **kwargs)
|
def __init__(
|
||||||
|
self,
|
||||||
|
label=None,
|
||||||
|
validators=None,
|
||||||
|
coerce=try_to_int,
|
||||||
|
choices=None,
|
||||||
|
validate_choice=True,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
super(TagSelectField, self).__init__(
|
||||||
|
label, validators, coerce, choices, validate_choice, **kwargs
|
||||||
|
)
|
||||||
|
|
||||||
def pre_validate(self, form):
|
def pre_validate(self, form):
|
||||||
if self.is_free_text():
|
if self.is_free_text():
|
||||||
if not self.data or not self.data.strip():
|
if not self.data or not self.data.strip():
|
||||||
raise StopValidation(gettext('This field is required'))
|
raise StopValidation(gettext("This field is required"))
|
||||||
else:
|
else:
|
||||||
super(TagSelectField, self).pre_validate(form)
|
super(TagSelectField, self).pre_validate(form)
|
||||||
|
|
||||||
|
|||||||
@ -1,32 +1,35 @@
|
|||||||
from project import app, babel
|
from project import app, babel
|
||||||
|
from flask_babelex import gettext
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
|
|
||||||
@babel.localeselector
|
@babel.localeselector
|
||||||
def get_locale():
|
def get_locale():
|
||||||
return request.accept_languages.best_match(app.config['LANGUAGES'])
|
return request.accept_languages.best_match(app.config["LANGUAGES"])
|
||||||
|
|
||||||
|
|
||||||
def print_dynamic_texts():
|
def print_dynamic_texts():
|
||||||
gettext('Event_Art')
|
gettext("Event_Art")
|
||||||
gettext('Event_Book')
|
gettext("Event_Book")
|
||||||
gettext('Event_Movie')
|
gettext("Event_Movie")
|
||||||
gettext('Event_Family')
|
gettext("Event_Family")
|
||||||
gettext('Event_Festival')
|
gettext("Event_Festival")
|
||||||
gettext('Event_Religious')
|
gettext("Event_Religious")
|
||||||
gettext('Event_Shopping')
|
gettext("Event_Shopping")
|
||||||
gettext('Event_Comedy')
|
gettext("Event_Comedy")
|
||||||
gettext('Event_Music')
|
gettext("Event_Music")
|
||||||
gettext('Event_Dance')
|
gettext("Event_Dance")
|
||||||
gettext('Event_Nightlife')
|
gettext("Event_Nightlife")
|
||||||
gettext('Event_Theater')
|
gettext("Event_Theater")
|
||||||
gettext('Event_Dining')
|
gettext("Event_Dining")
|
||||||
gettext('Event_Conference')
|
gettext("Event_Conference")
|
||||||
gettext('Event_Meetup')
|
gettext("Event_Meetup")
|
||||||
gettext('Event_Fitness')
|
gettext("Event_Fitness")
|
||||||
gettext('Event_Sports')
|
gettext("Event_Sports")
|
||||||
gettext('Event_Other')
|
gettext("Event_Other")
|
||||||
gettext('Typical Age range')
|
gettext("Typical Age range")
|
||||||
gettext('Administrator')
|
gettext("Administrator")
|
||||||
gettext('Event expert')
|
gettext("Event expert")
|
||||||
gettext('EventReviewStatus.inbox')
|
gettext("EventReviewStatus.inbox")
|
||||||
gettext('EventReviewStatus.verified')
|
gettext("EventReviewStatus.verified")
|
||||||
gettext('EventReviewStatus.rejected')
|
gettext("EventReviewStatus.rejected")
|
||||||
|
|||||||
@ -3,6 +3,7 @@ from project.services.user import upsert_user_role, add_roles_to_user
|
|||||||
from project.services.admin_unit import upsert_admin_unit_member_role
|
from project.services.admin_unit import upsert_admin_unit_member_role
|
||||||
from project.models import Location
|
from project.models import Location
|
||||||
|
|
||||||
|
|
||||||
@app.before_first_request
|
@app.before_first_request
|
||||||
def create_initial_data():
|
def create_initial_data():
|
||||||
admin_permissions = [
|
admin_permissions = [
|
||||||
@ -10,7 +11,8 @@ def create_initial_data():
|
|||||||
"admin_unit.members:invite",
|
"admin_unit.members:invite",
|
||||||
"admin_unit.members:read",
|
"admin_unit.members:read",
|
||||||
"admin_unit.members:update",
|
"admin_unit.members:update",
|
||||||
"admin_unit.members:delete"]
|
"admin_unit.members:delete",
|
||||||
|
]
|
||||||
event_permissions = [
|
event_permissions = [
|
||||||
"event:verify",
|
"event:verify",
|
||||||
"event:create",
|
"event:create",
|
||||||
@ -31,15 +33,16 @@ def create_initial_data():
|
|||||||
"reference_request:read",
|
"reference_request:read",
|
||||||
"reference_request:update",
|
"reference_request:update",
|
||||||
"reference_request:delete",
|
"reference_request:delete",
|
||||||
"reference_request:verify"]
|
"reference_request:verify",
|
||||||
|
]
|
||||||
|
|
||||||
upsert_admin_unit_member_role('admin', 'Administrator', admin_permissions)
|
upsert_admin_unit_member_role("admin", "Administrator", admin_permissions)
|
||||||
upsert_admin_unit_member_role('event_verifier', 'Event expert', event_permissions)
|
upsert_admin_unit_member_role("event_verifier", "Event expert", event_permissions)
|
||||||
|
|
||||||
upsert_user_role('admin', 'Administrator', admin_permissions)
|
upsert_user_role("admin", "Administrator", admin_permissions)
|
||||||
upsert_user_role('event_verifier', 'Event expert', event_permissions)
|
upsert_user_role("event_verifier", "Event expert", event_permissions)
|
||||||
add_roles_to_user('grams.daniel@gmail.com', ['admin', 'event_verifier'])
|
add_roles_to_user("grams.daniel@gmail.com", ["admin", "event_verifier"])
|
||||||
|
|
||||||
Location.update_coordinates()
|
Location.update_coordinates()
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|||||||
@ -3,31 +3,37 @@ from project.utils import get_event_category_name, get_localized_enum_name
|
|||||||
from urllib.parse import quote_plus
|
from urllib.parse import quote_plus
|
||||||
import os
|
import os
|
||||||
|
|
||||||
def env_override(value, key):
|
|
||||||
return os.getenv(key, value)
|
|
||||||
|
|
||||||
app.jinja_env.filters['event_category_name'] = lambda u: get_event_category_name(u)
|
def env_override(value, key):
|
||||||
app.jinja_env.filters['loc_enum'] = lambda u: get_localized_enum_name(u)
|
return os.getenv(key, value)
|
||||||
app.jinja_env.filters['env_override'] = env_override
|
|
||||||
app.jinja_env.filters['quote_plus'] = lambda u: quote_plus(u)
|
|
||||||
|
app.jinja_env.filters["event_category_name"] = lambda u: get_event_category_name(u)
|
||||||
|
app.jinja_env.filters["loc_enum"] = lambda u: get_localized_enum_name(u)
|
||||||
|
app.jinja_env.filters["env_override"] = env_override
|
||||||
|
app.jinja_env.filters["quote_plus"] = lambda u: quote_plus(u)
|
||||||
|
|
||||||
|
|
||||||
@app.context_processor
|
@app.context_processor
|
||||||
def get_manage_menu_options_context_processor():
|
def get_manage_menu_options_context_processor():
|
||||||
|
def get_manage_menu_options(admin_unit):
|
||||||
|
from project.access import has_access
|
||||||
|
from project.services.event_suggestion import get_event_reviews_badge_query
|
||||||
|
from project.services.reference import (
|
||||||
|
get_reference_requests_incoming_badge_query,
|
||||||
|
)
|
||||||
|
|
||||||
def get_manage_menu_options(admin_unit):
|
reviews_badge = 0
|
||||||
from project.access import has_access
|
reference_requests_incoming_badge = get_reference_requests_incoming_badge_query(
|
||||||
from project.services.event_suggestion import get_event_reviews_badge_query
|
admin_unit
|
||||||
from project.services.reference import get_reference_requests_incoming_badge_query
|
).count()
|
||||||
|
|
||||||
reviews_badge = 0
|
if has_access(admin_unit, "event:verify"):
|
||||||
reference_requests_incoming_badge = get_reference_requests_incoming_badge_query(admin_unit).count()
|
reviews_badge = get_event_reviews_badge_query(admin_unit).count()
|
||||||
|
|
||||||
if has_access(admin_unit, 'event:verify'):
|
return {
|
||||||
reviews_badge = get_event_reviews_badge_query(admin_unit).count()
|
"reviews_badge": reviews_badge,
|
||||||
|
"reference_requests_incoming_badge": reference_requests_incoming_badge,
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return dict(get_manage_menu_options=get_manage_menu_options)
|
||||||
'reviews_badge': reviews_badge,
|
|
||||||
'reference_requests_incoming_badge': reference_requests_incoming_badge
|
|
||||||
}
|
|
||||||
|
|
||||||
return dict(get_manage_menu_options=get_manage_menu_options)
|
|
||||||
|
|||||||
@ -5,16 +5,17 @@ from flask import url_for
|
|||||||
from project.models import EventAttendanceMode, EventStatus
|
from project.models import EventAttendanceMode, EventStatus
|
||||||
import pytz
|
import pytz
|
||||||
|
|
||||||
berlin_tz = pytz.timezone('Europe/Berlin')
|
berlin_tz = pytz.timezone("Europe/Berlin")
|
||||||
|
|
||||||
|
|
||||||
# subclass JSONEncoder
|
|
||||||
class DateTimeEncoder(JSONEncoder):
|
class DateTimeEncoder(JSONEncoder):
|
||||||
#Override the default method
|
# Override the default method
|
||||||
def default(self, obj):
|
def default(self, obj):
|
||||||
if isinstance(obj, (datetime.date, datetime.datetime)):
|
if isinstance(obj, (datetime.date, datetime.datetime)):
|
||||||
return (obj.astimezone(berlin_tz)).isoformat()
|
return (obj.astimezone(berlin_tz)).isoformat()
|
||||||
if isinstance(obj, decimal.Decimal):
|
if isinstance(obj, decimal.Decimal):
|
||||||
return float(obj)
|
return float(obj)
|
||||||
|
|
||||||
|
|
||||||
def get_sd_for_admin_unit(admin_unit):
|
def get_sd_for_admin_unit(admin_unit):
|
||||||
result = {}
|
result = {}
|
||||||
@ -27,6 +28,7 @@ def get_sd_for_admin_unit(admin_unit):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_sd_for_organizer_organization(organizer):
|
def get_sd_for_organizer_organization(organizer):
|
||||||
result = {}
|
result = {}
|
||||||
result["@type"] = "Organization"
|
result["@type"] = "Organization"
|
||||||
@ -46,9 +48,11 @@ def get_sd_for_organizer_organization(organizer):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_sd_for_organizer(organizer):
|
def get_sd_for_organizer(organizer):
|
||||||
return get_sd_for_organizer_organization(organizer)
|
return get_sd_for_organizer_organization(organizer)
|
||||||
|
|
||||||
|
|
||||||
def get_sd_for_location(location):
|
def get_sd_for_location(location):
|
||||||
result = {}
|
result = {}
|
||||||
result["@type"] = "PostalAddress"
|
result["@type"] = "PostalAddress"
|
||||||
@ -63,6 +67,7 @@ def get_sd_for_location(location):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_sd_for_geo(location):
|
def get_sd_for_geo(location):
|
||||||
result = {}
|
result = {}
|
||||||
result["@type"] = "GeoCoordinates"
|
result["@type"] = "GeoCoordinates"
|
||||||
@ -70,6 +75,7 @@ def get_sd_for_geo(location):
|
|||||||
result["longitude"] = location.longitude
|
result["longitude"] = location.longitude
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_sd_for_place(place, use_ref=True):
|
def get_sd_for_place(place, use_ref=True):
|
||||||
result = {}
|
result = {}
|
||||||
result["@type"] = "Place"
|
result["@type"] = "Place"
|
||||||
@ -82,13 +88,14 @@ def get_sd_for_place(place, use_ref=True):
|
|||||||
result["geo"] = get_sd_for_geo(place.location)
|
result["geo"] = get_sd_for_geo(place.location)
|
||||||
|
|
||||||
if place.photo_id:
|
if place.photo_id:
|
||||||
result["photo"] = url_for('image', id=place.photo_id)
|
result["photo"] = url_for("image", id=place.photo_id)
|
||||||
|
|
||||||
if place.url:
|
if place.url:
|
||||||
result["url"] = place.url
|
result["url"] = place.url
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_sd_for_event_date(event_date):
|
def get_sd_for_event_date(event_date):
|
||||||
event = event_date.event
|
event = event_date.event
|
||||||
|
|
||||||
@ -101,7 +108,7 @@ def get_sd_for_event_date(event_date):
|
|||||||
result["startDate"] = event_date.start
|
result["startDate"] = event_date.start
|
||||||
|
|
||||||
url_list = list()
|
url_list = list()
|
||||||
url_list.append(url_for('event_date', id=event_date.id))
|
url_list.append(url_for("event_date", id=event_date.id))
|
||||||
|
|
||||||
if event.external_link:
|
if event.external_link:
|
||||||
url_list.append(event.external_link)
|
url_list.append(event.external_link)
|
||||||
@ -157,6 +164,6 @@ def get_sd_for_event_date(event_date):
|
|||||||
result["eventStatus"] = "EventRescheduled"
|
result["eventStatus"] = "EventRescheduled"
|
||||||
|
|
||||||
if event.photo_id:
|
if event.photo_id:
|
||||||
result["image"] = url_for('image', id=event.photo_id)
|
result["image"] = url_for("image", id=event.photo_id)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@ -3,9 +3,19 @@ from sqlalchemy.ext.declarative import declared_attr
|
|||||||
from sqlalchemy.ext.hybrid import hybrid_property
|
from sqlalchemy.ext.hybrid import hybrid_property
|
||||||
from sqlalchemy.orm import relationship, backref, deferred
|
from sqlalchemy.orm import relationship, backref, deferred
|
||||||
from sqlalchemy.schema import CheckConstraint
|
from sqlalchemy.schema import CheckConstraint
|
||||||
from sqlalchemy.types import TypeDecorator
|
|
||||||
from sqlalchemy.event import listens_for
|
from sqlalchemy.event import listens_for
|
||||||
from sqlalchemy import UniqueConstraint, Boolean, DateTime, Column, Integer, String, ForeignKey, Unicode, UnicodeText, Numeric, LargeBinary
|
from sqlalchemy import (
|
||||||
|
UniqueConstraint,
|
||||||
|
Boolean,
|
||||||
|
DateTime,
|
||||||
|
Column,
|
||||||
|
Integer,
|
||||||
|
String,
|
||||||
|
ForeignKey,
|
||||||
|
Unicode,
|
||||||
|
UnicodeText,
|
||||||
|
Numeric,
|
||||||
|
)
|
||||||
from sqlalchemy_utils import ColorType
|
from sqlalchemy_utils import ColorType
|
||||||
from flask_security import UserMixin, RoleMixin
|
from flask_security import UserMixin, RoleMixin
|
||||||
from flask_dance.consumer.storage.sqla import OAuthConsumerMixin
|
from flask_dance.consumer.storage.sqla import OAuthConsumerMixin
|
||||||
@ -15,23 +25,26 @@ from project.dbtypes import IntegerEnum
|
|||||||
from geoalchemy2 import Geometry
|
from geoalchemy2 import Geometry
|
||||||
from sqlalchemy import and_
|
from sqlalchemy import and_
|
||||||
|
|
||||||
### Base
|
# Base
|
||||||
|
|
||||||
|
|
||||||
class TrackableMixin(object):
|
class TrackableMixin(object):
|
||||||
created_at = Column(DateTime, default=datetime.datetime.utcnow)
|
created_at = Column(DateTime, default=datetime.datetime.utcnow)
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def created_by_id(cls):
|
def created_by_id(cls):
|
||||||
return Column('created_by_id', ForeignKey('user.id'))
|
return Column("created_by_id", ForeignKey("user.id"))
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
def created_by(cls):
|
def created_by(cls):
|
||||||
return relationship("User")
|
return relationship("User")
|
||||||
|
|
||||||
### Multi purpose
|
|
||||||
|
# Multi purpose
|
||||||
|
|
||||||
|
|
||||||
class Image(db.Model, TrackableMixin):
|
class Image(db.Model, TrackableMixin):
|
||||||
__tablename__ = 'image'
|
__tablename__ = "image"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
data = deferred(db.Column(db.LargeBinary))
|
data = deferred(db.Column(db.LargeBinary))
|
||||||
encoding_format = Column(String(80))
|
encoding_format = Column(String(80))
|
||||||
@ -40,24 +53,28 @@ class Image(db.Model, TrackableMixin):
|
|||||||
def is_empty(self):
|
def is_empty(self):
|
||||||
return not self.data
|
return not self.data
|
||||||
|
|
||||||
### User
|
|
||||||
|
# User
|
||||||
|
|
||||||
|
|
||||||
class RolesUsers(db.Model):
|
class RolesUsers(db.Model):
|
||||||
__tablename__ = 'roles_users'
|
__tablename__ = "roles_users"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
user_id = Column('user_id', Integer(), ForeignKey('user.id'))
|
user_id = Column("user_id", Integer(), ForeignKey("user.id"))
|
||||||
role_id = Column('role_id', Integer(), ForeignKey('role.id'))
|
role_id = Column("role_id", Integer(), ForeignKey("role.id"))
|
||||||
|
|
||||||
|
|
||||||
class Role(db.Model, RoleMixin):
|
class Role(db.Model, RoleMixin):
|
||||||
__tablename__ = 'role'
|
__tablename__ = "role"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
name = Column(String(80), unique=True)
|
name = Column(String(80), unique=True)
|
||||||
title = Column(Unicode(255))
|
title = Column(Unicode(255))
|
||||||
description = Column(String(255))
|
description = Column(String(255))
|
||||||
permissions = Column(UnicodeText())
|
permissions = Column(UnicodeText())
|
||||||
|
|
||||||
|
|
||||||
class User(db.Model, UserMixin):
|
class User(db.Model, UserMixin):
|
||||||
__tablename__ = 'user'
|
__tablename__ = "user"
|
||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
email = Column(String(255), unique=True)
|
email = Column(String(255), unique=True)
|
||||||
username = Column(String(255))
|
username = Column(String(255))
|
||||||
@ -70,63 +87,76 @@ class User(db.Model, UserMixin):
|
|||||||
active = Column(Boolean())
|
active = Column(Boolean())
|
||||||
fs_uniquifier = Column(String(255))
|
fs_uniquifier = Column(String(255))
|
||||||
confirmed_at = Column(DateTime())
|
confirmed_at = Column(DateTime())
|
||||||
roles = relationship('Role', secondary='roles_users',
|
roles = relationship(
|
||||||
backref=backref('users', lazy='dynamic'))
|
"Role", secondary="roles_users", backref=backref("users", lazy="dynamic")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class OAuth(OAuthConsumerMixin, db.Model):
|
class OAuth(OAuthConsumerMixin, db.Model):
|
||||||
provider_user_id = Column(String(256), unique=True, nullable=False)
|
provider_user_id = Column(String(256), unique=True, nullable=False)
|
||||||
user_id = Column(Integer(), ForeignKey('user.id'), nullable=False)
|
user_id = Column(Integer(), ForeignKey("user.id"), nullable=False)
|
||||||
user = db.relationship('User')
|
user = db.relationship("User")
|
||||||
|
|
||||||
|
|
||||||
|
# Admin Unit
|
||||||
|
|
||||||
### Admin Unit
|
|
||||||
|
|
||||||
class AdminUnitMemberRolesMembers(db.Model):
|
class AdminUnitMemberRolesMembers(db.Model):
|
||||||
__tablename__ = 'adminunitmemberroles_members'
|
__tablename__ = "adminunitmemberroles_members"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
member_id = Column('member_id', Integer(), ForeignKey('adminunitmember.id'))
|
member_id = Column("member_id", Integer(), ForeignKey("adminunitmember.id"))
|
||||||
role_id = Column('role_id', Integer(), ForeignKey('adminunitmemberrole.id'))
|
role_id = Column("role_id", Integer(), ForeignKey("adminunitmemberrole.id"))
|
||||||
|
|
||||||
|
|
||||||
class AdminUnitMemberRole(db.Model, RoleMixin):
|
class AdminUnitMemberRole(db.Model, RoleMixin):
|
||||||
__tablename__ = 'adminunitmemberrole'
|
__tablename__ = "adminunitmemberrole"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
name = Column(String(80), unique=True)
|
name = Column(String(80), unique=True)
|
||||||
title = Column(Unicode(255))
|
title = Column(Unicode(255))
|
||||||
description = Column(String(255))
|
description = Column(String(255))
|
||||||
permissions = Column(UnicodeText())
|
permissions = Column(UnicodeText())
|
||||||
|
|
||||||
|
|
||||||
class AdminUnitMember(db.Model):
|
class AdminUnitMember(db.Model):
|
||||||
__tablename__ = 'adminunitmember'
|
__tablename__ = "adminunitmember"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
admin_unit_id = db.Column(db.Integer, db.ForeignKey('adminunit.id'), nullable=False)
|
admin_unit_id = db.Column(db.Integer, db.ForeignKey("adminunit.id"), nullable=False)
|
||||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
|
user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=False)
|
||||||
user = db.relationship('User', backref=db.backref('adminunitmembers', lazy=True))
|
user = db.relationship("User", backref=db.backref("adminunitmembers", lazy=True))
|
||||||
roles = relationship('AdminUnitMemberRole', secondary='adminunitmemberroles_members',
|
roles = relationship(
|
||||||
order_by="AdminUnitMemberRole.id",
|
"AdminUnitMemberRole",
|
||||||
backref=backref('members', lazy='dynamic'))
|
secondary="adminunitmemberroles_members",
|
||||||
|
order_by="AdminUnitMemberRole.id",
|
||||||
|
backref=backref("members", lazy="dynamic"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AdminUnitMemberInvitation(db.Model):
|
class AdminUnitMemberInvitation(db.Model):
|
||||||
__tablename__ = 'adminunitmemberinvitation'
|
__tablename__ = "adminunitmemberinvitation"
|
||||||
__table_args__ = (
|
__table_args__ = (UniqueConstraint("email", "admin_unit_id"),)
|
||||||
UniqueConstraint('email', 'admin_unit_id'),
|
|
||||||
)
|
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
admin_unit_id = db.Column(db.Integer, db.ForeignKey('adminunit.id'), nullable=False)
|
admin_unit_id = db.Column(db.Integer, db.ForeignKey("adminunit.id"), nullable=False)
|
||||||
email = Column(String(255))
|
email = Column(String(255))
|
||||||
roles = Column(UnicodeText())
|
roles = Column(UnicodeText())
|
||||||
|
|
||||||
|
|
||||||
class AdminUnit(db.Model, TrackableMixin):
|
class AdminUnit(db.Model, TrackableMixin):
|
||||||
__tablename__ = 'adminunit'
|
__tablename__ = "adminunit"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
name = Column(Unicode(255), unique=True)
|
name = Column(Unicode(255), unique=True)
|
||||||
short_name = Column(Unicode(100), unique=True)
|
short_name = Column(Unicode(100), unique=True)
|
||||||
members = relationship('AdminUnitMember', backref=backref('adminunit', lazy=True))
|
members = relationship("AdminUnitMember", backref=backref("adminunit", lazy=True))
|
||||||
invitations = relationship('AdminUnitMemberInvitation', backref=backref('adminunit', lazy=True))
|
invitations = relationship(
|
||||||
event_organizers = relationship('EventOrganizer', backref=backref('adminunit', lazy=True))
|
"AdminUnitMemberInvitation", backref=backref("adminunit", lazy=True)
|
||||||
event_places = relationship('EventPlace', backref=backref('adminunit', lazy=True))
|
)
|
||||||
location_id = db.Column(db.Integer, db.ForeignKey('location.id'))
|
event_organizers = relationship(
|
||||||
location = db.relationship('Location')
|
"EventOrganizer", backref=backref("adminunit", lazy=True)
|
||||||
logo_id = db.Column(db.Integer, db.ForeignKey('image.id'))
|
)
|
||||||
logo = db.relationship('Image', uselist=False)
|
event_places = relationship("EventPlace", backref=backref("adminunit", lazy=True))
|
||||||
|
location_id = db.Column(db.Integer, db.ForeignKey("location.id"))
|
||||||
|
location = db.relationship("Location")
|
||||||
|
logo_id = db.Column(db.Integer, db.ForeignKey("image.id"))
|
||||||
|
logo = db.relationship("Image", uselist=False)
|
||||||
url = Column(String(255))
|
url = Column(String(255))
|
||||||
email = Column(Unicode(255))
|
email = Column(Unicode(255))
|
||||||
phone = Column(Unicode(255))
|
phone = Column(Unicode(255))
|
||||||
@ -136,95 +166,113 @@ class AdminUnit(db.Model, TrackableMixin):
|
|||||||
widget_primary_color = Column(ColorType)
|
widget_primary_color = Column(ColorType)
|
||||||
widget_link_color = Column(ColorType)
|
widget_link_color = Column(ColorType)
|
||||||
|
|
||||||
@listens_for(AdminUnit, 'before_insert')
|
|
||||||
@listens_for(AdminUnit, 'before_update')
|
@listens_for(AdminUnit, "before_insert")
|
||||||
|
@listens_for(AdminUnit, "before_update")
|
||||||
def purge_admin_unit(mapper, connect, self):
|
def purge_admin_unit(mapper, connect, self):
|
||||||
if self.logo and self.logo.is_empty():
|
if self.logo and self.logo.is_empty():
|
||||||
self.logo_id = None
|
self.logo_id = None
|
||||||
|
|
||||||
|
|
||||||
# Universal Types
|
# Universal Types
|
||||||
|
|
||||||
|
|
||||||
class Location(db.Model, TrackableMixin):
|
class Location(db.Model, TrackableMixin):
|
||||||
__tablename__ = 'location'
|
__tablename__ = "location"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
street = Column(Unicode(255))
|
street = Column(Unicode(255))
|
||||||
postalCode = Column(Unicode(255))
|
postalCode = Column(Unicode(255))
|
||||||
city = Column(Unicode(255))
|
city = Column(Unicode(255))
|
||||||
state = Column(Unicode(255))
|
state = Column(Unicode(255))
|
||||||
country = Column(Unicode(255))
|
country = Column(Unicode(255))
|
||||||
latitude = Column(Numeric(18,16))
|
latitude = Column(Numeric(18, 16))
|
||||||
longitude = Column(Numeric(19,16))
|
longitude = Column(Numeric(19, 16))
|
||||||
coordinate = Column(Geometry(geometry_type="POINT"))
|
coordinate = Column(Geometry(geometry_type="POINT"))
|
||||||
|
|
||||||
def is_empty(self):
|
def is_empty(self):
|
||||||
return (not self.street
|
return (
|
||||||
|
not self.street
|
||||||
and not self.postalCode
|
and not self.postalCode
|
||||||
and not self.city
|
and not self.city
|
||||||
and not self.state
|
and not self.state
|
||||||
and not self.country
|
and not self.country
|
||||||
and not self.latitude
|
and not self.latitude
|
||||||
and not self.longitude)
|
and not self.longitude
|
||||||
|
)
|
||||||
|
|
||||||
def update_coordinate(self):
|
def update_coordinate(self):
|
||||||
if self.latitude and self.longitude:
|
if self.latitude and self.longitude:
|
||||||
point = 'POINT({} {})'.format(self.longitude, self.latitude)
|
point = "POINT({} {})".format(self.longitude, self.latitude)
|
||||||
self.coordinate = point
|
self.coordinate = point
|
||||||
else:
|
else:
|
||||||
self.coordinate = None
|
self.coordinate = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def update_coordinates(cls):
|
def update_coordinates(cls):
|
||||||
locations = Location.query.filter(and_(Location.latitude != None, Location.latitude != 0, Location.coordinate == None)).all()
|
locations = Location.query.filter(
|
||||||
|
and_(
|
||||||
|
Location.latitude is not None,
|
||||||
|
Location.latitude != 0,
|
||||||
|
Location.coordinate is None,
|
||||||
|
)
|
||||||
|
).all()
|
||||||
|
|
||||||
for location in locations:
|
for location in locations:
|
||||||
location.update_coordinate()
|
location.update_coordinate()
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
@listens_for(Location, 'before_insert')
|
|
||||||
@listens_for(Location, 'before_update')
|
@listens_for(Location, "before_insert")
|
||||||
|
@listens_for(Location, "before_update")
|
||||||
def update_location_coordinate(mapper, connect, self):
|
def update_location_coordinate(mapper, connect, self):
|
||||||
self.update_coordinate()
|
self.update_coordinate()
|
||||||
|
|
||||||
|
|
||||||
# Events
|
# Events
|
||||||
class EventPlace(db.Model, TrackableMixin):
|
class EventPlace(db.Model, TrackableMixin):
|
||||||
__tablename__ = 'eventplace'
|
__tablename__ = "eventplace"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
name = Column(Unicode(255), nullable=False)
|
name = Column(Unicode(255), nullable=False)
|
||||||
location_id = db.Column(db.Integer, db.ForeignKey('location.id'))
|
location_id = db.Column(db.Integer, db.ForeignKey("location.id"))
|
||||||
location = db.relationship('Location', uselist=False)
|
location = db.relationship("Location", uselist=False)
|
||||||
photo_id = db.Column(db.Integer, db.ForeignKey('image.id'))
|
photo_id = db.Column(db.Integer, db.ForeignKey("image.id"))
|
||||||
photo = db.relationship('Image', uselist=False)
|
photo = db.relationship("Image", uselist=False)
|
||||||
url = Column(String(255))
|
url = Column(String(255))
|
||||||
description = Column(UnicodeText())
|
description = Column(UnicodeText())
|
||||||
admin_unit_id = db.Column(db.Integer, db.ForeignKey('adminunit.id'), nullable=True)
|
admin_unit_id = db.Column(db.Integer, db.ForeignKey("adminunit.id"), nullable=True)
|
||||||
|
|
||||||
def is_empty(self):
|
def is_empty(self):
|
||||||
return (not self.name)
|
return not self.name
|
||||||
|
|
||||||
@listens_for(EventPlace, 'before_insert')
|
|
||||||
@listens_for(EventPlace, 'before_update')
|
@listens_for(EventPlace, "before_insert")
|
||||||
|
@listens_for(EventPlace, "before_update")
|
||||||
def purge_event_place(mapper, connect, self):
|
def purge_event_place(mapper, connect, self):
|
||||||
if self.location and self.location.is_empty():
|
if self.location and self.location.is_empty():
|
||||||
self.location_id = None
|
self.location_id = None
|
||||||
if self.photo and self.photo.is_empty():
|
if self.photo and self.photo.is_empty():
|
||||||
self.photo_id = None
|
self.photo_id = None
|
||||||
|
|
||||||
|
|
||||||
class EventCategory(db.Model):
|
class EventCategory(db.Model):
|
||||||
__tablename__ = 'eventcategory'
|
__tablename__ = "eventcategory"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
name = Column(Unicode(255), nullable=False, unique=True)
|
name = Column(Unicode(255), nullable=False, unique=True)
|
||||||
|
|
||||||
|
|
||||||
class EventTargetGroupOrigin(IntEnum):
|
class EventTargetGroupOrigin(IntEnum):
|
||||||
both = 1
|
both = 1
|
||||||
tourist = 2
|
tourist = 2
|
||||||
resident = 3
|
resident = 3
|
||||||
|
|
||||||
|
|
||||||
class EventAttendanceMode(IntEnum):
|
class EventAttendanceMode(IntEnum):
|
||||||
offline = 1
|
offline = 1
|
||||||
online = 2
|
online = 2
|
||||||
mixed = 3
|
mixed = 3
|
||||||
|
|
||||||
|
|
||||||
class EventStatus(IntEnum):
|
class EventStatus(IntEnum):
|
||||||
scheduled = 1
|
scheduled = 1
|
||||||
cancelled = 2
|
cancelled = 2
|
||||||
@ -232,65 +280,77 @@ class EventStatus(IntEnum):
|
|||||||
postponed = 4
|
postponed = 4
|
||||||
rescheduled = 5
|
rescheduled = 5
|
||||||
|
|
||||||
|
|
||||||
class EventReviewStatus(IntEnum):
|
class EventReviewStatus(IntEnum):
|
||||||
inbox = 1
|
inbox = 1
|
||||||
verified = 2
|
verified = 2
|
||||||
rejected = 3
|
rejected = 3
|
||||||
|
|
||||||
|
|
||||||
class EventRejectionReason(IntEnum):
|
class EventRejectionReason(IntEnum):
|
||||||
duplicate = 1
|
duplicate = 1
|
||||||
untrustworthy = 2
|
untrustworthy = 2
|
||||||
illegal = 3
|
illegal = 3
|
||||||
|
|
||||||
|
|
||||||
class EventReferenceRequestReviewStatus(IntEnum):
|
class EventReferenceRequestReviewStatus(IntEnum):
|
||||||
inbox = 1
|
inbox = 1
|
||||||
verified = 2
|
verified = 2
|
||||||
rejected = 3
|
rejected = 3
|
||||||
|
|
||||||
|
|
||||||
class EventReferenceRequestRejectionReason(IntEnum):
|
class EventReferenceRequestRejectionReason(IntEnum):
|
||||||
duplicate = 1
|
duplicate = 1
|
||||||
untrustworthy = 2
|
untrustworthy = 2
|
||||||
illegal = 3
|
illegal = 3
|
||||||
irrelevant = 4
|
irrelevant = 4
|
||||||
|
|
||||||
|
|
||||||
class EventOrganizer(db.Model, TrackableMixin):
|
class EventOrganizer(db.Model, TrackableMixin):
|
||||||
__tablename__ = 'eventorganizer'
|
__tablename__ = "eventorganizer"
|
||||||
__table_args__ = (UniqueConstraint('name', 'admin_unit_id'),)
|
__table_args__ = (UniqueConstraint("name", "admin_unit_id"),)
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
name = Column(Unicode(255), nullable=False)
|
name = Column(Unicode(255), nullable=False)
|
||||||
url = Column(String(255))
|
url = Column(String(255))
|
||||||
email = Column(Unicode(255))
|
email = Column(Unicode(255))
|
||||||
phone = Column(Unicode(255))
|
phone = Column(Unicode(255))
|
||||||
fax = Column(Unicode(255))
|
fax = Column(Unicode(255))
|
||||||
location_id = db.Column(db.Integer, db.ForeignKey('location.id'))
|
location_id = db.Column(db.Integer, db.ForeignKey("location.id"))
|
||||||
location = db.relationship('Location')
|
location = db.relationship("Location")
|
||||||
logo_id = db.Column(db.Integer, db.ForeignKey('image.id'))
|
logo_id = db.Column(db.Integer, db.ForeignKey("image.id"))
|
||||||
logo = db.relationship('Image', uselist=False)
|
logo = db.relationship("Image", uselist=False)
|
||||||
admin_unit_id = db.Column(db.Integer, db.ForeignKey('adminunit.id'), nullable=True)
|
admin_unit_id = db.Column(db.Integer, db.ForeignKey("adminunit.id"), nullable=True)
|
||||||
|
|
||||||
def is_empty(self):
|
def is_empty(self):
|
||||||
return not self.name
|
return not self.name
|
||||||
|
|
||||||
@listens_for(EventOrganizer, 'before_insert')
|
|
||||||
@listens_for(EventOrganizer, 'before_update')
|
@listens_for(EventOrganizer, "before_insert")
|
||||||
|
@listens_for(EventOrganizer, "before_update")
|
||||||
def purge_event_organizer(mapper, connect, self):
|
def purge_event_organizer(mapper, connect, self):
|
||||||
if self.logo and self.logo.is_empty():
|
if self.logo and self.logo.is_empty():
|
||||||
self.logo_id = None
|
self.logo_id = None
|
||||||
|
|
||||||
|
|
||||||
class EventReference(db.Model, TrackableMixin):
|
class EventReference(db.Model, TrackableMixin):
|
||||||
__tablename__ = 'eventreference'
|
__tablename__ = "eventreference"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
event_id = db.Column(db.Integer, db.ForeignKey('event.id'), nullable=False)
|
event_id = db.Column(db.Integer, db.ForeignKey("event.id"), nullable=False)
|
||||||
admin_unit_id = db.Column(db.Integer, db.ForeignKey('adminunit.id'), nullable=False)
|
admin_unit_id = db.Column(db.Integer, db.ForeignKey("adminunit.id"), nullable=False)
|
||||||
admin_unit = db.relationship('AdminUnit', backref=db.backref('references', lazy=True))
|
admin_unit = db.relationship(
|
||||||
|
"AdminUnit", backref=db.backref("references", lazy=True)
|
||||||
|
)
|
||||||
rating = Column(Integer())
|
rating = Column(Integer())
|
||||||
|
|
||||||
|
|
||||||
class EventReferenceRequest(db.Model, TrackableMixin):
|
class EventReferenceRequest(db.Model, TrackableMixin):
|
||||||
__tablename__ = 'eventreferencerequest'
|
__tablename__ = "eventreferencerequest"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
event_id = db.Column(db.Integer, db.ForeignKey('event.id'), nullable=False)
|
event_id = db.Column(db.Integer, db.ForeignKey("event.id"), nullable=False)
|
||||||
admin_unit_id = db.Column(db.Integer, db.ForeignKey('adminunit.id'), nullable=False)
|
admin_unit_id = db.Column(db.Integer, db.ForeignKey("adminunit.id"), nullable=False)
|
||||||
admin_unit = db.relationship('AdminUnit', backref=db.backref('reference_requests', lazy=True))
|
admin_unit = db.relationship(
|
||||||
|
"AdminUnit", backref=db.backref("reference_requests", lazy=True)
|
||||||
|
)
|
||||||
review_status = Column(IntegerEnum(EventReferenceRequestReviewStatus))
|
review_status = Column(IntegerEnum(EventReferenceRequestReviewStatus))
|
||||||
rejection_reason = Column(IntegerEnum(EventReferenceRequestRejectionReason))
|
rejection_reason = Column(IntegerEnum(EventReferenceRequestRejectionReason))
|
||||||
|
|
||||||
@ -298,12 +358,13 @@ class EventReferenceRequest(db.Model, TrackableMixin):
|
|||||||
def verified(self):
|
def verified(self):
|
||||||
return self.review_status == EventReferenceRequestReviewStatus.verified
|
return self.review_status == EventReferenceRequestReviewStatus.verified
|
||||||
|
|
||||||
|
|
||||||
class EventSuggestion(db.Model, TrackableMixin):
|
class EventSuggestion(db.Model, TrackableMixin):
|
||||||
__tablename__ = 'eventsuggestion'
|
__tablename__ = "eventsuggestion"
|
||||||
__table_args__ = (
|
__table_args__ = (
|
||||||
CheckConstraint('NOT(event_place_id IS NULL AND event_place_text IS NULL)'),
|
CheckConstraint("NOT(event_place_id IS NULL AND event_place_text IS NULL)"),
|
||||||
CheckConstraint('NOT(organizer_id IS NULL AND organizer_text IS NULL)'),
|
CheckConstraint("NOT(organizer_id IS NULL AND organizer_text IS NULL)"),
|
||||||
)
|
)
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
|
|
||||||
name = Column(Unicode(255), nullable=False)
|
name = Column(Unicode(255), nullable=False)
|
||||||
@ -318,29 +379,38 @@ class EventSuggestion(db.Model, TrackableMixin):
|
|||||||
contact_phone = Column(Unicode(255))
|
contact_phone = Column(Unicode(255))
|
||||||
contact_email_notice = Column(Boolean())
|
contact_email_notice = Column(Boolean())
|
||||||
|
|
||||||
admin_unit_id = db.Column(db.Integer, db.ForeignKey('adminunit.id'), nullable=False)
|
admin_unit_id = db.Column(db.Integer, db.ForeignKey("adminunit.id"), nullable=False)
|
||||||
admin_unit = db.relationship('AdminUnit', backref=db.backref('eventsuggestions', lazy=True))
|
admin_unit = db.relationship(
|
||||||
|
"AdminUnit", backref=db.backref("eventsuggestions", lazy=True)
|
||||||
|
)
|
||||||
|
|
||||||
event_place_id = db.Column(db.Integer, db.ForeignKey('eventplace.id'), nullable=True)
|
event_place_id = db.Column(
|
||||||
event_place = db.relationship('EventPlace', uselist=False)
|
db.Integer, db.ForeignKey("eventplace.id"), nullable=True
|
||||||
|
)
|
||||||
|
event_place = db.relationship("EventPlace", uselist=False)
|
||||||
event_place_text = Column(Unicode(255), nullable=True)
|
event_place_text = Column(Unicode(255), nullable=True)
|
||||||
|
|
||||||
organizer_id = db.Column(db.Integer, db.ForeignKey('eventorganizer.id'), nullable=True)
|
organizer_id = db.Column(
|
||||||
organizer = db.relationship('EventOrganizer', uselist=False)
|
db.Integer, db.ForeignKey("eventorganizer.id"), nullable=True
|
||||||
|
)
|
||||||
|
organizer = db.relationship("EventOrganizer", uselist=False)
|
||||||
organizer_text = Column(Unicode(255), nullable=True)
|
organizer_text = Column(Unicode(255), nullable=True)
|
||||||
|
|
||||||
photo_id = db.Column(db.Integer, db.ForeignKey('image.id'))
|
photo_id = db.Column(db.Integer, db.ForeignKey("image.id"))
|
||||||
photo = db.relationship('Image', uselist=False)
|
photo = db.relationship("Image", uselist=False)
|
||||||
|
|
||||||
event_id = db.Column(db.Integer, db.ForeignKey('event.id', ondelete='SET NULL'), nullable=True)
|
event_id = db.Column(
|
||||||
event = db.relationship('Event', uselist=False)
|
db.Integer, db.ForeignKey("event.id", ondelete="SET NULL"), nullable=True
|
||||||
|
)
|
||||||
|
event = db.relationship("Event", uselist=False)
|
||||||
|
|
||||||
@hybrid_property
|
@hybrid_property
|
||||||
def verified(self):
|
def verified(self):
|
||||||
return self.review_status == EventReviewStatus.verified
|
return self.review_status == EventReviewStatus.verified
|
||||||
|
|
||||||
@listens_for(EventSuggestion, 'before_insert')
|
|
||||||
@listens_for(EventSuggestion, 'before_update')
|
@listens_for(EventSuggestion, "before_insert")
|
||||||
|
@listens_for(EventSuggestion, "before_update")
|
||||||
def purge_event_suggestion(mapper, connect, self):
|
def purge_event_suggestion(mapper, connect, self):
|
||||||
if self.organizer and self.organizer.is_empty():
|
if self.organizer and self.organizer.is_empty():
|
||||||
self.organizer_id = None
|
self.organizer_id = None
|
||||||
@ -353,23 +423,28 @@ def purge_event_suggestion(mapper, connect, self):
|
|||||||
if self.photo and self.photo.is_empty():
|
if self.photo and self.photo.is_empty():
|
||||||
self.photo_id = None
|
self.photo_id = None
|
||||||
|
|
||||||
|
|
||||||
class Event(db.Model, TrackableMixin):
|
class Event(db.Model, TrackableMixin):
|
||||||
__tablename__ = 'event'
|
__tablename__ = "event"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
admin_unit_id = db.Column(db.Integer, db.ForeignKey('adminunit.id'), nullable=False)
|
admin_unit_id = db.Column(db.Integer, db.ForeignKey("adminunit.id"), nullable=False)
|
||||||
admin_unit = db.relationship('AdminUnit', backref=db.backref('events', lazy=True))
|
admin_unit = db.relationship("AdminUnit", backref=db.backref("events", lazy=True))
|
||||||
organizer_id = db.Column(db.Integer, db.ForeignKey('eventorganizer.id'), nullable=True)
|
organizer_id = db.Column(
|
||||||
organizer = db.relationship('EventOrganizer', uselist=False)
|
db.Integer, db.ForeignKey("eventorganizer.id"), nullable=True
|
||||||
event_place_id = db.Column(db.Integer, db.ForeignKey('eventplace.id'), nullable=True)
|
)
|
||||||
event_place = db.relationship('EventPlace', uselist=False)
|
organizer = db.relationship("EventOrganizer", uselist=False)
|
||||||
|
event_place_id = db.Column(
|
||||||
|
db.Integer, db.ForeignKey("eventplace.id"), nullable=True
|
||||||
|
)
|
||||||
|
event_place = db.relationship("EventPlace", uselist=False)
|
||||||
name = Column(Unicode(255), nullable=False)
|
name = Column(Unicode(255), nullable=False)
|
||||||
description = Column(UnicodeText(), nullable=False)
|
description = Column(UnicodeText(), nullable=False)
|
||||||
external_link = Column(String(255))
|
external_link = Column(String(255))
|
||||||
ticket_link = Column(String(255))
|
ticket_link = Column(String(255))
|
||||||
|
|
||||||
photo_id = db.Column(db.Integer, db.ForeignKey('image.id'))
|
photo_id = db.Column(db.Integer, db.ForeignKey("image.id"))
|
||||||
photo = db.relationship('Image', uselist=False)
|
photo = db.relationship("Image", uselist=False)
|
||||||
categories = relationship('EventCategory', secondary='event_eventcategories')
|
categories = relationship("EventCategory", secondary="event_eventcategories")
|
||||||
tags = Column(UnicodeText())
|
tags = Column(UnicodeText())
|
||||||
kid_friendly = Column(Boolean())
|
kid_friendly = Column(Boolean())
|
||||||
accessible_for_free = Column(Boolean())
|
accessible_for_free = Column(Boolean())
|
||||||
@ -389,10 +464,20 @@ class Event(db.Model, TrackableMixin):
|
|||||||
recurrence_rule = Column(UnicodeText())
|
recurrence_rule = Column(UnicodeText())
|
||||||
start = db.Column(db.DateTime(timezone=True), nullable=True)
|
start = db.Column(db.DateTime(timezone=True), nullable=True)
|
||||||
end = db.Column(db.DateTime(timezone=True), nullable=True)
|
end = db.Column(db.DateTime(timezone=True), nullable=True)
|
||||||
dates = relationship('EventDate', backref=backref('event', lazy=False), cascade="all, delete-orphan")
|
dates = relationship(
|
||||||
|
"EventDate", backref=backref("event", lazy=False), cascade="all, delete-orphan"
|
||||||
|
)
|
||||||
|
|
||||||
references = relationship('EventReference', backref=backref('event', lazy=False), cascade="all, delete-orphan")
|
references = relationship(
|
||||||
reference_requests = relationship('EventReferenceRequest', backref=backref('event', lazy=False), cascade="all, delete-orphan")
|
"EventReference",
|
||||||
|
backref=backref("event", lazy=False),
|
||||||
|
cascade="all, delete-orphan",
|
||||||
|
)
|
||||||
|
reference_requests = relationship(
|
||||||
|
"EventReferenceRequest",
|
||||||
|
backref=backref("event", lazy=False),
|
||||||
|
cascade="all, delete-orphan",
|
||||||
|
)
|
||||||
|
|
||||||
@hybrid_property
|
@hybrid_property
|
||||||
def category(self):
|
def category(self):
|
||||||
@ -401,8 +486,9 @@ class Event(db.Model, TrackableMixin):
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@listens_for(Event, 'before_insert')
|
|
||||||
@listens_for(Event, 'before_update')
|
@listens_for(Event, "before_insert")
|
||||||
|
@listens_for(Event, "before_update")
|
||||||
def purge_event(mapper, connect, self):
|
def purge_event(mapper, connect, self):
|
||||||
if self.organizer and self.organizer.is_empty():
|
if self.organizer and self.organizer.is_empty():
|
||||||
self.organizer_id = None
|
self.organizer_id = None
|
||||||
@ -411,36 +497,45 @@ def purge_event(mapper, connect, self):
|
|||||||
if self.photo and self.photo.is_empty():
|
if self.photo and self.photo.is_empty():
|
||||||
self.photo_id = None
|
self.photo_id = None
|
||||||
|
|
||||||
|
|
||||||
class EventDate(db.Model):
|
class EventDate(db.Model):
|
||||||
__tablename__ = 'eventdate'
|
__tablename__ = "eventdate"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
event_id = db.Column(db.Integer, db.ForeignKey('event.id'), nullable=False)
|
event_id = db.Column(db.Integer, db.ForeignKey("event.id"), nullable=False)
|
||||||
start = db.Column(db.DateTime(timezone=True), nullable=False)
|
start = db.Column(db.DateTime(timezone=True), nullable=False)
|
||||||
end = db.Column(db.DateTime(timezone=True), nullable=True)
|
end = db.Column(db.DateTime(timezone=True), nullable=True)
|
||||||
|
|
||||||
|
|
||||||
class EventEventCategories(db.Model):
|
class EventEventCategories(db.Model):
|
||||||
__tablename__ = 'event_eventcategories'
|
__tablename__ = "event_eventcategories"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
event_id = db.Column(db.Integer, db.ForeignKey('event.id'), nullable=False)
|
event_id = db.Column(db.Integer, db.ForeignKey("event.id"), nullable=False)
|
||||||
category_id = db.Column(db.Integer, db.ForeignKey('eventcategory.id'), nullable=False)
|
category_id = db.Column(
|
||||||
|
db.Integer, db.ForeignKey("eventcategory.id"), nullable=False
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Analytics(db.Model):
|
class Analytics(db.Model):
|
||||||
__tablename__ = 'analytics'
|
__tablename__ = "analytics"
|
||||||
id = Column(Integer(), primary_key=True)
|
id = Column(Integer(), primary_key=True)
|
||||||
key = Column(Unicode(255))
|
key = Column(Unicode(255))
|
||||||
value1 = Column(Unicode(255))
|
value1 = Column(Unicode(255))
|
||||||
value2 = Column(Unicode(255))
|
value2 = Column(Unicode(255))
|
||||||
created_at = Column(DateTime, default=datetime.datetime.utcnow)
|
created_at = Column(DateTime, default=datetime.datetime.utcnow)
|
||||||
|
|
||||||
|
|
||||||
# Deprecated begin
|
# Deprecated begin
|
||||||
class FeaturedEventReviewStatus(IntEnum):
|
class FeaturedEventReviewStatus(IntEnum):
|
||||||
inbox = 1
|
inbox = 1
|
||||||
verified = 2
|
verified = 2
|
||||||
rejected = 3
|
rejected = 3
|
||||||
|
|
||||||
|
|
||||||
class FeaturedEventRejectionReason(IntEnum):
|
class FeaturedEventRejectionReason(IntEnum):
|
||||||
duplicate = 1
|
duplicate = 1
|
||||||
untrustworthy = 2
|
untrustworthy = 2
|
||||||
illegal = 3
|
illegal = 3
|
||||||
irrelevant = 4
|
irrelevant = 4
|
||||||
|
|
||||||
|
|
||||||
# Deprecated end
|
# Deprecated end
|
||||||
|
|||||||
@ -3,8 +3,7 @@ from flask_security import current_user, login_user
|
|||||||
from flask_dance.contrib.google import make_google_blueprint
|
from flask_dance.contrib.google import make_google_blueprint
|
||||||
from flask_dance.consumer import oauth_authorized, oauth_error
|
from flask_dance.consumer import oauth_authorized, oauth_error
|
||||||
from flask_dance.consumer.storage.sqla import SQLAlchemyStorage
|
from flask_dance.consumer.storage.sqla import SQLAlchemyStorage
|
||||||
from sqlalchemy.orm.exc import NoResultFound
|
from project.models import OAuth
|
||||||
from project.models import User, OAuth
|
|
||||||
from project import db, user_datastore
|
from project import db, user_datastore
|
||||||
from flask_babelex import gettext
|
from flask_babelex import gettext
|
||||||
|
|
||||||
@ -31,14 +30,16 @@ def google_logged_in(blueprint, token):
|
|||||||
user_id = info["id"]
|
user_id = info["id"]
|
||||||
|
|
||||||
# Find this OAuth token in the database, or create it
|
# Find this OAuth token in the database, or create it
|
||||||
oauth = OAuth.query.filter_by(provider=blueprint.name, provider_user_id=user_id).first()
|
oauth = OAuth.query.filter_by(
|
||||||
|
provider=blueprint.name, provider_user_id=user_id
|
||||||
|
).first()
|
||||||
if oauth is None:
|
if oauth is None:
|
||||||
oauth = OAuth(provider=blueprint.name, provider_user_id=user_id, token=token)
|
oauth = OAuth(provider=blueprint.name, provider_user_id=user_id, token=token)
|
||||||
|
|
||||||
if oauth.user:
|
if oauth.user:
|
||||||
login_user(oauth.user, authn_via=["google"])
|
login_user(oauth.user, authn_via=["google"])
|
||||||
user_datastore.commit()
|
user_datastore.commit()
|
||||||
flash(gettext("Successfully signed in."), 'success')
|
flash(gettext("Successfully signed in."), "success")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Create a new local user account for this user
|
# Create a new local user account for this user
|
||||||
@ -51,7 +52,7 @@ def google_logged_in(blueprint, token):
|
|||||||
# Log in the new local user account
|
# Log in the new local user account
|
||||||
login_user(user, authn_via=["google"])
|
login_user(user, authn_via=["google"])
|
||||||
user_datastore.commit()
|
user_datastore.commit()
|
||||||
flash(gettext("Successfully signed in."), 'success')
|
flash(gettext("Successfully signed in."), "success")
|
||||||
|
|
||||||
# Disable Flask-Dance's default behavior for saving the OAuth token
|
# Disable Flask-Dance's default behavior for saving the OAuth token
|
||||||
return False
|
return False
|
||||||
|
|||||||
@ -1,23 +1,34 @@
|
|||||||
from project import app, db, get_admin_unit, update_event_dates_with_recurrence_rule, upsert_event_category
|
from project import (
|
||||||
|
db,
|
||||||
|
get_admin_unit,
|
||||||
|
update_event_dates_with_recurrence_rule,
|
||||||
|
upsert_event_category,
|
||||||
|
)
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
import datetime
|
import datetime
|
||||||
from dateutil import parser, tz
|
|
||||||
import pytz
|
import pytz
|
||||||
from urllib.request import urlopen, URLError
|
from urllib.request import urlopen
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
import requests
|
|
||||||
from os import path
|
from os import path
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
import unicodedata
|
|
||||||
import decimal
|
import decimal
|
||||||
from project.models import EventReviewStatus, EventTargetGroupOrigin, Location, Event, EventStatus, EventCategory, EventPlace, EventOrganizer, AdminUnit
|
from project.models import (
|
||||||
from sqlalchemy import and_, or_, not_
|
EventReviewStatus,
|
||||||
|
EventTargetGroupOrigin,
|
||||||
|
Location,
|
||||||
|
Event,
|
||||||
|
EventStatus,
|
||||||
|
EventPlace,
|
||||||
|
EventOrganizer,
|
||||||
|
)
|
||||||
|
from sqlalchemy import and_
|
||||||
|
|
||||||
|
berlin_tz = pytz.timezone("Europe/Berlin")
|
||||||
|
|
||||||
berlin_tz = pytz.timezone('Europe/Berlin')
|
|
||||||
|
|
||||||
def scrape(debug):
|
def scrape(debug):
|
||||||
url = 'https://goslar.feripro.de/programm/42/anmeldung/veranstaltungen'
|
url = "https://goslar.feripro.de/programm/42/anmeldung/veranstaltungen"
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
filename = "tmp/fp.html"
|
filename = "tmp/fp.html"
|
||||||
@ -27,51 +38,61 @@ def scrape(debug):
|
|||||||
with open(filename, "wb") as text_file:
|
with open(filename, "wb") as text_file:
|
||||||
text_file.write(response.read())
|
text_file.write(response.read())
|
||||||
|
|
||||||
doc = BeautifulSoup(open(filename), 'html.parser')
|
doc = BeautifulSoup(open(filename), "html.parser")
|
||||||
else:
|
else:
|
||||||
response = urlopen(url)
|
response = urlopen(url)
|
||||||
doc = BeautifulSoup(response, 'html.parser')
|
doc = BeautifulSoup(response, "html.parser")
|
||||||
|
|
||||||
js_assigns_regex = r"(\w*)\s*:\s*JSON\.parse\('(.*)'\)"
|
js_assigns_regex = r"(\w*)\s*:\s*JSON\.parse\('(.*)'\)"
|
||||||
js_assigns = dict()
|
js_assigns = dict()
|
||||||
javascripts = doc.find_all('script')
|
javascripts = doc.find_all("script")
|
||||||
for javascript in javascripts:
|
for javascript in javascripts:
|
||||||
javascript_contents = javascript.contents[0] if len(javascript.contents) > 0 else ''
|
javascript_contents = (
|
||||||
|
javascript.contents[0] if len(javascript.contents) > 0 else ""
|
||||||
|
)
|
||||||
|
|
||||||
if 'window.fp_initial' in javascript_contents:
|
if "window.fp_initial" in javascript_contents:
|
||||||
matches = re.findall(js_assigns_regex, javascript_contents, re.MULTILINE)
|
matches = re.findall(js_assigns_regex, javascript_contents, re.MULTILINE)
|
||||||
for match in matches:
|
for match in matches:
|
||||||
key = match[0]
|
key = match[0]
|
||||||
|
|
||||||
if not key in ['events']:
|
if key not in ["events"]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
json_str = match[1]
|
json_str = match[1]
|
||||||
decoded_json_str = json_str.encode('utf-8').decode('unicode_escape').encode('latin-1').decode('utf-8')
|
decoded_json_str = (
|
||||||
|
json_str.encode("utf-8")
|
||||||
|
.decode("unicode_escape")
|
||||||
|
.encode("latin-1")
|
||||||
|
.decode("utf-8")
|
||||||
|
)
|
||||||
value = json.loads(decoded_json_str, strict=False)
|
value = json.loads(decoded_json_str, strict=False)
|
||||||
js_assigns[key] = value
|
js_assigns[key] = value
|
||||||
break
|
break
|
||||||
|
|
||||||
admin_unit = get_admin_unit('Ferienpass Goslar')
|
admin_unit = get_admin_unit("Ferienpass Goslar")
|
||||||
category = upsert_event_category('Other')
|
category = upsert_event_category("Other")
|
||||||
|
|
||||||
for js_event in js_assigns['events']:
|
for js_event in js_assigns["events"]:
|
||||||
if not 'event_id' in js_event:
|
if "event_id" not in js_event:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
event_id = js_event['event_id']
|
event_id = js_event["event_id"]
|
||||||
if not event_id:
|
if not event_id:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
external_link = url + '#' + str(event_id)
|
external_link = url + "#" + str(event_id)
|
||||||
event = Event.query.filter(Event.external_link == external_link).first()
|
event = Event.query.filter(Event.external_link == external_link).first()
|
||||||
did_create = False
|
did_create = False
|
||||||
|
|
||||||
# Event
|
# Event
|
||||||
if event is None:
|
if event is None:
|
||||||
|
|
||||||
if js_event['name'] in ['Entfällt', 'Diese Veranstaltung muss leider ausfallen ...']:
|
if js_event["name"] in [
|
||||||
|
"Entfällt",
|
||||||
|
"Diese Veranstaltung muss leider ausfallen ...",
|
||||||
|
]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
event = Event()
|
event = Event()
|
||||||
@ -83,27 +104,46 @@ def scrape(debug):
|
|||||||
event.review_status = EventReviewStatus.verified
|
event.review_status = EventReviewStatus.verified
|
||||||
event.rating = 5
|
event.rating = 5
|
||||||
event.target_group_origin = EventTargetGroupOrigin.resident
|
event.target_group_origin = EventTargetGroupOrigin.resident
|
||||||
event.name = js_event['name']
|
event.name = js_event["name"]
|
||||||
event.description = js_event['description']
|
event.description = js_event["description"]
|
||||||
start = parse_date_time_str(js_event['start'])
|
start = parse_date_time_str(js_event["start"])
|
||||||
end = parse_date_time_str(js_event['end'])
|
end = parse_date_time_str(js_event["end"])
|
||||||
update_event_dates_with_recurrence_rule(event, start, end)
|
update_event_dates_with_recurrence_rule(event, start, end)
|
||||||
|
|
||||||
# Organizer
|
# Organizer
|
||||||
js_organizer = js_event['organizer']
|
js_organizer = js_event["organizer"]
|
||||||
organizer_name = js_event['name_public'] if js_event['name_public'] else js_organizer['name']
|
organizer_name = (
|
||||||
organizer_phone = js_event['phone_public'] if js_event['phone_public'] else js_organizer['phone']
|
js_event["name_public"]
|
||||||
organizer_email = js_event['email_public'] if js_event['email_public'] else js_organizer['email']
|
if js_event["name_public"]
|
||||||
organizer_url = js_organizer['website'] if js_organizer['website'] else js_organizer['facebook']
|
else js_organizer["name"]
|
||||||
|
)
|
||||||
|
organizer_phone = (
|
||||||
|
js_event["phone_public"]
|
||||||
|
if js_event["phone_public"]
|
||||||
|
else js_organizer["phone"]
|
||||||
|
)
|
||||||
|
organizer_email = (
|
||||||
|
js_event["email_public"]
|
||||||
|
if js_event["email_public"]
|
||||||
|
else js_organizer["email"]
|
||||||
|
)
|
||||||
|
organizer_url = (
|
||||||
|
js_organizer["website"]
|
||||||
|
if js_organizer["website"]
|
||||||
|
else js_organizer["facebook"]
|
||||||
|
)
|
||||||
|
|
||||||
organizer = EventOrganizer.query.filter(and_(
|
organizer = EventOrganizer.query.filter(
|
||||||
EventOrganizer.admin_unit_id == admin_unit.id,
|
and_(
|
||||||
EventOrganizer.name == organizer_name)).first()
|
EventOrganizer.admin_unit_id == admin_unit.id,
|
||||||
|
EventOrganizer.name == organizer_name,
|
||||||
|
)
|
||||||
|
).first()
|
||||||
|
|
||||||
if organizer is None:
|
if organizer is None:
|
||||||
organizer = EventOrganizer(
|
organizer = EventOrganizer(
|
||||||
admin_unit_id = admin_unit.id,
|
admin_unit_id=admin_unit.id, name=organizer_name
|
||||||
name = organizer_name)
|
)
|
||||||
|
|
||||||
organizer.phone = organizer_phone
|
organizer.phone = organizer_phone
|
||||||
organizer.email = organizer_email
|
organizer.email = organizer_email
|
||||||
@ -115,16 +155,19 @@ def scrape(debug):
|
|||||||
place_description = ""
|
place_description = ""
|
||||||
place_location = None
|
place_location = None
|
||||||
|
|
||||||
meeting_point = js_event['meeting_point'].replace('\r\n', ', ')
|
meeting_point = js_event["meeting_point"].replace("\r\n", ", ")
|
||||||
if len(meeting_point) > 80:
|
if len(meeting_point) > 80:
|
||||||
place_name = meeting_point[:80] + '...'
|
place_name = meeting_point[:80] + "..."
|
||||||
place_description = meeting_point
|
place_description = meeting_point
|
||||||
else:
|
else:
|
||||||
place_name = meeting_point
|
place_name = meeting_point
|
||||||
|
|
||||||
if 'meeting_point_latitude' in js_event and 'meeting_point_longitude' in js_event:
|
if (
|
||||||
meeting_point_latitude = js_event['meeting_point_latitude']
|
"meeting_point_latitude" in js_event
|
||||||
meeting_point_longitude = js_event['meeting_point_longitude']
|
and "meeting_point_longitude" in js_event
|
||||||
|
):
|
||||||
|
meeting_point_latitude = js_event["meeting_point_latitude"]
|
||||||
|
meeting_point_longitude = js_event["meeting_point_longitude"]
|
||||||
if meeting_point_latitude and meeting_point_longitude:
|
if meeting_point_latitude and meeting_point_longitude:
|
||||||
latitude = decimal.Decimal(meeting_point_latitude)
|
latitude = decimal.Decimal(meeting_point_latitude)
|
||||||
longitude = decimal.Decimal(meeting_point_longitude)
|
longitude = decimal.Decimal(meeting_point_longitude)
|
||||||
@ -133,45 +176,55 @@ def scrape(debug):
|
|||||||
place_location.latitude = latitude
|
place_location.latitude = latitude
|
||||||
place_location.longitude = longitude
|
place_location.longitude = longitude
|
||||||
|
|
||||||
place = EventPlace.query.filter(and_(
|
place = EventPlace.query.filter(
|
||||||
EventPlace.admin_unit_id == admin_unit.id,
|
and_(
|
||||||
EventPlace.organizer_id == organizer.id,
|
EventPlace.admin_unit_id == admin_unit.id,
|
||||||
EventPlace.name == place_name)).first()
|
EventPlace.organizer_id == organizer.id,
|
||||||
|
EventPlace.name == place_name,
|
||||||
|
)
|
||||||
|
).first()
|
||||||
|
|
||||||
if place is None:
|
if place is None:
|
||||||
place = EventPlace(
|
place = EventPlace(
|
||||||
admin_unit_id = admin_unit.id,
|
admin_unit_id=admin_unit.id,
|
||||||
organizer_id = organizer.id,
|
organizer_id=organizer.id,
|
||||||
name = place_name)
|
name=place_name,
|
||||||
|
)
|
||||||
|
|
||||||
place.description = place_description
|
place.description = place_description
|
||||||
place.location = place_location
|
place.location = place_location
|
||||||
event.event_place = place
|
event.event_place = place
|
||||||
|
|
||||||
# Additional data
|
# Additional data
|
||||||
event.status = EventStatus.cancelled if js_event['canceled'] else EventStatus.scheduled
|
event.status = (
|
||||||
|
EventStatus.cancelled if js_event["canceled"] else EventStatus.scheduled
|
||||||
|
)
|
||||||
event.kid_friendly = True
|
event.kid_friendly = True
|
||||||
event.accessible_for_free = js_event['price'] == '0.00'
|
event.accessible_for_free = js_event["price"] == "0.00"
|
||||||
|
|
||||||
tag_list = js_event['tags']
|
tag_list = js_event["tags"]
|
||||||
tag_list.append('Ferienpass')
|
tag_list.append("Ferienpass")
|
||||||
event.tags = ','.join(tag_list)
|
event.tags = ",".join(tag_list)
|
||||||
|
|
||||||
if js_event['min_age']:
|
if js_event["min_age"]:
|
||||||
event.age_from = int(js_event['min_age'])
|
event.age_from = int(js_event["min_age"])
|
||||||
|
|
||||||
if js_event['max_age']:
|
if js_event["max_age"]:
|
||||||
event.age_to = int(js_event['max_age'])
|
event.age_to = int(js_event["max_age"])
|
||||||
|
|
||||||
print("%s %s %s %s" % (event.dates[0].start, event.name, organizer.id, organizer.name))
|
print(
|
||||||
|
"%s %s %s %s"
|
||||||
|
% (event.dates[0].start, event.name, organizer.id, organizer.name)
|
||||||
|
)
|
||||||
if did_create:
|
if did_create:
|
||||||
db.session.add(event)
|
db.session.add(event)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except:
|
except Exception:
|
||||||
print("Exception")
|
print("Exception")
|
||||||
pprint(js_event)
|
pprint(js_event)
|
||||||
|
|
||||||
|
|
||||||
def parse_date_time_str(date_time_str):
|
def parse_date_time_str(date_time_str):
|
||||||
if not date_time_str:
|
if not date_time_str:
|
||||||
return None
|
return None
|
||||||
@ -179,5 +232,6 @@ def parse_date_time_str(date_time_str):
|
|||||||
date_time = datetime.datetime.fromisoformat(date_time_str)
|
date_time = datetime.datetime.fromisoformat(date_time_str)
|
||||||
return berlin_tz.localize(date_time)
|
return berlin_tz.localize(date_time)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
if __name__ == "__main__":
|
||||||
scrape(False)
|
scrape(False)
|
||||||
|
|||||||
@ -1,45 +1,50 @@
|
|||||||
from project import app, db
|
from project import db
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
import datetime
|
import datetime
|
||||||
from dateutil import parser, tz
|
from urllib import request
|
||||||
import pytz
|
|
||||||
from urllib import request, parse
|
|
||||||
from urllib.request import urlopen, URLError
|
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
import requests
|
|
||||||
from os import path
|
from os import path
|
||||||
import json
|
import json
|
||||||
from flask import jsonify
|
|
||||||
import re
|
|
||||||
import unicodedata
|
|
||||||
import decimal
|
import decimal
|
||||||
from project.models import EventReviewStatus, EventTargetGroupOrigin, Location, Event, EventStatus, EventCategory, EventPlace, EventOrganizer, AdminUnit
|
from project.models import (
|
||||||
from sqlalchemy import and_, or_, not_
|
EventReviewStatus,
|
||||||
from project.dateutils import berlin_tz
|
Location,
|
||||||
|
Event,
|
||||||
|
EventStatus,
|
||||||
|
EventPlace,
|
||||||
|
EventOrganizer,
|
||||||
|
)
|
||||||
|
from sqlalchemy import and_, not_
|
||||||
from project.services.admin_unit import get_admin_unit
|
from project.services.admin_unit import get_admin_unit
|
||||||
from project.services.event import upsert_event_category, update_event_dates_with_recurrence_rule
|
from project.services.event import (
|
||||||
|
upsert_event_category,
|
||||||
|
update_event_dates_with_recurrence_rule,
|
||||||
|
)
|
||||||
|
|
||||||
admin_unit = get_admin_unit('Harzinfo')
|
admin_unit = get_admin_unit("Harzinfo")
|
||||||
category = upsert_event_category('Other')
|
category = upsert_event_category("Other")
|
||||||
base_url = "https://www.harzinfo.de"
|
base_url = "https://www.harzinfo.de"
|
||||||
url = base_url + "/?ndssearch=fullsearch&no_cache=1&L=0"
|
url = base_url + "/?ndssearch=fullsearch&no_cache=1&L=0"
|
||||||
|
|
||||||
with open('scrape_hi_req.json') as json_file:
|
with open("scrape_hi_req.json") as json_file:
|
||||||
request_object = json.load(json_file)
|
request_object = json.load(json_file)
|
||||||
|
|
||||||
with open('scrape_hi_cities.json') as json_file:
|
with open("scrape_hi_cities.json") as json_file:
|
||||||
cities = json.load(json_file)
|
cities = json.load(json_file)
|
||||||
|
|
||||||
|
|
||||||
def response_from_url(city):
|
def response_from_url(city):
|
||||||
body = request_object
|
body = request_object
|
||||||
body["searchFilter"]["ndsdestinationdataevent"]["city"] = { str(city['id']): city['short_name'] or city['title'] }
|
body["searchFilter"]["ndsdestinationdataevent"]["city"] = {
|
||||||
req = request.Request(url, data=bytes(json.dumps(body), encoding='utf-8'))
|
str(city["id"]): city["short_name"] or city["title"]
|
||||||
req.add_header('Content-Type', 'application/json')
|
}
|
||||||
|
req = request.Request(url, data=bytes(json.dumps(body), encoding="utf-8"))
|
||||||
|
req.add_header("Content-Type", "application/json")
|
||||||
return request.urlopen(req)
|
return request.urlopen(req)
|
||||||
|
|
||||||
|
|
||||||
def load_json(debug, city):
|
def load_json(debug, city):
|
||||||
if debug:
|
if debug:
|
||||||
filename = "tmp/hi_%d.html" % (city['id'])
|
filename = "tmp/hi_%d.html" % (city["id"])
|
||||||
|
|
||||||
if not path.exists(filename):
|
if not path.exists(filename):
|
||||||
response = response_from_url(city)
|
response = response_from_url(city)
|
||||||
@ -52,24 +57,27 @@ def load_json(debug, city):
|
|||||||
response = response_from_url(city)
|
response = response_from_url(city)
|
||||||
return json.load(response)
|
return json.load(response)
|
||||||
|
|
||||||
|
|
||||||
def parse_date_time_str(date_time_str):
|
def parse_date_time_str(date_time_str):
|
||||||
if not date_time_str:
|
if not date_time_str:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return datetime.datetime.fromisoformat(date_time_str + ':00')
|
return datetime.datetime.fromisoformat(date_time_str + ":00")
|
||||||
|
|
||||||
|
|
||||||
def scrape(debug, city):
|
def scrape(debug, city):
|
||||||
|
|
||||||
# Organizer
|
# Organizer
|
||||||
organizer_name = city['short_name'] or city['title']
|
organizer_name = city["short_name"] or city["title"]
|
||||||
organizer = EventOrganizer.query.filter(and_(
|
organizer = EventOrganizer.query.filter(
|
||||||
EventOrganizer.admin_unit_id == admin_unit.id,
|
and_(
|
||||||
EventOrganizer.name == organizer_name)).first()
|
EventOrganizer.admin_unit_id == admin_unit.id,
|
||||||
|
EventOrganizer.name == organizer_name,
|
||||||
|
)
|
||||||
|
).first()
|
||||||
|
|
||||||
if organizer is None:
|
if organizer is None:
|
||||||
organizer = EventOrganizer(
|
organizer = EventOrganizer(admin_unit_id=admin_unit.id, name=organizer_name)
|
||||||
admin_unit_id = admin_unit.id,
|
|
||||||
name = organizer_name)
|
|
||||||
db.session.add(organizer)
|
db.session.add(organizer)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
@ -81,8 +89,13 @@ def scrape(debug, city):
|
|||||||
for item in result:
|
for item in result:
|
||||||
try:
|
try:
|
||||||
uid = str(item["uid"])
|
uid = str(item["uid"])
|
||||||
external_link = base_url + item["link"] + '#' + uid
|
external_link = base_url + item["link"] + "#" + uid
|
||||||
event = Event.query.filter(and_(Event.organizer_id == organizer.id, Event.external_link == external_link)).first()
|
event = Event.query.filter(
|
||||||
|
and_(
|
||||||
|
Event.organizer_id == organizer.id,
|
||||||
|
Event.external_link == external_link,
|
||||||
|
)
|
||||||
|
).first()
|
||||||
did_create = False
|
did_create = False
|
||||||
|
|
||||||
if event is None:
|
if event is None:
|
||||||
@ -100,7 +113,7 @@ def scrape(debug, city):
|
|||||||
event.name = item["title"]
|
event.name = item["title"]
|
||||||
event.description = item["title"]
|
event.description = item["title"]
|
||||||
|
|
||||||
start = parse_date_time_str(item['date'])
|
start = parse_date_time_str(item["date"])
|
||||||
update_event_dates_with_recurrence_rule(event, start, None)
|
update_event_dates_with_recurrence_rule(event, start, None)
|
||||||
|
|
||||||
# Place
|
# Place
|
||||||
@ -108,9 +121,9 @@ def scrape(debug, city):
|
|||||||
place_description = ""
|
place_description = ""
|
||||||
place_location = None
|
place_location = None
|
||||||
|
|
||||||
if 'latitude' in item and 'longitude' in item:
|
if "latitude" in item and "longitude" in item:
|
||||||
meeting_point_latitude = item['latitude']
|
meeting_point_latitude = item["latitude"]
|
||||||
meeting_point_longitude = item['longitude']
|
meeting_point_longitude = item["longitude"]
|
||||||
if meeting_point_latitude and meeting_point_longitude:
|
if meeting_point_latitude and meeting_point_longitude:
|
||||||
latitude = decimal.Decimal(meeting_point_latitude)
|
latitude = decimal.Decimal(meeting_point_latitude)
|
||||||
longitude = decimal.Decimal(meeting_point_longitude)
|
longitude = decimal.Decimal(meeting_point_longitude)
|
||||||
@ -119,74 +132,87 @@ def scrape(debug, city):
|
|||||||
place_location.latitude = latitude
|
place_location.latitude = latitude
|
||||||
place_location.longitude = longitude
|
place_location.longitude = longitude
|
||||||
|
|
||||||
place = EventPlace.query.filter(and_(
|
place = EventPlace.query.filter(
|
||||||
EventPlace.admin_unit_id == admin_unit.id,
|
and_(
|
||||||
EventPlace.organizer_id == organizer.id,
|
EventPlace.admin_unit_id == admin_unit.id,
|
||||||
EventPlace.name == place_name)).first()
|
EventPlace.organizer_id == organizer.id,
|
||||||
|
EventPlace.name == place_name,
|
||||||
|
)
|
||||||
|
).first()
|
||||||
|
|
||||||
if place is None:
|
if place is None:
|
||||||
place = EventPlace(
|
place = EventPlace(
|
||||||
admin_unit_id = admin_unit.id,
|
admin_unit_id=admin_unit.id,
|
||||||
organizer_id = organizer.id,
|
organizer_id=organizer.id,
|
||||||
name = place_name)
|
name=place_name,
|
||||||
|
)
|
||||||
|
|
||||||
place.description = place_description
|
place.description = place_description
|
||||||
place.location = place_location
|
place.location = place_location
|
||||||
event.event_place = place
|
event.event_place = place
|
||||||
|
|
||||||
# Additional data
|
# Additional data
|
||||||
event.status = EventStatus.cancelled if item['canceled'] else EventStatus.scheduled
|
event.status = (
|
||||||
|
EventStatus.cancelled if item["canceled"] else EventStatus.scheduled
|
||||||
|
)
|
||||||
|
|
||||||
if 'categories' in item:
|
if "categories" in item:
|
||||||
tag_list = list(item['categories'].values())
|
tag_list = list(item["categories"].values())
|
||||||
|
|
||||||
if 'Ausstellung/Kunst' in tag_list:
|
if "Ausstellung/Kunst" in tag_list:
|
||||||
event.category = upsert_event_category('Art')
|
event.category = upsert_event_category("Art")
|
||||||
elif 'Comedy' in tag_list:
|
elif "Comedy" in tag_list:
|
||||||
event.category = upsert_event_category('Comedy')
|
event.category = upsert_event_category("Comedy")
|
||||||
elif 'Konzert/Musik' in tag_list:
|
elif "Konzert/Musik" in tag_list:
|
||||||
event.category = upsert_event_category('Music')
|
event.category = upsert_event_category("Music")
|
||||||
elif 'Theater' in tag_list:
|
elif "Theater" in tag_list:
|
||||||
event.category = upsert_event_category('Theater')
|
event.category = upsert_event_category("Theater")
|
||||||
elif 'Genuss/Gourmet' in tag_list:
|
elif "Genuss/Gourmet" in tag_list:
|
||||||
event.category = upsert_event_category('Dining')
|
event.category = upsert_event_category("Dining")
|
||||||
elif 'Gesundheit/Wellness' in tag_list:
|
elif "Gesundheit/Wellness" in tag_list:
|
||||||
event.category = upsert_event_category('Fitness')
|
event.category = upsert_event_category("Fitness")
|
||||||
elif 'Kinder/Jugend' in tag_list:
|
elif "Kinder/Jugend" in tag_list:
|
||||||
event.category = upsert_event_category('Family')
|
event.category = upsert_event_category("Family")
|
||||||
elif 'Markt/Flohmarkt' in tag_list:
|
elif "Markt/Flohmarkt" in tag_list:
|
||||||
event.category = upsert_event_category('Shopping')
|
event.category = upsert_event_category("Shopping")
|
||||||
elif 'Sport' in tag_list:
|
elif "Sport" in tag_list:
|
||||||
event.category = upsert_event_category('Sports')
|
event.category = upsert_event_category("Sports")
|
||||||
elif 'Vortrag/Lesung' in tag_list:
|
elif "Vortrag/Lesung" in tag_list:
|
||||||
event.category = upsert_event_category('Book')
|
event.category = upsert_event_category("Book")
|
||||||
elif 'Kabarett' in tag_list:
|
elif "Kabarett" in tag_list:
|
||||||
event.category = upsert_event_category('Art')
|
event.category = upsert_event_category("Art")
|
||||||
elif 'Musical' in tag_list:
|
elif "Musical" in tag_list:
|
||||||
event.category = upsert_event_category('Theater')
|
event.category = upsert_event_category("Theater")
|
||||||
elif 'Weihnachtsmärkte' in tag_list:
|
elif "Weihnachtsmärkte" in tag_list:
|
||||||
event.category = upsert_event_category('Festival')
|
event.category = upsert_event_category("Festival")
|
||||||
elif 'Stadt- und Volksfeste' in tag_list:
|
elif "Stadt- und Volksfeste" in tag_list:
|
||||||
event.category = upsert_event_category('Festival')
|
event.category = upsert_event_category("Festival")
|
||||||
|
|
||||||
if 'Kinder/Jugend' in tag_list:
|
if "Kinder/Jugend" in tag_list:
|
||||||
event.kid_friendly = True
|
event.kid_friendly = True
|
||||||
|
|
||||||
tag_list.append('Harzinfo')
|
tag_list.append("Harzinfo")
|
||||||
event.tags = ','.join(tag_list)
|
event.tags = ",".join(tag_list)
|
||||||
|
|
||||||
print("%s %s %d" % (event.dates[0].start, event.name, event.rating))
|
print("%s %s %d" % (event.dates[0].start, event.name, event.rating))
|
||||||
if did_create:
|
if did_create:
|
||||||
db.session.add(event)
|
db.session.add(event)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except:
|
except Exception:
|
||||||
print("Exception")
|
print("Exception")
|
||||||
pprint(item)
|
pprint(item)
|
||||||
|
|
||||||
Event.query.filter(and_(Event.admin_unit_id == admin_unit.id, Event.organizer_id == organizer.id, not_(Event.id.in_(event_ids)))).delete(synchronize_session='fetch')
|
Event.query.filter(
|
||||||
|
and_(
|
||||||
|
Event.admin_unit_id == admin_unit.id,
|
||||||
|
Event.organizer_id == organizer.id,
|
||||||
|
not_(Event.id.in_(event_ids)),
|
||||||
|
)
|
||||||
|
).delete(synchronize_session="fetch")
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
if __name__ == "__main__":
|
||||||
for city in cities.values():
|
for city in cities.values():
|
||||||
scrape(False, city)
|
scrape(False, city)
|
||||||
|
|||||||
@ -1,26 +1,29 @@
|
|||||||
from project import db
|
from project import db
|
||||||
from project.models import AdminUnit, AdminUnitMember, AdminUnitMemberRole
|
from project.models import AdminUnit, AdminUnitMember, AdminUnitMemberRole
|
||||||
|
|
||||||
def upsert_admin_unit(unit_name, short_name = None):
|
|
||||||
admin_unit = AdminUnit.query.filter_by(name = unit_name).first()
|
def upsert_admin_unit(unit_name, short_name=None):
|
||||||
|
admin_unit = AdminUnit.query.filter_by(name=unit_name).first()
|
||||||
if admin_unit is None:
|
if admin_unit is None:
|
||||||
admin_unit = AdminUnit(name = unit_name)
|
admin_unit = AdminUnit(name=unit_name)
|
||||||
db.session.add(admin_unit)
|
db.session.add(admin_unit)
|
||||||
|
|
||||||
admin_unit.short_name = short_name
|
admin_unit.short_name = short_name
|
||||||
upsert_org_or_admin_unit_for_admin_unit(admin_unit)
|
|
||||||
return admin_unit
|
return admin_unit
|
||||||
|
|
||||||
|
|
||||||
def get_admin_unit(unit_name):
|
def get_admin_unit(unit_name):
|
||||||
return AdminUnit.query.filter_by(name = unit_name).first()
|
return AdminUnit.query.filter_by(name=unit_name).first()
|
||||||
|
|
||||||
|
|
||||||
def get_admin_unit_member_role(role_name):
|
def get_admin_unit_member_role(role_name):
|
||||||
return AdminUnitMemberRole.query.filter_by(name = role_name).first()
|
return AdminUnitMemberRole.query.filter_by(name=role_name).first()
|
||||||
|
|
||||||
|
|
||||||
def upsert_admin_unit_member_role(role_name, role_title, permissions):
|
def upsert_admin_unit_member_role(role_name, role_title, permissions):
|
||||||
result = AdminUnitMemberRole.query.filter_by(name = role_name).first()
|
result = AdminUnitMemberRole.query.filter_by(name=role_name).first()
|
||||||
if result is None:
|
if result is None:
|
||||||
result = AdminUnitMemberRole(name = role_name)
|
result = AdminUnitMemberRole(name=role_name)
|
||||||
db.session.add(result)
|
db.session.add(result)
|
||||||
|
|
||||||
result.title = role_title
|
result.title = role_title
|
||||||
@ -28,25 +31,36 @@ def upsert_admin_unit_member_role(role_name, role_title, permissions):
|
|||||||
result.add_permissions(permissions)
|
result.add_permissions(permissions)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def add_user_to_admin_unit(user, admin_unit):
|
def add_user_to_admin_unit(user, admin_unit):
|
||||||
result = AdminUnitMember.query.with_parent(admin_unit).filter_by(user_id = user.id).first()
|
result = (
|
||||||
|
AdminUnitMember.query.with_parent(admin_unit).filter_by(user_id=user.id).first()
|
||||||
|
)
|
||||||
if result is None:
|
if result is None:
|
||||||
result = AdminUnitMember(user = user, admin_unit_id=admin_unit.id)
|
result = AdminUnitMember(user=user, admin_unit_id=admin_unit.id)
|
||||||
admin_unit.members.append(result)
|
admin_unit.members.append(result)
|
||||||
db.session.add(result)
|
db.session.add(result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def add_user_to_admin_unit_with_roles(user, admin_unit, role_names):
|
def add_user_to_admin_unit_with_roles(user, admin_unit, role_names):
|
||||||
member = add_user_to_admin_unit(user, admin_unit)
|
member = add_user_to_admin_unit(user, admin_unit)
|
||||||
add_roles_to_admin_unit_member(member, role_names)
|
add_roles_to_admin_unit_member(member, role_names)
|
||||||
|
|
||||||
return member
|
return member
|
||||||
|
|
||||||
|
|
||||||
def add_roles_to_admin_unit_member(member, role_names):
|
def add_roles_to_admin_unit_member(member, role_names):
|
||||||
for role_name in role_names:
|
for role_name in role_names:
|
||||||
role = get_admin_unit_member_role(role_name)
|
role = get_admin_unit_member_role(role_name)
|
||||||
add_role_to_admin_unit_member(member, role)
|
add_role_to_admin_unit_member(member, role)
|
||||||
|
|
||||||
|
|
||||||
def add_role_to_admin_unit_member(admin_unit_member, role):
|
def add_role_to_admin_unit_member(admin_unit_member, role):
|
||||||
if AdminUnitMemberRole.query.with_parent(admin_unit_member).filter_by(name = role.name).first() is None:
|
if (
|
||||||
|
AdminUnitMemberRole.query.with_parent(admin_unit_member)
|
||||||
|
.filter_by(name=role.name)
|
||||||
|
.first()
|
||||||
|
is None
|
||||||
|
):
|
||||||
admin_unit_member.roles.append(role)
|
admin_unit_member.roles.append(role)
|
||||||
|
|||||||
@ -1,49 +1,84 @@
|
|||||||
from project.models import EventReviewStatus, EventCategory, Event, EventDate, EventReference, EventPlace, Location, EventSuggestion
|
from project import db
|
||||||
from project.dateutils import dates_from_recurrence_rule, today, date_add_time, date_set_end_of_day
|
from project.models import (
|
||||||
from sqlalchemy import and_, or_, not_, func
|
EventCategory,
|
||||||
|
Event,
|
||||||
|
EventDate,
|
||||||
|
EventReference,
|
||||||
|
EventPlace,
|
||||||
|
Location,
|
||||||
|
)
|
||||||
|
from project.dateutils import (
|
||||||
|
dates_from_recurrence_rule,
|
||||||
|
today,
|
||||||
|
date_add_time,
|
||||||
|
)
|
||||||
|
from sqlalchemy import and_, or_, func
|
||||||
from sqlalchemy.sql import extract
|
from sqlalchemy.sql import extract
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
|
|
||||||
def upsert_event_category(category_name):
|
def upsert_event_category(category_name):
|
||||||
result = EventCategory.query.filter_by(name = category_name).first()
|
result = EventCategory.query.filter_by(name=category_name).first()
|
||||||
if result is None:
|
if result is None:
|
||||||
result = EventCategory(name = category_name)
|
result = EventCategory(name=category_name)
|
||||||
db.session.add(result)
|
db.session.add(result)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def fill_event_filter(event_filter, params):
|
def fill_event_filter(event_filter, params):
|
||||||
if params.keyword:
|
if params.keyword:
|
||||||
like_keyword = '%' + params.keyword + '%'
|
like_keyword = "%" + params.keyword + "%"
|
||||||
event_filter = and_(event_filter, or_(Event.name.ilike(like_keyword), Event.description.ilike(like_keyword), Event.tags.ilike(like_keyword)))
|
event_filter = and_(
|
||||||
|
event_filter,
|
||||||
|
or_(
|
||||||
|
Event.name.ilike(like_keyword),
|
||||||
|
Event.description.ilike(like_keyword),
|
||||||
|
Event.tags.ilike(like_keyword),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
if params.category_id:
|
if params.category_id:
|
||||||
if type(params.category_id) is list:
|
if type(params.category_id) is list:
|
||||||
category_ids = params.category_id
|
category_ids = params.category_id
|
||||||
else:
|
else:
|
||||||
category_ids = [params.category_id]
|
category_ids = [params.category_id]
|
||||||
event_filter = and_(event_filter, Event.categories.any(EventCategory.id.in_(category_ids)))
|
event_filter = and_(
|
||||||
|
event_filter, Event.categories.any(EventCategory.id.in_(category_ids))
|
||||||
|
)
|
||||||
|
|
||||||
if params.organizer_id:
|
if params.organizer_id:
|
||||||
event_filter = and_(event_filter, Event.organizer_id == params.organizer_id)
|
event_filter = and_(event_filter, Event.organizer_id == params.organizer_id)
|
||||||
|
|
||||||
if params.latitude and params.longitude and params.distance:
|
if params.latitude and params.longitude and params.distance:
|
||||||
point = 'POINT({} {})'.format(params.longitude, params.latitude)
|
point = "POINT({} {})".format(params.longitude, params.latitude)
|
||||||
event_filter = and_(event_filter, func.ST_DistanceSphere(Location.coordinate, point) <= params.distance)
|
event_filter = and_(
|
||||||
|
event_filter,
|
||||||
|
func.ST_DistanceSphere(Location.coordinate, point) <= params.distance,
|
||||||
|
)
|
||||||
|
|
||||||
return event_filter
|
return event_filter
|
||||||
|
|
||||||
|
|
||||||
def get_event_dates_query(params):
|
def get_event_dates_query(params):
|
||||||
event_filter = (1 == 1)
|
event_filter = 1 == 1
|
||||||
date_filter = (EventDate.start >= today)
|
date_filter = EventDate.start >= today
|
||||||
|
|
||||||
event_filter = fill_event_filter(event_filter, params)
|
event_filter = fill_event_filter(event_filter, params)
|
||||||
|
|
||||||
if params.admin_unit_id:
|
if params.admin_unit_id:
|
||||||
event_filter = and_(event_filter, or_(Event.admin_unit_id == params.admin_unit_id, Event.references.any(EventReference.admin_unit_id == params.admin_unit_id)))
|
event_filter = and_(
|
||||||
|
event_filter,
|
||||||
|
or_(
|
||||||
|
Event.admin_unit_id == params.admin_unit_id,
|
||||||
|
Event.references.any(
|
||||||
|
EventReference.admin_unit_id == params.admin_unit_id
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
if params.date_from:
|
if params.date_from:
|
||||||
date_filter = (EventDate.start >= params.date_from)
|
date_filter = EventDate.start >= params.date_from
|
||||||
|
|
||||||
if params.date_to:
|
if params.date_to:
|
||||||
date_filter = and_(date_filter, EventDate.start < params.date_to)
|
date_filter = and_(date_filter, EventDate.start < params.date_to)
|
||||||
@ -54,13 +89,21 @@ def get_event_dates_query(params):
|
|||||||
weekdays = params.weekday
|
weekdays = params.weekday
|
||||||
else:
|
else:
|
||||||
weekdays = [params.weekday]
|
weekdays = [params.weekday]
|
||||||
date_filter = and_(date_filter, extract('dow', EventDate.start).in_(weekdays))
|
date_filter = and_(date_filter, extract("dow", EventDate.start).in_(weekdays))
|
||||||
|
|
||||||
|
return (
|
||||||
|
EventDate.query.join(Event)
|
||||||
|
.join(EventPlace, isouter=True)
|
||||||
|
.join(Location, isouter=True)
|
||||||
|
.filter(date_filter)
|
||||||
|
.filter(event_filter)
|
||||||
|
.order_by(EventDate.start)
|
||||||
|
)
|
||||||
|
|
||||||
return EventDate.query.join(Event).join(EventPlace, isouter=True).join(Location, isouter=True).filter(date_filter).filter(event_filter).order_by(EventDate.start)
|
|
||||||
|
|
||||||
def get_events_query(params):
|
def get_events_query(params):
|
||||||
event_filter = (1 == 1)
|
event_filter = 1 == 1
|
||||||
date_filter = (EventDate.start >= today)
|
date_filter = EventDate.start >= today
|
||||||
|
|
||||||
event_filter = fill_event_filter(event_filter, params)
|
event_filter = fill_event_filter(event_filter, params)
|
||||||
|
|
||||||
@ -68,13 +111,19 @@ def get_events_query(params):
|
|||||||
event_filter = and_(event_filter, Event.admin_unit_id == params.admin_unit_id)
|
event_filter = and_(event_filter, Event.admin_unit_id == params.admin_unit_id)
|
||||||
|
|
||||||
if params.date_from:
|
if params.date_from:
|
||||||
date_filter = (EventDate.start >= params.date_from)
|
date_filter = EventDate.start >= params.date_from
|
||||||
|
|
||||||
if params.date_to:
|
if params.date_to:
|
||||||
date_filter = and_(date_filter, EventDate.start < params.date_to)
|
date_filter = and_(date_filter, EventDate.start < params.date_to)
|
||||||
|
|
||||||
event_filter = and_(event_filter, Event.dates.any(date_filter))
|
event_filter = and_(event_filter, Event.dates.any(date_filter))
|
||||||
return Event.query.join(EventPlace, isouter=True).join(Location, isouter=True).filter(event_filter).order_by(Event.start)
|
return (
|
||||||
|
Event.query.join(EventPlace, isouter=True)
|
||||||
|
.join(Location, isouter=True)
|
||||||
|
.filter(event_filter)
|
||||||
|
.order_by(Event.start)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def update_event_dates_with_recurrence_rule(event, start, end):
|
def update_event_dates_with_recurrence_rule(event, start, end):
|
||||||
event.start = start
|
event.start = start
|
||||||
@ -92,19 +141,30 @@ def update_event_dates_with_recurrence_rule(event, start, end):
|
|||||||
rr_dates = [start]
|
rr_dates = [start]
|
||||||
|
|
||||||
for rr_date in rr_dates:
|
for rr_date in rr_dates:
|
||||||
rr_date_start = date_add_time(rr_date, start.hour, start.minute, start.second, rr_date.tzinfo)
|
rr_date_start = date_add_time(
|
||||||
|
rr_date, start.hour, start.minute, start.second, rr_date.tzinfo
|
||||||
|
)
|
||||||
|
|
||||||
if end:
|
if end:
|
||||||
rr_date_end = rr_date_start + time_difference
|
rr_date_end = rr_date_start + time_difference
|
||||||
else:
|
else:
|
||||||
rr_date_end = None
|
rr_date_end = None
|
||||||
|
|
||||||
existing_date = next((date for date in event.dates if date.start == rr_date_start and date.end == rr_date_end), None)
|
existing_date = next(
|
||||||
|
(
|
||||||
|
date
|
||||||
|
for date in event.dates
|
||||||
|
if date.start == rr_date_start and date.end == rr_date_end
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
)
|
||||||
if existing_date:
|
if existing_date:
|
||||||
dates_to_remove.remove(existing_date)
|
dates_to_remove.remove(existing_date)
|
||||||
else:
|
else:
|
||||||
new_date = EventDate(event_id = event.id, start=rr_date_start, end=rr_date_end)
|
new_date = EventDate(
|
||||||
|
event_id=event.id, start=rr_date_start, end=rr_date_end
|
||||||
|
)
|
||||||
dates_to_add.append(new_date)
|
dates_to_add.append(new_date)
|
||||||
|
|
||||||
event.dates = [date for date in event.dates if date not in dates_to_remove]
|
event.dates = [date for date in event.dates if date not in dates_to_remove]
|
||||||
event.dates.extend(dates_to_add)
|
event.dates.extend(dates_to_add)
|
||||||
|
|||||||
@ -1,9 +1,14 @@
|
|||||||
from project.dateutils import today, date_add_time, date_set_end_of_day, form_input_from_date, form_input_to_date
|
from project.dateutils import (
|
||||||
|
today,
|
||||||
|
date_set_end_of_day,
|
||||||
|
form_input_from_date,
|
||||||
|
form_input_to_date,
|
||||||
|
)
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
class EventSearchParams(object):
|
|
||||||
|
|
||||||
|
class EventSearchParams(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._date_from = None
|
self._date_from = None
|
||||||
self._date_to = None
|
self._date_to = None
|
||||||
@ -77,30 +82,30 @@ class EventSearchParams(object):
|
|||||||
self.date_to = date_set_end_of_day(today + relativedelta(months=3))
|
self.date_to = date_set_end_of_day(today + relativedelta(months=3))
|
||||||
|
|
||||||
def load_from_request(self):
|
def load_from_request(self):
|
||||||
if 'date_from' in request.args:
|
if "date_from" in request.args:
|
||||||
self.date_from_str = request.args['date_from']
|
self.date_from_str = request.args["date_from"]
|
||||||
|
|
||||||
if 'date_to' in request.args:
|
if "date_to" in request.args:
|
||||||
self.date_to_str = request.args['date_to']
|
self.date_to_str = request.args["date_to"]
|
||||||
|
|
||||||
if 'keyword' in request.args:
|
if "keyword" in request.args:
|
||||||
self.keyword = request.args['keyword']
|
self.keyword = request.args["keyword"]
|
||||||
|
|
||||||
if "coordinate" in request.args:
|
if "coordinate" in request.args:
|
||||||
self.coordinate = request.args['coordinate']
|
self.coordinate = request.args["coordinate"]
|
||||||
|
|
||||||
if "distance" in request.args:
|
if "distance" in request.args:
|
||||||
self.distance = request.args['distance']
|
self.distance = request.args["distance"]
|
||||||
|
|
||||||
if "category_id" in request.args:
|
if "category_id" in request.args:
|
||||||
category_ids = request.args.getlist('category_id')
|
category_ids = request.args.getlist("category_id")
|
||||||
if '0' in category_ids:
|
if "0" in category_ids:
|
||||||
category_ids.remove('0')
|
category_ids.remove("0")
|
||||||
if len(category_ids) > 0:
|
if len(category_ids) > 0:
|
||||||
self.category_id = category_ids
|
self.category_id = category_ids
|
||||||
|
|
||||||
if "weekday" in request.args:
|
if "weekday" in request.args:
|
||||||
self.weekday = request.args.getlist('weekday')
|
self.weekday = request.args.getlist("weekday")
|
||||||
|
|
||||||
if "organizer_id" in request.args:
|
if "organizer_id" in request.args:
|
||||||
self.organizer_id = request.args['organizer_id']
|
self.organizer_id = request.args["organizer_id"]
|
||||||
|
|||||||
@ -1,9 +1,15 @@
|
|||||||
from project.models import EventReviewStatus, EventSuggestion
|
from project.models import EventReviewStatus, EventSuggestion
|
||||||
from sqlalchemy import and_
|
from sqlalchemy import and_
|
||||||
|
|
||||||
|
|
||||||
def get_event_reviews_badge_query(admin_unit):
|
def get_event_reviews_badge_query(admin_unit):
|
||||||
return EventSuggestion.query.filter(and_(EventSuggestion.admin_unit_id == admin_unit.id, EventSuggestion.review_status == EventReviewStatus.inbox))
|
return EventSuggestion.query.filter(
|
||||||
|
and_(
|
||||||
|
EventSuggestion.admin_unit_id == admin_unit.id,
|
||||||
|
EventSuggestion.review_status == EventReviewStatus.inbox,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_event_reviews_query(admin_unit):
|
def get_event_reviews_query(admin_unit):
|
||||||
return EventSuggestion.query.filter(EventSuggestion.admin_unit_id == admin_unit.id)
|
return EventSuggestion.query.filter(EventSuggestion.admin_unit_id == admin_unit.id)
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,13 @@
|
|||||||
|
from project import db
|
||||||
from project.models import Location
|
from project.models import Location
|
||||||
|
|
||||||
def upsert_location(street, postalCode, city, latitude = 0, longitude = 0, state = None):
|
|
||||||
result = Location.query.filter_by(street = street, postalCode=postalCode, city=city, state=state).first()
|
def upsert_location(street, postalCode, city, latitude=0, longitude=0, state=None):
|
||||||
|
result = Location.query.filter_by(
|
||||||
|
street=street, postalCode=postalCode, city=city, state=state
|
||||||
|
).first()
|
||||||
if result is None:
|
if result is None:
|
||||||
result = Location(street = street, postalCode=postalCode, city=city, state=state)
|
result = Location(street=street, postalCode=postalCode, city=city, state=state)
|
||||||
db.session.add(result)
|
db.session.add(result)
|
||||||
|
|
||||||
result.latitude = latitude
|
result.latitude = latitude
|
||||||
@ -20,4 +24,4 @@ def assign_location_values(target, origin):
|
|||||||
target.state = origin.state
|
target.state = origin.state
|
||||||
target.country = origin.country
|
target.country = origin.country
|
||||||
target.latitude = origin.latitude
|
target.latitude = origin.latitude
|
||||||
target.longitude = origin.longitude
|
target.longitude = origin.longitude
|
||||||
|
|||||||
@ -1,16 +1,25 @@
|
|||||||
from project.models import EventOrganizer, EventPlace
|
from project import db
|
||||||
from sqlalchemy import and_, or_, not_
|
from project.models import EventOrganizer, EventPlace, Location
|
||||||
from sqlalchemy.sql import asc, func
|
from sqlalchemy import and_
|
||||||
|
from sqlalchemy.sql import func
|
||||||
|
|
||||||
|
|
||||||
def upsert_event_organizer(admin_unit_id, name):
|
def upsert_event_organizer(admin_unit_id, name):
|
||||||
result = EventOrganizer.query.filter(and_(EventOrganizer.name == name, EventOrganizer.admin_unit_id == admin_unit_id)).first()
|
result = EventOrganizer.query.filter(
|
||||||
|
and_(EventOrganizer.name == name, EventOrganizer.admin_unit_id == admin_unit_id)
|
||||||
|
).first()
|
||||||
if result is None:
|
if result is None:
|
||||||
result = EventOrganizer(name = name, admin_unit_id=admin_unit_id)
|
result = EventOrganizer(name=name, admin_unit_id=admin_unit_id)
|
||||||
result.location = Location()
|
result.location = Location()
|
||||||
db.session.add(result)
|
db.session.add(result)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_event_places(organizer_id):
|
def get_event_places(organizer_id):
|
||||||
organizer = EventOrganizer.query.get(organizer_id)
|
organizer = EventOrganizer.query.get(organizer_id)
|
||||||
return EventPlace.query.filter(EventPlace.admin_unit_id==organizer.admin_unit_id).order_by(func.lower(EventPlace.name)).all()
|
return (
|
||||||
|
EventPlace.query.filter(EventPlace.admin_unit_id == organizer.admin_unit_id)
|
||||||
|
.order_by(func.lower(EventPlace.name))
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|||||||
@ -1,14 +1,29 @@
|
|||||||
from project.models import EventPlace
|
from project import db
|
||||||
from sqlalchemy.sql import asc, func
|
from project.models import EventPlace, Location
|
||||||
|
from sqlalchemy.sql import and_, func
|
||||||
|
|
||||||
|
|
||||||
def upsert_event_place(admin_unit_id, organizer_id, name):
|
def upsert_event_place(admin_unit_id, organizer_id, name):
|
||||||
result = EventPlace.query.filter(and_(EventPlace.name == name, EventPlace.admin_unit_id == admin_unit_id, EventPlace.organizer_id == organizer_id)).first()
|
result = EventPlace.query.filter(
|
||||||
|
and_(
|
||||||
|
EventPlace.name == name,
|
||||||
|
EventPlace.admin_unit_id == admin_unit_id,
|
||||||
|
EventPlace.organizer_id == organizer_id,
|
||||||
|
)
|
||||||
|
).first()
|
||||||
if result is None:
|
if result is None:
|
||||||
result = EventPlace(name = name, admin_unit_id=admin_unit_id, organizer_id=organizer_id)
|
result = EventPlace(
|
||||||
|
name=name, admin_unit_id=admin_unit_id, organizer_id=organizer_id
|
||||||
|
)
|
||||||
result.location = Location()
|
result.location = Location()
|
||||||
db.session.add(result)
|
db.session.add(result)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_event_places(admin_unit_id):
|
def get_event_places(admin_unit_id):
|
||||||
return EventPlace.query.filter(EventPlace.admin_unit_id==admin_unit_id).order_by(func.lower(EventPlace.name)).all()
|
return (
|
||||||
|
EventPlace.query.filter(EventPlace.admin_unit_id == admin_unit_id)
|
||||||
|
.order_by(func.lower(EventPlace.name))
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|||||||
@ -1,20 +1,44 @@
|
|||||||
from project import db
|
from project import db
|
||||||
from project.models import EventReference, EventReferenceRequest, EventReferenceRequestReviewStatus
|
from project.models import (
|
||||||
from sqlalchemy import and_, or_, not_
|
EventReference,
|
||||||
|
EventReferenceRequest,
|
||||||
|
EventReferenceRequestReviewStatus,
|
||||||
|
)
|
||||||
|
from sqlalchemy import and_
|
||||||
|
|
||||||
|
|
||||||
def create_event_reference_for_request(request):
|
def create_event_reference_for_request(request):
|
||||||
result = EventReference.query.filter(and_(EventReference.event_id == request.event_id,
|
result = EventReference.query.filter(
|
||||||
EventReference.admin_unit_id == request.admin_unit_id)).first()
|
and_(
|
||||||
|
EventReference.event_id == request.event_id,
|
||||||
|
EventReference.admin_unit_id == request.admin_unit_id,
|
||||||
|
)
|
||||||
|
).first()
|
||||||
|
|
||||||
if result is None:
|
if result is None:
|
||||||
result = EventReference(event_id = request.event_id,
|
result = EventReference(
|
||||||
admin_unit_id = request.admin_unit_id)
|
event_id=request.event_id, admin_unit_id=request.admin_unit_id
|
||||||
|
)
|
||||||
db.session.add(result)
|
db.session.add(result)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_reference_requests_incoming_query(admin_unit):
|
def get_reference_requests_incoming_query(admin_unit):
|
||||||
return EventReferenceRequest.query.filter(and_(EventReferenceRequest.review_status != EventReferenceRequestReviewStatus.verified, EventReferenceRequest.admin_unit_id == admin_unit.id))
|
return EventReferenceRequest.query.filter(
|
||||||
|
and_(
|
||||||
|
EventReferenceRequest.review_status
|
||||||
|
!= EventReferenceRequestReviewStatus.verified,
|
||||||
|
EventReferenceRequest.admin_unit_id == admin_unit.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_reference_requests_incoming_badge_query(admin_unit):
|
def get_reference_requests_incoming_badge_query(admin_unit):
|
||||||
return EventReferenceRequest.query.filter(and_(EventReferenceRequest.review_status == EventReferenceRequestReviewStatus.inbox, EventReferenceRequest.admin_unit_id == admin_unit.id))
|
return EventReferenceRequest.query.filter(
|
||||||
|
and_(
|
||||||
|
EventReferenceRequest.review_status
|
||||||
|
== EventReferenceRequestReviewStatus.inbox,
|
||||||
|
EventReferenceRequest.admin_unit_id == admin_unit.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|||||||
@ -1,17 +1,22 @@
|
|||||||
from project import user_datastore
|
from project import user_datastore
|
||||||
from flask_security import Security, current_user, auth_required, roles_required, hash_password
|
from flask_security import hash_password
|
||||||
|
|
||||||
|
|
||||||
def upsert_user(email, password="password"):
|
def upsert_user(email, password="password"):
|
||||||
result = user_datastore.find_user(email=email)
|
result = user_datastore.find_user(email=email)
|
||||||
if result is None:
|
if result is None:
|
||||||
result = user_datastore.create_user(email=email, password=hash_password(password))
|
result = user_datastore.create_user(
|
||||||
|
email=email, password=hash_password(password)
|
||||||
|
)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def add_roles_to_user(user_name, role_names):
|
def add_roles_to_user(user_name, role_names):
|
||||||
user = upsert_user(user_name)
|
user = upsert_user(user_name)
|
||||||
for role_name in role_names:
|
for role_name in role_names:
|
||||||
user_datastore.add_role_to_user(user, role_name)
|
user_datastore.add_role_to_user(user, role_name)
|
||||||
|
|
||||||
|
|
||||||
def upsert_user_role(role_name, role_title, permissions):
|
def upsert_user_role(role_name, role_title, permissions):
|
||||||
role = user_datastore.find_or_create_role(role_name)
|
role = user_datastore.find_or_create_role(role_name)
|
||||||
role.title = role_title
|
role.title = role_title
|
||||||
@ -19,5 +24,6 @@ def upsert_user_role(role_name, role_title, permissions):
|
|||||||
role.add_permissions(permissions)
|
role.add_permissions(permissions)
|
||||||
return role
|
return role
|
||||||
|
|
||||||
|
|
||||||
def find_user_by_email(email):
|
def find_user_by_email(email):
|
||||||
return user_datastore.find_user(email=email)
|
return user_datastore.find_user(email=email)
|
||||||
|
|||||||
@ -164,7 +164,7 @@
|
|||||||
rangeByEndDateHuman: 'ends on',
|
rangeByEndDateHuman: 'ends on',
|
||||||
|
|
||||||
including: ', and also',
|
including: ', and also',
|
||||||
except: ', except for',
|
except Exception: ', except for',
|
||||||
|
|
||||||
cancel: 'Cancel',
|
cancel: 'Cancel',
|
||||||
save: 'Save',
|
save: 'Save',
|
||||||
|
|||||||
@ -51,7 +51,7 @@ jQuery.tools.recurrenceinput.localize('de', {
|
|||||||
rangeByEndDate: 'Bis ',
|
rangeByEndDate: 'Bis ',
|
||||||
rangeByEndDateHuman: 'endet am ',
|
rangeByEndDateHuman: 'endet am ',
|
||||||
including: ', und auch ',
|
including: ', und auch ',
|
||||||
except: ', ausser für',
|
except Exception: ', ausser für',
|
||||||
cancel: 'Abbrechen',
|
cancel: 'Abbrechen',
|
||||||
save: 'Speichern',
|
save: 'Speichern',
|
||||||
recurrenceStart: 'Beginn der Wiederholung',
|
recurrenceStart: 'Beginn der Wiederholung',
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
from flask_babelex import lazy_gettext
|
from flask_babelex import lazy_gettext
|
||||||
|
|
||||||
|
|
||||||
def get_event_category_name(category):
|
def get_event_category_name(category):
|
||||||
return lazy_gettext('Event_' + category.name)
|
return lazy_gettext("Event_" + category.name)
|
||||||
|
|
||||||
|
|
||||||
def get_localized_enum_name(enum):
|
def get_localized_enum_name(enum):
|
||||||
return lazy_gettext(enum.__class__.__name__ + '.' + enum.name)
|
return lazy_gettext(enum.__class__.__name__ + "." + enum.name)
|
||||||
|
|||||||
@ -1,18 +1,16 @@
|
|||||||
from project import app, db
|
from project import app
|
||||||
from project.models import AdminUnit
|
from project.models import AdminUnit
|
||||||
from flask import render_template, flash, url_for, redirect, request, jsonify
|
from flask import render_template
|
||||||
from flask_babelex import gettext
|
from flask_security import roles_required
|
||||||
from flask_security import auth_required, roles_required
|
|
||||||
from project.access import has_access, access_or_401
|
|
||||||
from sqlalchemy.sql import asc, func
|
|
||||||
|
|
||||||
@app.route("/admin")
|
@app.route("/admin")
|
||||||
@roles_required("admin")
|
@roles_required("admin")
|
||||||
def admin():
|
def admin():
|
||||||
return render_template('admin/admin.html')
|
return render_template("admin/admin.html")
|
||||||
|
|
||||||
|
|
||||||
@app.route("/admin/admin_units")
|
@app.route("/admin/admin_units")
|
||||||
@roles_required("admin")
|
@roles_required("admin")
|
||||||
def admin_admin_units():
|
def admin_admin_units():
|
||||||
return render_template('admin/admin_units.html',
|
return render_template("admin/admin_units.html", admin_units=AdminUnit.query.all())
|
||||||
admin_units=AdminUnit.query.all())
|
|
||||||
|
|||||||
@ -1,20 +1,26 @@
|
|||||||
from project import app, db
|
from project import app, db
|
||||||
from flask import url_for, render_template, request, redirect, flash
|
from flask import url_for, render_template, redirect, flash
|
||||||
from flask_babelex import gettext
|
from flask_babelex import gettext
|
||||||
from flask_security import auth_required, current_user
|
from flask_security import auth_required, current_user
|
||||||
from project.models import AdminUnitMemberInvitation
|
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
from project.access import get_admin_unit_for_manage_or_404, access_or_401, has_access
|
from project.access import get_admin_unit_for_manage_or_404, has_access
|
||||||
from project.forms.admin_unit import CreateAdminUnitForm, UpdateAdminUnitForm
|
from project.forms.admin_unit import CreateAdminUnitForm, UpdateAdminUnitForm
|
||||||
from project.views.utils import upsert_image_with_data, handleSqlError, permission_missing, flash_errors
|
from project.views.utils import (
|
||||||
|
upsert_image_with_data,
|
||||||
|
handleSqlError,
|
||||||
|
permission_missing,
|
||||||
|
flash_errors,
|
||||||
|
)
|
||||||
from project.models import AdminUnit, Location, EventOrganizer
|
from project.models import AdminUnit, Location, EventOrganizer
|
||||||
from project.services.admin_unit import add_user_to_admin_unit_with_roles
|
from project.services.admin_unit import add_user_to_admin_unit_with_roles
|
||||||
from project.services.location import assign_location_values
|
from project.services.location import assign_location_values
|
||||||
|
|
||||||
|
|
||||||
def update_admin_unit_with_form(admin_unit, form):
|
def update_admin_unit_with_form(admin_unit, form):
|
||||||
form.populate_obj(admin_unit)
|
form.populate_obj(admin_unit)
|
||||||
|
|
||||||
@app.route("/admin_unit/create", methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/admin_unit/create", methods=("GET", "POST"))
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def admin_unit_create():
|
def admin_unit_create():
|
||||||
form = CreateAdminUnitForm()
|
form = CreateAdminUnitForm()
|
||||||
@ -28,7 +34,9 @@ def admin_unit_create():
|
|||||||
db.session.add(admin_unit)
|
db.session.add(admin_unit)
|
||||||
|
|
||||||
# Aktuellen Nutzer als Admin hinzufügen
|
# Aktuellen Nutzer als Admin hinzufügen
|
||||||
add_user_to_admin_unit_with_roles(current_user, admin_unit, ['admin', 'event_verifier'])
|
add_user_to_admin_unit_with_roles(
|
||||||
|
current_user, admin_unit, ["admin", "event_verifier"]
|
||||||
|
)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
# Organizer anlegen
|
# Organizer anlegen
|
||||||
@ -42,27 +50,32 @@ def admin_unit_create():
|
|||||||
organizer.location = Location()
|
organizer.location = Location()
|
||||||
assign_location_values(organizer.location, admin_unit.location)
|
assign_location_values(organizer.location, admin_unit.location)
|
||||||
if admin_unit.logo:
|
if admin_unit.logo:
|
||||||
organizer.logo = upsert_image_with_data(organizer.logo, admin_unit.logo.data, admin_unit.logo.encoding_format)
|
organizer.logo = upsert_image_with_data(
|
||||||
|
organizer.logo,
|
||||||
|
admin_unit.logo.data,
|
||||||
|
admin_unit.logo.encoding_format,
|
||||||
|
)
|
||||||
db.session.add(organizer)
|
db.session.add(organizer)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
flash(gettext('Admin unit successfully created'), 'success')
|
flash(gettext("Admin unit successfully created"), "success")
|
||||||
return redirect(url_for('manage_admin_unit', id=admin_unit.id))
|
return redirect(url_for("manage_admin_unit", id=admin_unit.id))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('admin_unit/create.html', form=form)
|
return render_template("admin_unit/create.html", form=form)
|
||||||
|
|
||||||
@app.route('/admin_unit/<int:id>/update', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/admin_unit/<int:id>/update", methods=("GET", "POST"))
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def admin_unit_update(id):
|
def admin_unit_update(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
|
|
||||||
if not has_access(admin_unit, 'admin_unit:update'):
|
if not has_access(admin_unit, "admin_unit:update"):
|
||||||
return permission_missing(url_for('manage_admin_unit', id=admin_unit.id))
|
return permission_missing(url_for("manage_admin_unit", id=admin_unit.id))
|
||||||
|
|
||||||
form = UpdateAdminUnitForm(obj=admin_unit)
|
form = UpdateAdminUnitForm(obj=admin_unit)
|
||||||
|
|
||||||
@ -71,14 +84,12 @@ def admin_unit_update(id):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('AdminUnit successfully updated'), 'success')
|
flash(gettext("AdminUnit successfully updated"), "success")
|
||||||
return redirect(url_for('admin_unit_update', id=admin_unit.id))
|
return redirect(url_for("admin_unit_update", id=admin_unit.id))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('admin_unit/update.html',
|
return render_template("admin_unit/update.html", form=form, admin_unit=admin_unit)
|
||||||
form=form,
|
|
||||||
admin_unit=admin_unit)
|
|
||||||
|
|||||||
@ -1,25 +1,36 @@
|
|||||||
from project import app, db
|
from project import app, db
|
||||||
from flask import url_for, render_template, request, redirect, flash
|
from flask import url_for, render_template, redirect, flash
|
||||||
from flask_babelex import gettext
|
from flask_babelex import gettext
|
||||||
from flask_security import auth_required, current_user
|
from flask_security import auth_required
|
||||||
from project.models import AdminUnitMember, AdminUnitMemberRole
|
from project.models import AdminUnitMember, AdminUnitMemberRole
|
||||||
from project.forms.admin_unit_member import DeleteAdminUnitMemberForm, UpdateAdminUnitMemberForm
|
from project.forms.admin_unit_member import (
|
||||||
from project.views.utils import permission_missing, send_mail, handleSqlError, flash_errors
|
DeleteAdminUnitMemberForm,
|
||||||
from project.access import get_admin_unit_for_manage_or_404, has_access
|
UpdateAdminUnitMemberForm,
|
||||||
|
)
|
||||||
|
from project.views.utils import (
|
||||||
|
permission_missing,
|
||||||
|
handleSqlError,
|
||||||
|
flash_errors,
|
||||||
|
)
|
||||||
|
from project.access import has_access
|
||||||
from project.services.admin_unit import add_roles_to_admin_unit_member
|
from project.services.admin_unit import add_roles_to_admin_unit_member
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
|
||||||
@app.route('/manage/member/<int:id>/update', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/manage/member/<int:id>/update", methods=("GET", "POST"))
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_member_update(id):
|
def manage_admin_unit_member_update(id):
|
||||||
member = AdminUnitMember.query.get_or_404(id)
|
member = AdminUnitMember.query.get_or_404(id)
|
||||||
admin_unit = member.adminunit
|
admin_unit = member.adminunit
|
||||||
|
|
||||||
if not has_access(admin_unit, 'admin_unit.members:update'):
|
if not has_access(admin_unit, "admin_unit.members:update"):
|
||||||
return permission_missing(url_for('manage_admin_unit', id=admin_unit.id))
|
return permission_missing(url_for("manage_admin_unit", id=admin_unit.id))
|
||||||
|
|
||||||
form = UpdateAdminUnitMemberForm()
|
form = UpdateAdminUnitMemberForm()
|
||||||
form.roles.choices = [(c.name, gettext(c.title)) for c in AdminUnitMemberRole.query.order_by(AdminUnitMemberRole.id).all()]
|
form.roles.choices = [
|
||||||
|
(c.name, gettext(c.title))
|
||||||
|
for c in AdminUnitMemberRole.query.order_by(AdminUnitMemberRole.id).all()
|
||||||
|
]
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
member.roles.clear()
|
member.roles.clear()
|
||||||
@ -27,45 +38,43 @@ def manage_admin_unit_member_update(id):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Member successfully updated'), 'success')
|
flash(gettext("Member successfully updated"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_members', id=admin_unit.id))
|
return redirect(url_for("manage_admin_unit_members", id=admin_unit.id))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
form.roles.data = [c.name for c in member.roles]
|
form.roles.data = [c.name for c in member.roles]
|
||||||
|
|
||||||
return render_template('admin_unit/update_member.html',
|
return render_template(
|
||||||
admin_unit=admin_unit,
|
"admin_unit/update_member.html", admin_unit=admin_unit, member=member, form=form
|
||||||
member=member,
|
)
|
||||||
form=form)
|
|
||||||
|
|
||||||
@app.route('/manage/member/<int:id>/delete', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/manage/member/<int:id>/delete", methods=("GET", "POST"))
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_member_delete(id):
|
def manage_admin_unit_member_delete(id):
|
||||||
member = AdminUnitMember.query.get_or_404(id)
|
member = AdminUnitMember.query.get_or_404(id)
|
||||||
admin_unit = member.adminunit
|
admin_unit = member.adminunit
|
||||||
|
|
||||||
if not has_access(admin_unit, 'admin_unit.members:delete'):
|
if not has_access(admin_unit, "admin_unit.members:delete"):
|
||||||
return permission_missing(url_for('manage_admin_unit', id=admin_unit.id))
|
return permission_missing(url_for("manage_admin_unit", id=admin_unit.id))
|
||||||
|
|
||||||
form = DeleteAdminUnitMemberForm()
|
form = DeleteAdminUnitMemberForm()
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
if form.email.data != member.user.email:
|
if form.email.data != member.user.email:
|
||||||
flash(gettext('Entered email does not match member email'), 'danger')
|
flash(gettext("Entered email does not match member email"), "danger")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
db.session.delete(member)
|
db.session.delete(member)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Member successfully deleted'), 'success')
|
flash(gettext("Member successfully deleted"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_members', id=admin_unit.id))
|
return redirect(url_for("manage_admin_unit_members", id=admin_unit.id))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('manage/delete_member.html',
|
return render_template("manage/delete_member.html", form=form, member=member)
|
||||||
form=form,
|
|
||||||
member=member)
|
|
||||||
|
|||||||
@ -1,113 +1,130 @@
|
|||||||
from project import app, db
|
from project import app, db
|
||||||
from flask import url_for, render_template, request, redirect, flash
|
from flask import url_for, render_template, redirect, flash
|
||||||
from flask_babelex import gettext
|
from flask_babelex import gettext
|
||||||
from flask_security import auth_required, current_user
|
from flask_security import auth_required, current_user
|
||||||
from project.models import AdminUnitMemberInvitation, AdminUnitMemberRole
|
from project.models import AdminUnitMemberInvitation, AdminUnitMemberRole
|
||||||
from project.forms.admin_unit_member import NegotiateAdminUnitMemberInvitationForm, InviteAdminUnitMemberForm, DeleteAdminUnitInvitationForm
|
from project.forms.admin_unit_member import (
|
||||||
from project.views.utils import permission_missing, send_mail, handleSqlError, flash_errors
|
NegotiateAdminUnitMemberInvitationForm,
|
||||||
|
InviteAdminUnitMemberForm,
|
||||||
|
DeleteAdminUnitInvitationForm,
|
||||||
|
)
|
||||||
|
from project.views.utils import (
|
||||||
|
permission_missing,
|
||||||
|
send_mail,
|
||||||
|
handleSqlError,
|
||||||
|
flash_errors,
|
||||||
|
)
|
||||||
from project.access import get_admin_unit_for_manage_or_404, has_access
|
from project.access import get_admin_unit_for_manage_or_404, has_access
|
||||||
from project.services.admin_unit import add_user_to_admin_unit_with_roles
|
from project.services.admin_unit import add_user_to_admin_unit_with_roles
|
||||||
from project.services.user import find_user_by_email
|
from project.services.user import find_user_by_email
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
|
||||||
@app.route('/invitations/<int:id>', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/invitations/<int:id>", methods=("GET", "POST"))
|
||||||
def admin_unit_member_invitation(id):
|
def admin_unit_member_invitation(id):
|
||||||
invitation = AdminUnitMemberInvitation.query.get_or_404(id)
|
invitation = AdminUnitMemberInvitation.query.get_or_404(id)
|
||||||
|
|
||||||
# Wenn Email nicht als Nutzer vorhanden, dann direkt zu Registrierung
|
# Wenn Email nicht als Nutzer vorhanden, dann direkt zu Registrierung
|
||||||
if not find_user_by_email(invitation.email):
|
if not find_user_by_email(invitation.email):
|
||||||
return redirect(url_for('security.register'))
|
return redirect(url_for("security.register"))
|
||||||
|
|
||||||
if not current_user.is_authenticated:
|
if not current_user.is_authenticated:
|
||||||
return app.login_manager.unauthorized()
|
return app.login_manager.unauthorized()
|
||||||
|
|
||||||
if invitation.email != current_user.email:
|
if invitation.email != current_user.email:
|
||||||
return permission_missing(url_for('profile'))
|
return permission_missing(url_for("profile"))
|
||||||
|
|
||||||
form = NegotiateAdminUnitMemberInvitationForm()
|
form = NegotiateAdminUnitMemberInvitationForm()
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
try:
|
try:
|
||||||
if form.accept.data:
|
if form.accept.data:
|
||||||
message = gettext('Invitation successfully accepted')
|
message = gettext("Invitation successfully accepted")
|
||||||
roles = invitation.roles.split(',')
|
roles = invitation.roles.split(",")
|
||||||
add_user_to_admin_unit_with_roles(current_user, invitation.adminunit, roles)
|
add_user_to_admin_unit_with_roles(
|
||||||
|
current_user, invitation.adminunit, roles
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
message = gettext('Invitation successfully declined')
|
message = gettext("Invitation successfully declined")
|
||||||
|
|
||||||
db.session.delete(invitation)
|
db.session.delete(invitation)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(message, 'success')
|
flash(message, "success")
|
||||||
return redirect(url_for('manage'))
|
return redirect(url_for("manage"))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
|
|
||||||
return render_template('invitation/read.html',
|
return render_template("invitation/read.html", form=form, invitation=invitation)
|
||||||
form=form,
|
|
||||||
invitation=invitation)
|
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>/members/invite', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>/members/invite", methods=("GET", "POST"))
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_member_invite(id):
|
def manage_admin_unit_member_invite(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
|
|
||||||
if not has_access(admin_unit, 'admin_unit.members:invite'):
|
if not has_access(admin_unit, "admin_unit.members:invite"):
|
||||||
return permission_missing(url_for('manage_admin_unit', id=admin_unit.id))
|
return permission_missing(url_for("manage_admin_unit", id=admin_unit.id))
|
||||||
|
|
||||||
form = InviteAdminUnitMemberForm()
|
form = InviteAdminUnitMemberForm()
|
||||||
form.roles.choices = [(c.name, gettext(c.title)) for c in AdminUnitMemberRole.query.order_by(AdminUnitMemberRole.id).all()]
|
form.roles.choices = [
|
||||||
|
(c.name, gettext(c.title))
|
||||||
|
for c in AdminUnitMemberRole.query.order_by(AdminUnitMemberRole.id).all()
|
||||||
|
]
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
invitation = AdminUnitMemberInvitation()
|
invitation = AdminUnitMemberInvitation()
|
||||||
invitation.admin_unit_id = admin_unit.id
|
invitation.admin_unit_id = admin_unit.id
|
||||||
form.populate_obj(invitation)
|
form.populate_obj(invitation)
|
||||||
invitation.roles = ','.join(form.roles.data)
|
invitation.roles = ",".join(form.roles.data)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
db.session.add(invitation)
|
db.session.add(invitation)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
send_mail(invitation.email,
|
send_mail(
|
||||||
gettext('You have received an invitation'),
|
invitation.email,
|
||||||
'invitation_notice',
|
gettext("You have received an invitation"),
|
||||||
invitation=invitation)
|
"invitation_notice",
|
||||||
|
invitation=invitation,
|
||||||
|
)
|
||||||
|
|
||||||
flash(gettext('Invitation successfully sent'), 'success')
|
flash(gettext("Invitation successfully sent"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_members', id=admin_unit.id))
|
return redirect(url_for("manage_admin_unit_members", id=admin_unit.id))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
return render_template('admin_unit/invite_member.html',
|
return render_template(
|
||||||
admin_unit=admin_unit,
|
"admin_unit/invite_member.html", admin_unit=admin_unit, form=form
|
||||||
form=form)
|
)
|
||||||
|
|
||||||
@app.route('/manage/invitation/<int:id>/delete', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/manage/invitation/<int:id>/delete", methods=("GET", "POST"))
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_invitation_delete(id):
|
def manage_admin_unit_invitation_delete(id):
|
||||||
invitation = AdminUnitMemberInvitation.query.get_or_404(id)
|
invitation = AdminUnitMemberInvitation.query.get_or_404(id)
|
||||||
admin_unit = invitation.adminunit
|
admin_unit = invitation.adminunit
|
||||||
|
|
||||||
if not has_access(admin_unit, 'admin_unit.members:invite'):
|
if not has_access(admin_unit, "admin_unit.members:invite"):
|
||||||
return permission_missing(url_for('manage_admin_unit', id=id))
|
return permission_missing(url_for("manage_admin_unit", id=id))
|
||||||
|
|
||||||
form = DeleteAdminUnitInvitationForm()
|
form = DeleteAdminUnitInvitationForm()
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
if form.email.data != invitation.email:
|
if form.email.data != invitation.email:
|
||||||
flash(gettext('Entered email does not match invitation email'), 'danger')
|
flash(gettext("Entered email does not match invitation email"), "danger")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
db.session.delete(invitation)
|
db.session.delete(invitation)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Invitation successfully deleted'), 'success')
|
flash(gettext("Invitation successfully deleted"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_members', id=admin_unit.id))
|
return redirect(url_for("manage_admin_unit_members", id=admin_unit.id))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('manage/delete_invitation.html',
|
return render_template(
|
||||||
form=form,
|
"manage/delete_invitation.html", form=form, invitation=invitation
|
||||||
invitation=invitation)
|
)
|
||||||
|
|||||||
@ -7,11 +7,18 @@ from project.services.event import get_event_dates_query
|
|||||||
from project.services.event_search import EventSearchParams
|
from project.services.event_search import EventSearchParams
|
||||||
from project.services.organizer import get_event_places
|
from project.services.organizer import get_event_places
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/events")
|
@app.route("/api/events")
|
||||||
def api_events():
|
def api_events():
|
||||||
dates = EventDate.query.join(Event).filter(EventDate.start >= today).order_by(EventDate.start).all()
|
dates = (
|
||||||
|
EventDate.query.join(Event)
|
||||||
|
.filter(EventDate.start >= today)
|
||||||
|
.order_by(EventDate.start)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
return json_from_event_dates(dates)
|
return json_from_event_dates(dates)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/event_dates")
|
@app.route("/api/event_dates")
|
||||||
def api_event_dates():
|
def api_event_dates():
|
||||||
params = EventSearchParams()
|
params = EventSearchParams()
|
||||||
@ -20,9 +27,12 @@ def api_event_dates():
|
|||||||
dates = get_event_dates_query(params).paginate()
|
dates = get_event_dates_query(params).paginate()
|
||||||
return json_from_event_dates(dates.items)
|
return json_from_event_dates(dates.items)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/<string:au_short_name>/event_dates")
|
@app.route("/api/<string:au_short_name>/event_dates")
|
||||||
def api_infoscreen(au_short_name):
|
def api_infoscreen(au_short_name):
|
||||||
admin_unit = AdminUnit.query.filter(AdminUnit.short_name == au_short_name).first_or_404()
|
admin_unit = AdminUnit.query.filter(
|
||||||
|
AdminUnit.short_name == au_short_name
|
||||||
|
).first_or_404()
|
||||||
|
|
||||||
params = EventSearchParams()
|
params = EventSearchParams()
|
||||||
params.load_from_request()
|
params.load_from_request()
|
||||||
@ -31,6 +41,7 @@ def api_infoscreen(au_short_name):
|
|||||||
dates = get_event_dates_query(params).paginate()
|
dates = get_event_dates_query(params).paginate()
|
||||||
return json_from_event_dates(dates.items)
|
return json_from_event_dates(dates.items)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/organizer/<int:id>/event_places")
|
@app.route("/api/organizer/<int:id>/event_places")
|
||||||
def api_event_places(id):
|
def api_event_places(id):
|
||||||
places = get_event_places(id)
|
places = get_event_places(id)
|
||||||
@ -44,16 +55,17 @@ def api_event_places(id):
|
|||||||
|
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
|
|
||||||
|
|
||||||
def json_from_event_dates(dates):
|
def json_from_event_dates(dates):
|
||||||
structured_events = list()
|
structured_events = list()
|
||||||
for event_date in dates:
|
for event_date in dates:
|
||||||
structured_event = get_sd_for_event_date(event_date)
|
structured_event = get_sd_for_event_date(event_date)
|
||||||
structured_event.pop('@context', None)
|
structured_event.pop("@context", None)
|
||||||
structured_events.append(structured_event)
|
structured_events.append(structured_event)
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
result["@context"] = "https://schema.org"
|
result["@context"] = "https://schema.org"
|
||||||
result["@type"] = "Project"
|
result["@type"] = "Project"
|
||||||
result["name"] = "Prototyp"
|
result["name"] = "Prototyp"
|
||||||
result['event'] = structured_events
|
result["event"] = structured_events
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
|
|||||||
@ -1,58 +1,95 @@
|
|||||||
from project import app, db
|
from project import app, db
|
||||||
from project.models import User, Event, EventDate, EventReviewStatus, AdminUnit, AdminUnitMember, EventOrganizer, EventCategory, EventSuggestion
|
from project.models import (
|
||||||
from flask import render_template, flash, url_for, redirect, request, jsonify, abort
|
Event,
|
||||||
|
EventDate,
|
||||||
|
EventReviewStatus,
|
||||||
|
AdminUnit,
|
||||||
|
EventOrganizer,
|
||||||
|
EventCategory,
|
||||||
|
EventSuggestion,
|
||||||
|
)
|
||||||
|
from flask import render_template, flash, url_for, redirect, request, jsonify
|
||||||
from flask_babelex import gettext
|
from flask_babelex import gettext
|
||||||
from flask_security import auth_required
|
from project.access import (
|
||||||
from project.access import has_access, access_or_401, can_reference_event, has_admin_unit_member_permission
|
has_access,
|
||||||
|
access_or_401,
|
||||||
|
can_reference_event,
|
||||||
|
)
|
||||||
from project.dateutils import today
|
from project.dateutils import today
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from project.forms.event import CreateEventForm, UpdateEventForm, DeleteEventForm
|
from project.forms.event import CreateEventForm, UpdateEventForm, DeleteEventForm
|
||||||
from project.views.utils import flash_errors, upsert_image_with_data, send_mail, handleSqlError, flash_message
|
from project.views.utils import (
|
||||||
|
flash_errors,
|
||||||
|
handleSqlError,
|
||||||
|
flash_message,
|
||||||
|
)
|
||||||
from project.utils import get_event_category_name
|
from project.utils import get_event_category_name
|
||||||
from project.services.event import upsert_event_category, update_event_dates_with_recurrence_rule
|
from project.services.event import (
|
||||||
|
upsert_event_category,
|
||||||
|
update_event_dates_with_recurrence_rule,
|
||||||
|
)
|
||||||
from project.services.place import get_event_places
|
from project.services.place import get_event_places
|
||||||
from sqlalchemy.sql import asc, func
|
from sqlalchemy.sql import func
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
from project.views.event_suggestion import send_event_suggestion_review_status_mail
|
from project.views.event_suggestion import send_event_suggestion_review_status_mail
|
||||||
|
|
||||||
@app.route('/event/<int:event_id>')
|
|
||||||
|
@app.route("/event/<int:event_id>")
|
||||||
def event(event_id):
|
def event(event_id):
|
||||||
event = Event.query.get_or_404(event_id)
|
event = Event.query.get_or_404(event_id)
|
||||||
user_rights = get_user_rights(event)
|
user_rights = get_user_rights(event)
|
||||||
dates = EventDate.query.with_parent(event).filter(EventDate.start >= today).order_by(EventDate.start).all()
|
dates = (
|
||||||
|
EventDate.query.with_parent(event)
|
||||||
|
.filter(EventDate.start >= today)
|
||||||
|
.order_by(EventDate.start)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
return render_template('event/read.html',
|
return render_template(
|
||||||
event=event,
|
"event/read.html", event=event, dates=dates, user_rights=user_rights
|
||||||
dates=dates,
|
)
|
||||||
user_rights=user_rights)
|
|
||||||
|
|
||||||
@app.route("/admin_unit/<int:id>/events/create", methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/admin_unit/<int:id>/events/create", methods=("GET", "POST"))
|
||||||
def event_create_for_admin_unit_id(id):
|
def event_create_for_admin_unit_id(id):
|
||||||
admin_unit = AdminUnit.query.get_or_404(id)
|
admin_unit = AdminUnit.query.get_or_404(id)
|
||||||
access_or_401(admin_unit, 'event:create')
|
access_or_401(admin_unit, "event:create")
|
||||||
|
|
||||||
form = CreateEventForm(admin_unit_id=admin_unit.id, category_ids=[upsert_event_category('Other').id])
|
form = CreateEventForm(
|
||||||
|
admin_unit_id=admin_unit.id, category_ids=[upsert_event_category("Other").id]
|
||||||
|
)
|
||||||
prepare_event_form(form, admin_unit)
|
prepare_event_form(form, admin_unit)
|
||||||
|
|
||||||
# Vorlagen
|
# Vorlagen
|
||||||
event_suggestion = None
|
event_suggestion = None
|
||||||
event_template = None
|
event_template = None
|
||||||
|
|
||||||
event_template_id = int(request.args.get('template_id')) if 'template_id' in request.args else 0
|
event_template_id = (
|
||||||
|
int(request.args.get("template_id")) if "template_id" in request.args else 0
|
||||||
|
)
|
||||||
if event_template_id > 0:
|
if event_template_id > 0:
|
||||||
event_template = Event.query.get_or_404(event_template_id)
|
event_template = Event.query.get_or_404(event_template_id)
|
||||||
if not form.is_submitted():
|
if not form.is_submitted():
|
||||||
form.process(obj=event_template)
|
form.process(obj=event_template)
|
||||||
|
|
||||||
if not event_template:
|
if not event_template:
|
||||||
event_suggestion_id = int(request.args.get('event_suggestion_id')) if 'event_suggestion_id' in request.args else 0
|
event_suggestion_id = (
|
||||||
|
int(request.args.get("event_suggestion_id"))
|
||||||
|
if "event_suggestion_id" in request.args
|
||||||
|
else 0
|
||||||
|
)
|
||||||
|
|
||||||
if event_suggestion_id > 0:
|
if event_suggestion_id > 0:
|
||||||
event_suggestion = EventSuggestion.query.get_or_404(event_suggestion_id)
|
event_suggestion = EventSuggestion.query.get_or_404(event_suggestion_id)
|
||||||
access_or_401(event_suggestion.admin_unit, 'event:verify')
|
access_or_401(event_suggestion.admin_unit, "event:verify")
|
||||||
|
|
||||||
if event_suggestion.verified and event_suggestion.event_id:
|
if event_suggestion.verified and event_suggestion.event_id:
|
||||||
return redirect(url_for('event_suggestion_review_status', event_suggestion_id=event_suggestion.id))
|
return redirect(
|
||||||
|
url_for(
|
||||||
|
"event_suggestion_review_status",
|
||||||
|
event_suggestion_id=event_suggestion.id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
prepare_event_form_for_suggestion(form, event_suggestion)
|
prepare_event_form_for_suggestion(form, event_suggestion)
|
||||||
if form.is_submitted():
|
if form.is_submitted():
|
||||||
@ -81,21 +118,27 @@ def event_create_for_admin_unit_id(id):
|
|||||||
if event_suggestion:
|
if event_suggestion:
|
||||||
send_event_suggestion_review_status_mail(event_suggestion)
|
send_event_suggestion_review_status_mail(event_suggestion)
|
||||||
|
|
||||||
flash_message(gettext('Event successfully created'), url_for('event', event_id=event.id))
|
flash_message(
|
||||||
return redirect(url_for('manage_admin_unit_events', id=event.admin_unit_id))
|
gettext("Event successfully created"),
|
||||||
|
url_for("event", event_id=event.id),
|
||||||
|
)
|
||||||
|
return redirect(url_for("manage_admin_unit_events", id=event.admin_unit_id))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
return render_template('event/create.html', form=form, event_suggestion=event_suggestion)
|
return render_template(
|
||||||
|
"event/create.html", form=form, event_suggestion=event_suggestion
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/event/<int:event_id>/update', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/event/<int:event_id>/update", methods=("GET", "POST"))
|
||||||
def event_update(event_id):
|
def event_update(event_id):
|
||||||
event = Event.query.get_or_404(event_id)
|
event = Event.query.get_or_404(event_id)
|
||||||
access_or_401(event.admin_unit, 'event:update')
|
access_or_401(event.admin_unit, "event:update")
|
||||||
|
|
||||||
form = UpdateEventForm(obj=event,start=event.start,end=event.end)
|
form = UpdateEventForm(obj=event, start=event.start, end=event.end)
|
||||||
prepare_event_form(form, event.admin_unit)
|
prepare_event_form(form, event.admin_unit)
|
||||||
|
|
||||||
if not form.is_submitted():
|
if not form.is_submitted():
|
||||||
@ -106,72 +149,86 @@ def event_update(event_id):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash_message(gettext('Event successfully updated'), url_for('event', event_id=event.id))
|
flash_message(
|
||||||
return redirect(url_for('manage_admin_unit_events', id=event.admin_unit_id))
|
gettext("Event successfully updated"),
|
||||||
|
url_for("event", event_id=event.id),
|
||||||
|
)
|
||||||
|
return redirect(url_for("manage_admin_unit_events", id=event.admin_unit_id))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('event/update.html',
|
return render_template("event/update.html", form=form, event=event)
|
||||||
form=form,
|
|
||||||
event=event)
|
|
||||||
|
|
||||||
@app.route('/event/<int:event_id>/delete', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/event/<int:event_id>/delete", methods=("GET", "POST"))
|
||||||
def event_delete(event_id):
|
def event_delete(event_id):
|
||||||
event = Event.query.get_or_404(event_id)
|
event = Event.query.get_or_404(event_id)
|
||||||
access_or_401(event.admin_unit, 'event:delete')
|
access_or_401(event.admin_unit, "event:delete")
|
||||||
|
|
||||||
form = DeleteEventForm()
|
form = DeleteEventForm()
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
if form.name.data != event.name:
|
if form.name.data != event.name:
|
||||||
flash(gettext('Entered name does not match event name'), 'danger')
|
flash(gettext("Entered name does not match event name"), "danger")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
admin_unit_id = event.admin_unit.id
|
admin_unit_id = event.admin_unit.id
|
||||||
db.session.delete(event)
|
db.session.delete(event)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Event successfully deleted'), 'success')
|
flash(gettext("Event successfully deleted"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_events', id=admin_unit_id))
|
return redirect(url_for("manage_admin_unit_events", id=admin_unit_id))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('event/delete.html',
|
return render_template("event/delete.html", form=form, event=event)
|
||||||
form=form,
|
|
||||||
event=event)
|
|
||||||
|
|
||||||
@app.route("/events/rrule", methods=['POST'])
|
|
||||||
|
@app.route("/events/rrule", methods=["POST"])
|
||||||
def event_rrule():
|
def event_rrule():
|
||||||
year = request.json['year']
|
year = request.json["year"]
|
||||||
month = request.json['month']
|
month = request.json["month"]
|
||||||
day = request.json['day']
|
day = request.json["day"]
|
||||||
rrule_str = request.json['rrule']
|
rrule_str = request.json["rrule"]
|
||||||
output_format = request.json['format']
|
start = int(request.json["start"])
|
||||||
start = int(request.json['start'])
|
|
||||||
batch_size = 10
|
batch_size = 10
|
||||||
start_date = datetime(year, month, day)
|
start_date = datetime(year, month, day)
|
||||||
|
|
||||||
from project.dateutils import calculate_occurrences
|
from project.dateutils import calculate_occurrences
|
||||||
result = calculate_occurrences(start_date, '"%d.%m.%Y"', rrule_str, start, batch_size)
|
|
||||||
|
result = calculate_occurrences(
|
||||||
|
start_date, '"%d.%m.%Y"', rrule_str, start, batch_size
|
||||||
|
)
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
|
|
||||||
|
|
||||||
def get_event_category_choices():
|
def get_event_category_choices():
|
||||||
return sorted([(c.id, get_event_category_name(c)) for c in EventCategory.query.all()], key=lambda category: category[1])
|
return sorted(
|
||||||
|
[(c.id, get_event_category_name(c)) for c in EventCategory.query.all()],
|
||||||
|
key=lambda category: category[1],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def prepare_event_form(form, admin_unit):
|
def prepare_event_form(form, admin_unit):
|
||||||
form.organizer_id.choices = [(o.id, o.name) for o in EventOrganizer.query.filter(EventOrganizer.admin_unit_id == admin_unit.id).order_by(func.lower(EventOrganizer.name))]
|
form.organizer_id.choices = [
|
||||||
|
(o.id, o.name)
|
||||||
|
for o in EventOrganizer.query.filter(
|
||||||
|
EventOrganizer.admin_unit_id == admin_unit.id
|
||||||
|
).order_by(func.lower(EventOrganizer.name))
|
||||||
|
]
|
||||||
form.category_ids.choices = get_event_category_choices()
|
form.category_ids.choices = get_event_category_choices()
|
||||||
|
|
||||||
places = get_event_places(admin_unit.id)
|
places = get_event_places(admin_unit.id)
|
||||||
form.event_place_id.choices = [(p.id, p.name) for p in places]
|
form.event_place_id.choices = [(p.id, p.name) for p in places]
|
||||||
|
|
||||||
form.organizer_id.choices.insert(0, (0, ''))
|
form.organizer_id.choices.insert(0, (0, ""))
|
||||||
form.event_place_id.choices.insert(0, (0, ''))
|
form.event_place_id.choices.insert(0, (0, ""))
|
||||||
|
|
||||||
|
|
||||||
def prepare_event_form_for_suggestion(form, event_suggestion):
|
def prepare_event_form_for_suggestion(form, event_suggestion):
|
||||||
form.name.data = event_suggestion.name
|
form.name.data = event_suggestion.name
|
||||||
@ -194,16 +251,22 @@ def prepare_event_form_for_suggestion(form, event_suggestion):
|
|||||||
form.organizer_choice.data = 2
|
form.organizer_choice.data = 2
|
||||||
form.new_organizer.form.name.data = event_suggestion.organizer_text
|
form.new_organizer.form.name.data = event_suggestion.organizer_text
|
||||||
|
|
||||||
def update_event_with_form(event, form, event_suggestion = None):
|
|
||||||
|
def update_event_with_form(event, form, event_suggestion=None):
|
||||||
form.populate_obj(event)
|
form.populate_obj(event)
|
||||||
event.categories = EventCategory.query.filter(EventCategory.id.in_(form.category_ids.data)).all()
|
event.categories = EventCategory.query.filter(
|
||||||
|
EventCategory.id.in_(form.category_ids.data)
|
||||||
|
).all()
|
||||||
update_event_dates_with_recurrence_rule(event, form.start.data, form.end.data)
|
update_event_dates_with_recurrence_rule(event, form.start.data, form.end.data)
|
||||||
|
|
||||||
|
|
||||||
def get_user_rights(event):
|
def get_user_rights(event):
|
||||||
return {
|
return {
|
||||||
"can_duplicate_event": has_access(event.admin_unit, 'event:create'),
|
"can_duplicate_event": has_access(event.admin_unit, "event:create"),
|
||||||
"can_verify_event": has_access(event.admin_unit, 'event:verify'),
|
"can_verify_event": has_access(event.admin_unit, "event:verify"),
|
||||||
"can_update_event": has_access(event.admin_unit, 'event:update'),
|
"can_update_event": has_access(event.admin_unit, "event:update"),
|
||||||
"can_reference_event": can_reference_event(event),
|
"can_reference_event": can_reference_event(event),
|
||||||
"can_create_reference_request": has_access(event.admin_unit, 'reference_request:create')
|
"can_create_reference_request": has_access(
|
||||||
}
|
event.admin_unit, "reference_request:create"
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|||||||
@ -1,21 +1,18 @@
|
|||||||
from project import app, db
|
from project import app
|
||||||
from project.models import Event, EventDate, EventReviewStatus
|
from project.models import EventDate
|
||||||
from flask import render_template, flash, url_for, redirect, request
|
from flask import render_template, url_for, redirect, request
|
||||||
from flask_babelex import gettext
|
from project.views.utils import flash_errors, track_analytics
|
||||||
from project.dateutils import today, date_set_end_of_day, form_input_from_date, form_input_to_date
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
from project.views.utils import flash_errors, track_analytics, get_pagination_urls
|
|
||||||
from sqlalchemy import and_, or_, not_
|
|
||||||
import json
|
import json
|
||||||
from project.jsonld import get_sd_for_event_date, DateTimeEncoder
|
from project.jsonld import get_sd_for_event_date, DateTimeEncoder
|
||||||
from project.services.event_search import EventSearchParams
|
from project.services.event_search import EventSearchParams
|
||||||
from project.services.event import get_event_dates_query
|
|
||||||
from project.forms.event_date import FindEventDateForm
|
from project.forms.event_date import FindEventDateForm
|
||||||
from project.views.event import get_event_category_choices, get_user_rights
|
from project.views.event import get_event_category_choices, get_user_rights
|
||||||
|
|
||||||
|
|
||||||
def prepare_event_date_form(form):
|
def prepare_event_date_form(form):
|
||||||
form.category_id.choices = get_event_category_choices()
|
form.category_id.choices = get_event_category_choices()
|
||||||
form.category_id.choices.insert(0, (0, ''))
|
form.category_id.choices.insert(0, (0, ""))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/eventdates")
|
@app.route("/eventdates")
|
||||||
def event_dates():
|
def event_dates():
|
||||||
@ -30,20 +27,23 @@ def event_dates():
|
|||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('event_date/list.html',
|
return render_template("event_date/list.html", form=form, params=params)
|
||||||
form=form,
|
|
||||||
params=params)
|
|
||||||
|
|
||||||
@app.route('/eventdate/<int:id>')
|
|
||||||
|
@app.route("/eventdate/<int:id>")
|
||||||
def event_date(id):
|
def event_date(id):
|
||||||
event_date = EventDate.query.get_or_404(id)
|
event_date = EventDate.query.get_or_404(id)
|
||||||
|
|
||||||
if 'src' in request.args:
|
if "src" in request.args:
|
||||||
track_analytics("event_date", str(id), request.args['src'])
|
track_analytics("event_date", str(id), request.args["src"])
|
||||||
return redirect(url_for('event_date', id=id))
|
return redirect(url_for("event_date", id=id))
|
||||||
|
|
||||||
structured_data = json.dumps(get_sd_for_event_date(event_date), indent=2, cls=DateTimeEncoder)
|
structured_data = json.dumps(
|
||||||
return render_template('event_date/read.html',
|
get_sd_for_event_date(event_date), indent=2, cls=DateTimeEncoder
|
||||||
|
)
|
||||||
|
return render_template(
|
||||||
|
"event_date/read.html",
|
||||||
event_date=event_date,
|
event_date=event_date,
|
||||||
structured_data=structured_data,
|
structured_data=structured_data,
|
||||||
user_rights = get_user_rights(event_date.event))
|
user_rights=get_user_rights(event_date.event),
|
||||||
|
)
|
||||||
|
|||||||
@ -1,19 +1,26 @@
|
|||||||
from project import app, db
|
from project import app, db
|
||||||
from project.models import EventOrganizer, EventPlace, Location
|
from project.models import EventPlace, Location
|
||||||
from flask import render_template, flash, url_for, redirect, request, jsonify
|
from flask import render_template, flash, url_for, redirect
|
||||||
from flask_babelex import gettext
|
from flask_babelex import gettext
|
||||||
from flask_security import auth_required
|
from flask_security import auth_required
|
||||||
from project.access import has_access, access_or_401, get_admin_unit_for_manage_or_404
|
from project.access import access_or_401, get_admin_unit_for_manage_or_404
|
||||||
from project.forms.event_place import UpdateEventPlaceForm, CreateEventPlaceForm, DeleteEventPlaceForm
|
from project.forms.event_place import (
|
||||||
from project.views.utils import flash_errors, upsert_image_with_data, send_mail, handleSqlError
|
UpdateEventPlaceForm,
|
||||||
from sqlalchemy.sql import asc, func
|
CreateEventPlaceForm,
|
||||||
|
DeleteEventPlaceForm,
|
||||||
|
)
|
||||||
|
from project.views.utils import (
|
||||||
|
flash_errors,
|
||||||
|
handleSqlError,
|
||||||
|
)
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>/places/create', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>/places/create", methods=("GET", "POST"))
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_places_create(id):
|
def manage_admin_unit_places_create(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
access_or_401(admin_unit, 'place:create')
|
access_or_401(admin_unit, "place:create")
|
||||||
|
|
||||||
form = CreateEventPlaceForm()
|
form = CreateEventPlaceForm()
|
||||||
|
|
||||||
@ -26,18 +33,19 @@ def manage_admin_unit_places_create(id):
|
|||||||
try:
|
try:
|
||||||
db.session.add(place)
|
db.session.add(place)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Place successfully created'), 'success')
|
flash(gettext("Place successfully created"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_event_places', id=admin_unit.id))
|
return redirect(url_for("manage_admin_unit_event_places", id=admin_unit.id))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
return render_template('event_place/create.html', form=form)
|
return render_template("event_place/create.html", form=form)
|
||||||
|
|
||||||
@app.route('/event_place/<int:id>/update', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/event_place/<int:id>/update", methods=("GET", "POST"))
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def event_place_update(id):
|
def event_place_update(id):
|
||||||
place = EventPlace.query.get_or_404(id)
|
place = EventPlace.query.get_or_404(id)
|
||||||
access_or_401(place.adminunit, 'place:update')
|
access_or_401(place.adminunit, "place:update")
|
||||||
|
|
||||||
form = UpdateEventPlaceForm(obj=place)
|
form = UpdateEventPlaceForm(obj=place)
|
||||||
|
|
||||||
@ -46,44 +54,45 @@ def event_place_update(id):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Place successfully updated'), 'success')
|
flash(gettext("Place successfully updated"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_event_places', id=place.admin_unit_id))
|
return redirect(
|
||||||
|
url_for("manage_admin_unit_event_places", id=place.admin_unit_id)
|
||||||
|
)
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
|
|
||||||
return render_template('event_place/update.html',
|
return render_template("event_place/update.html", form=form, place=place)
|
||||||
form=form,
|
|
||||||
place=place)
|
|
||||||
|
|
||||||
@app.route('/event_place/<int:id>/delete', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/event_place/<int:id>/delete", methods=("GET", "POST"))
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def event_place_delete(id):
|
def event_place_delete(id):
|
||||||
place = EventPlace.query.get_or_404(id)
|
place = EventPlace.query.get_or_404(id)
|
||||||
access_or_401(place.adminunit, 'place:delete')
|
access_or_401(place.adminunit, "place:delete")
|
||||||
|
|
||||||
form = DeleteEventPlaceForm()
|
form = DeleteEventPlaceForm()
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
if form.name.data != place.name:
|
if form.name.data != place.name:
|
||||||
flash(gettext('Entered name does not match place name'), 'danger')
|
flash(gettext("Entered name does not match place name"), "danger")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
admin_unit_id=place.admin_unit_id
|
admin_unit_id = place.admin_unit_id
|
||||||
db.session.delete(place)
|
db.session.delete(place)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Place successfully deleted'), 'success')
|
flash(gettext("Place successfully deleted"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_event_places', id=admin_unit_id))
|
return redirect(
|
||||||
|
url_for("manage_admin_unit_event_places", id=admin_unit_id)
|
||||||
|
)
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('event_place/delete.html',
|
return render_template("event_place/delete.html", form=form, place=place)
|
||||||
form=form,
|
|
||||||
place=place)
|
|
||||||
|
|
||||||
def update_event_place_with_form(place, form):
|
def update_event_place_with_form(place, form):
|
||||||
form.populate_obj(place)
|
form.populate_obj(place)
|
||||||
|
|
||||||
|
|||||||
@ -1,34 +1,39 @@
|
|||||||
from project import app, db
|
from project import app, db
|
||||||
from project.models import EventSuggestion, User, Event, EventDate, EventReviewStatus, AdminUnit, AdminUnitMember, EventOrganizer, EventCategory
|
from project.models import (
|
||||||
from flask import render_template, flash, url_for, redirect, request, jsonify, abort
|
EventSuggestion,
|
||||||
|
EventReviewStatus,
|
||||||
|
)
|
||||||
|
from flask import render_template, flash, url_for, redirect
|
||||||
from flask_babelex import gettext
|
from flask_babelex import gettext
|
||||||
from flask_security import current_user
|
from project.access import access_or_401
|
||||||
from project.access import has_access, access_or_401, can_reference_event, has_admin_unit_member_permission
|
|
||||||
from project.dateutils import today
|
|
||||||
from datetime import datetime
|
|
||||||
from project.forms.event_suggestion import RejectEventSuggestionForm
|
from project.forms.event_suggestion import RejectEventSuggestionForm
|
||||||
from project.views.utils import flash_errors, send_mail, handleSqlError, flash_message
|
from project.views.utils import flash_errors, send_mail, handleSqlError
|
||||||
from project.utils import get_event_category_name
|
|
||||||
from project.services.event import upsert_event_category, update_event_dates_with_recurrence_rule
|
|
||||||
from sqlalchemy.sql import asc, func
|
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
|
||||||
@app.route('/event_suggestion/<int:event_suggestion_id>/review')
|
|
||||||
|
@app.route("/event_suggestion/<int:event_suggestion_id>/review")
|
||||||
def event_suggestion_review(event_suggestion_id):
|
def event_suggestion_review(event_suggestion_id):
|
||||||
event_suggestion = EventSuggestion.query.get_or_404(event_suggestion_id)
|
event_suggestion = EventSuggestion.query.get_or_404(event_suggestion_id)
|
||||||
access_or_401(event_suggestion.admin_unit, 'event:verify')
|
access_or_401(event_suggestion.admin_unit, "event:verify")
|
||||||
|
|
||||||
return render_template('event_suggestion/review.html',
|
return render_template(
|
||||||
|
"event_suggestion/review.html",
|
||||||
admin_unit=event_suggestion.admin_unit,
|
admin_unit=event_suggestion.admin_unit,
|
||||||
event_suggestion=event_suggestion)
|
event_suggestion=event_suggestion,
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/event_suggestion/<int:event_suggestion_id>/reject', methods=('GET', 'POST'))
|
|
||||||
|
@app.route(
|
||||||
|
"/event_suggestion/<int:event_suggestion_id>/reject", methods=("GET", "POST")
|
||||||
|
)
|
||||||
def event_suggestion_reject(event_suggestion_id):
|
def event_suggestion_reject(event_suggestion_id):
|
||||||
event_suggestion = EventSuggestion.query.get_or_404(event_suggestion_id)
|
event_suggestion = EventSuggestion.query.get_or_404(event_suggestion_id)
|
||||||
access_or_401(event_suggestion.admin_unit, 'event:verify')
|
access_or_401(event_suggestion.admin_unit, "event:verify")
|
||||||
|
|
||||||
if event_suggestion.verified:
|
if event_suggestion.verified:
|
||||||
return redirect(url_for('event_suggestion_review', event_suggestion_id=event_suggestion.id))
|
return redirect(
|
||||||
|
url_for("event_suggestion_review", event_suggestion_id=event_suggestion.id)
|
||||||
|
)
|
||||||
|
|
||||||
form = RejectEventSuggestionForm(obj=event_suggestion)
|
form = RejectEventSuggestionForm(obj=event_suggestion)
|
||||||
|
|
||||||
@ -42,29 +47,40 @@ def event_suggestion_reject(event_suggestion_id):
|
|||||||
try:
|
try:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
send_event_suggestion_review_status_mail(event_suggestion)
|
send_event_suggestion_review_status_mail(event_suggestion)
|
||||||
flash(gettext('Event suggestion successfully rejected'), 'success')
|
flash(gettext("Event suggestion successfully rejected"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_event_reviews', id=event_suggestion.admin_unit_id))
|
return redirect(
|
||||||
|
url_for(
|
||||||
|
"manage_admin_unit_event_reviews", id=event_suggestion.admin_unit_id
|
||||||
|
)
|
||||||
|
)
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('event_suggestion/reject.html',
|
return render_template(
|
||||||
|
"event_suggestion/reject.html",
|
||||||
form=form,
|
form=form,
|
||||||
admin_unit=event_suggestion.admin_unit,
|
admin_unit=event_suggestion.admin_unit,
|
||||||
event_suggestion=event_suggestion)
|
event_suggestion=event_suggestion,
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/event_suggestion/<int:event_suggestion_id>/review_status')
|
|
||||||
|
@app.route("/event_suggestion/<int:event_suggestion_id>/review_status")
|
||||||
def event_suggestion_review_status(event_suggestion_id):
|
def event_suggestion_review_status(event_suggestion_id):
|
||||||
event_suggestion = EventSuggestion.query.get_or_404(event_suggestion_id)
|
event_suggestion = EventSuggestion.query.get_or_404(event_suggestion_id)
|
||||||
|
|
||||||
return render_template('event_suggestion/review_status.html',
|
return render_template(
|
||||||
event_suggestion=event_suggestion)
|
"event_suggestion/review_status.html", event_suggestion=event_suggestion
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def send_event_suggestion_review_status_mail(event_suggestion):
|
def send_event_suggestion_review_status_mail(event_suggestion):
|
||||||
if event_suggestion.contact_email and event_suggestion.contact_email_notice:
|
if event_suggestion.contact_email and event_suggestion.contact_email_notice:
|
||||||
send_mail(event_suggestion.contact_email,
|
send_mail(
|
||||||
gettext('Event review status updated'),
|
event_suggestion.contact_email,
|
||||||
'review_status_notice',
|
gettext("Event review status updated"),
|
||||||
event_suggestion=event_suggestion)
|
"review_status_notice",
|
||||||
|
event_suggestion=event_suggestion,
|
||||||
|
)
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
from project import app
|
from project import app
|
||||||
from project.models import Image
|
from project.models import Image
|
||||||
|
|
||||||
@app.route('/image/<int:id>')
|
|
||||||
|
@app.route("/image/<int:id>")
|
||||||
def image(id):
|
def image(id):
|
||||||
image = Image.query.get_or_404(id)
|
image = Image.query.get_or_404(id)
|
||||||
return app.response_class(image.data, mimetype=image.encoding_format)
|
return app.response_class(image.data, mimetype=image.encoding_format)
|
||||||
|
|||||||
@ -1,12 +1,36 @@
|
|||||||
from project import app, db
|
from project import app, db
|
||||||
from project.models import AdminUnit, AdminUnitMember, AdminUnitMemberInvitation, Event, EventPlace, EventReviewStatus, EventOrganizer, User, EventSuggestion
|
from project.models import (
|
||||||
from flask import render_template, flash, url_for, redirect, request, jsonify, make_response
|
AdminUnitMember,
|
||||||
|
AdminUnitMemberInvitation,
|
||||||
|
EventPlace,
|
||||||
|
EventOrganizer,
|
||||||
|
User,
|
||||||
|
EventSuggestion,
|
||||||
|
)
|
||||||
|
from flask import (
|
||||||
|
render_template,
|
||||||
|
flash,
|
||||||
|
url_for,
|
||||||
|
redirect,
|
||||||
|
request,
|
||||||
|
make_response,
|
||||||
|
)
|
||||||
from flask_babelex import gettext
|
from flask_babelex import gettext
|
||||||
from flask_security import auth_required, roles_required, current_user
|
from flask_security import auth_required, current_user
|
||||||
from project.access import has_access, access_or_401, get_admin_unit_for_manage, get_admin_units_for_manage, get_admin_unit_for_manage_or_404
|
from project.access import (
|
||||||
from sqlalchemy.sql import asc, desc, func
|
has_access,
|
||||||
from sqlalchemy import and_, or_, not_
|
get_admin_unit_for_manage,
|
||||||
from project.views.utils import get_pagination_urls, permission_missing, handleSqlError, flash_errors
|
get_admin_units_for_manage,
|
||||||
|
get_admin_unit_for_manage_or_404,
|
||||||
|
)
|
||||||
|
from sqlalchemy.sql import desc, func
|
||||||
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
from project.views.utils import (
|
||||||
|
get_pagination_urls,
|
||||||
|
permission_missing,
|
||||||
|
handleSqlError,
|
||||||
|
flash_errors,
|
||||||
|
)
|
||||||
from project.forms.event_place import FindEventPlaceForm
|
from project.forms.event_place import FindEventPlaceForm
|
||||||
from project.forms.event import FindEventForm
|
from project.forms.event import FindEventForm
|
||||||
from project.forms.admin_unit import UpdateAdminUnitWidgetForm
|
from project.forms.admin_unit import UpdateAdminUnitWidgetForm
|
||||||
@ -15,57 +39,72 @@ from project.services.event import get_events_query
|
|||||||
from project.services.event_suggestion import get_event_reviews_query
|
from project.services.event_suggestion import get_event_reviews_query
|
||||||
from project.views.event import get_event_category_choices
|
from project.views.event import get_event_category_choices
|
||||||
|
|
||||||
|
|
||||||
@app.route("/manage")
|
@app.route("/manage")
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage():
|
def manage():
|
||||||
try:
|
try:
|
||||||
if 'manage_admin_unit_id' in request.cookies:
|
if "manage_admin_unit_id" in request.cookies:
|
||||||
manage_admin_unit_id = int(request.cookies.get('manage_admin_unit_id'))
|
manage_admin_unit_id = int(request.cookies.get("manage_admin_unit_id"))
|
||||||
admin_unit = get_admin_unit_for_manage(manage_admin_unit_id)
|
admin_unit = get_admin_unit_for_manage(manage_admin_unit_id)
|
||||||
|
|
||||||
if admin_unit:
|
if admin_unit:
|
||||||
return redirect(url_for('manage_admin_unit', id=admin_unit.id))
|
return redirect(url_for("manage_admin_unit", id=admin_unit.id))
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return redirect(url_for('manage_admin_units'))
|
return redirect(url_for("manage_admin_units"))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/manage/admin_units")
|
@app.route("/manage/admin_units")
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_units():
|
def manage_admin_units():
|
||||||
admin_units = get_admin_units_for_manage()
|
admin_units = get_admin_units_for_manage()
|
||||||
invitations = AdminUnitMemberInvitation.query.filter(AdminUnitMemberInvitation.email == current_user.email).all()
|
invitations = AdminUnitMemberInvitation.query.filter(
|
||||||
|
AdminUnitMemberInvitation.email == current_user.email
|
||||||
|
).all()
|
||||||
|
|
||||||
admin_units.sort(key=lambda x: x.name)
|
admin_units.sort(key=lambda x: x.name)
|
||||||
invitations.sort(key=lambda x: x.adminunit.name)
|
invitations.sort(key=lambda x: x.adminunit.name)
|
||||||
|
|
||||||
return render_template('manage/admin_units.html',
|
return render_template(
|
||||||
invitations=invitations,
|
"manage/admin_units.html", invitations=invitations, admin_units=admin_units
|
||||||
admin_units=admin_units)
|
)
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>')
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>")
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit(id):
|
def manage_admin_unit(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
|
|
||||||
response = make_response(redirect(url_for('manage_admin_unit_events', id=admin_unit.id)))
|
response = make_response(
|
||||||
response.set_cookie('manage_admin_unit_id', str(admin_unit.id))
|
redirect(url_for("manage_admin_unit_events", id=admin_unit.id))
|
||||||
|
)
|
||||||
|
response.set_cookie("manage_admin_unit_id", str(admin_unit.id))
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>/reviews')
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>/reviews")
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_event_reviews(id):
|
def manage_admin_unit_event_reviews(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
|
|
||||||
event_suggestions_paginate = get_event_reviews_query(admin_unit).order_by(desc(EventSuggestion.created_at)).paginate()
|
event_suggestions_paginate = (
|
||||||
|
get_event_reviews_query(admin_unit)
|
||||||
|
.order_by(desc(EventSuggestion.created_at))
|
||||||
|
.paginate()
|
||||||
|
)
|
||||||
event_suggestions = event_suggestions_paginate.items
|
event_suggestions = event_suggestions_paginate.items
|
||||||
|
|
||||||
return render_template('manage/reviews.html',
|
return render_template(
|
||||||
|
"manage/reviews.html",
|
||||||
admin_unit=admin_unit,
|
admin_unit=admin_unit,
|
||||||
event_suggestions=event_suggestions,
|
event_suggestions=event_suggestions,
|
||||||
pagination = get_pagination_urls(event_suggestions_paginate, id=id))
|
pagination=get_pagination_urls(event_suggestions_paginate, id=id),
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>/events')
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>/events")
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_events(id):
|
def manage_admin_unit_events(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
@ -75,72 +114,107 @@ def manage_admin_unit_events(id):
|
|||||||
|
|
||||||
form = FindEventForm(formdata=request.args, obj=params)
|
form = FindEventForm(formdata=request.args, obj=params)
|
||||||
form.category_id.choices = get_event_category_choices()
|
form.category_id.choices = get_event_category_choices()
|
||||||
form.category_id.choices.insert(0, (0, ''))
|
form.category_id.choices.insert(0, (0, ""))
|
||||||
|
|
||||||
organizers = EventOrganizer.query.filter(EventOrganizer.admin_unit_id == admin_unit.id).order_by(func.lower(EventOrganizer.name)).all()
|
organizers = (
|
||||||
|
EventOrganizer.query.filter(EventOrganizer.admin_unit_id == admin_unit.id)
|
||||||
|
.order_by(func.lower(EventOrganizer.name))
|
||||||
|
.all()
|
||||||
|
)
|
||||||
form.organizer_id.choices = [(o.id, o.name) for o in organizers]
|
form.organizer_id.choices = [(o.id, o.name) for o in organizers]
|
||||||
form.organizer_id.choices.insert(0, (0, ''))
|
form.organizer_id.choices.insert(0, (0, ""))
|
||||||
|
|
||||||
if form.validate():
|
if form.validate():
|
||||||
form.populate_obj(params)
|
form.populate_obj(params)
|
||||||
|
|
||||||
params.admin_unit_id = admin_unit.id
|
params.admin_unit_id = admin_unit.id
|
||||||
events = get_events_query(params).paginate()
|
events = get_events_query(params).paginate()
|
||||||
return render_template('manage/events.html',
|
return render_template(
|
||||||
|
"manage/events.html",
|
||||||
admin_unit=admin_unit,
|
admin_unit=admin_unit,
|
||||||
form=form,
|
form=form,
|
||||||
events=events.items,
|
events=events.items,
|
||||||
pagination=get_pagination_urls(events, id=id))
|
pagination=get_pagination_urls(events, id=id),
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>/organizers')
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>/organizers")
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_organizers(id):
|
def manage_admin_unit_organizers(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
organizers = EventOrganizer.query.filter(EventOrganizer.admin_unit_id == admin_unit.id).order_by(func.lower(EventOrganizer.name)).paginate()
|
organizers = (
|
||||||
|
EventOrganizer.query.filter(EventOrganizer.admin_unit_id == admin_unit.id)
|
||||||
|
.order_by(func.lower(EventOrganizer.name))
|
||||||
|
.paginate()
|
||||||
|
)
|
||||||
|
|
||||||
return render_template('manage/organizers.html',
|
return render_template(
|
||||||
|
"manage/organizers.html",
|
||||||
admin_unit=admin_unit,
|
admin_unit=admin_unit,
|
||||||
organizers=organizers.items,
|
organizers=organizers.items,
|
||||||
pagination=get_pagination_urls(organizers, id=id))
|
pagination=get_pagination_urls(organizers, id=id),
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>/event_places')
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>/event_places")
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_event_places(id):
|
def manage_admin_unit_event_places(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
|
|
||||||
form = FindEventPlaceForm(**request.args)
|
form = FindEventPlaceForm(**request.args)
|
||||||
|
|
||||||
places = EventPlace.query.filter(EventPlace.admin_unit_id == admin_unit.id).order_by(func.lower(EventPlace.name)).paginate()
|
places = (
|
||||||
return render_template('manage/places.html',
|
EventPlace.query.filter(EventPlace.admin_unit_id == admin_unit.id)
|
||||||
|
.order_by(func.lower(EventPlace.name))
|
||||||
|
.paginate()
|
||||||
|
)
|
||||||
|
return render_template(
|
||||||
|
"manage/places.html",
|
||||||
admin_unit=admin_unit,
|
admin_unit=admin_unit,
|
||||||
form=form,
|
form=form,
|
||||||
places=places.items,
|
places=places.items,
|
||||||
pagination=get_pagination_urls(places, id=id))
|
pagination=get_pagination_urls(places, id=id),
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>/members')
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>/members")
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_members(id):
|
def manage_admin_unit_members(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
|
|
||||||
if not has_access(admin_unit, 'admin_unit.members:read'):
|
if not has_access(admin_unit, "admin_unit.members:read"):
|
||||||
return permission_missing(url_for('manage_admin_unit', id=id))
|
return permission_missing(url_for("manage_admin_unit", id=id))
|
||||||
|
|
||||||
members = AdminUnitMember.query.join(User).filter(AdminUnitMember.admin_unit_id == admin_unit.id).order_by(func.lower(User.email)).paginate()
|
members = (
|
||||||
invitations = AdminUnitMemberInvitation.query.filter(AdminUnitMemberInvitation.admin_unit_id == admin_unit.id).order_by(func.lower(AdminUnitMemberInvitation.email)).all()
|
AdminUnitMember.query.join(User)
|
||||||
|
.filter(AdminUnitMember.admin_unit_id == admin_unit.id)
|
||||||
|
.order_by(func.lower(User.email))
|
||||||
|
.paginate()
|
||||||
|
)
|
||||||
|
invitations = (
|
||||||
|
AdminUnitMemberInvitation.query.filter(
|
||||||
|
AdminUnitMemberInvitation.admin_unit_id == admin_unit.id
|
||||||
|
)
|
||||||
|
.order_by(func.lower(AdminUnitMemberInvitation.email))
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
return render_template('manage/members.html',
|
return render_template(
|
||||||
|
"manage/members.html",
|
||||||
admin_unit=admin_unit,
|
admin_unit=admin_unit,
|
||||||
can_invite_users=has_access(admin_unit, 'admin_unit.members:invite'),
|
can_invite_users=has_access(admin_unit, "admin_unit.members:invite"),
|
||||||
members=members.items,
|
members=members.items,
|
||||||
invitations=invitations,
|
invitations=invitations,
|
||||||
pagination=get_pagination_urls(members, id=id))
|
pagination=get_pagination_urls(members, id=id),
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>/widgets', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>/widgets", methods=("GET", "POST"))
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_widgets(id):
|
def manage_admin_unit_widgets(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
default_background_color = '#ffffff'
|
default_background_color = "#ffffff"
|
||||||
default_primary_color = '#007bff'
|
default_primary_color = "#007bff"
|
||||||
|
|
||||||
form = UpdateAdminUnitWidgetForm(obj=admin_unit)
|
form = UpdateAdminUnitWidgetForm(obj=admin_unit)
|
||||||
|
|
||||||
@ -154,8 +228,8 @@ def manage_admin_unit_widgets(id):
|
|||||||
form.widget_link_color.data = default_primary_color
|
form.widget_link_color.data = default_primary_color
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
if not has_access(admin_unit, 'admin_unit:update'):
|
if not has_access(admin_unit, "admin_unit:update"):
|
||||||
return permission_missing(url_for('manage_admin_unit', id=admin_unit.id))
|
return permission_missing(url_for("manage_admin_unit", id=admin_unit.id))
|
||||||
|
|
||||||
form.populate_obj(admin_unit)
|
form.populate_obj(admin_unit)
|
||||||
|
|
||||||
@ -170,14 +244,12 @@ def manage_admin_unit_widgets(id):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Settings successfully updated'), 'success')
|
flash(gettext("Settings successfully updated"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_widgets', id=admin_unit.id))
|
return redirect(url_for("manage_admin_unit_widgets", id=admin_unit.id))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('manage/widgets.html',
|
return render_template("manage/widgets.html", form=form, admin_unit=admin_unit)
|
||||||
form=form,
|
|
||||||
admin_unit=admin_unit)
|
|
||||||
|
|||||||
@ -1,19 +1,26 @@
|
|||||||
from project import app, db
|
from project import app, db
|
||||||
from project.models import EventOrganizer, Location
|
from project.models import EventOrganizer, Location
|
||||||
from flask import render_template, flash, url_for, redirect, request, jsonify
|
from flask import render_template, flash, url_for, redirect
|
||||||
from flask_babelex import gettext
|
from flask_babelex import gettext
|
||||||
from flask_security import auth_required
|
from flask_security import auth_required
|
||||||
from project.access import has_access, access_or_401, get_admin_unit_for_manage_or_404
|
from project.access import access_or_401, get_admin_unit_for_manage_or_404
|
||||||
from project.forms.organizer import CreateOrganizerForm, UpdateOrganizerForm, DeleteOrganizerForm
|
from project.forms.organizer import (
|
||||||
from project.views.utils import flash_errors, upsert_image_with_data, send_mail, handleSqlError
|
CreateOrganizerForm,
|
||||||
from sqlalchemy.sql import asc, func
|
UpdateOrganizerForm,
|
||||||
|
DeleteOrganizerForm,
|
||||||
|
)
|
||||||
|
from project.views.utils import (
|
||||||
|
flash_errors,
|
||||||
|
handleSqlError,
|
||||||
|
)
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>/organizers/create', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>/organizers/create", methods=("GET", "POST"))
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_organizer_create(id):
|
def manage_admin_unit_organizer_create(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
access_or_401(admin_unit, 'organizer:create')
|
access_or_401(admin_unit, "organizer:create")
|
||||||
|
|
||||||
form = CreateOrganizerForm()
|
form = CreateOrganizerForm()
|
||||||
|
|
||||||
@ -26,18 +33,21 @@ def manage_admin_unit_organizer_create(id):
|
|||||||
try:
|
try:
|
||||||
db.session.add(organizer)
|
db.session.add(organizer)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Organizer successfully created'), 'success')
|
flash(gettext("Organizer successfully created"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_organizers', id=organizer.admin_unit_id))
|
return redirect(
|
||||||
|
url_for("manage_admin_unit_organizers", id=organizer.admin_unit_id)
|
||||||
|
)
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
return render_template('organizer/create.html', form=form)
|
return render_template("organizer/create.html", form=form)
|
||||||
|
|
||||||
@app.route('/organizer/<int:id>/update', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/organizer/<int:id>/update", methods=("GET", "POST"))
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def organizer_update(id):
|
def organizer_update(id):
|
||||||
organizer = EventOrganizer.query.get_or_404(id)
|
organizer = EventOrganizer.query.get_or_404(id)
|
||||||
access_or_401(organizer.adminunit, 'organizer:update')
|
access_or_401(organizer.adminunit, "organizer:update")
|
||||||
|
|
||||||
form = UpdateOrganizerForm(obj=organizer)
|
form = UpdateOrganizerForm(obj=organizer)
|
||||||
|
|
||||||
@ -46,42 +56,44 @@ def organizer_update(id):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Organizer successfully updated'), 'success')
|
flash(gettext("Organizer successfully updated"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_organizers', id=organizer.admin_unit_id))
|
return redirect(
|
||||||
|
url_for("manage_admin_unit_organizers", id=organizer.admin_unit_id)
|
||||||
|
)
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
|
|
||||||
return render_template('organizer/update.html',
|
return render_template("organizer/update.html", form=form, organizer=organizer)
|
||||||
form=form,
|
|
||||||
organizer=organizer)
|
|
||||||
|
|
||||||
@app.route('/organizer/<int:id>/delete', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/organizer/<int:id>/delete", methods=("GET", "POST"))
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def organizer_delete(id):
|
def organizer_delete(id):
|
||||||
organizer = EventOrganizer.query.get_or_404(id)
|
organizer = EventOrganizer.query.get_or_404(id)
|
||||||
access_or_401(organizer.adminunit, 'organizer:delete')
|
access_or_401(organizer.adminunit, "organizer:delete")
|
||||||
|
|
||||||
form = DeleteOrganizerForm()
|
form = DeleteOrganizerForm()
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
if form.name.data != organizer.name:
|
if form.name.data != organizer.name:
|
||||||
flash(gettext('Entered name does not match organizer name'), 'danger')
|
flash(gettext("Entered name does not match organizer name"), "danger")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
db.session.delete(organizer)
|
db.session.delete(organizer)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Organizer successfully deleted'), 'success')
|
flash(gettext("Organizer successfully deleted"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_organizers', id=organizer.admin_unit_id))
|
return redirect(
|
||||||
|
url_for("manage_admin_unit_organizers", id=organizer.admin_unit_id)
|
||||||
|
)
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('organizer/delete.html',
|
return render_template("organizer/delete.html", form=form, organizer=organizer)
|
||||||
form=form,
|
|
||||||
organizer=organizer)
|
|
||||||
|
|
||||||
def update_organizer_with_form(organizer, form):
|
def update_organizer_with_form(organizer, form):
|
||||||
form.populate_obj(organizer)
|
form.populate_obj(organizer)
|
||||||
|
|||||||
@ -1,21 +1,14 @@
|
|||||||
from project import app, db
|
from project import app
|
||||||
from project.models import Event, EventDate, EventReviewStatus
|
from flask import render_template, request
|
||||||
from flask import render_template, flash, url_for, redirect, request
|
|
||||||
from flask_babelex import gettext
|
|
||||||
from project.dateutils import today, date_set_end_of_day, form_input_from_date, form_input_to_date
|
|
||||||
from dateutil.relativedelta import relativedelta
|
|
||||||
from project.views.utils import flash_errors, track_analytics, get_pagination_urls
|
|
||||||
from sqlalchemy import and_, or_, not_
|
|
||||||
import json
|
|
||||||
from project.jsonld import get_sd_for_event_date, DateTimeEncoder
|
|
||||||
from project.services.event_search import EventSearchParams
|
from project.services.event_search import EventSearchParams
|
||||||
from project.services.event import get_event_dates_query
|
|
||||||
from project.forms.planing import PlaningForm
|
from project.forms.planing import PlaningForm
|
||||||
from project.views.event import get_event_category_choices
|
from project.views.event import get_event_category_choices
|
||||||
|
|
||||||
|
|
||||||
def prepare_event_date_form(form):
|
def prepare_event_date_form(form):
|
||||||
form.category_id.choices = get_event_category_choices()
|
form.category_id.choices = get_event_category_choices()
|
||||||
form.category_id.choices.insert(0, (0, ''))
|
form.category_id.choices.insert(0, (0, ""))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/planing")
|
@app.route("/planing")
|
||||||
def planing():
|
def planing():
|
||||||
@ -25,6 +18,4 @@ def planing():
|
|||||||
form = PlaningForm(formdata=request.args, obj=params)
|
form = PlaningForm(formdata=request.args, obj=params)
|
||||||
prepare_event_date_form(form)
|
prepare_event_date_form(form)
|
||||||
|
|
||||||
return render_template('planing/list.html',
|
return render_template("planing/list.html", form=form, params=params)
|
||||||
form=form,
|
|
||||||
params=params)
|
|
||||||
|
|||||||
@ -1,7 +1,14 @@
|
|||||||
from project import app, db
|
from project import app, db
|
||||||
from project.views.utils import get_pagination_urls, flash_errors, handleSqlError
|
from project.views.utils import get_pagination_urls, flash_errors, handleSqlError
|
||||||
from project.access import get_admin_unit_for_manage_or_404, get_admin_units_for_event_reference
|
from project.access import (
|
||||||
from project.forms.reference import CreateEventReferenceForm, UpdateEventReferenceForm, DeleteReferenceForm
|
get_admin_unit_for_manage_or_404,
|
||||||
|
get_admin_units_for_event_reference,
|
||||||
|
)
|
||||||
|
from project.forms.reference import (
|
||||||
|
CreateEventReferenceForm,
|
||||||
|
UpdateEventReferenceForm,
|
||||||
|
DeleteReferenceForm,
|
||||||
|
)
|
||||||
from flask import render_template, flash, redirect, url_for, abort
|
from flask import render_template, flash, redirect, url_for, abort
|
||||||
from flask_babelex import gettext
|
from flask_babelex import gettext
|
||||||
from flask_security import auth_required
|
from flask_security import auth_required
|
||||||
@ -10,7 +17,8 @@ from project.access import access_or_401, can_reference_event
|
|||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
from sqlalchemy.sql import desc
|
from sqlalchemy.sql import desc
|
||||||
|
|
||||||
@app.route('/event/<int:event_id>/reference', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/event/<int:event_id>/reference", methods=("GET", "POST"))
|
||||||
def event_reference(event_id):
|
def event_reference(event_id):
|
||||||
event = Event.query.get_or_404(event_id)
|
event = Event.query.get_or_404(event_id)
|
||||||
user_can_reference_event = can_reference_event(event)
|
user_can_reference_event = can_reference_event(event)
|
||||||
@ -19,7 +27,13 @@ def event_reference(event_id):
|
|||||||
abort(401)
|
abort(401)
|
||||||
|
|
||||||
form = CreateEventReferenceForm()
|
form = CreateEventReferenceForm()
|
||||||
form.admin_unit_id.choices = sorted([(admin_unit.id, admin_unit.name) for admin_unit in get_admin_units_for_event_reference(event)], key=lambda admin_unit: admin_unit[1])
|
form.admin_unit_id.choices = sorted(
|
||||||
|
[
|
||||||
|
(admin_unit.id, admin_unit.name)
|
||||||
|
for admin_unit in get_admin_units_for_event_reference(event)
|
||||||
|
],
|
||||||
|
key=lambda admin_unit: admin_unit[1],
|
||||||
|
)
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
reference = EventReference()
|
reference = EventReference()
|
||||||
@ -29,22 +43,21 @@ def event_reference(event_id):
|
|||||||
try:
|
try:
|
||||||
db.session.add(reference)
|
db.session.add(reference)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Event successfully referenced'), 'success')
|
flash(gettext("Event successfully referenced"), "success")
|
||||||
return redirect(url_for('event', event_id=event.id))
|
return redirect(url_for("event", event_id=event.id))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('event/reference.html',
|
return render_template("event/reference.html", form=form, event=event)
|
||||||
form=form,
|
|
||||||
event=event)
|
|
||||||
|
|
||||||
@app.route('/reference/<int:id>/update', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/reference/<int:id>/update", methods=("GET", "POST"))
|
||||||
def event_reference_update(id):
|
def event_reference_update(id):
|
||||||
reference = EventReference.query.get_or_404(id)
|
reference = EventReference.query.get_or_404(id)
|
||||||
access_or_401(reference.admin_unit, 'reference:update')
|
access_or_401(reference.admin_unit, "reference:update")
|
||||||
|
|
||||||
form = UpdateEventReferenceForm(obj=reference)
|
form = UpdateEventReferenceForm(obj=reference)
|
||||||
|
|
||||||
@ -53,62 +66,83 @@ def event_reference_update(id):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Reference successfully updated'), 'success')
|
flash(gettext("Reference successfully updated"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_references_incoming', id=reference.admin_unit_id))
|
return redirect(
|
||||||
|
url_for(
|
||||||
|
"manage_admin_unit_references_incoming", id=reference.admin_unit_id
|
||||||
|
)
|
||||||
|
)
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('reference/update.html',
|
return render_template("reference/update.html", form=form, reference=reference)
|
||||||
form=form,
|
|
||||||
reference=reference)
|
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>/references/incoming')
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>/references/incoming")
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_references_incoming(id):
|
def manage_admin_unit_references_incoming(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
references = EventReference.query.filter(EventReference.admin_unit_id == admin_unit.id).order_by(desc(EventReference.created_at)).paginate()
|
references = (
|
||||||
|
EventReference.query.filter(EventReference.admin_unit_id == admin_unit.id)
|
||||||
|
.order_by(desc(EventReference.created_at))
|
||||||
|
.paginate()
|
||||||
|
)
|
||||||
|
|
||||||
return render_template('manage/references_incoming.html',
|
return render_template(
|
||||||
|
"manage/references_incoming.html",
|
||||||
admin_unit=admin_unit,
|
admin_unit=admin_unit,
|
||||||
references=references.items,
|
references=references.items,
|
||||||
pagination=get_pagination_urls(references, id=id))
|
pagination=get_pagination_urls(references, id=id),
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>/references/outgoing')
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>/references/outgoing")
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_references_outgoing(id):
|
def manage_admin_unit_references_outgoing(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
references = EventReference.query.join(Event).filter(Event.admin_unit_id == admin_unit.id).order_by(desc(EventReference.created_at)).paginate()
|
references = (
|
||||||
|
EventReference.query.join(Event)
|
||||||
|
.filter(Event.admin_unit_id == admin_unit.id)
|
||||||
|
.order_by(desc(EventReference.created_at))
|
||||||
|
.paginate()
|
||||||
|
)
|
||||||
|
|
||||||
return render_template('manage/references_outgoing.html',
|
return render_template(
|
||||||
|
"manage/references_outgoing.html",
|
||||||
admin_unit=admin_unit,
|
admin_unit=admin_unit,
|
||||||
references=references.items,
|
references=references.items,
|
||||||
pagination=get_pagination_urls(references, id=id))
|
pagination=get_pagination_urls(references, id=id),
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/reference/<int:id>/delete', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/reference/<int:id>/delete", methods=("GET", "POST"))
|
||||||
def reference_delete(id):
|
def reference_delete(id):
|
||||||
reference = EventReference.query.get_or_404(id)
|
reference = EventReference.query.get_or_404(id)
|
||||||
access_or_401(reference.admin_unit, 'reference:delete')
|
access_or_401(reference.admin_unit, "reference:delete")
|
||||||
|
|
||||||
form = DeleteReferenceForm()
|
form = DeleteReferenceForm()
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
if form.name.data != reference.event.name:
|
if form.name.data != reference.event.name:
|
||||||
flash(gettext('Entered name does not match event name'), 'danger')
|
flash(gettext("Entered name does not match event name"), "danger")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
db.session.delete(reference)
|
db.session.delete(reference)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash(gettext('Reference successfully deleted'), 'success')
|
flash(gettext("Reference successfully deleted"), "success")
|
||||||
return redirect(url_for('manage_admin_unit_references_incoming', id=reference.admin_unit_id))
|
return redirect(
|
||||||
|
url_for(
|
||||||
|
"manage_admin_unit_references_incoming",
|
||||||
|
id=reference.admin_unit_id,
|
||||||
|
)
|
||||||
|
)
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('reference/delete.html',
|
return render_template("reference/delete.html", form=form, reference=reference)
|
||||||
form=form,
|
|
||||||
reference=reference)
|
|
||||||
|
|||||||
@ -1,45 +1,79 @@
|
|||||||
from project import app, db
|
from project import app, db
|
||||||
from project.views.utils import get_pagination_urls, flash_errors, handleSqlError, send_mail
|
from project.views.utils import (
|
||||||
from project.forms.reference_request import CreateEventReferenceRequestForm, DeleteReferenceRequestForm
|
get_pagination_urls,
|
||||||
|
flash_errors,
|
||||||
|
handleSqlError,
|
||||||
|
send_mail,
|
||||||
|
)
|
||||||
|
from project.forms.reference_request import CreateEventReferenceRequestForm
|
||||||
from flask import render_template, flash, redirect, url_for
|
from flask import render_template, flash, redirect, url_for
|
||||||
from flask_babelex import gettext
|
from flask_babelex import gettext
|
||||||
from flask_security import auth_required
|
from flask_security import auth_required
|
||||||
from project.models import EventReferenceRequest, Event, AdminUnit, AdminUnitMember, User, EventReferenceRequestReviewStatus
|
from project.models import (
|
||||||
from project.access import access_or_401, get_admin_unit_for_manage_or_404, has_admin_unit_member_permission
|
EventReferenceRequest,
|
||||||
|
Event,
|
||||||
|
AdminUnit,
|
||||||
|
AdminUnitMember,
|
||||||
|
User,
|
||||||
|
EventReferenceRequestReviewStatus,
|
||||||
|
)
|
||||||
|
from project.access import (
|
||||||
|
access_or_401,
|
||||||
|
get_admin_unit_for_manage_or_404,
|
||||||
|
has_admin_unit_member_permission,
|
||||||
|
)
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
from sqlalchemy import and_, or_, not_
|
|
||||||
from sqlalchemy.sql import desc
|
from sqlalchemy.sql import desc
|
||||||
from project.services.reference import get_reference_requests_incoming_query
|
from project.services.reference import get_reference_requests_incoming_query
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>/reference_requests/incoming')
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>/reference_requests/incoming")
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_reference_requests_incoming(id):
|
def manage_admin_unit_reference_requests_incoming(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
requests = get_reference_requests_incoming_query(admin_unit).order_by(desc(EventReferenceRequest.created_at)).paginate()
|
requests = (
|
||||||
|
get_reference_requests_incoming_query(admin_unit)
|
||||||
|
.order_by(desc(EventReferenceRequest.created_at))
|
||||||
|
.paginate()
|
||||||
|
)
|
||||||
|
|
||||||
return render_template('manage/reference_requests_incoming.html',
|
return render_template(
|
||||||
|
"manage/reference_requests_incoming.html",
|
||||||
admin_unit=admin_unit,
|
admin_unit=admin_unit,
|
||||||
requests=requests.items,
|
requests=requests.items,
|
||||||
pagination=get_pagination_urls(requests, id=id))
|
pagination=get_pagination_urls(requests, id=id),
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/manage/admin_unit/<int:id>/reference_requests/outgoing')
|
|
||||||
|
@app.route("/manage/admin_unit/<int:id>/reference_requests/outgoing")
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def manage_admin_unit_reference_requests_outgoing(id):
|
def manage_admin_unit_reference_requests_outgoing(id):
|
||||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||||
requests = EventReferenceRequest.query.join(Event).filter(Event.admin_unit_id == admin_unit.id).order_by(desc(EventReferenceRequest.created_at)).paginate()
|
requests = (
|
||||||
|
EventReferenceRequest.query.join(Event)
|
||||||
|
.filter(Event.admin_unit_id == admin_unit.id)
|
||||||
|
.order_by(desc(EventReferenceRequest.created_at))
|
||||||
|
.paginate()
|
||||||
|
)
|
||||||
|
|
||||||
return render_template('manage/reference_requests_outgoing.html',
|
return render_template(
|
||||||
|
"manage/reference_requests_outgoing.html",
|
||||||
admin_unit=admin_unit,
|
admin_unit=admin_unit,
|
||||||
requests=requests.items,
|
requests=requests.items,
|
||||||
pagination=get_pagination_urls(requests, id=id))
|
pagination=get_pagination_urls(requests, id=id),
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/event/<int:event_id>/reference_request/create', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/event/<int:event_id>/reference_request/create", methods=("GET", "POST"))
|
||||||
def event_reference_request_create(event_id):
|
def event_reference_request_create(event_id):
|
||||||
event = Event.query.get_or_404(event_id)
|
event = Event.query.get_or_404(event_id)
|
||||||
access_or_401(event.admin_unit, 'reference_request:create')
|
access_or_401(event.admin_unit, "reference_request:create")
|
||||||
|
|
||||||
form = CreateEventReferenceRequestForm()
|
form = CreateEventReferenceRequestForm()
|
||||||
form.admin_unit_id.choices = sorted([(admin_unit.id, admin_unit.name) for admin_unit in AdminUnit.query.all()], key=lambda admin_unit: admin_unit[1])
|
form.admin_unit_id.choices = sorted(
|
||||||
|
[(admin_unit.id, admin_unit.name) for admin_unit in AdminUnit.query.all()],
|
||||||
|
key=lambda admin_unit: admin_unit[1],
|
||||||
|
)
|
||||||
|
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
request = EventReferenceRequest()
|
request = EventReferenceRequest()
|
||||||
@ -51,25 +85,30 @@ def event_reference_request_create(event_id):
|
|||||||
db.session.add(request)
|
db.session.add(request)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
send_reference_request_inbox_mails(request)
|
send_reference_request_inbox_mails(request)
|
||||||
flash(gettext('Request successfully created'), 'success')
|
flash(gettext("Request successfully created"), "success")
|
||||||
return redirect(url_for('event', event_id=event.id))
|
return redirect(url_for("event", event_id=event.id))
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
return render_template('event/reference_request.html',
|
return render_template("event/reference_request.html", form=form, event=event)
|
||||||
form=form,
|
|
||||||
event=event)
|
|
||||||
|
|
||||||
def send_reference_request_inbox_mails(request):
|
def send_reference_request_inbox_mails(request):
|
||||||
# Benachrichtige alle Mitglieder der AdminUnit, die diesen Request verifizieren können
|
# Benachrichtige alle Mitglieder der AdminUnit, die diesen Request verifizieren können
|
||||||
members = AdminUnitMember.query.join(User).filter(AdminUnitMember.admin_unit_id == request.admin_unit_id).all()
|
members = (
|
||||||
|
AdminUnitMember.query.join(User)
|
||||||
|
.filter(AdminUnitMember.admin_unit_id == request.admin_unit_id)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
for member in members:
|
for member in members:
|
||||||
if has_admin_unit_member_permission(member, 'reference_request:verify'):
|
if has_admin_unit_member_permission(member, "reference_request:verify"):
|
||||||
send_mail(member.user.email,
|
send_mail(
|
||||||
gettext('New reference request'),
|
member.user.email,
|
||||||
'reference_request_notice',
|
gettext("New reference request"),
|
||||||
request=request)
|
"reference_request_notice",
|
||||||
|
request=request,
|
||||||
|
)
|
||||||
|
|||||||
@ -1,23 +1,38 @@
|
|||||||
from project import app, db
|
from project import app, db
|
||||||
from project.models import Event, EventDate, EventReferenceRequest, EventReferenceRequestReviewStatus, AdminUnitMember, User
|
from project.models import (
|
||||||
|
EventDate,
|
||||||
|
EventReferenceRequest,
|
||||||
|
EventReferenceRequestReviewStatus,
|
||||||
|
AdminUnitMember,
|
||||||
|
User,
|
||||||
|
)
|
||||||
from flask import render_template, flash, url_for, redirect, abort
|
from flask import render_template, flash, url_for, redirect, abort
|
||||||
from flask_babelex import gettext
|
from flask_babelex import gettext
|
||||||
from flask_security import auth_required
|
from project.access import (
|
||||||
from project.access import has_access, access_or_401, can_reference_event, has_admin_unit_member_permission
|
has_access,
|
||||||
|
access_or_401,
|
||||||
|
has_admin_unit_member_permission,
|
||||||
|
)
|
||||||
from project.dateutils import today
|
from project.dateutils import today
|
||||||
from project.forms.reference_request import ReferenceRequestReviewForm
|
from project.forms.reference_request import ReferenceRequestReviewForm
|
||||||
from project.views.utils import flash_errors, send_mail, handleSqlError
|
from project.views.utils import flash_errors, send_mail, handleSqlError
|
||||||
from project.services.reference import create_event_reference_for_request
|
from project.services.reference import create_event_reference_for_request
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
|
||||||
@app.route('/reference_request/<int:id>/review', methods=('GET', 'POST'))
|
|
||||||
|
@app.route("/reference_request/<int:id>/review", methods=("GET", "POST"))
|
||||||
def event_reference_request_review(id):
|
def event_reference_request_review(id):
|
||||||
request = EventReferenceRequest.query.get_or_404(id)
|
request = EventReferenceRequest.query.get_or_404(id)
|
||||||
access_or_401(request.admin_unit, 'reference_request:verify')
|
access_or_401(request.admin_unit, "reference_request:verify")
|
||||||
|
|
||||||
if request.review_status == EventReferenceRequestReviewStatus.verified:
|
if request.review_status == EventReferenceRequestReviewStatus.verified:
|
||||||
flash(gettext('Request already verified'), 'danger')
|
flash(gettext("Request already verified"), "danger")
|
||||||
return redirect(url_for('manage_admin_unit_reference_requests_incoming', id=request.admin_unit_id))
|
return redirect(
|
||||||
|
url_for(
|
||||||
|
"manage_admin_unit_reference_requests_incoming",
|
||||||
|
id=request.admin_unit_id,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
form = ReferenceRequestReviewForm(obj=request)
|
form = ReferenceRequestReviewForm(obj=request)
|
||||||
|
|
||||||
@ -34,45 +49,69 @@ def event_reference_request_review(id):
|
|||||||
if request.review_status == EventReferenceRequestReviewStatus.verified:
|
if request.review_status == EventReferenceRequestReviewStatus.verified:
|
||||||
reference = create_event_reference_for_request(request)
|
reference = create_event_reference_for_request(request)
|
||||||
reference.rating = form.rating.data
|
reference.rating = form.rating.data
|
||||||
msg = gettext('Request successfully updated')
|
msg = gettext("Request successfully updated")
|
||||||
else:
|
else:
|
||||||
msg = gettext('Reference successfully created')
|
msg = gettext("Reference successfully created")
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
send_reference_request_review_status_mails(request)
|
send_reference_request_review_status_mails(request)
|
||||||
flash(msg, 'success')
|
flash(msg, "success")
|
||||||
return redirect(url_for('manage_admin_unit_reference_requests_incoming', id=request.admin_unit_id))
|
return redirect(
|
||||||
|
url_for(
|
||||||
|
"manage_admin_unit_reference_requests_incoming",
|
||||||
|
id=request.admin_unit_id,
|
||||||
|
)
|
||||||
|
)
|
||||||
except SQLAlchemyError as e:
|
except SQLAlchemyError as e:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash(handleSqlError(e), 'danger')
|
flash(handleSqlError(e), "danger")
|
||||||
else:
|
else:
|
||||||
flash_errors(form)
|
flash_errors(form)
|
||||||
|
|
||||||
dates = EventDate.query.with_parent(request.event).filter(EventDate.start >= today).order_by(EventDate.start).all()
|
dates = (
|
||||||
return render_template('reference_request/review.html',
|
EventDate.query.with_parent(request.event)
|
||||||
|
.filter(EventDate.start >= today)
|
||||||
|
.order_by(EventDate.start)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
return render_template(
|
||||||
|
"reference_request/review.html",
|
||||||
form=form,
|
form=form,
|
||||||
dates=dates,
|
dates=dates,
|
||||||
request=request,
|
request=request,
|
||||||
event=request.event)
|
event=request.event,
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/reference_request/<int:id>/review_status')
|
|
||||||
|
@app.route("/reference_request/<int:id>/review_status")
|
||||||
def event_reference_request_review_status(id):
|
def event_reference_request_review_status(id):
|
||||||
request = EventReferenceRequest.query.get_or_404(id)
|
request = EventReferenceRequest.query.get_or_404(id)
|
||||||
|
|
||||||
if not has_access(request.admin_unit, 'reference_request:verify') and not has_access(request.event.admin_unit, 'reference_request:create'):
|
if not has_access(
|
||||||
|
request.admin_unit, "reference_request:verify"
|
||||||
|
) and not has_access(request.event.admin_unit, "reference_request:create"):
|
||||||
abort(401)
|
abort(401)
|
||||||
|
|
||||||
return render_template('reference_request/review_status.html',
|
return render_template(
|
||||||
|
"reference_request/review_status.html",
|
||||||
reference_request=request,
|
reference_request=request,
|
||||||
event=request.event)
|
event=request.event,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def send_reference_request_review_status_mails(request):
|
def send_reference_request_review_status_mails(request):
|
||||||
# Benachrichtige alle Mitglieder der AdminUnit, die diesen Request erstellt hatte
|
# Benachrichtige alle Mitglieder der AdminUnit, die diesen Request erstellt hatte
|
||||||
members = AdminUnitMember.query.join(User).filter(AdminUnitMember.admin_unit_id == request.event.admin_unit_id).all()
|
members = (
|
||||||
|
AdminUnitMember.query.join(User)
|
||||||
|
.filter(AdminUnitMember.admin_unit_id == request.event.admin_unit_id)
|
||||||
|
.all()
|
||||||
|
)
|
||||||
|
|
||||||
for member in members:
|
for member in members:
|
||||||
if has_admin_unit_member_permission(member, 'reference_request:create'):
|
if has_admin_unit_member_permission(member, "reference_request:create"):
|
||||||
send_mail(member.user.email,
|
send_mail(
|
||||||
gettext('Event review status updated'),
|
member.user.email,
|
||||||
'reference_request_review_status_notice',
|
gettext("Event review status updated"),
|
||||||
request=request)
|
"reference_request_review_status_notice",
|
||||||
|
request=request,
|
||||||
|
)
|
||||||
|
|||||||
@ -2,26 +2,31 @@ from project import app
|
|||||||
from project.views.utils import track_analytics
|
from project.views.utils import track_analytics
|
||||||
from flask import url_for, render_template, request, redirect
|
from flask import url_for, render_template, request, redirect
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def home():
|
def home():
|
||||||
if 'src' in request.args:
|
if "src" in request.args:
|
||||||
track_analytics("home", '', request.args['src'])
|
track_analytics("home", "", request.args["src"])
|
||||||
return redirect(url_for('home'))
|
return redirect(url_for("home"))
|
||||||
|
|
||||||
|
return render_template("home.html")
|
||||||
|
|
||||||
return render_template('home.html')
|
|
||||||
|
|
||||||
@app.route("/example")
|
@app.route("/example")
|
||||||
def example():
|
def example():
|
||||||
return render_template('example.html')
|
return render_template("example.html")
|
||||||
|
|
||||||
|
|
||||||
@app.route("/impressum")
|
@app.route("/impressum")
|
||||||
def impressum():
|
def impressum():
|
||||||
return render_template('impressum.html')
|
return render_template("impressum.html")
|
||||||
|
|
||||||
|
|
||||||
@app.route("/datenschutz")
|
@app.route("/datenschutz")
|
||||||
def datenschutz():
|
def datenschutz():
|
||||||
return render_template('datenschutz.html')
|
return render_template("datenschutz.html")
|
||||||
|
|
||||||
|
|
||||||
@app.route("/developer")
|
@app.route("/developer")
|
||||||
def developer():
|
def developer():
|
||||||
return render_template('developer/read.html')
|
return render_template("developer/read.html")
|
||||||
|
|||||||
@ -3,12 +3,15 @@ from project.models import AdminUnitMember, AdminUnitMemberInvitation
|
|||||||
from flask import render_template
|
from flask import render_template
|
||||||
from flask_security import auth_required, current_user
|
from flask_security import auth_required, current_user
|
||||||
|
|
||||||
|
|
||||||
@app.route("/profile")
|
@app.route("/profile")
|
||||||
@auth_required()
|
@auth_required()
|
||||||
def profile():
|
def profile():
|
||||||
admin_unit_members = AdminUnitMember.query.filter_by(user_id = current_user.id).all()
|
admin_unit_members = AdminUnitMember.query.filter_by(user_id=current_user.id).all()
|
||||||
invitations = AdminUnitMemberInvitation.query.filter(AdminUnitMemberInvitation.email == current_user.email).all()
|
invitations = AdminUnitMemberInvitation.query.filter(
|
||||||
|
AdminUnitMemberInvitation.email == current_user.email
|
||||||
|
).all()
|
||||||
|
|
||||||
return render_template('profile.html',
|
return render_template(
|
||||||
admin_unit_members=admin_unit_members,
|
"profile.html", admin_unit_members=admin_unit_members, invitations=invitations
|
||||||
invitations=invitations)
|
)
|
||||||
|
|||||||
@ -4,8 +4,9 @@ from flask_babelex import gettext
|
|||||||
from flask import request, url_for, render_template, flash, redirect, Markup
|
from flask import request, url_for, render_template, flash, redirect, Markup
|
||||||
from flask_mail import Message
|
from flask_mail import Message
|
||||||
|
|
||||||
|
|
||||||
def track_analytics(key, value1, value2):
|
def track_analytics(key, value1, value2):
|
||||||
result = Analytics(key = key, value1 = value1)
|
result = Analytics(key=key, value1=value1)
|
||||||
|
|
||||||
if value2 is not None:
|
if value2 is not None:
|
||||||
result.value2 = value2
|
result.value2 = value2
|
||||||
@ -15,12 +16,14 @@ def track_analytics(key, value1, value2):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def handleSqlError(e):
|
def handleSqlError(e):
|
||||||
message = str(e.__dict__['orig'])
|
message = str(e.__dict__["orig"])
|
||||||
print(message)
|
print(message)
|
||||||
return message
|
return message
|
||||||
|
|
||||||
def upsert_image_with_data(image, data, encoding_format = "image/jpeg"):
|
|
||||||
|
def upsert_image_with_data(image, data, encoding_format="image/jpeg"):
|
||||||
if image is None:
|
if image is None:
|
||||||
image = Image()
|
image = Image()
|
||||||
|
|
||||||
@ -29,6 +32,7 @@ def upsert_image_with_data(image, data, encoding_format = "image/jpeg"):
|
|||||||
|
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
|
||||||
def get_pagination_urls(pagination, **kwargs):
|
def get_pagination_urls(pagination, **kwargs):
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
@ -47,28 +51,34 @@ def get_pagination_urls(pagination, **kwargs):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def flash_errors(form):
|
def flash_errors(form):
|
||||||
for field, errors in form.errors.items():
|
for field, errors in form.errors.items():
|
||||||
for error in errors:
|
for error in errors:
|
||||||
flash(gettext("Error in the %s field - %s") % (
|
flash(
|
||||||
getattr(form, field).label.text,
|
gettext("Error in the %s field - %s")
|
||||||
error
|
% (getattr(form, field).label.text, error),
|
||||||
), 'danger')
|
"danger",
|
||||||
|
)
|
||||||
|
|
||||||
def flash_message(msg, url, link_text = None, category = 'success'):
|
|
||||||
|
def flash_message(msg, url, link_text=None, category="success"):
|
||||||
if not link_text:
|
if not link_text:
|
||||||
link_text = gettext('Show')
|
link_text = gettext("Show")
|
||||||
link = ' – <a href="%s">%s</a>' % (url, link_text)
|
link = ' – <a href="%s">%s</a>' % (url, link_text)
|
||||||
message = Markup(msg + link)
|
message = Markup(msg + link)
|
||||||
flash(message, category)
|
flash(message, category)
|
||||||
|
|
||||||
|
|
||||||
def permission_missing(redirect_location):
|
def permission_missing(redirect_location):
|
||||||
flash('You do not have permission for this action', 'danger')
|
flash("You do not have permission for this action", "danger")
|
||||||
return redirect(redirect_location)
|
return redirect(redirect_location)
|
||||||
|
|
||||||
|
|
||||||
def send_mail(recipient, subject, template, **context):
|
def send_mail(recipient, subject, template, **context):
|
||||||
send_mails([recipient], subject, template, **context)
|
send_mails([recipient], subject, template, **context)
|
||||||
|
|
||||||
|
|
||||||
def send_mails(recipients, subject, template, **context):
|
def send_mails(recipients, subject, template, **context):
|
||||||
msg = Message(subject)
|
msg = Message(subject)
|
||||||
msg.recipients = recipients
|
msg.recipients = recipients
|
||||||
@ -80,4 +90,4 @@ def send_mails(recipients, subject, template, **context):
|
|||||||
print(msg.body)
|
print(msg.body)
|
||||||
return
|
return
|
||||||
|
|
||||||
mail.send(msg)
|
mail.send(msg)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user