Browse Source

Formatting

Peter Justin 6 years ago
parent
commit
584742a9ae
3 changed files with 136 additions and 167 deletions
  1. 36 73
      flaskbb/app.py
  2. 8 8
      flaskbb/user/models.py
  3. 92 86
      flaskbb/utils/helpers.py

+ 36 - 73
flaskbb/app.py

@@ -23,72 +23,33 @@ from sqlalchemy.engine import Engine
 from sqlalchemy.exc import OperationalError, ProgrammingError
 from sqlalchemy.exc import OperationalError, ProgrammingError
 
 
 from flaskbb._compat import iteritems, string_types
 from flaskbb._compat import iteritems, string_types
-
 # extensions
 # extensions
-from flaskbb.extensions import (
-    alembic,
-    allows,
-    babel,
-    cache,
-    celery,
-    csrf,
-    db,
-    debugtoolbar,
-    limiter,
-    login_manager,
-    mail,
-    redis_store,
-    themes,
-    whooshee,
-)
+from flaskbb.extensions import (alembic, allows, babel, cache, celery, csrf,
+                                db, debugtoolbar, limiter, login_manager, mail,
+                                redis_store, themes, whooshee)
 from flaskbb.plugins import spec
 from flaskbb.plugins import spec
 from flaskbb.plugins.manager import FlaskBBPluginManager
 from flaskbb.plugins.manager import FlaskBBPluginManager
 from flaskbb.plugins.models import PluginRegistry
 from flaskbb.plugins.models import PluginRegistry
 from flaskbb.plugins.utils import remove_zombie_plugins_from_db, template_hook
 from flaskbb.plugins.utils import remove_zombie_plugins_from_db, template_hook
-
 # models
 # models
 from flaskbb.user.models import Guest, User
 from flaskbb.user.models import Guest, User
-
 # various helpers
 # various helpers
-from flaskbb.utils.helpers import (
-    app_config_from_env,
-    crop_title,
-    format_date,
-    format_datetime,
-    forum_is_unread,
-    get_alembic_locations,
-    get_flaskbb_config,
-    is_online,
-    mark_online,
-    render_template,
-    time_since,
-    time_utcnow,
-    topic_is_unread,
-)
-
+from flaskbb.utils.helpers import (app_config_from_env, crop_title,
+                                   format_date, format_datetime,
+                                   forum_is_unread, get_alembic_locations,
+                                   get_flaskbb_config, is_online, mark_online,
+                                   render_template, time_since, time_utcnow,
+                                   topic_is_unread)
 # permission checks (here they are used for the jinja filters)
 # permission checks (here they are used for the jinja filters)
-from flaskbb.utils.requirements import (
-    CanBanUser,
-    CanEditUser,
-    IsAdmin,
-    IsAtleastModerator,
-    can_delete_topic,
-    can_edit_post,
-    can_moderate,
-    can_post_reply,
-    can_post_topic,
-    has_permission,
-    permission_with_identity,
-)
-
+from flaskbb.utils.requirements import (CanBanUser, CanEditUser, IsAdmin,
+                                        IsAtleastModerator, can_delete_topic,
+                                        can_edit_post, can_moderate,
+                                        can_post_reply, can_post_topic,
+                                        has_permission,
+                                        permission_with_identity)
 # whooshees
 # whooshees
-from flaskbb.utils.search import (
-    ForumWhoosheer,
-    PostWhoosheer,
-    TopicWhoosheer,
-    UserWhoosheer,
-)
-
+from flaskbb.utils.search import (ForumWhoosheer, PostWhoosheer,
+                                  TopicWhoosheer, UserWhoosheer)
 # app specific configurations
 # app specific configurations
 from flaskbb.utils.settings import flaskbb_config
 from flaskbb.utils.settings import flaskbb_config
 from flaskbb.utils.translations import FlaskBBDomain
 from flaskbb.utils.translations import FlaskBBDomain
@@ -96,10 +57,10 @@ from flaskbb.utils.translations import FlaskBBDomain
 from . import markup  # noqa
 from . import markup  # noqa
 from .auth import views as auth_views  # noqa
 from .auth import views as auth_views  # noqa
 from .deprecation import FlaskBBDeprecation
 from .deprecation import FlaskBBDeprecation
+from .display.navigation import NavigationContentType
 from .forum import views as forum_views  # noqa
 from .forum import views as forum_views  # noqa
 from .management import views as management_views  # noqa
 from .management import views as management_views  # noqa
 from .user import views as user_views  # noqa
 from .user import views as user_views  # noqa
-from .display.navigation import NavigationContentType
 
 
 logger = logging.getLogger(__name__)
 logger = logging.getLogger(__name__)
 
 
@@ -183,21 +144,24 @@ def configure_app(app, config):
     if not app.testing:  # pragma: no branch
     if not app.testing:  # pragma: no branch
         warnings.simplefilter(deprecation_level, FlaskBBDeprecation)
         warnings.simplefilter(deprecation_level, FlaskBBDeprecation)
 
 
-    debug_panels = app.config.setdefault('DEBUG_TB_PANELS', [
-        'flask_debugtoolbar.panels.versions.VersionDebugPanel',
-        'flask_debugtoolbar.panels.timer.TimerDebugPanel',
-        'flask_debugtoolbar.panels.headers.HeaderDebugPanel',
-        'flask_debugtoolbar.panels.request_vars.RequestVarsDebugPanel',
-        'flask_debugtoolbar.panels.config_vars.ConfigVarsDebugPanel',
-        'flask_debugtoolbar.panels.template.TemplateDebugPanel',
-        'flask_debugtoolbar.panels.sqlalchemy.SQLAlchemyDebugPanel',
-        'flask_debugtoolbar.panels.logger.LoggingPanel',
-        'flask_debugtoolbar.panels.route_list.RouteListDebugPanel',
-        'flask_debugtoolbar.panels.profiler.ProfilerDebugPanel',
-    ])
-
-    if all('WarningsPanel' not in p for p in debug_panels):
-        debug_panels.append('flask_debugtoolbar_warnings.WarningsPanel')
+    debug_panels = app.config.setdefault(
+        "DEBUG_TB_PANELS",
+        [
+            "flask_debugtoolbar.panels.versions.VersionDebugPanel",
+            "flask_debugtoolbar.panels.timer.TimerDebugPanel",
+            "flask_debugtoolbar.panels.headers.HeaderDebugPanel",
+            "flask_debugtoolbar.panels.request_vars.RequestVarsDebugPanel",
+            "flask_debugtoolbar.panels.config_vars.ConfigVarsDebugPanel",
+            "flask_debugtoolbar.panels.template.TemplateDebugPanel",
+            "flask_debugtoolbar.panels.sqlalchemy.SQLAlchemyDebugPanel",
+            "flask_debugtoolbar.panels.logger.LoggingPanel",
+            "flask_debugtoolbar.panels.route_list.RouteListDebugPanel",
+            "flask_debugtoolbar.panels.profiler.ProfilerDebugPanel",
+        ],
+    )
+
+    if all("WarningsPanel" not in p for p in debug_panels):
+        debug_panels.append("flask_debugtoolbar_warnings.WarningsPanel")
 
 
     app.pluggy = FlaskBBPluginManager("flaskbb")
     app.pluggy = FlaskBBPluginManager("flaskbb")
 
 
@@ -210,7 +174,6 @@ def configure_celery_app(app, celery):
     TaskBase = celery.Task
     TaskBase = celery.Task
 
 
     class ContextTask(TaskBase):
     class ContextTask(TaskBase):
-
         def __call__(self, *args, **kwargs):
         def __call__(self, *args, **kwargs):
             with app.app_context():
             with app.app_context():
                 return TaskBase.__call__(self, *args, **kwargs)
                 return TaskBase.__call__(self, *args, **kwargs)

+ 8 - 8
flaskbb/user/models.py

@@ -9,17 +9,18 @@
     :license: BSD, see LICENSE for more details.
     :license: BSD, see LICENSE for more details.
 """
 """
 import logging
 import logging
-from werkzeug.security import generate_password_hash, check_password_hash
+
 from flask import url_for
 from flask import url_for
-from flask_login import UserMixin, AnonymousUserMixin
+from flask_login import AnonymousUserMixin, UserMixin
+from werkzeug.security import check_password_hash, generate_password_hash
 
 
-from flaskbb.extensions import db, cache
+from flaskbb.deprecation import deprecated
 from flaskbb.exceptions import AuthenticationError
 from flaskbb.exceptions import AuthenticationError
+from flaskbb.extensions import cache, db
+from flaskbb.forum.models import Forum, Post, Topic, topictracker
+from flaskbb.utils.database import CRUDMixin, UTCDateTime, make_comparable
 from flaskbb.utils.helpers import time_utcnow
 from flaskbb.utils.helpers import time_utcnow
 from flaskbb.utils.settings import flaskbb_config
 from flaskbb.utils.settings import flaskbb_config
-from flaskbb.utils.database import CRUDMixin, UTCDateTime, make_comparable
-from flaskbb.forum.models import Post, Topic, Forum, topictracker
-from flaskbb.deprecation import deprecated
 
 
 logger = logging.getLogger(__name__)
 logger = logging.getLogger(__name__)
 
 
@@ -286,8 +287,7 @@ class User(db.Model, UserMixin, CRUDMixin):
 
 
     def recalculate(self):
     def recalculate(self):
         """Recalculates the post count from the user."""
         """Recalculates the post count from the user."""
-        post_count = Post.query.filter_by(user_id=self.id).count()
-        self.post_count = post_count
+        self.post_count = Post.query.filter_by(user_id=self.id).count()
         self.save()
         self.save()
         return self
         return self
 
 

+ 92 - 86
flaskbb/utils/helpers.py

@@ -12,38 +12,36 @@ import ast
 import itertools
 import itertools
 import logging
 import logging
 import operator
 import operator
-import warnings
 import os
 import os
 import re
 import re
 import time
 import time
+import warnings
 from datetime import datetime, timedelta
 from datetime import datetime, timedelta
 from email import message_from_string
 from email import message_from_string
 from functools import wraps
 from functools import wraps
 
 
-from pkg_resources import get_distribution
-
+import pkg_resources
 import requests
 import requests
 import unidecode
 import unidecode
 from babel.core import get_locale_identifier
 from babel.core import get_locale_identifier
-from babel.dates import (
-    format_timedelta as babel_format_timedelta,
-    format_datetime as babel_format_datetime,
-    format_date as babel_format_date)
-from werkzeug.utils import import_string, ImportStringError
+from babel.dates import format_date as babel_format_date
+from babel.dates import format_datetime as babel_format_datetime
+from babel.dates import format_timedelta as babel_format_timedelta
 from flask import flash, g, redirect, request, session, url_for
 from flask import flash, g, redirect, request, session, url_for
 from flask_allows import Permission
 from flask_allows import Permission
 from flask_babelplus import lazy_gettext as _
 from flask_babelplus import lazy_gettext as _
 from flask_login import current_user
 from flask_login import current_user
 from flask_themes2 import get_themes_list, render_theme_template
 from flask_themes2 import get_themes_list, render_theme_template
-from flaskbb._compat import (iteritems, range_method, text_type, string_types,
-                             to_bytes, to_unicode)
-from flaskbb.extensions import babel, redis_store
-from flaskbb.utils.settings import flaskbb_config
 from jinja2 import Markup
 from jinja2 import Markup
 from PIL import ImageFile
 from PIL import ImageFile
 from pytz import UTC
 from pytz import UTC
 from werkzeug.local import LocalProxy
 from werkzeug.local import LocalProxy
+from werkzeug.utils import ImportStringError, import_string
 
 
+from flaskbb._compat import (iteritems, range_method, string_types, text_type,
+                             to_bytes, to_unicode)
+from flaskbb.extensions import babel, redis_store
+from flaskbb.utils.settings import flaskbb_config
 
 
 try:  # compat
 try:  # compat
     FileNotFoundError
     FileNotFoundError
@@ -55,7 +53,7 @@ logger = logging.getLogger(__name__)
 _punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+')
 _punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+')
 
 
 
 
-def slugify(text, delim=u'-'):
+def slugify(text, delim=u"-"):
     """Generates an slightly worse ASCII-only slug.
     """Generates an slightly worse ASCII-only slug.
     Taken from the Flask Snippets page.
     Taken from the Flask Snippets page.
 
 
@@ -76,9 +74,7 @@ def redirect_or_next(endpoint, **kwargs):
 
 
     :param endpoint: The fallback endpoint.
     :param endpoint: The fallback endpoint.
     """
     """
-    return redirect(
-        request.args.get('next') or endpoint, **kwargs
-    )
+    return redirect(request.args.get("next") or endpoint, **kwargs)
 
 
 
 
 def render_template(template, **context):  # pragma: no cover
 def render_template(template, **context):  # pragma: no cover
@@ -88,7 +84,7 @@ def render_template(template, **context):  # pragma: no cover
     if current_user.is_authenticated and current_user.theme:
     if current_user.is_authenticated and current_user.theme:
         theme = current_user.theme
         theme = current_user.theme
     else:
     else:
-        theme = session.get('theme', flaskbb_config['DEFAULT_THEME'])
+        theme = session.get("theme", flaskbb_config["DEFAULT_THEME"])
     return render_theme_template(theme, template, **context)
     return render_theme_template(theme, template, **context)
 
 
 
 
@@ -107,18 +103,21 @@ def do_topic_action(topics, user, action, reverse):  # noqa: C901
     if not topics:
     if not topics:
         return False
         return False
 
 
-    from flaskbb.utils.requirements import (IsAtleastModeratorInForum,
-                                            CanDeleteTopic, Has)
+    from flaskbb.utils.requirements import (
+        IsAtleastModeratorInForum,
+        CanDeleteTopic,
+        Has,
+    )
 
 
     if not Permission(IsAtleastModeratorInForum(forum=topics[0].forum)):
     if not Permission(IsAtleastModeratorInForum(forum=topics[0].forum)):
         flash(
         flash(
             _("You do not have the permissions to execute this action."),
             _("You do not have the permissions to execute this action."),
-            "danger"
+            "danger",
         )
         )
         return False
         return False
 
 
     modified_topics = 0
     modified_topics = 0
-    if action not in {'delete', 'hide', 'unhide'}:
+    if action not in {"delete", "hide", "unhide"}:
         for topic in topics:
         for topic in topics:
             if getattr(topic, action) and not reverse:
             if getattr(topic, action) and not reverse:
                 continue
                 continue
@@ -131,7 +130,7 @@ def do_topic_action(topics, user, action, reverse):  # noqa: C901
         if not Permission(CanDeleteTopic):
         if not Permission(CanDeleteTopic):
             flash(
             flash(
                 _("You do not have the permissions to delete these topics."),
                 _("You do not have the permissions to delete these topics."),
-                "danger"
+                "danger",
             )
             )
             return False
             return False
 
 
@@ -139,11 +138,11 @@ def do_topic_action(topics, user, action, reverse):  # noqa: C901
             modified_topics += 1
             modified_topics += 1
             topic.delete()
             topic.delete()
 
 
-    elif action == 'hide':
-        if not Permission(Has('makehidden')):
+    elif action == "hide":
+        if not Permission(Has("makehidden")):
             flash(
             flash(
                 _("You do not have the permissions to hide these topics."),
                 _("You do not have the permissions to hide these topics."),
-                "danger"
+                "danger",
             )
             )
             return False
             return False
 
 
@@ -153,11 +152,11 @@ def do_topic_action(topics, user, action, reverse):  # noqa: C901
             modified_topics += 1
             modified_topics += 1
             topic.hide(user)
             topic.hide(user)
 
 
-    elif action == 'unhide':
-        if not Permission(Has('makehidden')):
+    elif action == "unhide":
+        if not Permission(Has("makehidden")):
             flash(
             flash(
                 _("You do not have the permissions to unhide these topics."),
                 _("You do not have the permissions to unhide these topics."),
-                "danger"
+                "danger",
             )
             )
             return False
             return False
 
 
@@ -256,7 +255,8 @@ def forum_is_unread(forum, forumsread, user):
         return False
         return False
 
 
     read_cutoff = time_utcnow() - timedelta(
     read_cutoff = time_utcnow() - timedelta(
-        days=flaskbb_config["TRACKER_LENGTH"])
+        days=flaskbb_config["TRACKER_LENGTH"]
+    )
 
 
     # disable tracker if TRACKER_LENGTH is set to 0
     # disable tracker if TRACKER_LENGTH is set to 0
     if flaskbb_config["TRACKER_LENGTH"] == 0:
     if flaskbb_config["TRACKER_LENGTH"] == 0:
@@ -307,7 +307,8 @@ def topic_is_unread(topic, topicsread, user, forumsread=None):
         return False
         return False
 
 
     read_cutoff = time_utcnow() - timedelta(
     read_cutoff = time_utcnow() - timedelta(
-        days=flaskbb_config["TRACKER_LENGTH"])
+        days=flaskbb_config["TRACKER_LENGTH"]
+    )
 
 
     # disable tracker if read_cutoff is set to 0
     # disable tracker if read_cutoff is set to 0
     if flaskbb_config["TRACKER_LENGTH"] == 0:
     if flaskbb_config["TRACKER_LENGTH"] == 0:
@@ -344,13 +345,13 @@ def mark_online(user_id, guest=False):  # pragma: no cover
     """
     """
     user_id = to_bytes(user_id)
     user_id = to_bytes(user_id)
     now = int(time.time())
     now = int(time.time())
-    expires = now + (flaskbb_config['ONLINE_LAST_MINUTES'] * 60) + 10
+    expires = now + (flaskbb_config["ONLINE_LAST_MINUTES"] * 60) + 10
     if guest:
     if guest:
-        all_users_key = 'online-guests/%d' % (now // 60)
-        user_key = 'guest-activity/%s' % user_id
+        all_users_key = "online-guests/%d" % (now // 60)
+        user_key = "guest-activity/%s" % user_id
     else:
     else:
-        all_users_key = 'online-users/%d' % (now // 60)
-        user_key = 'user-activity/%s' % user_id
+        all_users_key = "online-users/%d" % (now // 60)
+        user_key = "user-activity/%s" % user_id
     p = redis_store.pipeline()
     p = redis_store.pipeline()
     p.sadd(all_users_key, user_id)
     p.sadd(all_users_key, user_id)
     p.set(user_key, now)
     p.set(user_key, now)
@@ -365,13 +366,15 @@ def get_online_users(guest=False):  # pragma: no cover
     :param guest: If True, it will return the online guests
     :param guest: If True, it will return the online guests
     """
     """
     current = int(time.time()) // 60
     current = int(time.time()) // 60
-    minutes = range_method(flaskbb_config['ONLINE_LAST_MINUTES'])
+    minutes = range_method(flaskbb_config["ONLINE_LAST_MINUTES"])
     if guest:
     if guest:
-        users = redis_store.sunion(['online-guests/%d' % (current - x)
-                                    for x in minutes])
+        users = redis_store.sunion(
+            ["online-guests/%d" % (current - x) for x in minutes]
+        )
     else:
     else:
-        users = redis_store.sunion(['online-users/%d' % (current - x)
-                                    for x in minutes])
+        users = redis_store.sunion(
+            ["online-users/%d" % (current - x) for x in minutes]
+        )
 
 
     return [to_unicode(u) for u in users]
     return [to_unicode(u) for u in users]
 
 
@@ -384,12 +387,12 @@ def crop_title(title, length=None, suffix="..."):
     :param suffix: The suffix which should be appended at the
     :param suffix: The suffix which should be appended at the
                    end of the title.
                    end of the title.
     """
     """
-    length = flaskbb_config['TITLE_LENGTH'] if length is None else length
+    length = flaskbb_config["TITLE_LENGTH"] if length is None else length
 
 
     if len(title) <= length:
     if len(title) <= length:
         return title
         return title
 
 
-    return title[:length].rsplit(' ', 1)[0] + suffix
+    return title[:length].rsplit(" ", 1)[0] + suffix
 
 
 
 
 def is_online(user):
 def is_online(user):
@@ -411,7 +414,7 @@ def time_diff():
     variable from the configuration.
     variable from the configuration.
     """
     """
     now = time_utcnow()
     now = time_utcnow()
-    diff = now - timedelta(minutes=flaskbb_config['ONLINE_LAST_MINUTES'])
+    diff = now - timedelta(minutes=flaskbb_config["ONLINE_LAST_MINUTES"])
     return diff
     return diff
 
 
 
 
@@ -423,25 +426,24 @@ def _get_user_locale():
 
 
 
 
 def _format_html_time_tag(datetime, what_to_display):
 def _format_html_time_tag(datetime, what_to_display):
-    if what_to_display == 'date-only':
+    if what_to_display == "date-only":
         content = babel_format_date(datetime, locale=_get_user_locale())
         content = babel_format_date(datetime, locale=_get_user_locale())
-    elif what_to_display == 'date-and-time':
+    elif what_to_display == "date-and-time":
         content = babel_format_datetime(
         content = babel_format_datetime(
-            datetime,
-            tzinfo=UTC,
-            locale=_get_user_locale()
+            datetime, tzinfo=UTC, locale=_get_user_locale()
         )
         )
         # While this could be done with a format string, that would
         # While this could be done with a format string, that would
         # hinder internationalization and honestly why bother.
         # hinder internationalization and honestly why bother.
-        content += ' UTC'
+        content += " UTC"
     else:
     else:
-        raise ValueError('what_to_display argument invalid')
+        raise ValueError("what_to_display argument invalid")
 
 
     isoformat = datetime.isoformat()
     isoformat = datetime.isoformat()
 
 
     return Markup(
     return Markup(
-        '<time datetime="{}" data-what_to_display="{}">{}</time>'
-        .format(isoformat, what_to_display, content)
+        '<time datetime="{}" data-what_to_display="{}">{}</time>'.format(
+            isoformat, what_to_display, content
+        )
     )
     )
 
 
 
 
@@ -451,7 +453,7 @@ def format_datetime(datetime):
     :param value: The datetime object that should be formatted
     :param value: The datetime object that should be formatted
     :rtype: Markup
     :rtype: Markup
     """
     """
-    return _format_html_time_tag(datetime, 'date-and-time')
+    return _format_html_time_tag(datetime, "date-and-time")
 
 
 
 
 def format_date(datetime, format=None):
 def format_date(datetime, format=None):
@@ -462,14 +464,14 @@ def format_date(datetime, format=None):
     """
     """
     if format:
     if format:
         warnings.warn(
         warnings.warn(
-            'This API has been deprecated due to i18n concerns.  Please use  '
-            'Jinja filters format_datetime and format_date without arguments '
-            'to format complete and date-only timestamps respectively.',
-            DeprecationWarning
+            "This API has been deprecated due to i18n concerns.  Please use  "
+            "Jinja filters format_datetime and format_date without arguments "
+            "to format complete and date-only timestamps respectively.",
+            DeprecationWarning,
         )
         )
-        if '%H' in format:
+        if "%H" in format:
             return format_datetime(datetime)
             return format_datetime(datetime)
-    return _format_html_time_tag(datetime, 'date-only')
+    return _format_html_time_tag(datetime, "date-only")
 
 
 
 
 def format_timedelta(delta, **kwargs):
 def format_timedelta(delta, **kwargs):
@@ -495,10 +497,11 @@ def format_quote(username, content):
     :param username: The username of a user.
     :param username: The username of a user.
     :param content: The content of the quote
     :param content: The content of the quote
     """
     """
-    profile_url = url_for('user.profile', username=username)
-    content = "\n> ".join(content.strip().split('\n'))
-    quote = u"**[{username}]({profile_url}) wrote:**\n> {content}\n".\
-            format(username=username, profile_url=profile_url, content=content)
+    profile_url = url_for("user.profile", username=username)
+    content = "\n> ".join(content.strip().split("\n"))
+    quote = u"**[{username}]({profile_url}) wrote:**\n> {content}\n".format(
+        username=username, profile_url=profile_url, content=content
+    )
 
 
     return quote
     return quote
 
 
@@ -517,7 +520,7 @@ def get_image_info(url):
         "content_type": "",
         "content_type": "",
         "size": image_size,
         "size": image_size,
         "width": 0,
         "width": 0,
-        "height": 0
+        "height": 0,
     }
     }
 
 
     # lets set a hard limit of 10MB
     # lets set a hard limit of 10MB
@@ -563,8 +566,7 @@ def check_image(url):
 
 
     if not img_info["content_type"] in flaskbb_config["AVATAR_TYPES"]:
     if not img_info["content_type"] in flaskbb_config["AVATAR_TYPES"]:
         error = "Image type {} is not allowed. Allowed types are: {}".format(
         error = "Image type {} is not allowed. Allowed types are: {}".format(
-            img_info["content_type"],
-            ", ".join(flaskbb_config["AVATAR_TYPES"])
+            img_info["content_type"], ", ".join(flaskbb_config["AVATAR_TYPES"])
         )
         )
         return error, False
         return error, False
 
 
@@ -635,7 +637,7 @@ def app_config_from_env(app, prefix="FLASKBB_"):
     """
     """
     for key, value in iteritems(os.environ):
     for key, value in iteritems(os.environ):
         if key.startswith(prefix):
         if key.startswith(prefix):
-            key = key[len(prefix):]
+            key = key[len(prefix) :]
             try:
             try:
                 value = ast.literal_eval(value)
                 value = ast.literal_eval(value)
             except (ValueError, SyntaxError):
             except (ValueError, SyntaxError):
@@ -724,24 +726,26 @@ class ReverseProxyPathFix(object):
         self.force_https = force_https
         self.force_https = force_https
 
 
     def __call__(self, environ, start_response):
     def __call__(self, environ, start_response):
-        script_name = environ.get('HTTP_X_SCRIPT_NAME', '')
+        script_name = environ.get("HTTP_X_SCRIPT_NAME", "")
         if script_name:
         if script_name:
-            environ['SCRIPT_NAME'] = script_name
-            path_info = environ.get('PATH_INFO', '')
+            environ["SCRIPT_NAME"] = script_name
+            path_info = environ.get("PATH_INFO", "")
             if path_info and path_info.startswith(script_name):
             if path_info and path_info.startswith(script_name):
-                environ['PATH_INFO'] = path_info[len(script_name):]
-        server = environ.get('HTTP_X_FORWARDED_SERVER_CUSTOM',
-                             environ.get('HTTP_X_FORWARDED_SERVER', ''))
+                environ["PATH_INFO"] = path_info[len(script_name) :]
+        server = environ.get(
+            "HTTP_X_FORWARDED_SERVER_CUSTOM",
+            environ.get("HTTP_X_FORWARDED_SERVER", ""),
+        )
         if server:
         if server:
-            environ['HTTP_HOST'] = server
+            environ["HTTP_HOST"] = server
 
 
-        scheme = environ.get('HTTP_X_SCHEME', '')
+        scheme = environ.get("HTTP_X_SCHEME", "")
 
 
         if scheme:
         if scheme:
-            environ['wsgi.url_scheme'] = scheme
+            environ["wsgi.url_scheme"] = scheme
 
 
         if self.force_https:
         if self.force_https:
-            environ['wsgi.url_scheme'] = 'https'
+            environ["wsgi.url_scheme"] = "https"
 
 
         return self.app(environ, start_response)
         return self.app(environ, start_response)
 
 
@@ -757,32 +761,35 @@ def real(obj):
 
 
 def parse_pkg_metadata(dist_name):
 def parse_pkg_metadata(dist_name):
     try:
     try:
-        raw_metadata = get_distribution(dist_name).get_metadata('METADATA')
+        raw_metadata = pkg_resources.get_distribution(dist_name).get_metadata(
+            "METADATA"
+        )
     except FileNotFoundError:
     except FileNotFoundError:
-        raw_metadata = get_distribution(dist_name).get_metadata('PKG-INFO')
+        raw_metadata = pkg_resources.get_distribution(dist_name).get_metadata(
+            "PKG-INFO"
+        )
 
 
     metadata = {}
     metadata = {}
 
 
     # lets use the Parser from email to parse our metadata :)
     # lets use the Parser from email to parse our metadata :)
     for key, value in message_from_string(raw_metadata).items():
     for key, value in message_from_string(raw_metadata).items():
-        metadata[key.replace('-', '_').lower()] = value
+        metadata[key.replace("-", "_").lower()] = value
 
 
     return metadata
     return metadata
 
 
 
 
 def anonymous_required(f):
 def anonymous_required(f):
-
     @wraps(f)
     @wraps(f)
     def wrapper(*a, **k):
     def wrapper(*a, **k):
         if current_user is not None and current_user.is_authenticated:
         if current_user is not None and current_user.is_authenticated:
-            return redirect_or_next(url_for('forum.index'))
+            return redirect_or_next(url_for("forum.index"))
         return f(*a, **k)
         return f(*a, **k)
 
 
     return wrapper
     return wrapper
 
 
 
 
 def enforce_recaptcha(limiter):
 def enforce_recaptcha(limiter):
-    current_limit = getattr(g, 'view_rate_limit', None)
+    current_limit = getattr(g, "view_rate_limit", None)
     login_recaptcha = False
     login_recaptcha = False
     if current_limit is not None:
     if current_limit is not None:
         window_stats = limiter.limiter.get_window_stats(*current_limit)
         window_stats = limiter.limiter.get_window_stats(*current_limit)
@@ -792,7 +799,6 @@ def enforce_recaptcha(limiter):
 
 
 
 
 def registration_enabled(f):
 def registration_enabled(f):
-
     @wraps(f)
     @wraps(f)
     def wrapper(*a, **k):
     def wrapper(*a, **k):
         if not flaskbb_config["REGISTRATION_ENABLED"]:
         if not flaskbb_config["REGISTRATION_ENABLED"]:
@@ -804,13 +810,13 @@ def registration_enabled(f):
 
 
 
 
 def requires_unactivated(f):
 def requires_unactivated(f):
-
     @wraps(f)
     @wraps(f)
     def wrapper(*a, **k):
     def wrapper(*a, **k):
         if current_user.is_active or not flaskbb_config["ACTIVATE_ACCOUNT"]:
         if current_user.is_active or not flaskbb_config["ACTIVATE_ACCOUNT"]:
             flash(_("This account is already activated."), "info")
             flash(_("This account is already activated."), "info")
-            return redirect(url_for('forum.index'))
+            return redirect(url_for("forum.index"))
         return f(*a, **k)
         return f(*a, **k)
+
     return wrapper
     return wrapper