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
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
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
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
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
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
def app(): app = create_app(__name__, '', settings) context = app.test_request_context() context.push() return app
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
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
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
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
"""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()
"""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()
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