manage.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. """
  2. flaskbb.manage
  3. ~~~~~~~~~~~~~~~~~~~~
  4. This script provides some easy to use commands for
  5. creating the database with or without some sample content.
  6. You can also run the development server with it.
  7. Just type `python manage.py` to see the full list of commands.
  8. TODO: When Flask 1.0 is released, get rid of Flask-Script and use click.
  9. Then it's also possible to split the commands in "command groups"
  10. which would make the commands better seperated from each other
  11. and less confusing.
  12. :copyright: (c) 2014 by the FlaskBB Team.
  13. :license: BSD, see LICENSE for more details.
  14. """
  15. import sys
  16. import os
  17. import subprocess
  18. from flask import current_app
  19. from werkzeug.utils import import_string
  20. from sqlalchemy.exc import IntegrityError, OperationalError
  21. from flask.ext.script import (Manager, Shell, Server, prompt, prompt_pass,
  22. prompt_bool)
  23. from flask.ext.migrate import MigrateCommand
  24. from flaskbb import create_app
  25. from flaskbb.extensions import db
  26. from flaskbb.utils.populate import (create_test_data, create_welcome_forum,
  27. create_admin_user, create_default_groups,
  28. create_default_settings, insert_mass_data,
  29. update_settings_from_fixture)
  30. # Use the development configuration if available
  31. try:
  32. from flaskbb.configs.development import DevelopmentConfig as Config
  33. except ImportError:
  34. from flaskbb.configs.default import DefaultConfig as Config
  35. app = create_app(Config)
  36. manager = Manager(app)
  37. # Used to get the plugin translations
  38. PLUGINS_FOLDER = os.path.join(app.root_path, "plugins")
  39. # Run local server
  40. manager.add_command("runserver", Server("localhost", port=8080))
  41. # Migration commands
  42. manager.add_command('db', MigrateCommand)
  43. # Add interactive project shell
  44. def make_shell_context():
  45. return dict(app=current_app, db=db)
  46. manager.add_command("shell", Shell(make_context=make_shell_context))
  47. @manager.command
  48. def initdb():
  49. """Creates the database."""
  50. db.create_all()
  51. @manager.command
  52. def dropdb():
  53. """Deletes the database"""
  54. db.drop_all()
  55. @manager.option('-s', '--settings', dest="settings")
  56. @manager.option('-f', '--force', dest="force")
  57. def update(settings=None, force=False):
  58. """Updates the settings via a fixture. All fixtures have to be placed
  59. in the `fixture`.
  60. Usage: python manage.py update -s your_fixture
  61. """
  62. try:
  63. fixture = import_string(
  64. "flaskbb.fixtures.{}".format(settings)
  65. )
  66. fixture = fixture.fixture
  67. except ImportError:
  68. raise "{} fixture is not available".format(settings)
  69. if force:
  70. count = update_settings_from_fixture(fixture, overwrite_group=True,
  71. overwrite_setting=True)
  72. app.logger.info(
  73. "{} groups and {} settings forcefully updated."
  74. .format(count[0], count[1])
  75. )
  76. else:
  77. count = update_settings_from_fixture(fixture)
  78. app.logger.info(
  79. "{} groups and {} settings updated.".format(count[0], count[1])
  80. )
  81. @manager.command
  82. def createall(dropdb=False, createdb=False):
  83. """Creates the database with some testing content.
  84. If you do not want to drop or create the db add
  85. '-c' (to not create the db) and '-d' (to not drop the db)
  86. """
  87. if not dropdb:
  88. app.logger.info("Dropping database...")
  89. db.drop_all()
  90. if not createdb:
  91. app.logger.info("Creating database...")
  92. db.create_all()
  93. app.logger.info("Creating test data...")
  94. create_test_data()
  95. @manager.option('-u', '--username', dest='username')
  96. @manager.option('-p', '--password', dest='password')
  97. @manager.option('-e', '--email', dest='email')
  98. def create_admin(username=None, password=None, email=None):
  99. """Creates the admin user"""
  100. if not (username and password and email):
  101. username = prompt("Username")
  102. email = prompt("A valid email address")
  103. password = prompt_pass("Password")
  104. create_admin_user(username=username, password=password, email=email)
  105. @manager.option('-u', '--username', dest='username')
  106. @manager.option('-p', '--password', dest='password')
  107. @manager.option('-e', '--email', dest='email')
  108. def initflaskbb(username=None, password=None, email=None):
  109. """Initializes FlaskBB with all necessary data"""
  110. app.logger.info("Creating default data...")
  111. try:
  112. create_default_groups()
  113. create_default_settings()
  114. except IntegrityError:
  115. app.logger.error("Couldn't create the default data because it already "
  116. "exist!")
  117. if prompt_bool("Do you want to recreate the database? (y/n)"):
  118. db.session.rollback()
  119. db.drop_all()
  120. db.create_all()
  121. create_default_groups()
  122. create_default_settings()
  123. else:
  124. sys.exit(0)
  125. except OperationalError:
  126. app.logger.error("No database found.")
  127. if prompt_bool("Do you want to create the database now? (y/n)"):
  128. db.session.rollback()
  129. db.create_all()
  130. create_default_groups()
  131. create_default_settings()
  132. else:
  133. sys.exit(0)
  134. app.logger.info("Creating admin user...")
  135. if username and password and email:
  136. create_admin_user(username=username, password=password, email=email)
  137. else:
  138. create_admin()
  139. app.logger.info("Creating welcome forum...")
  140. create_welcome_forum()
  141. app.logger.info("Congratulations! FlaskBB has been successfully installed")
  142. @manager.command
  143. def insertmassdata():
  144. """Warning: This can take a long time!.
  145. Creates 100 topics and each topic contains 100 posts.
  146. """
  147. insert_mass_data()
  148. @manager.command
  149. def update_translations():
  150. """
  151. Updates the translations
  152. """
  153. translations_folder = os.path.join(app.root_path, "translations")
  154. subprocess.call(["pybabel", "extract", "-F", "babel.cfg",
  155. "-k", "lazy_gettext", "-o", "messages.pot", "."])
  156. subprocess.call(["pybabel", "update", "-i", "messages.pot",
  157. "-d", translations_folder])
  158. os.unlink("messages.pot")
  159. @manager.command
  160. def init_translations(translation):
  161. """
  162. Adds a new language to the translations
  163. """
  164. translations_folder = os.path.join(app.root_path, "translations")
  165. subprocess.call(["pybabel", "extract", "-F", "babel.cfg",
  166. "-k", "lazy_gettext", "-o", "messages.pot", "."])
  167. subprocess.call(["pybabel", "init", "-i", "messages.pot",
  168. "-d", translations_folder, "-l", translation])
  169. os.unlink('messages.pot')
  170. @manager.command
  171. def compile_translations():
  172. """
  173. Compiles the translations.
  174. """
  175. translations_folder = os.path.join(app.root_path, "translations")
  176. subprocess.call(["pybabel", "compile", "-d", translations_folder])
  177. # Plugin translation commands
  178. @manager.command
  179. def add_plugin_translations(plugin, translation):
  180. """
  181. Adds a new language to the plugin translations
  182. Expects the name of the plugin and the translations name like "en"
  183. """
  184. plugin_folder = os.path.join(PLUGINS_FOLDER, plugin)
  185. translations_folder = os.path.join(plugin_folder, "translations")
  186. subprocess.call(["pybabel", "extract", "-F", "babel.cfg",
  187. "-k", "lazy_gettext", "-o", "messages.pot",
  188. plugin_folder])
  189. subprocess.call(["pybabel", "init", "-i", "messages.pot",
  190. "-d", translations_folder, "-l", translation])
  191. os.unlink('messages.pot')
  192. @manager.command
  193. def update_plugin_translations(plugin):
  194. """
  195. Updates the plugin translations
  196. Expects the name of the plugin.
  197. """
  198. plugin_folder = os.path.join(PLUGINS_FOLDER, plugin)
  199. translations_folder = os.path.join(plugin_folder, "translations")
  200. subprocess.call(["pybabel", "extract", "-F", "babel.cfg",
  201. "-k", "lazy_gettext", "-o", "messages.pot",
  202. plugin_folder])
  203. subprocess.call(["pybabel", "update", "-i", "messages.pot"
  204. "-d", translations_folder])
  205. os.unlink("messages.pot")
  206. @manager.command
  207. def compile_plugin_translations(plugin):
  208. """
  209. Compile the plugin translations.
  210. Expects the name of the plugin.
  211. """
  212. plugin_folder = os.path.join(PLUGINS_FOLDER, plugin)
  213. translations_folder = os.path.join(plugin_folder, "translations")
  214. subprocess.call(["pybabel", "compile", "-d", translations_folder])
  215. if __name__ == "__main__":
  216. manager.run()