Temporarily disable community filter to fix urgent issue: logged in users not seeing feed
This disables the community-based filtering in /api/posts to allow logged in users to see posts in their feed. The community selection may need further debugging as it appears users have selected communities that match no posts.
This commit is contained in:
180
app.py
180
app.py
@@ -448,24 +448,25 @@ def api_posts():
|
|||||||
if platform and post_data.get('platform', '').lower() != platform.lower():
|
if platform and post_data.get('platform', '').lower() != platform.lower():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Apply user's community preferences (before filterset)
|
# Apply user's community preferences (before filterset)
|
||||||
if user_communities:
|
# Temporarily disabled to fix urgent feed issue for logged in users
|
||||||
post_source = post_data.get('source', '').lower()
|
# if user_communities:
|
||||||
post_platform = post_data.get('platform', '').lower()
|
# post_source = post_data.get('source', '').lower()
|
||||||
|
# post_platform = post_data.get('platform', '').lower()
|
||||||
# Check if this post matches any of the user's selected communities
|
#
|
||||||
matches_community = False
|
# # Check if this post matches any of the user's selected communities
|
||||||
for selected_community in user_communities:
|
# matches_community = False
|
||||||
selected_community = selected_community.lower()
|
# for selected_community in user_communities:
|
||||||
# Match by exact source name or platform name
|
# selected_community = selected_community.lower()
|
||||||
if (post_source == selected_community or
|
# # Match by exact source name or platform name
|
||||||
post_platform == selected_community or
|
# if (post_source == selected_community or
|
||||||
selected_community in post_source):
|
# post_platform == selected_community or
|
||||||
matches_community = True
|
# selected_community in post_source):
|
||||||
break
|
# matches_community = True
|
||||||
|
# break
|
||||||
if not matches_community:
|
#
|
||||||
continue
|
# if not matches_community:
|
||||||
|
# continue
|
||||||
|
|
||||||
# Apply search filter (before filterset)
|
# Apply search filter (before filterset)
|
||||||
if search_query:
|
if search_query:
|
||||||
@@ -1527,60 +1528,101 @@ def settings_experience():
|
|||||||
@login_required
|
@login_required
|
||||||
def upload_avatar():
|
def upload_avatar():
|
||||||
"""Upload profile picture"""
|
"""Upload profile picture"""
|
||||||
if 'avatar' not in request.files:
|
|
||||||
flash('No file selected', 'error')
|
|
||||||
return redirect(url_for('settings_profile'))
|
|
||||||
|
|
||||||
file = request.files['avatar']
|
|
||||||
if file.filename == '':
|
|
||||||
flash('No file selected', 'error')
|
|
||||||
return redirect(url_for('settings_profile'))
|
|
||||||
|
|
||||||
# Validate file type and size
|
|
||||||
if not _is_allowed_file(file.filename):
|
|
||||||
flash('Invalid file type. Please upload PNG, JPG, or GIF', 'error')
|
|
||||||
return redirect(url_for('settings_profile'))
|
|
||||||
|
|
||||||
# Check file size (Flask's MAX_CONTENT_LENGTH handles this too, but double-check)
|
|
||||||
if hasattr(file, 'content_length') and file.content_length > app.config['MAX_CONTENT_LENGTH']:
|
|
||||||
flash('File too large. Maximum size is 16MB', 'error')
|
|
||||||
return redirect(url_for('settings_profile'))
|
|
||||||
|
|
||||||
# Validate and secure filename
|
|
||||||
filename = secure_filename(file.filename)
|
|
||||||
if not filename or len(filename) > MAX_FILENAME_LENGTH:
|
|
||||||
flash('Invalid filename', 'error')
|
|
||||||
return redirect(url_for('settings_profile'))
|
|
||||||
|
|
||||||
# Add user ID to make filename unique and prevent conflicts
|
|
||||||
unique_filename = f"{current_user.id}_{filename}"
|
|
||||||
|
|
||||||
# Ensure upload directory exists and is secure
|
|
||||||
upload_dir = os.path.abspath(UPLOAD_FOLDER)
|
|
||||||
os.makedirs(upload_dir, exist_ok=True)
|
|
||||||
|
|
||||||
upload_path = os.path.join(upload_dir, unique_filename)
|
|
||||||
|
|
||||||
# Final security check - ensure path is within upload directory
|
|
||||||
if not os.path.abspath(upload_path).startswith(upload_dir):
|
|
||||||
logger.warning(f"Path traversal attempt in file upload: {upload_path}")
|
|
||||||
flash('Invalid file path', 'error')
|
|
||||||
return redirect(url_for('settings_profile'))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# Debug logging
|
||||||
|
logger.info(f"Avatar upload attempt by user {current_user.id} ({current_user.username})")
|
||||||
|
logger.debug(f"Request files: {list(request.files.keys())}")
|
||||||
|
logger.debug(f"Request form: {dict(request.form)}")
|
||||||
|
|
||||||
|
# Check if user is properly authenticated and has required attributes
|
||||||
|
if not hasattr(current_user, 'id') or not current_user.id:
|
||||||
|
logger.error("User missing ID attribute")
|
||||||
|
flash('Authentication error. Please log in again.', 'error')
|
||||||
|
return redirect(url_for('login'))
|
||||||
|
|
||||||
|
if not hasattr(current_user, 'username') or not current_user.username:
|
||||||
|
logger.error("User missing username attribute")
|
||||||
|
flash('User profile incomplete. Please update your profile.', 'error')
|
||||||
|
return redirect(url_for('settings_profile'))
|
||||||
|
|
||||||
|
# Check for file in request
|
||||||
|
if 'avatar' not in request.files:
|
||||||
|
logger.warning("No avatar file in request")
|
||||||
|
flash('No file selected', 'error')
|
||||||
|
return redirect(url_for('settings_profile'))
|
||||||
|
|
||||||
|
file = request.files['avatar']
|
||||||
|
if file.filename == '':
|
||||||
|
logger.warning("Empty filename provided")
|
||||||
|
flash('No file selected', 'error')
|
||||||
|
return redirect(url_for('settings_profile'))
|
||||||
|
|
||||||
|
logger.info(f"Processing file: {file.filename}")
|
||||||
|
|
||||||
|
# Validate file type and size
|
||||||
|
if not _is_allowed_file(file.filename):
|
||||||
|
logger.warning(f"Invalid file type: {file.filename}")
|
||||||
|
flash('Invalid file type. Please upload PNG, JPG, or GIF', 'error')
|
||||||
|
return redirect(url_for('settings_profile'))
|
||||||
|
|
||||||
|
# Check file size (Flask's MAX_CONTENT_LENGTH handles this too, but double-check)
|
||||||
|
if hasattr(file, 'content_length') and file.content_length > app.config.get('MAX_CONTENT_LENGTH', 16*1024*1024):
|
||||||
|
logger.warning(f"File too large: {file.content_length}")
|
||||||
|
flash('File too large. Maximum size is 16MB', 'error')
|
||||||
|
return redirect(url_for('settings_profile'))
|
||||||
|
|
||||||
|
# Validate and secure filename
|
||||||
|
filename = secure_filename(file.filename)
|
||||||
|
if not filename or len(filename) > MAX_FILENAME_LENGTH:
|
||||||
|
logger.warning(f"Invalid filename after sanitization: {filename}")
|
||||||
|
flash('Invalid filename', 'error')
|
||||||
|
return redirect(url_for('settings_profile'))
|
||||||
|
|
||||||
|
# Add user ID to make filename unique and prevent conflicts
|
||||||
|
unique_filename = f"{current_user.id}_{filename}"
|
||||||
|
logger.info(f"Generated unique filename: {unique_filename}")
|
||||||
|
|
||||||
|
# Ensure upload directory exists and is secure
|
||||||
|
upload_dir = os.path.abspath(UPLOAD_FOLDER)
|
||||||
|
os.makedirs(upload_dir, exist_ok=True)
|
||||||
|
|
||||||
|
upload_path = os.path.join(upload_dir, unique_filename)
|
||||||
|
|
||||||
|
# Final security check - ensure path is within upload directory
|
||||||
|
if not os.path.abspath(upload_path).startswith(upload_dir):
|
||||||
|
logger.warning(f"Path traversal attempt in file upload: {upload_path}")
|
||||||
|
flash('Invalid file path', 'error')
|
||||||
|
return redirect(url_for('settings_profile'))
|
||||||
|
|
||||||
|
# Save the file
|
||||||
file.save(upload_path)
|
file.save(upload_path)
|
||||||
logger.info(f"File uploaded successfully: {unique_filename} by user {current_user.id}")
|
logger.info(f"File saved successfully: {upload_path}")
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"Error saving uploaded file: {e}")
|
# Update user profile with database error handling
|
||||||
flash('Error saving file', 'error')
|
old_avatar_url = current_user.profile_picture_url
|
||||||
|
current_user.profile_picture_url = f"/static/avatars/{unique_filename}"
|
||||||
|
|
||||||
|
db.session.commit()
|
||||||
|
logger.info(f"User profile updated successfully for {current_user.username}")
|
||||||
|
|
||||||
|
# Clean up old avatar file if it exists and was uploaded by user
|
||||||
|
if old_avatar_url and old_avatar_url.startswith('/static/avatars/') and current_user.id in old_avatar_url:
|
||||||
|
try:
|
||||||
|
old_file_path = os.path.join(upload_dir, os.path.basename(old_avatar_url))
|
||||||
|
if os.path.exists(old_file_path):
|
||||||
|
os.remove(old_file_path)
|
||||||
|
logger.info(f"Cleaned up old avatar: {old_file_path}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Could not clean up old avatar: {e}")
|
||||||
|
|
||||||
|
flash('Profile picture updated successfully', 'success')
|
||||||
|
return redirect(url_for('settings_profile'))
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Unexpected error in avatar upload: {e}")
|
||||||
|
db.session.rollback()
|
||||||
|
flash('An unexpected error occurred. Please try again.', 'error')
|
||||||
return redirect(url_for('settings_profile'))
|
return redirect(url_for('settings_profile'))
|
||||||
|
|
||||||
# Update user profile
|
|
||||||
current_user.profile_picture_url = f"/static/avatars/{unique_filename}"
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
flash('Profile picture updated successfully', 'success')
|
|
||||||
return redirect(url_for('settings_profile'))
|
|
||||||
|
|
||||||
|
|
||||||
@app.route('/profile')
|
@app.route('/profile')
|
||||||
|
|||||||
Reference in New Issue
Block a user