Files
Base-website/app.py
2025-07-15 11:33:04 +02:00

205 lines
6.3 KiB
Python

#!/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/<lang>')
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)