#!/usr/bin/env python3 """ Kobelly Base Website - Flask Application A professional, multilanguage website template for small businesses """ import os import json from datetime import datetime from flask import Flask, render_template, request, session, redirect, url_for, flash, jsonify from flask_mail import Mail, Message from translation_manager import init_app as init_translations, translate, get_current_language, set_language # Initialize Flask app app = Flask(__name__) # Configuration app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'dev-secret-key-change-in-production') app.config['MAIL_SERVER'] = os.environ.get('MAIL_SERVER', 'smtp.gmail.com') app.config['MAIL_PORT'] = int(os.environ.get('MAIL_PORT', 587)) app.config['MAIL_USE_TLS'] = os.environ.get('MAIL_USE_TLS', 'True').lower() == 'true' app.config['MAIL_USE_SSL'] = os.environ.get('MAIL_USE_SSL', 'False').lower() == 'true' app.config['MAIL_USERNAME'] = os.environ.get('MAIL_USERNAME', 'your-email@gmail.com') app.config['MAIL_PASSWORD'] = os.environ.get('MAIL_PASSWORD', 'your-password') app.config['MAIL_DEFAULT_SENDER'] = os.environ.get('MAIL_DEFAULT_SENDER', 'your-email@gmail.com') # Initialize extensions mail = Mail(app) # Initialize translation system init_translations(app) # Development vs Production mode DEBUG_MODE = os.environ.get('FLASK_DEBUG', '0') == '1' def get_asset_url(filename, asset_type='css'): """Get the appropriate asset URL based on environment""" if DEBUG_MODE: return url_for('static', filename=f'{asset_type}/{filename}') else: # In production, use minified assets with cache busting static_dir = 'static' asset_dir = os.path.join(static_dir, asset_type) if asset_type == 'css': base_name = 'main.min.css' else: base_name = 'main.min.js' # Look for cache-busted version if os.path.exists(asset_dir): for file in os.listdir(asset_dir): if file.startswith('main.') and file.endswith(f'.min.{asset_type}'): return url_for('static', filename=f'{asset_type}/{file}') # Fallback to regular minified version return url_for('static', filename=f'{asset_type}/{base_name}') @app.context_processor def inject_globals(): """Inject global variables into templates""" return { 'get_asset_url': get_asset_url, 'current_year': datetime.now().year, 'debug_mode': DEBUG_MODE, 't': translate } @app.route('/') def index(): """Homepage""" return render_template('index.html') @app.route('/services') def services(): """Services page""" return render_template('services.html') @app.route('/about') def about(): """About page""" return render_template('about.html') @app.route('/contact') def contact(): """Contact page""" return render_template('contact.html') @app.route('/set-language/') def set_language_route(lang): """Set language and redirect back""" if set_language(lang): # Redirect back to the previous page or home return redirect(request.referrer or url_for('index')) return redirect(url_for('index')) @app.route('/contact', methods=['POST']) def contact_submit(): """Handle contact form submission""" try: name = request.form.get('name', '').strip() email = request.form.get('email', '').strip() subject = request.form.get('subject', '').strip() message = request.form.get('message', '').strip() # Basic validation if not all([name, email, subject, message]): flash(translate('Please fill in all fields'), 'error') return redirect(url_for('contact')) # Create email message msg = Message( subject=f"Contact Form: {subject}", recipients=[app.config['MAIL_DEFAULT_SENDER']], body=f""" New contact form submission: Name: {name} Email: {email} Subject: {subject} Message: {message} --- Sent from the website contact form. """.strip() ) # Send email mail.send(msg) flash(translate('Thank you! Your message has been sent successfully.'), 'success') return redirect(url_for('contact')) except Exception as e: print(f"Error sending email: {e}") flash(translate('Sorry, there was an error sending your message. Please try again.'), 'error') return redirect(url_for('contact')) @app.route('/sitemap.xml') def sitemap(): """Generate sitemap for SEO""" pages = [ {'url': url_for('index', _external=True), 'priority': '1.0'}, {'url': url_for('services', _external=True), 'priority': '0.8'}, {'url': url_for('about', _external=True), 'priority': '0.7'}, {'url': url_for('contact', _external=True), 'priority': '0.6'}, ] sitemap_xml = render_template('sitemap.xml', pages=pages) response = app.make_response(sitemap_xml) response.headers["Content-Type"] = "application/xml" return response @app.errorhandler(400) def bad_request(error): return render_template('400.html'), 400 @app.errorhandler(401) def unauthorized(error): return render_template('401.html'), 401 @app.errorhandler(403) def forbidden(error): return render_template('403.html'), 403 @app.errorhandler(405) def method_not_allowed(error): return render_template('405.html'), 405 @app.errorhandler(502) def bad_gateway(error): return render_template('502.html'), 502 @app.errorhandler(503) def service_unavailable(error): return render_template('503.html'), 503 @app.errorhandler(504) def gateway_timeout(error): return render_template('504.html'), 504 @app.errorhandler(404) def not_found(error): """404 error handler""" return render_template('404.html'), 404 @app.errorhandler(500) def internal_error(error): """500 error handler""" return render_template('500.html'), 500 if __name__ == '__main__': # Build assets if in production if not DEBUG_MODE: try: from build_assets import create_cache_busted_assets create_cache_busted_assets() except Exception as e: print(f"Warning: Could not build assets: {e}") # Run the application port = int(os.environ.get('PORT', 5000)) app.run(host='0.0.0.0', port=port, debug=DEBUG_MODE)