From 7669cfe361dba0407511a7716a4da4e9df3f14c0 Mon Sep 17 00:00:00 2001 From: Roland Date: Tue, 16 Apr 2024 10:04:06 -0600 Subject: [PATCH] Ordering suggested channel names by video count. --- app/src/components/Search.js | 28 +++++++++++++++------------- modules/videos/channel/lib.py | 35 ++++++++++++++++++++++++----------- wrolpi/root_api.py | 2 +- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/app/src/components/Search.js b/app/src/components/Search.js index 4eb5eb3a..dd065609 100644 --- a/app/src/components/Search.js +++ b/app/src/components/Search.js @@ -110,8 +110,8 @@ export function useSuggestions(searchStr, tagNames, filter) { React.useEffect(() => { if ((searchStr && searchStr.length > 0) || (tagNames && tagNames.length > 0)) { - setSuggestions(defaultSuggestions); const mimetypes = filterToMimetypes(filter); + setSuggestions(defaultSuggestions); sendGeneralReqeust(async () => await searchSuggestions(searchStr)); sendFilesRequest(async () => await searchEstimateFiles(searchStr, tagNames, mimetypes, months, dateRange)); sendZimRequest(async () => await searchEstimateZims(searchStr, tagNames)); @@ -127,29 +127,31 @@ export function useSuggestions(searchStr, tagNames, filter) { React.useEffect(() => { if (!_.isEmpty(generalData)) { - setSuggestions({ - ...suggestions, - channels: generalData.channels, - domains: generalData.domains, + setSuggestions((prevState) => { + return { + ...prevState, + channels: generalData.channels, + domains: generalData.domains, + } }); } - }, [JSON.stringify(generalData)]); + }, [setSuggestions, generalData]); React.useEffect(() => { if (!_.isEmpty(filesData)) { - console.log(filesData); - setSuggestions({ - ...suggestions, - fileGroups: filesData.fileGroups, + setSuggestions((prevState) => { + return {...prevState, fileGroups: filesData.fileGroups} }); } - }, [JSON.stringify(filesData)]); + }, [setSuggestions, filesData]); React.useEffect(() => { if (!_.isEmpty(zimData)) { - setSuggestions({...suggestions, zimsEstimates: zimData.zimsEstimates}); + setSuggestions((prevState) => { + return {...prevState, zimsEstimates: zimData.zimsEstimates} + }); } - }, [JSON.stringify(zimData)]); + }, [setSuggestions, zimData]); return {suggestions, loading: generalLoading || zimLoading || filesLoading} } diff --git a/modules/videos/channel/lib.py b/modules/videos/channel/lib.py index 9170ae52..4e7e3b6e 100644 --- a/modules/videos/channel/lib.py +++ b/modules/videos/channel/lib.py @@ -1,7 +1,7 @@ from pathlib import Path from typing import List, Dict, Union -from sqlalchemy import asc, or_ +from sqlalchemy import or_, func, desc, asc from sqlalchemy.orm import Session from sqlalchemy.orm.exc import NoResultFound @@ -14,7 +14,7 @@ from .. import schema from ..common import check_for_channel_conflicts from ..errors import UnknownChannel from ..lib import save_channels_config -from ..models import Channel +from ..models import Channel, Video logger = logger.getChild(__name__) @@ -202,15 +202,28 @@ def download_channel(id_: int, reset_attempts: bool = False): @optional_session -async def search_channels_by_name(name: str, limit: int = 5, session: Session = None) -> List[Channel]: +async def search_channels_by_name(name: str, limit: int = 5, session: Session = None, + order_by_video_count: bool = False) -> List[Channel]: name = name or '' name_no_spaces = ''.join(name.split(' ')) - stmt = session.query(Channel) \ - .filter(or_( - Channel.name.ilike(f'%{name}%'), - Channel.name.ilike(f'%{name_no_spaces}%'), - )) \ - .order_by(asc(Channel.name)) \ - .limit(limit) - channels = stmt.all() + if order_by_video_count: + stmt = session.query(Channel, func.count(Video.id).label('video_count')) \ + .filter(or_( + Channel.name.ilike(f'%{name}%'), + Channel.name.ilike(f'%{name_no_spaces}%'), + )) \ + .join(Video, Video.channel_id == Channel.id) \ + .group_by(Channel.id, Channel.name) \ + .order_by(desc('video_count')) \ + .limit(limit) + channels = [i[0] for i in stmt] + else: + stmt = session.query(Channel) \ + .filter(or_( + Channel.name.ilike(f'%{name}%'), + Channel.name.ilike(f'%{name_no_spaces}%'), + )) \ + .order_by(asc(Channel.name)) \ + .limit(limit) + channels = stmt.all() return channels diff --git a/wrolpi/root_api.py b/wrolpi/root_api.py index 24852383..77a3ac30 100644 --- a/wrolpi/root_api.py +++ b/wrolpi/root_api.py @@ -544,7 +544,7 @@ async def post_search_suggestions(_: Request, body: schema.SearchFileEstimateReq from modules.archive.lib import search_domains_by_name channels, domains = await asyncio.gather( - search_channels_by_name(body.search_str), + search_channels_by_name(body.search_str, order_by_video_count=True), search_domains_by_name(body.search_str), )