|
@@ -30,10 +30,12 @@ from sqlalchemy_utils.functions import database_exists, drop_database
|
|
|
from flask_migrate import upgrade as upgrade_database
|
|
|
from flask_plugins import (get_all_plugins, get_enabled_plugins,
|
|
|
get_plugin_from_all)
|
|
|
+from flask_themes2 import get_themes_list, get_theme
|
|
|
|
|
|
from flaskbb import create_app
|
|
|
from flaskbb._compat import iteritems
|
|
|
from flaskbb.extensions import db, whooshee, plugin_manager
|
|
|
+from flaskbb.utils.settings import flaskbb_config
|
|
|
from flaskbb.utils.populate import (create_test_data, create_welcome_forum,
|
|
|
create_user, create_default_groups,
|
|
|
create_default_settings, insert_bulk_data,
|
|
@@ -62,10 +64,6 @@ except ImportError:
|
|
|
_email_regex = r"[^@]+@[^@]+\.[^@]+"
|
|
|
|
|
|
|
|
|
-def make_app(config):
|
|
|
- return create_app(Config)
|
|
|
-
|
|
|
-
|
|
|
class FlaskBBCLIError(click.ClickException):
|
|
|
"""An exception that signals a usage error including color support.
|
|
|
This aborts any further handling.
|
|
@@ -113,6 +111,14 @@ def validate_plugin(plugin):
|
|
|
return True
|
|
|
|
|
|
|
|
|
+def validate_theme(theme):
|
|
|
+ """Checks if a theme is installed."""
|
|
|
+ try:
|
|
|
+ get_theme(theme)
|
|
|
+ except KeyError:
|
|
|
+ raise FlaskBBCLIError("Theme {} not found.".format(theme), fg="red")
|
|
|
+
|
|
|
+
|
|
|
def check_cookiecutter(ctx, param, value):
|
|
|
if not cookiecutter_available:
|
|
|
raise FlaskBBCLIError(
|
|
@@ -379,14 +385,14 @@ def list_plugins():
|
|
|
if len(enabled_plugins) > 0:
|
|
|
click.secho("[+] Enabled Plugins:", fg="blue", bold=True)
|
|
|
for plugin in enabled_plugins:
|
|
|
- click.secho(" * {} (version {})".format(
|
|
|
- plugin.name, plugin.version)
|
|
|
+ click.secho(" - {} (version {})".format(
|
|
|
+ plugin.name, plugin.version), bold=True
|
|
|
)
|
|
|
if len(disabled_plugins) > 0:
|
|
|
click.secho("[+] Disabled Plugins:", fg="yellow", bold=True)
|
|
|
for plugin in disabled_plugins:
|
|
|
- click.secho(" * {} (version {})".format(
|
|
|
- plugin.name, plugin.version)
|
|
|
+ click.secho(" - {} (version {})".format(
|
|
|
+ plugin.name, plugin.version), bold=True
|
|
|
)
|
|
|
|
|
|
|
|
@@ -396,6 +402,62 @@ def themes():
|
|
|
pass
|
|
|
|
|
|
|
|
|
+@themes.command("list")
|
|
|
+def list_themes():
|
|
|
+ """Lists all installed themes."""
|
|
|
+ click.secho("[+] Listing all installed themes...", fg="cyan")
|
|
|
+
|
|
|
+ active_theme = get_theme(flaskbb_config['DEFAULT_THEME'])
|
|
|
+ available_themes = set(get_themes_list()) - set([active_theme])
|
|
|
+
|
|
|
+ click.secho("[+] Active Theme:", fg="blue", bold=True)
|
|
|
+ click.secho(" - {} (version {})".format(
|
|
|
+ active_theme.name, active_theme.version), bold=True
|
|
|
+ )
|
|
|
+
|
|
|
+ click.secho("[+] Available Themes:", fg="yellow", bold=True)
|
|
|
+ for theme in available_themes:
|
|
|
+ click.secho(" - {} (version {})".format(
|
|
|
+ theme.name, theme.version), bold=True
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+@themes.command("new")
|
|
|
+@click.argument("theme_identifier", callback=check_cookiecutter)
|
|
|
+@click.option("--template", "-t", type=click.STRING,
|
|
|
+ default="https://github.com/sh4nks/cookiecutter-flaskbb-theme",
|
|
|
+ help="Path to a cookiecutter template or to a valid git repo.")
|
|
|
+def new_theme(theme_identifier, template):
|
|
|
+ """Creates a new theme based on the cookiecutter theme
|
|
|
+ template. Defaults to this template:
|
|
|
+ https://github.com:sh4nks/cookiecutter-flaskbb-theme.
|
|
|
+ It will either accept a valid path on the filesystem
|
|
|
+ or a URL to a Git repository which contains the cookiecutter template.
|
|
|
+ """
|
|
|
+ out_dir = os.path.join(current_app.root_path, "themes")
|
|
|
+ click.secho("[+] Creating new theme {}".format(theme_identifier),
|
|
|
+ fg="cyan")
|
|
|
+ cookiecutter(template, output_dir=out_dir)
|
|
|
+ click.secho("[+] Done. Created in {}".format(out_dir),
|
|
|
+ fg="green", bold=True)
|
|
|
+
|
|
|
+
|
|
|
+@themes.command("remove")
|
|
|
+@click.argument("theme_identifier")
|
|
|
+@click.option("--force", "-f", default=False, is_flag=True,
|
|
|
+ help="Removes the theme without asking for confirmation.")
|
|
|
+def remove_theme(theme_identifier, force):
|
|
|
+ """Removes a theme from the filesystem."""
|
|
|
+ validate_theme(theme_identifier)
|
|
|
+ if not force and not \
|
|
|
+ click.confirm(click.style("Are you sure?", fg="magenta")):
|
|
|
+ sys.exit(0)
|
|
|
+
|
|
|
+ theme = get_theme(theme_identifier)
|
|
|
+ click.secho("[+] Removing theme from filesystem...", fg="cyan")
|
|
|
+ shutil.rmtree(theme.path, ignore_errors=False, onerror=None)
|
|
|
+
|
|
|
+
|
|
|
@main.group()
|
|
|
def users():
|
|
|
"""Create, update or delete users."""
|