123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- #!/usr/bin/env python
- """
- flaskbb.manage
- ~~~~~~~~~~~~~~~~~~~~
- This script provides some easy to use commands for
- creating the database with or without some sample content.
- You can also run the development server with it.
- Just type `python manage.py` to see the full list of commands.
- TODO: When Flask 1.0 is released, get rid of Flask-Script and use click.
- Then it's also possible to split the commands in "command groups"
- which would make the commands better seperated from each other
- and less confusing.
- :copyright: (c) 2014 by the FlaskBB Team.
- :license: BSD, see LICENSE for more details.
- """
- from __future__ import print_function
- import sys
- import os
- import subprocess
- import requests
- from flask import current_app
- from werkzeug.utils import import_string
- from sqlalchemy.exc import IntegrityError, OperationalError
- from flask_script import (Manager, Shell, Server, prompt, prompt_pass,
- prompt_bool)
- from flask_migrate import MigrateCommand, upgrade
- from flaskbb import create_app
- from flaskbb.extensions import db, plugin_manager
- from flaskbb.utils.populate import (create_test_data, create_welcome_forum,
- create_admin_user, create_default_groups,
- create_default_settings, insert_mass_data,
- update_settings_from_fixture)
- # Use the development configuration if available
- try:
- from flaskbb.configs.development import DevelopmentConfig as Config
- except ImportError:
- from flaskbb.configs.default import DefaultConfig as Config
- app = create_app(Config)
- manager = Manager(app)
- # Used to get the plugin translations
- PLUGINS_FOLDER = os.path.join(app.root_path, "plugins")
- # Run local server
- manager.add_command("runserver", Server("localhost", port=8080))
- # Migration commands
- manager.add_command('db', MigrateCommand)
- # Add interactive project shell
- def make_shell_context():
- return dict(app=current_app, db=db)
- manager.add_command("shell", Shell(make_context=make_shell_context))
- @manager.command
- def initdb():
- """Creates the database."""
- upgrade()
- @manager.command
- def dropdb():
- """Deletes the database."""
- db.drop_all()
- @manager.command
- def populate(dropdb=False, createdb=False):
- """Creates the database with some default data.
- To drop or create the databse use the '-d' or '-c' options.
- """
- if dropdb:
- print("Dropping database...")
- db.drop_all()
- if createdb:
- print("Creating database...")
- upgrade()
- app.logger.info("Creating test data...")
- create_test_data()
- @manager.option('-u', '--username', dest='username')
- @manager.option('-p', '--password', dest='password')
- @manager.option('-e', '--email', dest='email')
- def create_admin(username=None, password=None, email=None):
- """Creates the admin user."""
- if not (username and password and email):
- username = prompt("Username")
- email = prompt("A valid email address")
- password = prompt_pass("Password")
- create_admin_user(username=username, password=password, email=email)
- @manager.option('-u', '--username', dest='username')
- @manager.option('-p', '--password', dest='password')
- @manager.option('-e', '--email', dest='email')
- def install(username=None, password=None, email=None):
- """Installs FlaskBB with all necessary data."""
- print("Creating default data...")
- try:
- create_default_groups()
- create_default_settings()
- except IntegrityError:
- print("Couldn't create the default data because it already exist!")
- if prompt_bool("Found an existing database."
- "Do you want to recreate the database? (y/n)"):
- db.session.rollback()
- db.drop_all()
- upgrade()
- create_default_groups()
- create_default_settings()
- else:
- sys.exit(0)
- except OperationalError:
- print("No database found.")
- if prompt_bool("Do you want to create the database now? (y/n)"):
- db.session.rollback()
- upgrade()
- create_default_groups()
- create_default_settings()
- else:
- sys.exit(0)
- print("Creating admin user...")
- if username and password and email:
- create_admin_user(username=username, password=password, email=email)
- else:
- create_admin()
- print("Creating welcome forum...")
- create_welcome_forum()
- print("Compiling translations...")
- compile_translations()
- if prompt_bool("Do you want to use Emojis? (y/n)"):
- print("Downloading emojis. This can take a few minutes.")
- download_emoji()
- print("Congratulations! FlaskBB has been successfully installed")
- @manager.command
- def insertmassdata():
- """Warning: This can take a long time!.
- Creates 100 topics and each topic contains 100 posts.
- """
- insert_mass_data()
- @manager.option('-s', '--settings', dest="settings")
- @manager.option('-f', '--force', dest="force", default=False)
- def update(settings=None, force=False):
- """Updates the settings via a fixture. All fixtures have to be placed
- in the `fixture`.
- Usage: python manage.py update -s your_fixture
- """
- try:
- fixture = import_string(
- "flaskbb.fixtures.{}".format(settings)
- )
- fixture = fixture.fixture
- except ImportError:
- raise "{} fixture is not available".format(settings)
- overwrite_group = overwrite_setting = False
- if force:
- overwrite_group = overwrite_setting = True
- count = update_settings_from_fixture(
- fixture=fixture,
- overwrite_group=overwrite_group,
- overwrite_setting=overwrite_setting
- )
- print("{} groups and {} settings updated.".format(
- len(count.keys()), len(count.values()))
- )
- @manager.command
- def update_translations():
- """Updates all translations."""
- # update flaskbb translations
- translations_folder = os.path.join(app.root_path, "translations")
- source_file = os.path.join(translations_folder, "messages.pot")
- subprocess.call(["pybabel", "extract", "-F", "babel.cfg",
- "-k", "lazy_gettext", "-o", source_file, "."])
- subprocess.call(["pybabel", "update", "-i", source_file,
- "-d", translations_folder])
- # updates all plugin translations too
- for plugin in plugin_manager.all_plugins:
- update_plugin_translations(plugin)
- @manager.command
- def add_translations(translation):
- """Adds a new language to the translations."""
- translations_folder = os.path.join(app.root_path, "translations")
- source_file = os.path.join(translations_folder, "messages.pot")
- subprocess.call(["pybabel", "extract", "-F", "babel.cfg",
- "-k", "lazy_gettext", "-o", source_file, "."])
- subprocess.call(["pybabel", "init", "-i", source_file,
- "-d", translations_folder, "-l", translation])
- @manager.command
- def compile_translations():
- """Compiles all translations."""
- # compile flaskbb translations
- translations_folder = os.path.join(app.root_path, "translations")
- subprocess.call(["pybabel", "compile", "-d", translations_folder])
- # compile all plugin translations
- for plugin in plugin_manager.all_plugins:
- compile_plugin_translations(plugin)
- # Plugin translation commands
- @manager.command
- def add_plugin_translations(plugin, translation):
- """Adds a new language to the plugin translations. Expects the name
- of the plugin and the translations name like "en".
- """
- plugin_folder = os.path.join(PLUGINS_FOLDER, plugin)
- translations_folder = os.path.join(plugin_folder, "translations")
- source_file = os.path.join(translations_folder, "messages.pot")
- subprocess.call(["pybabel", "extract", "-F", "babel.cfg",
- "-k", "lazy_gettext", "-o", source_file,
- plugin_folder])
- subprocess.call(["pybabel", "init", "-i", source_file,
- "-d", translations_folder, "-l", translation])
- @manager.command
- def update_plugin_translations(plugin):
- """Updates the plugin translations. Expects the name of the plugin."""
- plugin_folder = os.path.join(PLUGINS_FOLDER, plugin)
- translations_folder = os.path.join(plugin_folder, "translations")
- source_file = os.path.join(translations_folder, "messages.pot")
- subprocess.call(["pybabel", "extract", "-F", "babel.cfg",
- "-k", "lazy_gettext", "-o", source_file,
- plugin_folder])
- subprocess.call(["pybabel", "update", "-i", source_file,
- "-d", translations_folder])
- @manager.command
- def compile_plugin_translations(plugin):
- """Compile the plugin translations. Expects the name of the plugin."""
- plugin_folder = os.path.join(PLUGINS_FOLDER, plugin)
- translations_folder = os.path.join(plugin_folder, "translations")
- subprocess.call(["pybabel", "compile", "-d", translations_folder])
- @manager.command
- def download_emoji():
- """Downloads emojis from emoji-cheat-sheet.com."""
- HOSTNAME = "https://api.github.com"
- REPO = "/repos/arvida/emoji-cheat-sheet.com/contents/public/graphics/emojis"
- FULL_URL = "{}{}".format(HOSTNAME, REPO)
- DOWNLOAD_PATH = os.path.join(app.static_folder, "emoji")
- response = requests.get(FULL_URL)
- cached_count = 0
- count = 0
- for image in response.json():
- if not os.path.exists(os.path.abspath(DOWNLOAD_PATH)):
- print("{} does not exist.".format(os.path.abspath(DOWNLOAD_PATH)))
- sys.exit(1)
- full_path = os.path.join(DOWNLOAD_PATH, image["name"])
- if not os.path.exists(full_path):
- count += 1
- f = open(full_path, 'wb')
- f.write(requests.get(image["download_url"]).content)
- f.close()
- if count == cached_count + 50:
- cached_count = count
- print("{} out of {} Emojis downloaded...".format(
- cached_count, len(response.json())))
- print("Finished downloading {} Emojis.".format(count))
- if __name__ == "__main__":
- manager.run()
|