Example #1
0
def create_app(settings_override=None):
    """Return the PyGotham admin application.

    :param settings_override: a ``dict`` of settings to override.
    """
    app = factory.create_app(__name__, __path__, settings_override)

    app.jinja_env.filters['rst'] = filters.rst_to_html

    # Because the admin is being wrapped inside an app, the url needs to
    # be overridden to use / instead of the default of /admin/. One of
    # the side effects of doing this is that the static assets won't
    # serve correctly without overriding static_url_path as well.
    admin = Admin(
        app,
        name='PyGotham',
        static_url_path='/admin',
        subdomain='<event_slug>',
        index_view=HomeView(endpoint='', url='/'),
    )

    # Iterate through all the modules of the current package. For each
    # module, check the public API for any instances of types that can
    # be added to the Flask-Admin menu and register them.
    for _, name, _ in pkgutil.iter_modules(__path__):
        module = importlib.import_module('{}.{}'.format(__name__, name))
        for attr in dir(module):
            view = getattr(module, attr)
            if isinstance(view, ModelView):
                admin.add_view(view)
            elif isinstance(view, MenuLink):
                admin.add_link(view)

    return app
Example #2
0
def create_app(settings_override=None):
    """Return the PyGotham frontend application.

    :param settings_override: a ``dict`` of settings to override.

    """
    app = factory.create_app(__name__, __path__, settings_override)

    Sentry(app)

    @app.before_request
    def register_about_page_navbar_links():
        """Generate all about page titles and URLs for use in the navbar."""
        # NOTE: Because of the unconventional usage of Flask-Copilot
        # (i.e. not as a routing decorator and always assigning an
        # endpoint), our shorter navbar_paths must come before longer
        # ones.
        for page in AboutPage.query.current.filter_by(active=True).order_by(
                func.array_length(AboutPage.navbar_path, 1)):
            copilot.register_entry({
                'path': page.navbar_path,
                'endpoint': 'about.rst_content',
                'url_for_kwargs': {'slug': page.slug},
            })

    app.jinja_env.filters['clean_url'] = filters.clean_url
    app.jinja_env.filters['is_hidden_field'] = filters.is_hidden_field
    app.jinja_env.filters['rst'] = filters.rst_to_html
    app.jinja_env.filters['time_zone'] = filters.time_zone

    if not app.debug:
        for e in (404, 500):
            app.errorhandler(e)(handle_error)

    return app
Example #3
0
def create_app(settings_override=None):
    """Return the PyGotham API application.

    :param settings_override: a ``dict`` of settings to override.
    """
    app = factory.create_app(__name__, __path__, settings_override)
    return app
Example #4
0
def create_app(settings_override=None):
    """Return the PyGotham admin application.

    :param settings_override: a ``dict`` of settings to override.

    """
    app = factory.create_app(__name__, __path__, settings_override)

    app.jinja_env.filters['rst'] = filters.rst_to_html

    # Because the admin is being wrapped inside an app, the url needs to
    # be overridden to use / instead of the default of /admin/. One of
    # the side effects of doing this is that the static assets won't
    # serve correctly without overriding static_url_path as well.
    admin = Admin(
        app, name='PyGotham',
        static_url_path='/admin',
        index_view=HomeView(endpoint='', url='/'),
    )

    # Iterate through all the modules of the current package. For each
    # module, check the public API for any instances of types that can
    # be added to the Flask-Admin menu and register them.
    for _, name, _ in pkgutil.iter_modules(__path__):
        module = importlib.import_module('{}.{}'.format(__name__, name))
        for attr in dir(module):
            view = getattr(module, attr)
            if isinstance(view, ModelView):
                admin.add_view(view)
            elif isinstance(view, MenuLink):
                admin.add_link(view)

    return app
Example #5
0
def create_app(settings_override=None):
    """Return the PyGotham frontend application.

    :param settings_override: a ``dict`` of settings to override.

    """
    app = factory.create_app(__name__, __path__, settings_override)

    Sentry(app)

    @app.before_request
    def register_about_page_navbar_links():
        """Generate all about page titles and URLs for use in the navbar."""
        for page in AboutPage.query.current.filter_by(active=True):
            copilot.register_entry({
                'path': (page.navbar_section, page.title),
                'endpoint': 'about.rst_content',
                'url_for_kwargs': {'slug': page.slug},
            })

    app.jinja_env.filters['clean_url'] = filters.clean_url
    app.jinja_env.filters['is_hidden_field'] = filters.is_hidden_field
    app.jinja_env.filters['rst'] = filters.rst_to_html
    app.jinja_env.filters['time_zone'] = filters.time_zone

    if not app.debug:
        for e in (404, 500):
            app.errorhandler(e)(handle_error)

    return app
Example #6
0
def create_app(settings_override=None):
    """Return the PyGotham frontend application.

    :param settings_override: a ``dict`` of settings to override.

    """
    app = factory.create_app(__name__, __path__, settings_override)

    Sentry(app)

    @app.before_request
    def register_about_page_navbar_links():
        """Generate all about page titles and URLs for use in the navbar."""
        for page in AboutPage.query.current.filter_by(active=True):
            copilot.register_entry({
                'path': (page.navbar_section, page.title),
                'endpoint': 'about.rst_content',
                'url_for_kwargs': {
                    'slug': page.slug
                },
            })

    app.jinja_env.filters['clean_url'] = filters.clean_url
    app.jinja_env.filters['is_hidden_field'] = filters.is_hidden_field
    app.jinja_env.filters['rst'] = filters.rst_to_html
    app.jinja_env.filters['time_zone'] = filters.time_zone

    if not app.debug:
        for e in (404, 500):
            app.errorhandler(e)(handle_error)

    return app
Example #7
0
def app():
    app = create_app(__name__, '', settings)

    context = app.test_request_context()
    context.push()

    return app
Example #8
0
def create_app(settings_override=None):
    """Return the PyGotham frontend application.

    :param settings_override: a ``dict`` of settings to override.

    """
    app = factory.create_app(__name__, __path__, settings_override)

    Sentry(app)

    @app.url_defaults
    def add_event_slug(endpoint, values):
        if 'event_slug' in values or not g.current_event:
            return
        if app.url_map.is_endpoint_expecting(endpoint, 'event_slug'):
            values['event_slug'] = g.current_event.slug

    @app.url_value_preprocessor
    def current_event_from_url(endpoint, values):
        if values is None:
            values = {}
        if endpoint and app.url_map.is_endpoint_expecting(
                endpoint, 'event_slug'):
            now = arrow.utcnow().to('America/New_York').naive
            g.current_event = Event.query.filter(
                Event.slug == values.pop('event_slug', None),
                Event.active == True,
                or_(Event.activity_begins == None,
                    Event.activity_begins <= now),
                or_(Event.activity_ends == None, Event.activity_ends > now),
            ).order_by(Event.activity_begins).first_or_404()
        else:
            g.current_event = Event.query.first()

    @app.context_processor
    def current_event():
        return {'current_event': g.current_event}

    @app.before_request
    def register_about_page_navbar_links():
        """Generate all about page titles and URLs for use in the navbar."""
        for page in AboutPage.query.current.filter_by(active=True):
            copilot.register_entry({
                'path': (page.navbar_section, page.title),
                'endpoint': 'about.rst_content',
                'url_for_kwargs': {
                    'slug': page.slug
                },
            })

    app.jinja_env.filters['clean_url'] = filters.clean_url
    app.jinja_env.filters['is_hidden_field'] = filters.is_hidden_field
    app.jinja_env.filters['rst'] = filters.rst_to_html

    if not app.debug:
        for e in (404, 500):
            app.errorhandler(e)(handle_error)

    return app
Example #9
0
def create_app(settings_override=None):
    """Return the PyGotham API application.

    :param settings_override: a ``dict`` of settings to override.
    """
    app = factory.create_app(__name__, __path__, settings_override)
    marshmallow.init_app(app)
    return app
Example #10
0
def create_app(settings_override=None):
    """Return the PyGotham frontend application.

    :param settings_override: a ``dict`` of settings to override.

    """
    app = factory.create_app(__name__, __path__, settings_override)

    Sentry(app)

    @app.url_defaults
    def add_event_slug(endpoint, values):
        if 'event_slug' in values or not g.current_event:
            return
        if app.url_map.is_endpoint_expecting(endpoint, 'event_slug'):
            values['event_slug'] = g.current_event.slug

    @app.url_value_preprocessor
    def current_event_from_url(endpoint, values):
        if values is None:
            values = {}
        if endpoint and app.url_map.is_endpoint_expecting(endpoint, 'event_slug'):
            now = arrow.utcnow().to('America/New_York').naive
            g.current_event = Event.query.filter(
                Event.slug == values.pop('event_slug', None),
                Event.active == True,
                or_(Event.activity_begins == None, Event.activity_begins <= now),
                or_(Event.activity_ends == None, Event.activity_ends > now),
            ).order_by(Event.activity_begins).first_or_404()
        else:
            g.current_event = Event.query.first()

    @app.context_processor
    def current_event():
        return {'current_event': g.current_event}

    @app.before_request
    def register_about_page_navbar_links():
        """Generate all about page titles and URLs for use in the navbar."""
        for page in AboutPage.query.current.filter_by(active=True):
            copilot.register_entry({
                'path': (page.navbar_section, page.title),
                'endpoint': 'about.rst_content',
                'url_for_kwargs': {'slug': page.slug},
            })

    app.jinja_env.filters['clean_url'] = filters.clean_url
    app.jinja_env.filters['is_hidden_field'] = filters.is_hidden_field
    app.jinja_env.filters['rst'] = filters.rst_to_html

    if not app.debug:
        for e in (404, 500):
            app.errorhandler(e)(handle_error)

    return app
Example #11
0
def create_app(settings_override=None):
    """Return the PyGotham frontend application.

    :param settings_override: a ``dict`` of settings to override.

    """
    app = factory.create_app(__name__, __path__, settings_override)

    Sentry(app)

    @app.before_request
    def register_about_page_navbar_links():
        """Generate all about page titles and URLs for use in the navbar."""
        # NOTE: Because of the unconventional usage of Flask-Copilot
        # (i.e. not as a routing decorator and always assigning an
        # endpoint), our shorter navbar_paths must come before longer
        # ones.
        for page in AboutPage.query.current.filter_by(active=True).order_by(
                func.array_length(AboutPage.navbar_path, 1)):
            copilot.register_entry({
                'path': page.navbar_path,
                'endpoint': 'about.rst_content',
                'url_for_kwargs': {
                    'slug': page.slug
                },
            })

    app.jinja_env.filters['clean_url'] = filters.clean_url
    app.jinja_env.filters['is_hidden_field'] = filters.is_hidden_field
    app.jinja_env.filters['rst'] = filters.rst_to_html
    app.jinja_env.filters['time_zone'] = filters.time_zone

    if not app.debug:
        for e in (404, 500):
            app.errorhandler(e)(handle_error)

    return app
Example #12
0
"""Management commands."""

from flask_migrate import MigrateCommand
from flask_script import Manager
from flask_script.commands import Shell

from pygotham.factory import create_app
from pygotham.manage import CreateAdmin, CreateEvent, CreateUser

manager = Manager(create_app(__name__, ''), with_default_commands=False)
manager.add_command('create_admin', CreateAdmin())
manager.add_command('create_event', CreateEvent())
manager.add_command('create_user', CreateUser())
manager.add_command('db', MigrateCommand)
manager.add_command('shell', Shell())

if __name__ == '__main__':
    manager.run()
Example #13
0
"""Management commands."""

from flask_migrate import MigrateCommand
from flask_script import Manager

from pygotham.factory import create_app
from pygotham.manage import CreateAdmin, CreateEvent, CreateUser

manager = Manager(create_app(__name__, ''))
manager.add_command('create_admin', CreateAdmin())
manager.add_command('create_event', CreateEvent())
manager.add_command('create_user', CreateUser())
manager.add_command('db', MigrateCommand)

if __name__ == '__main__':
    manager.run()
Example #14
0
def create_app(settings_override=None):
    """Return the PyGotham frontend application.

    :param settings_override: a ``dict`` of settings to override.

    """
    app = factory.create_app(__name__, __path__, settings_override)

    Sentry(app)

    @app.url_defaults
    def add_event_slug(endpoint, values):
        if 'event_slug' in values or not g.current_event:
            return
        if app.url_map.is_endpoint_expecting(endpoint, 'event_slug'):
            values['event_slug'] = g.current_event.slug

    @app.url_value_preprocessor
    def current_event_from_url(endpoint, values):
        if values is None:
            values = {}
        if endpoint and app.url_map.is_endpoint_expecting(endpoint, 'event_slug'):
            now = arrow.utcnow().to('America/New_York').naive
            g.current_event = Event.query.filter(
                Event.slug == values.pop('event_slug', None),
                Event.active == True,
                or_(Event.activity_begins == None, Event.activity_begins <= now),
                or_(Event.activity_ends == None, Event.activity_ends > now),
            ).order_by(Event.activity_begins).first_or_404()
        else:
            g.current_event = Event.query.first()

    @app.context_processor
    def current_event():
        return {'current_event': g.current_event}

    @app.context_processor
    def generate_navbar():
        """Autodiscover links that should populate the site's navbar."""
        # navbar_links is a dict of the form
        # {section_name: {link_name: link_value, ...}, ...}
        navbar_links = defaultdict(dict)

        # First, autogenerate a list based on available routes
        # Available routes are any that have a GET method and have all
        # arguments (if any) provided default values
        for rule in app.url_map.iter_rules():
            section_name = rule.endpoint.split('.')[0]
            get_allowed = 'get' in (method.lower() for method in rule.methods)
            required_args = set(rule.arguments)
            try:
                provided_args = set(rule.defaults.keys())
            except AttributeError:
                provided_args = set()
            missing_args = required_args.difference(provided_args)
            if get_allowed and not missing_args:
                rule_name = rule.endpoint.split('.')[1]
                rule_name = rule_name.replace('_', ' ').title()
                navbar_links[section_name][rule_name] = url_for(rule.endpoint)

        # Find module-specific overrides and update the routes
        for _, name, _ in pkgutil.iter_modules(__path__):
            m = importlib.import_module('{}.{}'.format(__name__, name))
            if hasattr(m, 'get_nav_links'):
                try:
                    del navbar_links[name]
                except KeyError:
                    # We need to do this before the update in case the
                    # section name has been changed
                    pass
                navbar_links.update(m.get_nav_links())

        # Exclude certain sections whose links are exposed elsewhere
        for section in ('home', 'security', 'profile'):
            try:
                del navbar_links[section]
            except KeyError:
                # This links are displayed elsewhere, so remove the sections
                # from the navbar entirely
                pass

        nav = []
        # Normalize, hoist, and sort
        for section, links in navbar_links.items():
            index_link = links.pop('Index', None) or links.pop('Home', None)
            subnav = sorted(links.items(), key=lambda item: item[0])
            if index_link:
                subnav.insert(0, ('Home', index_link))
            nav.append((section.title(), subnav))
        nav.sort(key=lambda item: item[0])
        return {'navbar': nav}

    app.jinja_env.filters['clean_url'] = filters.clean_url
    app.jinja_env.filters['is_hidden_field'] = filters.is_hidden_field
    app.jinja_env.filters['rst'] = filters.rst_to_html

    if not app.debug:
        for e in (404, 500):
            app.errorhandler(e)(handle_error)

    return app