Vowel is a Virtual Online Workspace for Education and Learning.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

160 lines
4.1 KiB

  1. #!/usr/bin/env python3
  2. # coding=utf-8
  3. #
  4. # run.py: Run vowel
  5. # Copyright (C) 2015, 2017 Sam Black <samwwwblack@lapwing.org>
  6. #
  7. # This program is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU Affero General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU Affero General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Affero General Public License
  18. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. #
  20. import eventlet
  21. eventlet.monkey_patch() # noqa
  22. import sys
  23. import click
  24. from flask_migrate import upgrade as db_upgrade
  25. from sqlalchemy_utils.functions import create_database
  26. from sqlalchemy_utils.functions import database_exists
  27. from vowel.models import db
  28. from vowel.utils.user import AddUserError
  29. from vowel.utils.user import add_user
  30. from vowel.utils.user import check_email_validity
  31. from vowel.utils.user import create_default_roles
  32. from vowel.web import create_app
  33. app = create_app()
  34. def _check_db_exists():
  35. """
  36. Check if the database exists.
  37. :return: True if DB exists, False otherwise
  38. :rtype: bool
  39. """
  40. db_url = app.config["SQLALCHEMY_DATABASE_URI"]
  41. return database_exists(db_url)
  42. def _check_db_tables_exist():
  43. """
  44. Check if the database exists and has tables.
  45. :return: True if the DB exists and has tables, False otherwise
  46. :rtype: bool
  47. """
  48. return _check_db_exists() and db.engine.dialect.has_table(db.engine,
  49. "user")
  50. def _init_db():
  51. """
  52. Create the database, tables and required starting data.
  53. """
  54. db_url = app.config["SQLALCHEMY_DATABASE_URI"]
  55. if db_url.startswith("postgres://"):
  56. click.echo(
  57. ("'SQLALCHEMY_DATABASE_URI' must start with 'postgresql://', "
  58. "not 'postgres://'; please update your instance config."))
  59. sys.exit(1)
  60. if not _check_db_exists():
  61. create_database(db_url)
  62. if _check_db_tables_exist():
  63. click.echo("Database already exists.")
  64. click.echo("Please check your installation.")
  65. sys.exit(1)
  66. db_upgrade()
  67. create_default_roles()
  68. db.session.commit()
  69. @app.cli.command()
  70. def init_db():
  71. """
  72. Create the database and populate the required data.
  73. """
  74. _init_db()
  75. @app.cli.command()
  76. def create_user():
  77. """
  78. Create a new user.
  79. """
  80. if not _check_db_tables_exist():
  81. click.echo("Database does not exist yet.")
  82. click.echo("Please check your installation, "
  83. "or run 'FLASK_APP=run.py flask first_run'")
  84. sys.exit(1)
  85. email = None
  86. while not email:
  87. email_tmp = click.prompt("Email")
  88. try:
  89. check_email_validity(email_tmp)
  90. except AddUserError:
  91. click.echo("Email is invalid")
  92. else:
  93. email = email_tmp
  94. password = None
  95. while not password:
  96. password = click.prompt("Password", hide_input=True,
  97. confirmation_prompt=True)
  98. admin = click.confirm("Administrator?")
  99. roles = ("Admin",) if admin else ()
  100. add_user(email, password, roles)
  101. click.echo("User added")
  102. @app.cli.command()
  103. def first_run():
  104. """
  105. Init the database and
  106. query the user for an administrator email/password.
  107. """
  108. _init_db()
  109. email = None
  110. while not email:
  111. email_tmp = click.prompt("Administrator email")
  112. try:
  113. check_email_validity(email_tmp)
  114. except AddUserError:
  115. click.echo("Email is invalid")
  116. else:
  117. email = email_tmp
  118. password = None
  119. while not password:
  120. password = click.prompt("Administrator Password",
  121. hide_input=True, confirmation_prompt=True)
  122. add_user(email, password, ("Admin",), True)
  123. click.echo("Setup complete")