""" Blueprints Package ================== Central registration of all Flask blueprints. """ import logging logger = logging.getLogger(__name__) def register_blueprints(app): """ Register all blueprints with the Flask application. Args: app: Flask application instance """ # Phase 1: Low-risk modules # Reports blueprint try: from blueprints.reports import bp as reports_bp app.register_blueprint(reports_bp) logger.info("Registered blueprint: reports") except ImportError as e: logger.debug(f"Blueprint reports not yet available: {e}") # API blueprint (analytics tracking) try: from blueprints.api import bp as api_bp from blueprints.api.routes_analytics import exempt_from_csrf app.register_blueprint(api_bp) exempt_from_csrf(app) logger.info("Registered blueprint: api (with CSRF exemption)") except ImportError as e: logger.debug(f"Blueprint api not yet available: {e}") except Exception as e: logger.error(f"Error registering api blueprint: {e}") # Push blueprint (Web Push VAPID) try: from blueprints.push import bp as push_bp from blueprints.push.routes import exempt_from_csrf as push_exempt app.register_blueprint(push_bp) push_exempt(app) logger.info("Registered blueprint: push (with CSRF exemption)") except ImportError as e: logger.debug(f"Blueprint push not yet available: {e}") except Exception as e: logger.error(f"Error registering push blueprint: {e}") # Unsubscribe blueprint (one-click e-mail unsubscribe, signed tokens) try: from blueprints.unsubscribe import bp as unsub_bp from blueprints.unsubscribe.routes import exempt_from_csrf as unsub_exempt app.register_blueprint(unsub_bp) unsub_exempt(app) logger.info("Registered blueprint: unsubscribe (with CSRF exemption)") except ImportError as e: logger.debug(f"Blueprint unsubscribe not yet available: {e}") except Exception as e: logger.error(f"Error registering unsubscribe blueprint: {e}") # Community blueprints - register directly (not nested) # to preserve endpoint names like 'calendar_index' instead of 'community.calendar.calendar_index' try: from blueprints.community.contacts import bp as contacts_bp app.register_blueprint(contacts_bp) logger.info("Registered blueprint: contacts") except ImportError as e: logger.debug(f"Blueprint contacts not yet available: {e}") try: from blueprints.community.classifieds import bp as classifieds_bp app.register_blueprint(classifieds_bp) logger.info("Registered blueprint: classifieds") except ImportError as e: logger.debug(f"Blueprint classifieds not yet available: {e}") try: from blueprints.community.calendar import bp as calendar_bp app.register_blueprint(calendar_bp) logger.info("Registered blueprint: calendar") except ImportError as e: logger.debug(f"Blueprint calendar not yet available: {e}") # Education blueprint try: from blueprints.education import bp as education_bp app.register_blueprint(education_bp) logger.info("Registered blueprint: education") except ImportError as e: logger.debug(f"Blueprint education not yet available: {e}") # Board blueprint (Rada Izby) try: from blueprints.board import bp as board_bp app.register_blueprint(board_bp) logger.info("Registered blueprint: board (Rada Izby)") except ImportError as e: logger.debug(f"Blueprint board not yet available: {e}") # IT Audit blueprint try: from blueprints.it_audit import bp as it_audit_bp app.register_blueprint(it_audit_bp) logger.info("Registered blueprint: it_audit") # Create aliases for backward compatibility _create_endpoint_aliases(app, it_audit_bp, { 'it_audit_form': 'it_audit.it_audit_form', 'it_audit_save': 'it_audit.it_audit_save', 'api_it_audit_matches': 'it_audit.api_it_audit_matches', 'api_it_audit_history': 'it_audit.api_it_audit_history', 'api_it_audit_export': 'it_audit.api_it_audit_export', }) logger.info("Created it_audit endpoint aliases") except ImportError as e: logger.debug(f"Blueprint it_audit not yet available: {e}") except Exception as e: logger.error(f"Error registering it_audit blueprint: {e}") # Audit dashboards blueprint (user-facing) try: from blueprints.audit import bp as audit_bp app.register_blueprint(audit_bp) logger.info("Registered blueprint: audit") # Create aliases for backward compatibility _create_endpoint_aliases(app, audit_bp, { 'seo_audit_dashboard': 'audit.seo_audit_dashboard', 'social_audit_dashboard': 'audit.social_audit_dashboard', 'gbp_audit_dashboard': 'audit.gbp_audit_dashboard', 'it_audit_dashboard': 'audit.it_audit_dashboard', }) logger.info("Created audit endpoint aliases") except ImportError as e: logger.debug(f"Blueprint audit not yet available: {e}") except Exception as e: logger.error(f"Error registering audit blueprint: {e}") # Phase 2: Auth + Public blueprints (with backward-compatible aliases) try: from blueprints.auth import bp as auth_bp app.register_blueprint(auth_bp) logger.info("Registered blueprint: auth") # Create aliases for backward compatibility # Old url_for('login') will still work alongside url_for('auth.login') _create_endpoint_aliases(app, auth_bp, { 'register': 'auth.register', 'login': 'auth.login', 'logout': 'auth.logout', 'verify_2fa': 'auth.verify_2fa', 'settings_2fa': 'auth.settings_2fa', 'settings_privacy': 'auth.settings_privacy', 'settings_blocks': 'auth.settings_blocks', 'settings_blocks_add': 'auth.settings_blocks_add', 'settings_blocks_remove': 'auth.settings_blocks_remove', 'forgot_password': 'auth.forgot_password', 'reset_password': 'auth.reset_password', 'verify_email': 'auth.verify_email', 'resend_verification': 'auth.resend_verification', # Account routes (konto) 'konto_dane': 'auth.konto_dane', 'konto_dane_save': 'auth.konto_dane_post', 'konto_prywatnosc': 'auth.konto_prywatnosc', 'konto_bezpieczenstwo': 'auth.konto_bezpieczenstwo', 'konto_blokady': 'auth.konto_blokady', 'konto_blokady_dodaj': 'auth.konto_blokady_dodaj', 'konto_blokady_usun': 'auth.konto_blokady_usun', }) logger.info("Created auth endpoint aliases") except ImportError as e: logger.debug(f"Blueprint auth not yet available: {e}") except Exception as e: logger.error(f"Error registering auth blueprint: {e}") try: from blueprints.public import bp as public_bp app.register_blueprint(public_bp) logger.info("Registered blueprint: public") # Create aliases for backward compatibility _create_endpoint_aliases(app, public_bp, { 'index': 'public.index', 'company_detail': 'public.company_detail', 'company_detail_by_slug': 'public.company_detail_by_slug', 'person_detail': 'public.person_detail', 'company_recommend': 'public.company_recommend', 'search': 'public.search', 'events': 'public.events', 'new_members': 'public.new_members', 'connections_map': 'public.connections_map', 'dashboard': 'public.dashboard', 'release_notes': 'public.release_notes', # ZOPK Public routes 'zopk_index': 'public.zopk_index', 'zopk_project_detail': 'public.zopk_project_detail', 'zopk_news_list': 'public.zopk_news_list', # PEJ Public routes 'pej_index': 'public.pej_index', 'pej_local_content': 'public.pej_local_content', 'pej_news': 'public.pej_news', # Announcements 'announcements_list': 'public.announcements_list', 'announcement_detail': 'public.announcement_detail', # Company Edit 'company_edit': 'public.company_edit', 'company_edit_save': 'public.company_edit_save', }) logger.info("Created public endpoint aliases") except ImportError as e: logger.debug(f"Blueprint public not yet available: {e}") except Exception as e: logger.error(f"Error registering public blueprint: {e}") # Phase 3: Forum blueprint try: from blueprints.forum import bp as forum_bp app.register_blueprint(forum_bp) logger.info("Registered blueprint: forum") # Create aliases for backward compatibility _create_endpoint_aliases(app, forum_bp, { 'forum_index': 'forum.forum_index', 'forum_new_topic': 'forum.forum_new_topic', 'forum_topic': 'forum.forum_topic', 'forum_reply': 'forum.forum_reply', 'admin_forum': 'forum.admin_forum', 'admin_forum_pin': 'forum.admin_forum_pin', 'admin_forum_lock': 'forum.admin_forum_lock', 'admin_forum_delete_topic': 'forum.admin_forum_delete_topic', 'admin_forum_delete_reply': 'forum.admin_forum_delete_reply', 'admin_forum_change_status': 'forum.admin_forum_change_status', # New forum modernization endpoints 'edit_topic': 'forum.edit_topic', 'edit_reply': 'forum.edit_reply', 'delete_own_reply': 'forum.delete_own_reply', 'react_to_topic': 'forum.react_to_topic', 'react_to_reply': 'forum.react_to_reply', 'subscribe_to_topic': 'forum.subscribe_to_topic', 'unsubscribe_from_topic': 'forum.unsubscribe_from_topic', 'report_content': 'forum.report_content', 'admin_edit_topic': 'forum.admin_edit_topic', 'admin_edit_reply': 'forum.admin_edit_reply', 'mark_as_solution': 'forum.mark_as_solution', 'restore_topic': 'forum.restore_topic', 'restore_reply': 'forum.restore_reply', 'admin_forum_reports': 'forum.admin_forum_reports', 'review_report': 'forum.review_report', 'topic_edit_history': 'forum.topic_edit_history', 'reply_edit_history': 'forum.reply_edit_history', 'admin_deleted_content': 'forum.admin_deleted_content', 'user_forum_stats': 'forum.user_forum_stats', 'admin_forum_bulk_action': 'forum.admin_forum_bulk_action', # Admin analytics & tools 'admin_forum_analytics': 'forum.admin_forum_analytics', 'admin_forum_export_activity': 'forum.admin_forum_export_activity', 'admin_move_topic': 'forum.admin_move_topic', 'admin_merge_topics': 'forum.admin_merge_topics', 'admin_forum_search': 'forum.admin_forum_search', 'admin_user_forum_activity': 'forum.admin_user_forum_activity', }) logger.info("Created forum endpoint aliases") except ImportError as e: logger.debug(f"Blueprint forum not yet available: {e}") except Exception as e: logger.error(f"Error registering forum blueprint: {e}") # Phase 4: Messages + Notifications blueprint try: from blueprints.messages import bp as messages_bp app.register_blueprint(messages_bp) logger.info("Registered blueprint: messages") # Create aliases for backward compatibility _create_endpoint_aliases(app, messages_bp, { 'messages_inbox': 'messages.messages_inbox', 'messages_sent': 'messages.messages_sent', 'messages_new': 'messages.messages_new', 'messages_send': 'messages.messages_send', 'messages_view': 'messages.messages_view', 'messages_reply': 'messages.messages_reply', 'messages_delete': 'messages.messages_delete', 'api_unread_count': 'messages.api_unread_count', 'api_notifications': 'messages.api_notifications', 'api_notification_mark_read': 'messages.api_notification_mark_read', 'api_notifications_mark_all_read': 'messages.api_notifications_mark_all_read', 'api_notifications_unread_count': 'messages.api_notifications_unread_count', 'group_compose': 'messages.group_compose', 'group_create': 'messages.group_create', 'group_view': 'messages.group_view', 'group_send': 'messages.group_send', 'group_manage': 'messages.group_manage', 'group_add_member': 'messages.group_add_member', 'group_remove_member': 'messages.group_remove_member', 'group_change_role': 'messages.group_change_role', 'group_edit': 'messages.group_edit', 'group_poll_messages': 'messages.group_poll_messages', }) logger.info("Created messages endpoint aliases") except ImportError as e: logger.debug(f"Blueprint messages not yet available: {e}") except Exception as e: logger.error(f"Error registering messages blueprint: {e}") # Phase 5: Chat blueprint try: from blueprints.chat import bp as chat_bp app.register_blueprint(chat_bp) logger.info("Registered blueprint: chat") # Create aliases for backward compatibility _create_endpoint_aliases(app, chat_bp, { 'chat': 'chat.chat', 'chat_settings': 'chat.chat_settings', 'chat_start': 'chat.chat_start', 'chat_send_message': 'chat.chat_send_message', 'chat_get_history': 'chat.chat_get_history', 'chat_list_conversations': 'chat.chat_list_conversations', 'chat_delete_conversation': 'chat.chat_delete_conversation', 'chat_feedback': 'chat.chat_feedback', 'chat_analytics': 'chat.chat_analytics', }) logger.info("Created chat endpoint aliases") except ImportError as e: logger.debug(f"Blueprint chat not yet available: {e}") except Exception as e: logger.error(f"Error registering chat blueprint: {e}") # Phase 6: Admin blueprint (part 1: users, recommendations, fees, calendar) try: from blueprints.admin import bp as admin_bp app.register_blueprint(admin_bp) logger.info("Registered blueprint: admin") # Create aliases for backward compatibility _create_endpoint_aliases(app, admin_bp, { # Recommendations 'admin_recommendations': 'admin.admin_recommendations', 'admin_recommendation_approve': 'admin.admin_recommendation_approve', 'admin_recommendation_reject': 'admin.admin_recommendation_reject', # Users 'admin_users': 'admin.admin_users', 'admin_user_add': 'admin.admin_user_add', 'admin_user_toggle_admin': 'admin.admin_user_toggle_admin', 'admin_user_toggle_verified': 'admin.admin_user_toggle_verified', 'admin_user_update': 'admin.admin_user_update', 'admin_user_assign_company': 'admin.admin_user_assign_company', 'admin_user_delete': 'admin.admin_user_delete', 'admin_user_reset_password': 'admin.admin_user_reset_password', # Fees 'admin_fees': 'admin.admin_fees', 'admin_fees_generate': 'admin.admin_fees_generate', 'admin_fees_mark_paid': 'admin.admin_fees_mark_paid', 'admin_fees_bulk_mark_paid': 'admin.admin_fees_bulk_mark_paid', 'admin_fees_export': 'admin.admin_fees_export', # Calendar 'admin_calendar': 'admin.admin_calendar', 'admin_calendar_new': 'admin.admin_calendar_new', 'admin_calendar_delete': 'admin.admin_calendar_delete', # SEO & Audits (Phase 6.2a) 'admin_seo': 'admin.admin_seo', 'admin_gbp_audit': 'admin.admin_gbp_audit', # Status, Health (Phase 6.2c) 'admin_status': 'admin.admin_status', 'admin_health': 'admin.admin_health', # Social Media (Phase 6.2e) 'admin_social_audit': 'admin.admin_social_audit', # Digital Maturity & KRS Audit (Phase 6.2f) 'digital_maturity_dashboard': 'admin.digital_maturity_dashboard', 'admin_krs_audit': 'admin.admin_krs_audit', 'admin_it_audit': 'admin.admin_it_audit', # Security (Phase 6.2d) 'admin_security': 'admin.admin_security', 'acknowledge_security_alert': 'admin.acknowledge_security_alert', 'resolve_security_alert': 'admin.resolve_security_alert', 'unlock_account': 'admin.unlock_account', 'api_geoip_stats': 'admin.api_geoip_stats', # Announcements (Phase 6.2d) 'admin_announcements': 'admin.admin_announcements', 'admin_announcements_new': 'admin.admin_announcements_new', 'admin_announcements_edit': 'admin.admin_announcements_edit', 'admin_announcements_publish': 'admin.admin_announcements_publish', 'admin_announcements_archive': 'admin.admin_announcements_archive', 'admin_announcements_delete': 'admin.admin_announcements_delete', # Insights (Phase 6.2b) 'admin_insights': 'admin.admin_insights', 'api_get_insights': 'admin.api_get_insights', 'api_update_insight_status': 'admin.api_update_insight_status', 'api_sync_insights': 'admin.api_sync_insights', 'api_insights_stats': 'admin.api_insights_stats', 'api_ai_learning_status': 'admin.api_ai_learning_status', 'api_chat_stats': 'admin.api_chat_stats', # Analytics (Phase 6.2b) 'admin_analytics': 'admin.admin_analytics', 'admin_analytics_export': 'admin.admin_analytics_export', # AI Usage Monitoring (Phase 6.2b) 'admin_ai_usage': 'admin.admin_ai_usage', 'admin_ai_usage_user': 'admin.admin_ai_usage_user', # ZOPK Dashboard & News (Phase 6.3) 'admin_zopk': 'admin.admin_zopk', 'admin_zopk_news': 'admin.admin_zopk_news', 'admin_zopk_news_approve': 'admin.admin_zopk_news_approve', 'admin_zopk_news_reject': 'admin.admin_zopk_news_reject', 'admin_zopk_news_add': 'admin.admin_zopk_news_add', 'admin_zopk_reject_old_news': 'admin.admin_zopk_reject_old_news', 'admin_zopk_news_star_counts': 'admin.admin_zopk_news_star_counts', 'admin_zopk_reject_by_stars': 'admin.admin_zopk_reject_by_stars', 'admin_zopk_evaluate_ai': 'admin.admin_zopk_evaluate_ai', 'admin_zopk_reevaluate_scores': 'admin.admin_zopk_reevaluate_scores', 'admin_zopk_reevaluate_low_scores': 'admin.admin_zopk_reevaluate_low_scores', 'admin_zopk_scrape_stats': 'admin.admin_zopk_scrape_stats', 'admin_zopk_scrape_content': 'admin.admin_zopk_scrape_content', 'admin_zopk_scrape_single': 'admin.admin_zopk_scrape_single', 'admin_zopk_news_scrape_stream': 'admin.admin_zopk_news_scrape_stream', 'api_zopk_search_news': 'admin.api_zopk_search_news', # ZOPK Knowledge (Phase 6.3) 'admin_zopk_knowledge_stats': 'admin.admin_zopk_knowledge_stats', 'admin_zopk_knowledge_extract': 'admin.admin_zopk_knowledge_extract', 'admin_zopk_knowledge_extract_single': 'admin.admin_zopk_knowledge_extract_single', 'admin_zopk_generate_embeddings': 'admin.admin_zopk_generate_embeddings', 'admin_zopk_knowledge_extract_stream': 'admin.admin_zopk_knowledge_extract_stream', 'admin_zopk_embeddings_stream': 'admin.admin_zopk_embeddings_stream', 'admin_zopk_knowledge_dashboard': 'admin.admin_zopk_knowledge_dashboard', 'admin_zopk_knowledge_chunks': 'admin.admin_zopk_knowledge_chunks', 'admin_zopk_knowledge_facts': 'admin.admin_zopk_knowledge_facts', 'admin_zopk_knowledge_entities': 'admin.admin_zopk_knowledge_entities', 'admin_zopk_knowledge_duplicates': 'admin.admin_zopk_knowledge_duplicates', 'admin_zopk_knowledge_graph': 'admin.admin_zopk_knowledge_graph', 'admin_zopk_fact_duplicates': 'admin.admin_zopk_fact_duplicates', # ZOPK Timeline (Phase 6.3) 'admin_zopk_timeline': 'admin.admin_zopk_timeline', # KRS API (Phase 6.4) 'api_krs_audit_trigger': 'admin.api_krs_audit_trigger', 'api_krs_audit_batch': 'admin.api_krs_audit_batch', 'api_krs_pdf_download': 'admin.api_krs_pdf_download', }) logger.info("Created admin endpoint aliases") except ImportError as e: logger.debug(f"Blueprint admin not yet available: {e}") except Exception as e: logger.error(f"Error registering admin blueprint: {e}") # Membership Application blueprint try: from blueprints.membership import bp as membership_bp app.register_blueprint(membership_bp) logger.info("Registered blueprint: membership") # Create aliases for backward compatibility _create_endpoint_aliases(app, membership_bp, { 'membership_apply': 'membership.apply', 'membership_apply_step': 'membership.apply_step', 'membership_status': 'membership.status', 'membership_data_request': 'membership.data_request', }) logger.info("Created membership endpoint aliases") except ImportError as e: logger.debug(f"Blueprint membership not yet available: {e}") except Exception as e: logger.error(f"Error registering membership blueprint: {e}") # Benefits blueprint (Member Benefits / Affiliate offers) try: from blueprints.benefits import bp as benefits_bp app.register_blueprint(benefits_bp) logger.info("Registered blueprint: benefits") # Create aliases for backward compatibility _create_endpoint_aliases(app, benefits_bp, { 'benefits_list': 'benefits.benefits_list', 'benefit_detail': 'benefits.benefit_detail', 'benefit_redirect': 'benefits.benefit_redirect', }) logger.info("Created benefits endpoint aliases") except ImportError as e: logger.debug(f"Blueprint benefits not yet available: {e}") except Exception as e: logger.error(f"Error registering benefits blueprint: {e}") # Phase 6 (continued) + Phase 7-10: Future blueprints will be added here def _create_endpoint_aliases(app, blueprint, aliases): """ Create backward-compatible endpoint aliases. This allows old code using url_for('login') to work alongside new code using url_for('auth.login'). Args: app: Flask application instance blueprint: The blueprint that was just registered aliases: Dict mapping old_name -> new_name (blueprint.endpoint) """ for old_name, new_name in aliases.items(): if new_name in app.view_functions: # Find the URL rule for the new endpoint for rule in app.url_map.iter_rules(): if rule.endpoint == new_name: try: # Register the same view function under the old name app.add_url_rule( rule.rule, old_name, app.view_functions[new_name], methods=list(rule.methods - {'OPTIONS', 'HEAD'}) ) logger.debug(f"Created alias: {old_name} -> {new_name}") except AssertionError: # Endpoint already exists (e.g., still in app.py) logger.debug(f"Alias {old_name} already exists, skipping") break