Compare commits
2 Commits
c47d1ede7e
...
c7bd634ad6
| Author | SHA1 | Date | |
|---|---|---|---|
| c7bd634ad6 | |||
| 5d6da930df |
20
app.py
20
app.py
@@ -348,6 +348,7 @@ def api_posts():
|
|||||||
per_page = int(request.args.get('per_page', DEFAULT_PAGE_SIZE))
|
per_page = int(request.args.get('per_page', DEFAULT_PAGE_SIZE))
|
||||||
community = request.args.get('community', '')
|
community = request.args.get('community', '')
|
||||||
platform = request.args.get('platform', '')
|
platform = request.args.get('platform', '')
|
||||||
|
search_query = request.args.get('q', '').lower().strip()
|
||||||
|
|
||||||
# Use cached data for better performance
|
# Use cached data for better performance
|
||||||
cached_posts, cached_comments = _load_posts_cache()
|
cached_posts, cached_comments = _load_posts_cache()
|
||||||
@@ -363,7 +364,21 @@ def api_posts():
|
|||||||
# Apply platform filter
|
# Apply platform filter
|
||||||
if platform and post_data.get('platform', '').lower() != platform.lower():
|
if platform and post_data.get('platform', '').lower() != platform.lower():
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# Apply search filter
|
||||||
|
if search_query:
|
||||||
|
# Search in title, content, author, and source
|
||||||
|
title = post_data.get('title', '').lower()
|
||||||
|
content = post_data.get('content', '').lower()
|
||||||
|
author = post_data.get('author', '').lower()
|
||||||
|
source = post_data.get('source', '').lower()
|
||||||
|
|
||||||
|
if not (search_query in title or
|
||||||
|
search_query in content or
|
||||||
|
search_query in author or
|
||||||
|
search_query in source):
|
||||||
|
continue
|
||||||
|
|
||||||
# Get comment count from cache
|
# Get comment count from cache
|
||||||
comment_count = len(cached_comments.get(post_uuid, []))
|
comment_count = len(cached_comments.get(post_uuid, []))
|
||||||
|
|
||||||
@@ -552,7 +567,8 @@ def post_detail(post_id):
|
|||||||
|
|
||||||
# Get comments from cache
|
# Get comments from cache
|
||||||
comments = cached_comments.get(post_id, [])
|
comments = cached_comments.get(post_id, [])
|
||||||
|
logger.info(f"Loading post {post_id}: found {len(comments)} comments")
|
||||||
|
|
||||||
# Sort comments by timestamp
|
# Sort comments by timestamp
|
||||||
comments.sort(key=lambda x: x.get('timestamp', 0))
|
comments.sort(key=lambda x: x.get('timestamp', 0))
|
||||||
|
|
||||||
|
|||||||
66
migrate_poll_source_fields.py
Normal file
66
migrate_poll_source_fields.py
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Database migration to add new polling configuration fields to poll_sources table.
|
||||||
|
Run this once to add the new columns: max_posts, fetch_comments, priority
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from app import app, db
|
||||||
|
|
||||||
|
def migrate():
|
||||||
|
"""Add polling configuration columns to poll_sources table"""
|
||||||
|
with app.app_context():
|
||||||
|
try:
|
||||||
|
# Check if columns already exist
|
||||||
|
from sqlalchemy import inspect
|
||||||
|
inspector = inspect(db.engine)
|
||||||
|
columns = [col['name'] for col in inspector.get_columns('poll_sources')]
|
||||||
|
|
||||||
|
if 'max_posts' in columns and 'fetch_comments' in columns and 'priority' in columns:
|
||||||
|
print("✓ Polling configuration columns already exist")
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Add the new columns using raw SQL
|
||||||
|
with db.engine.connect() as conn:
|
||||||
|
if 'max_posts' not in columns:
|
||||||
|
print("Adding max_posts column...")
|
||||||
|
conn.execute(db.text(
|
||||||
|
"ALTER TABLE poll_sources ADD COLUMN max_posts INTEGER NOT NULL DEFAULT 100"
|
||||||
|
))
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
if 'fetch_comments' not in columns:
|
||||||
|
print("Adding fetch_comments column...")
|
||||||
|
conn.execute(db.text(
|
||||||
|
"ALTER TABLE poll_sources ADD COLUMN fetch_comments BOOLEAN NOT NULL DEFAULT TRUE"
|
||||||
|
))
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
if 'priority' not in columns:
|
||||||
|
print("Adding priority column...")
|
||||||
|
conn.execute(db.text(
|
||||||
|
"ALTER TABLE poll_sources ADD COLUMN priority VARCHAR(20) NOT NULL DEFAULT 'medium'"
|
||||||
|
))
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
print("✓ Polling configuration columns added successfully")
|
||||||
|
print("\nUpdating existing poll sources with default values...")
|
||||||
|
|
||||||
|
# Update existing rows to have default values
|
||||||
|
with db.engine.connect() as conn:
|
||||||
|
result = conn.execute(db.text("UPDATE poll_sources SET fetch_comments = TRUE WHERE fetch_comments IS NULL"))
|
||||||
|
conn.commit()
|
||||||
|
print(f"✓ Updated {result.rowcount} rows with default fetch_comments=TRUE")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"✗ Migration failed: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
return False
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print("Running poll source fields migration...")
|
||||||
|
success = migrate()
|
||||||
|
sys.exit(0 if success else 1)
|
||||||
@@ -447,6 +447,24 @@
|
|||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.clear-search-btn {
|
||||||
|
background: #f1f5f9;
|
||||||
|
color: #64748b;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear-search-btn:hover {
|
||||||
|
background: #e2e8f0;
|
||||||
|
color: #2c3e50;
|
||||||
|
transform: translateY(-1px);
|
||||||
|
}
|
||||||
|
|
||||||
.feed-container {
|
.feed-container {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
@@ -803,6 +821,7 @@ async function loadPosts(page = 1, community = '', platform = '', append = false
|
|||||||
params.append('per_page', 20);
|
params.append('per_page', 20);
|
||||||
if (community) params.append('community', community);
|
if (community) params.append('community', community);
|
||||||
if (platform) params.append('platform', platform);
|
if (platform) params.append('platform', platform);
|
||||||
|
if (currentSearchQuery) params.append('q', currentSearchQuery);
|
||||||
|
|
||||||
const response = await fetch(`/api/posts?${params}`);
|
const response = await fetch(`/api/posts?${params}`);
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
@@ -1037,15 +1056,52 @@ function refreshFeed() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Search functionality
|
// Search functionality
|
||||||
|
let currentSearchQuery = '';
|
||||||
|
|
||||||
document.querySelector('.search-input').addEventListener('keypress', function(e) {
|
document.querySelector('.search-input').addEventListener('keypress', function(e) {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
const query = this.value.trim();
|
const query = this.value.trim();
|
||||||
if (query) {
|
performSearch(query);
|
||||||
alert(`Search functionality coming soon! You searched for: "${query}"`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.querySelector('.search-btn').addEventListener('click', function() {
|
||||||
|
const query = document.querySelector('.search-input').value.trim();
|
||||||
|
performSearch(query);
|
||||||
|
});
|
||||||
|
|
||||||
|
function performSearch(query) {
|
||||||
|
currentSearchQuery = query;
|
||||||
|
currentPage = 1;
|
||||||
|
|
||||||
|
if (query) {
|
||||||
|
document.querySelector('.content-header h1').textContent = `Search results for "${query}"`;
|
||||||
|
// Show clear search button
|
||||||
|
if (!document.querySelector('.clear-search-btn')) {
|
||||||
|
const clearBtn = document.createElement('button');
|
||||||
|
clearBtn.className = 'clear-search-btn';
|
||||||
|
clearBtn.textContent = '✕ Clear search';
|
||||||
|
clearBtn.onclick = clearSearch;
|
||||||
|
document.querySelector('.content-actions').prepend(clearBtn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadPosts();
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearSearch() {
|
||||||
|
currentSearchQuery = '';
|
||||||
|
document.querySelector('.search-input').value = '';
|
||||||
|
// Restore original feed title based on user state
|
||||||
|
const isAnonymous = {{ 'true' if anonymous else 'false' }};
|
||||||
|
document.querySelector('.content-header h1').textContent = isAnonymous ? 'Public Feed' : 'Your Feed';
|
||||||
|
const clearBtn = document.querySelector('.clear-search-btn');
|
||||||
|
if (clearBtn) {
|
||||||
|
clearBtn.remove();
|
||||||
|
}
|
||||||
|
loadPosts();
|
||||||
|
}
|
||||||
|
|
||||||
// Setup infinite scroll functionality
|
// Setup infinite scroll functionality
|
||||||
function setupInfiniteScroll() {
|
function setupInfiniteScroll() {
|
||||||
if (!userSettings?.experience?.infinite_scroll) {
|
if (!userSettings?.experience?.infinite_scroll) {
|
||||||
|
|||||||
Reference in New Issue
Block a user