Compare commits
2 Commits
377e379883
...
56c691c330
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56c691c330 | ||
|
|
c9c3c80f4f |
@@ -2,15 +2,34 @@ from flask import Blueprint, render_template, request, redirect, url_for, flash
|
||||
from flask_login import login_user, logout_user, login_required, current_user
|
||||
from werkzeug.security import check_password_hash
|
||||
from app.models import User, db
|
||||
from app.forms import LoginForm, RegisterForm, ForgotPasswordForm
|
||||
from app.routes.reset_password import RequestResetForm, ResetPasswordForm
|
||||
from flask_mail import Message
|
||||
from app.routes.mail import mail
|
||||
from app.utils.token import generate_reset_token, verify_reset_token
|
||||
import re
|
||||
from app.forms import LoginForm, RegisterForm, ForgotPasswordForm
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, PasswordField, BooleanField, SubmitField
|
||||
from wtforms.validators import DataRequired, Email, EqualTo, Length
|
||||
|
||||
auth = Blueprint('auth', __name__)
|
||||
|
||||
class LoginForm(FlaskForm):
|
||||
email = StringField('Email', validators=[DataRequired(), Email()])
|
||||
password = PasswordField('Password', validators=[DataRequired()])
|
||||
remember_me = BooleanField('Remember Me')
|
||||
submit = SubmitField('Sign In')
|
||||
|
||||
class RegisterForm(FlaskForm):
|
||||
nickname = StringField('Nickname', validators=[DataRequired(), Length(min=3, max=32)])
|
||||
email = StringField('Email', validators=[DataRequired(), Email()])
|
||||
password = PasswordField('Password', validators=[DataRequired(), Length(min=8)])
|
||||
password2 = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])
|
||||
submit = SubmitField('Register')
|
||||
|
||||
class ForgotPasswordForm(FlaskForm):
|
||||
email = StringField('Email', validators=[DataRequired(), Email()])
|
||||
submit = SubmitField('Request Password Reset')
|
||||
|
||||
@auth.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
"""User login page"""
|
||||
|
||||
@@ -229,10 +229,18 @@
|
||||
document.getElementById('sidebar').classList.toggle('show');
|
||||
});
|
||||
|
||||
// Auto-refresh stats every 30 seconds
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 30000);
|
||||
// Conditional auto-refresh logic
|
||||
{% if request.endpoint == 'admin.mail_settings' %}
|
||||
{% if settings and settings.enabled %}
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 30000);
|
||||
{% endif %}
|
||||
{% else %}
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 30000);
|
||||
{% endif %}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
{% extends 'admin/base.html' %}
|
||||
{% block admin_content %}
|
||||
<h2>Mail Server Settings</h2>
|
||||
<div class="alert alert-info" style="max-width:600px;">
|
||||
<strong>Recommended Gmail SMTP Settings:</strong><br>
|
||||
<ul style="margin-bottom:0;">
|
||||
<li><b>Server:</b> smtp.gmail.com</li>
|
||||
<li><b>Port:</b> 587</li>
|
||||
<li><b>Use TLS:</b> True</li>
|
||||
<li><b>Username:</b> your Gmail address (e.g. yourname@gmail.com)</li>
|
||||
<li><b>Password:</b> your Gmail <b>App Password</b> (not your regular password)</li>
|
||||
<li><b>Default sender:</b> your Gmail address (e.g. yourname@gmail.com)</li>
|
||||
</ul>
|
||||
<small>To use Gmail SMTP, you must create an <a href="https://myaccount.google.com/apppasswords" target="_blank">App Password</a> in your Google Account security settings.</small>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label for="enabled">Enable Email Sending</label>
|
||||
|
||||
147
test_media.py
147
test_media.py
@@ -1,147 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for the media management system
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
from io import BytesIO
|
||||
|
||||
# Add the app directory to the path
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
|
||||
from app import create_app
|
||||
from app.models import Post, PostImage, User
|
||||
from app.extensions import db
|
||||
from app.media_config import MediaConfig
|
||||
from PIL import Image
|
||||
|
||||
def test_media_folder_creation():
|
||||
"""Test that media folders are created correctly"""
|
||||
app = create_app()
|
||||
|
||||
with app.app_context():
|
||||
# Create a test user
|
||||
test_user = User.query.filter_by(email='test@example.com').first()
|
||||
if not test_user:
|
||||
test_user = User(
|
||||
nickname='testuser',
|
||||
email='test@example.com'
|
||||
)
|
||||
test_user.set_password('testpass')
|
||||
db.session.add(test_user)
|
||||
db.session.commit()
|
||||
|
||||
# Create a test post
|
||||
test_post = Post(
|
||||
title='Test Media Post',
|
||||
subtitle='Testing media folder creation',
|
||||
content='This is a test post for media functionality',
|
||||
difficulty=3,
|
||||
media_folder='test_post_12345678_20250723',
|
||||
published=True,
|
||||
author_id=test_user.id
|
||||
)
|
||||
|
||||
db.session.add(test_post)
|
||||
db.session.commit()
|
||||
|
||||
# Check that media folder methods work
|
||||
media_path = test_post.get_media_folder_path()
|
||||
media_url = test_post.get_media_url_path()
|
||||
|
||||
print(f"✅ Post created with ID: {test_post.id}")
|
||||
print(f"✅ Media folder: {test_post.media_folder}")
|
||||
print(f"✅ Media path: {media_path}")
|
||||
print(f"✅ Media URL: {media_url}")
|
||||
|
||||
# Test media config
|
||||
config_path = MediaConfig.get_media_path(app, test_post.media_folder, 'images')
|
||||
config_url = MediaConfig.get_media_url(test_post.media_folder, 'images', 'test.jpg')
|
||||
|
||||
print(f"✅ Config path: {config_path}")
|
||||
print(f"✅ Config URL: {config_url}")
|
||||
|
||||
# Test file validation
|
||||
valid_image = MediaConfig.is_allowed_file('test.jpg', 'images')
|
||||
valid_gpx = MediaConfig.is_allowed_file('route.gpx', 'gpx')
|
||||
invalid_file = MediaConfig.is_allowed_file('bad.exe', 'images')
|
||||
|
||||
print(f"✅ Valid image file: {valid_image}")
|
||||
print(f"✅ Valid GPX file: {valid_gpx}")
|
||||
print(f"✅ Invalid file rejected: {not invalid_file}")
|
||||
|
||||
return True
|
||||
|
||||
def test_image_processing():
|
||||
"""Test image processing functionality"""
|
||||
print("\n🖼️ Testing Image Processing...")
|
||||
|
||||
# Create a test image
|
||||
img = Image.new('RGB', (800, 600), color='red')
|
||||
img_buffer = BytesIO()
|
||||
img.save(img_buffer, format='JPEG')
|
||||
img_buffer.seek(0)
|
||||
|
||||
# Test image size limits
|
||||
max_size = MediaConfig.IMAGE_MAX_SIZE
|
||||
thumbnail_size = MediaConfig.THUMBNAIL_SIZE
|
||||
|
||||
print(f"✅ Max image size: {max_size}")
|
||||
print(f"✅ Thumbnail size: {thumbnail_size}")
|
||||
print(f"✅ Image quality: {MediaConfig.IMAGE_QUALITY}")
|
||||
|
||||
return True
|
||||
|
||||
def test_file_extensions():
|
||||
"""Test file extension validation"""
|
||||
print("\n📁 Testing File Extensions...")
|
||||
|
||||
# Test image extensions
|
||||
image_exts = MediaConfig.UPLOAD_EXTENSIONS['images']
|
||||
gpx_exts = MediaConfig.UPLOAD_EXTENSIONS['gpx']
|
||||
|
||||
print(f"✅ Allowed image extensions: {image_exts}")
|
||||
print(f"✅ Allowed GPX extensions: {gpx_exts}")
|
||||
|
||||
# Test MIME types
|
||||
valid_mimes = list(MediaConfig.ALLOWED_MIME_TYPES.keys())
|
||||
print(f"✅ Allowed MIME types: {valid_mimes}")
|
||||
|
||||
return True
|
||||
|
||||
def main():
|
||||
"""Run all tests"""
|
||||
print("🧪 Media Management System Tests")
|
||||
print("=" * 40)
|
||||
|
||||
try:
|
||||
# Test media folder creation
|
||||
print("\n📁 Testing Media Folder Creation...")
|
||||
test_media_folder_creation()
|
||||
|
||||
# Test image processing
|
||||
test_image_processing()
|
||||
|
||||
# Test file extensions
|
||||
test_file_extensions()
|
||||
|
||||
print("\n✅ All tests passed!")
|
||||
print("\n📋 Media System Summary:")
|
||||
print(" - Media folders created per post")
|
||||
print(" - Images automatically resized and compressed")
|
||||
print(" - Thumbnails generated for all images")
|
||||
print(" - GPX files validated and statistics extracted")
|
||||
print(" - File type validation enforced")
|
||||
print(" - Organized folder structure maintained")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Test failed: {str(e)}")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
if __name__ == '__main__':
|
||||
success = main()
|
||||
sys.exit(0 if success else 1)
|
||||
Reference in New Issue
Block a user