Allow uploading of files and folders.
This commit is contained in:
67
app.py
67
app.py
@@ -438,6 +438,39 @@ def favicon_16():
|
||||
def apple_touch_icon():
|
||||
return send_from_directory(app.static_folder, 'apple-touch-icon.png', mimetype='image/png')
|
||||
|
||||
@app.route('/uploads/<path:filename>')
|
||||
def serve_upload(filename):
|
||||
"""Serve uploaded files from the data directory"""
|
||||
import os
|
||||
from werkzeug.security import safe_join
|
||||
|
||||
# Ensure the request is from a logged-in user
|
||||
if not g.user:
|
||||
abort(403)
|
||||
|
||||
# Construct safe path to the uploaded file
|
||||
upload_dir = '/data/uploads'
|
||||
file_path = safe_join(upload_dir, filename)
|
||||
|
||||
if file_path is None or not os.path.exists(file_path):
|
||||
abort(404)
|
||||
|
||||
# For notes, check if user has permission to view
|
||||
if filename.startswith('notes/'):
|
||||
# Extract the note from the database to check permissions
|
||||
# This is a simplified check - in production you might want to store
|
||||
# file ownership in a separate table for faster lookups
|
||||
from models import Note
|
||||
note = Note.query.filter_by(
|
||||
file_path=filename.replace('notes/', ''),
|
||||
company_id=g.user.company_id
|
||||
).first()
|
||||
|
||||
if note and not note.can_user_view(g.user):
|
||||
abort(403)
|
||||
|
||||
return send_from_directory(upload_dir, filename)
|
||||
|
||||
@app.route('/')
|
||||
def home():
|
||||
if g.user:
|
||||
@@ -1138,6 +1171,31 @@ def profile():
|
||||
|
||||
return render_template('profile.html', title='My Profile', user=user)
|
||||
|
||||
@app.route('/update-note-preferences', methods=['POST'])
|
||||
@login_required
|
||||
def update_note_preferences():
|
||||
"""Update user's note preferences"""
|
||||
user = User.query.get(session['user_id'])
|
||||
|
||||
# Get or create user preferences
|
||||
if not user.preferences:
|
||||
preferences = UserPreferences(user_id=user.id)
|
||||
db.session.add(preferences)
|
||||
else:
|
||||
preferences = user.preferences
|
||||
|
||||
# Update font preference
|
||||
note_preview_font = request.form.get('note_preview_font', 'system')
|
||||
if note_preview_font in ['system', 'sans-serif', 'serif', 'monospace', 'georgia',
|
||||
'palatino', 'garamond', 'bookman', 'comic-sans',
|
||||
'trebuchet', 'arial-black', 'impact']:
|
||||
preferences.note_preview_font = note_preview_font
|
||||
|
||||
db.session.commit()
|
||||
flash('Note preferences updated successfully!', 'success')
|
||||
|
||||
return redirect(url_for('profile'))
|
||||
|
||||
@app.route('/update-avatar', methods=['POST'])
|
||||
@login_required
|
||||
def update_avatar():
|
||||
@@ -1233,7 +1291,7 @@ def upload_avatar():
|
||||
unique_filename = f"{user.id}_{uuid.uuid4().hex}.{file_ext}"
|
||||
|
||||
# Create user avatar directory if it doesn't exist
|
||||
avatar_dir = os.path.join(app.static_folder, 'uploads', 'avatars')
|
||||
avatar_dir = os.path.join('/data', 'uploads', 'avatars')
|
||||
os.makedirs(avatar_dir, exist_ok=True)
|
||||
|
||||
# Save the file
|
||||
@@ -1241,8 +1299,9 @@ def upload_avatar():
|
||||
file.save(file_path)
|
||||
|
||||
# Delete old avatar file if it exists and is a local upload
|
||||
if user.avatar_url and user.avatar_url.startswith('/static/uploads/avatars/'):
|
||||
old_file_path = os.path.join(app.root_path, user.avatar_url.lstrip('/'))
|
||||
if user.avatar_url and user.avatar_url.startswith('/uploads/avatars/'):
|
||||
old_filename = user.avatar_url.split('/')[-1]
|
||||
old_file_path = os.path.join(avatar_dir, old_filename)
|
||||
if os.path.exists(old_file_path):
|
||||
try:
|
||||
os.remove(old_file_path)
|
||||
@@ -1250,7 +1309,7 @@ def upload_avatar():
|
||||
logger.warning(f"Failed to delete old avatar: {e}")
|
||||
|
||||
# Update user's avatar URL
|
||||
user.avatar_url = f"/static/uploads/avatars/{unique_filename}"
|
||||
user.avatar_url = f"/uploads/avatars/{unique_filename}"
|
||||
db.session.commit()
|
||||
|
||||
flash('Avatar uploaded successfully!', 'success')
|
||||
|
||||
Reference in New Issue
Block a user