API: allow searching of existing communities, posts, users

This commit is contained in:
freamon 2025-01-22 00:51:41 +00:00
parent c84c1f9c4b
commit 42dc5cf512
4 changed files with 37 additions and 11 deletions

View file

@ -6,11 +6,11 @@ from app.models import Community, CommunityMember
from app.shared.community import join_community, leave_community, block_community, unblock_community
from app.utils import communities_banned_from, blocked_instances, blocked_communities
from sqlalchemy import desc
from sqlalchemy import desc, or_
@cache.memoize(timeout=3)
def cached_community_list(type, sort, limit, user_id):
def cached_community_list(type, sort, limit, user_id, query=''):
if type == 'Subscribed':
communities = Community.query.filter_by(banned=False).join(CommunityMember).filter(CommunityMember.user_id == user_id)
elif type == 'Local':
@ -29,6 +29,9 @@ def cached_community_list(type, sort, limit, user_id):
if blocked_community_ids:
communities = communities.filter(Community.id.not_in(blocked_community_ids))
if query:
communities = communities.filter(or_(Community.title.ilike(f"%{query}%"), Community.ap_id.ilike(f"%{query}%")))
if sort == 'Active': # 'Trending Communities' screen
communities = communities.order_by(desc(Community.last_active)).limit(limit)
@ -41,9 +44,11 @@ def get_community_list(auth, data):
page = int(data['page']) if data and 'page' in data else 1
limit = int(data['limit']) if data and 'limit' in data else 10
query = data['q'] if data and 'q' in data else ''
user_id = authorise_api_user(auth) if auth else None
communities = cached_community_list(type, sort, limit, user_id)
communities = cached_community_list(type, sort, limit, user_id, query)
start = (page - 1) * limit
end = start + limit

View file

@ -13,11 +13,12 @@ def get_search(auth, data):
data['type_'] = listing_type
search_json = search_view(type)
search_type = 'Posts' if type == 'Url' else type
search_json = search_view(search_type)
if type == 'Communities':
search_json['communities'] = get_community_list(auth, data)['communities']
elif type == 'Posts':
search_json['posts'] = get_post_list(auth, data)['posts']
elif type == 'Posts' or type == 'Url':
search_json['posts'] = get_post_list(auth, data, search_type=type)['posts']
elif type == 'Users':
search_json['users'] = get_user_list(auth, data)['users']

View file

@ -1,7 +1,7 @@
from app import cache
from app.api.alpha.views import post_view, post_report_view
from app.api.alpha.utils.validators import required, integer_expected, boolean_expected, string_expected
from app.constants import POST_TYPE_ARTICLE, POST_TYPE_LINK, POST_TYPE_IMAGE, POST_TYPE_VIDEO
from app.constants import POST_TYPE_ARTICLE, POST_TYPE_LINK, POST_TYPE_IMAGE, POST_TYPE_VIDEO, POST_TYPE_POLL
from app.models import Post, Community, CommunityMember, utcnow
from app.shared.post import vote_for_post, bookmark_the_post, remove_the_bookmark_from_post, toggle_post_notification, make_post, edit_post, \
delete_post, restore_post, report_post, lock_post, sticky_post, mod_remove_post, mod_restore_post
@ -12,7 +12,7 @@ from sqlalchemy import desc
@cache.memoize(timeout=3)
def cached_post_list(type, sort, user_id, community_id, community_name, person_id):
def cached_post_list(type, sort, user_id, community_id, community_name, person_id, query='', search_type='Posts'):
if type == "All":
if community_name:
name, ap_domain = community_name.split('@')
@ -32,6 +32,9 @@ def cached_post_list(type, sort, user_id, community_id, community_name, person_i
else:
posts = Post.query.filter_by(deleted=False)
# change when polls are supported
posts = posts.filter(Post.type != POST_TYPE_POLL)
if user_id is not None:
blocked_person_ids = blocked_users(user_id)
if blocked_person_ids:
@ -44,6 +47,12 @@ def cached_post_list(type, sort, user_id, community_id, community_name, person_i
posts = posts.filter(Post.instance_id.not_in(blocked_instance_ids)) # users from blocked instance
posts = posts.filter(Post.community_id.not_in(community_ids_from_instances(blocked_instance_ids))) # communities from blocked instance
if query:
if search_type == 'Url':
posts = posts.filter(Post.url.ilike(f"%{query}%"))
else:
posts = posts.filter(Post.title.ilike(f"%{query}%"))
if sort == "Hot":
posts = posts.order_by(desc(Post.ranking)).order_by(desc(Post.posted_at))
elif sort == "TopDay":
@ -56,12 +65,14 @@ def cached_post_list(type, sort, user_id, community_id, community_name, person_i
return posts.all()
def get_post_list(auth, data, user_id=None):
def get_post_list(auth, data, user_id=None, search_type='Posts'):
type = data['type_'] if data and 'type_' in data else "All"
sort = data['sort'] if data and 'sort' in data else "Hot"
page = int(data['page']) if data and 'page' in data else 1
limit = int(data['limit']) if data and 'limit' in data else 10
query = data['q'] if data and 'q' in data else ''
if auth:
user_id = authorise_api_user(auth)
@ -72,7 +83,7 @@ def get_post_list(auth, data, user_id=None):
community_name = data['community_name'] if data and 'community_name' in data else None
person_id = int(data['person_id']) if data and 'person_id' in data else None
posts = cached_post_list(type, sort, user_id, community_id, community_name, person_id)
posts = cached_post_list(type, sort, user_id, community_id, community_name, person_id, query, search_type)
start = (page - 1) * limit
end = start + limit

View file

@ -45,7 +45,16 @@ def get_user_list(auth, data):
page = int(data['page']) if data and 'page' in data else 1
limit = int(data['limit']) if data and 'limit' in data else 10
users = User.query.filter_by(instance_id=1, deleted=False).order_by(User.id)
query = data['q'] if data and 'q' in data else ''
if type == 'Local':
users = User.query.filter_by(instance_id=1, deleted=False).order_by(User.id)
else:
users = User.query.filter_by(deleted=False).order_by(User.id)
if query:
users = users.filter(User.user_name.ilike(f"%{query}%"))
users = users.paginate(page=page, per_page=limit, error_out=False)
user_list = []