From f3e5dcd7a0c4eff8700ac3f232dc0a03ea0b76c2 Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Thu, 26 Sep 2024 18:16:06 +0300 Subject: [PATCH 01/20] Used group search as a template for topic search file --- public/src/admin/manage/groups.js | 2 ++ public/src/client/groups/list.js | 3 +++ public/src/client/search.js | 2 ++ public/src/client/users.js | 2 ++ src/groups/index.js | 6 +++++ src/groups/search.js | 2 ++ src/socket.io/groups.js | 2 ++ src/topics/events.js | 6 +++++ src/topics/index.js | 1 + src/topics/search.js | 39 +++++++++++++++++++++++++++++++ src/user/search.js | 1 + 11 files changed, 66 insertions(+) create mode 100644 src/topics/search.js diff --git a/public/src/admin/manage/groups.js b/public/src/admin/manage/groups.js index 682dcadf21..0a31341fce 100644 --- a/public/src/admin/manage/groups.js +++ b/public/src/admin/manage/groups.js @@ -82,6 +82,8 @@ define('admin/manage/groups', [ function handleSearch() { const queryEl = $('#group-search'); + console.log('public/src/admin/manage/groups handleSearch'); + console.log(queryEl); function doSearch() { if (!queryEl.val()) { diff --git a/public/src/client/groups/list.js b/public/src/client/groups/list.js index aa270bf7f4..d250697c7c 100644 --- a/public/src/client/groups/list.js +++ b/public/src/client/groups/list.js @@ -62,6 +62,9 @@ define('forum/groups/list', [ const queryEl = $('#search-text'); const sortEl = $('#search-sort'); + console.log('entered public/src/client/groups/list groups.search'); + console.log(queryEl); + socket.emit('groups.search', { query: queryEl.val(), options: { diff --git a/public/src/client/search.js b/public/src/client/search.js index 5bf52a1ef9..279d621904 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -114,6 +114,7 @@ define('forum/search', [ } function getSearchDataFromDOM() { + console.log('testing'); const form = $('#advanced-search'); const searchData = { in: $('#search-in').val(), @@ -332,6 +333,7 @@ define('forum/search', [ } async function doSearch() { + console.log('mercy'); let result = { tags: [] }; const query = el.find('[component="tag/filter/search"]').val(); if (query && query.length > 1) { diff --git a/public/src/client/users.js b/public/src/client/users.js index d9bc4be595..8ea461ced1 100644 --- a/public/src/client/users.js +++ b/public/src/client/users.js @@ -26,12 +26,14 @@ define('forum/users', [ }; Users.handleSearch = function (params) { + console.log('entered public/src/client/users handleSearch'); searchResultCount = params && params.resultCount; $('#search-user').on('keyup', utils.debounce(doSearch, 250)); $('.search select, .search input[type="checkbox"]').on('change', doSearch); }; function doSearch() { + console.log('entered public/src/client/users doSearch'); if (!ajaxify.data.template.users) { return; } diff --git a/src/groups/index.js b/src/groups/index.js index 8aef1a7b51..1abc420f21 100644 --- a/src/groups/index.js +++ b/src/groups/index.js @@ -103,6 +103,10 @@ Groups.getNonPrivilegeGroups = async function (set, start, stop, flags) { }; Groups.getGroups = async function (set, start, stop) { + console.log('entered src/groups/index getGroups'); + console.log(set); + console.log(start); + console.log(stop); return await db.getSortedSetRevRange(set, start, stop); }; @@ -121,6 +125,8 @@ Groups.getGroupsAndMembers = async function (groupNames) { }; Groups.get = async function (groupName, options) { + console.log('hi'); + console.log(options); if (!groupName) { throw new Error('[[error:invalid-group]]'); } diff --git a/src/groups/search.js b/src/groups/search.js index 3e0dfd2def..982f6a2c4c 100644 --- a/src/groups/search.js +++ b/src/groups/search.js @@ -5,6 +5,8 @@ const db = require('../database'); module.exports = function (Groups) { Groups.search = async function (query, options) { + console.log('entered group search'); + console.log(query); if (!query) { return []; } diff --git a/src/socket.io/groups.js b/src/socket.io/groups.js index 789ac9941a..19bbd1a6e4 100644 --- a/src/socket.io/groups.js +++ b/src/socket.io/groups.js @@ -23,6 +23,7 @@ SocketGroups.before = async (socket, method, data) => { }; SocketGroups.search = async (socket, data) => { + console.log('entered socket search'); data.options = data.options || {}; if (!data.query) { @@ -46,6 +47,7 @@ SocketGroups.loadMore = async (socket, data) => { }; SocketGroups.searchMembers = async (socket, data) => { + console.log('entered socket search'); sockets.warnDeprecated(socket, 'GET /api/v3/groups/:groupName/members'); if (!data.groupName) { diff --git a/src/topics/events.js b/src/topics/events.js index f63f4b32a8..95407ed5ec 100644 --- a/src/topics/events.js +++ b/src/topics/events.js @@ -27,6 +27,7 @@ const Events = module.exports; * the user avatar/username will be rendered as part of the event text * see https://github.com/NodeBB/nodebb-plugin-question-and-answer/blob/master/library.js#L288-L306 */ +console.log('entered topic events'); Events._types = { pin: { icon: 'fa-thumb-tack', @@ -68,6 +69,11 @@ Events._types = { icon: 'fa-code-fork', translation: async (event, language) => translateEventArgs(event, language, 'topic:user-forked-topic', renderUser(event), `${relative_path}${event.href}`, renderTimeago(event)), }, + search: { + search: 'fa-fa-search', + translation: async (event, language) => translateEventArgs(event, language, 'topic:user-forked-topic', renderUser(event), `${relative_path}${event.href}`, renderTimeago(event)), + }, + }; Events.init = async () => { diff --git a/src/topics/index.js b/src/topics/index.js index 5724d8a276..456d0d5c36 100644 --- a/src/topics/index.js +++ b/src/topics/index.js @@ -20,6 +20,7 @@ require('./create')(Topics); require('./delete')(Topics); require('./sorted')(Topics); require('./unread')(Topics); +// require('./search')(Topics); require('./recent')(Topics); require('./user')(Topics); require('./fork')(Topics); diff --git a/src/topics/search.js b/src/topics/search.js new file mode 100644 index 0000000000..1cc05375fc --- /dev/null +++ b/src/topics/search.js @@ -0,0 +1,39 @@ +'use strict'; + +const db = require('../database'); + +module.exports = function (Topics) { + Topic.search = async function (query, options) { + console.log('entered topic search'); + console.log(query); + if (!query) { + return []; + } + query = String(query).toLowerCase(); + let topicTitles = Object.values(await db.getObject('topicslug:topictitle')); + topicTitles = topicTitles.filter( + name => name.toLowerCase().includes(query) && name !== Topics.BANNED_USERS // hide banned-users in searches + ); + topicTitles = topicTitles.slice(0, 100); + return Topics.sort(options.sort, topicTitles); + }; + + Topics.sort = function (strategy, groups) { + switch (strategy) { + case 'count': + topics.sort((a, b) => a.slug > b.slug) + .sort((a, b) => b.memberCount - a.memberCount); + break; + + case 'date': + topics.sort((a, b) => b.createtime - a.createtime); + break; + + case 'alpha': // intentional fall-through + default: + topics.sort((a, b) => (a.slug > b.slug ? 1 : -1)); + } + + return groups; + }; +} \ No newline at end of file diff --git a/src/user/search.js b/src/user/search.js index ec0b81d025..cbe1f35aab 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -26,6 +26,7 @@ module.exports = function (User) { User.search = async function (data) { + console.log('entered user.search in src/user/search'); const query = data.query || ''; const searchBy = data.searchBy || 'username'; const page = data.page || 1; From f8f0c1cc9b032cac5e69fa6d9c722b49e15b29f1 Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Thu, 26 Sep 2024 19:13:12 +0300 Subject: [PATCH 02/20] Added socket function in src/socket.io/topics --- src/socket.io/topics.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/socket.io/topics.js b/src/socket.io/topics.js index 3df9cdc1a2..31d9b806e5 100644 --- a/src/socket.io/topics.js +++ b/src/socket.io/topics.js @@ -62,6 +62,13 @@ SocketTopics.createTopicFromPosts = async function (socket, data) { return result; }; +SocketTopics.search = async (socket, data) => { + console.log('entered socket topics search'); + data.options = data.options || {}; + data.options.filterHidden = data.options.filterHidden || !await user.isAdministrator(socket.uid); + return await topics.search(data.query, data.options); +}; + SocketTopics.isFollowed = async function (socket, tid) { const isFollowing = await topics.isFollowing([tid], socket.uid); return isFollowing[0]; From 0d59d80ac51a311d274e2f96e9c4b5609ade9ccf Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Thu, 26 Sep 2024 19:18:59 +0300 Subject: [PATCH 03/20] Fixed syntax errors --- src/topics/search.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/topics/search.js b/src/topics/search.js index 1cc05375fc..d8ce02b80a 100644 --- a/src/topics/search.js +++ b/src/topics/search.js @@ -3,7 +3,7 @@ const db = require('../database'); module.exports = function (Topics) { - Topic.search = async function (query, options) { + Topics.search = async function (query, options) { console.log('entered topic search'); console.log(query); if (!query) { @@ -18,7 +18,7 @@ module.exports = function (Topics) { return Topics.sort(options.sort, topicTitles); }; - Topics.sort = function (strategy, groups) { + Topics.sort = function (strategy, topics) { switch (strategy) { case 'count': topics.sort((a, b) => a.slug > b.slug) @@ -33,7 +33,6 @@ module.exports = function (Topics) { default: topics.sort((a, b) => (a.slug > b.slug ? 1 : -1)); } - - return groups; + return topics; }; -} \ No newline at end of file +}; From 3dd712364e3e68ea137f3e75eb4fd99937b3703d Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Wed, 2 Oct 2024 11:47:13 +0300 Subject: [PATCH 04/20] adding missing search functions using the user search as a template --- dump.rdb | Bin 49070 -> 50531 bytes .../templates/category.tpl | 6 +- public/src/client/topic.js | 45 +++++ src/api/topics.js | 19 +- src/api/users.js | 3 + src/controllers/topics.js | 13 ++ src/controllers/users.js | 2 + src/topics/index.js | 2 +- src/topics/search.js | 165 +++++++++++++++--- 9 files changed, 225 insertions(+), 30 deletions(-) diff --git a/dump.rdb b/dump.rdb index 81882685ed07b4339e233b0f0a5e8262257f49b4..b0395ddf5f84a061e951952d84cac1015e3831a0 100644 GIT binary patch delta 4835 zcmai23sh5Qwm#!8K?N&Ss&y=S=~R#ld;F>K&12 zI1ua=HUx!@*)bUjkFVFk&k8StOHBjaR08MPd=z7Zp*==03~Jzt<#)-iIVA~;a=7I5 z(<}+~YypHuRB-7)0esn^fv&1c@Ls)+Vhqr4u7=@by4?qVd(Tr6VAqzRr?k-i5(8sZ zN1^akX+wjp$VL!E9+4uHkUfr~mXc(OIK5ImNoOV6E*HCLB8#P|$o^J0O-Yjl# zv;fZTe=O-8nL$E=FM#XX^he5nSPnPNsNvmJ8aT7*7<|pq@RRi_n6LXArPKj!E~)As z5MuF6kg3G)8c*!T8Rw9x#Kft^Vu(^yiYK<$E9JPFG3O)UV94)@3wINnQl3fUgc55~ zr4xh5Dm_f_xzMnq4CI}q(6fU9XQvWIchK;~!V#bc3Sf{_!Ij1-*x;^!d~cHBSxK<;}2l%P?%)rvvv2Da@UD4ZgWg1+@)7o2@JmbL<`H#-%GM5yRQ; z>3g(ipw|;bJa}?Tv?rS)A?N2eD5WJst324!xEP+?*$%E1hfy(Dv0Mx6ewvYV_lCWm z-t(>qyy?)dl2PO+zF|>#AQaE15*ng|)#Q@oSUemF`rI=KdSV{Y?w*-F8VSeZZVjDJ zk~;@N!TteZS-YFblT+kaZ@4=ca?7&lEOJ^|3cCzi*qu`Z){=uz)?V6Rs;fg$ONdk= zyS(ZSd%G^B>4qvqG%je%&~RGG!Qu7gu)_5K#UNl_7~dA^Wu-t<5)zYXevglVXLeQ zE-#&h$atF(W$1D%oNZ*`noA2`H>yF~EQiwhGO(go+x(|t!=h;N(E36W{_qqHLq8sb z(y>wy^tzI}#Q*dj;x9zR2WDcHSbN-eZ9CF^*Y}HKPR0}R^lpv^eKDt4zS#Myx}r>- zu(I5)6PA}LLe!Q7O``hZ`qTp1xEuu4bMT+VrJ&H~!Yz3*7}X5??NmR^IHd-iIfwl} zz0-7W?^r3=X|TcGjs{YX053;vhia-+gM7Xm-Y7UMs^YK4OU93&${^{Szg7!dsu<{5 zdsI}Hty@(8tEF&F8Y@iBc+el~iV7b8j2Vb`6c)NQ2fj+PZ5qinCPP})u0wN04W(=l zDL1h#2W0m@0teb?RP+RrK(Yz5#*NB~>r@7fKUBk^qd$j_J7w^ayAYNC?07X?l$4_2 zF2U;$N#P@9A!!m%lc{onjpsn%&DP|l>fUUq?1)2oyAi(H!-{b;+-K;ZJouizoML8+ zoWP8J_4!|ec4rTi>Cj^+BFgwF>^)?IlLtm9X6_wTKG&8fYVA$yZ{anDSyEmu3d7iK zVQ_LZK|Y0~!D*5ZsA_pgJe($HFj877VlsMXBIMtr{DXTo!AIM4h=3nkzS(>2@#irM zi0YUSi#eBiTCFSBt?P=~x7Z`Ag!b0JI=gqx=Ke)%mwL@{>jUQ(G7CAV8Fn(9wZmw2 znr%*#rM|?-anL_Jf0(oJ{s8X{I0T1>GX_i+uP>k4GGDz^WiU<2D>IyiU$!6!RCWp~s zGsDS*W@TrVHyYl^oWPL~8#PzIft_Sev4s?8abVI| zu7xx5W}Y*%zhsY3DJpU-Mx$x#R=BP-P-sfw77MixA`KgbQ_svwexg;ASewp{r)QSB zGCi|w^NzrDD-9pPE{BrAAR*r1myoAVh*edI^x2J>bvJb0VJW;bXQk7~-CWsLF0y?1 zSZa>uuGB<@?qDn)^%Q0u6O?YEJWigVg6&x)Z@J|UOi_AJsg zZmdZu9Yf5Er+G-H-uZn`n_HbX5{rA{1F_tZM6oV+N4Gx`?eZb$giu_DMn9q)8vWZb zPdA2#qdLFzbd||d#hI#>ht18am-PplS1$EgmiM;xZ|d8yxL&uR_ksIbEZs})=U1D3 z>-@2nZ|e=Ly*S zGB1xv?K2yAtJz}kxa2ak&*~4*Rv*t>yxwX&Bl^i2_~L9WQe+MWsS0@H+&p+e-=DnT zX;fmlJ3C$lpBt`<*06500(LFbpz(B36n$(5)AD&OUs>KA4G%<|10h(RQ>H*>0Z%oN zEz?YmSV_Z!pJ$HILa0Roic)-3DNOMUY}%oO)=pIEi4l-Jm{!!)(yO9}zy^L!*5_!L zj$~XGX81pFS-zsfP^n{Re^Y|C2ded3c*#|Z>|nLH4*bhLybinpVX^>TwGY8kz%E1r3+(kM2CFe+5uIu3 z-1P#>2CcOsQV2Cnr!;EFfAo{paHiZt&dzjCK0KWL7ts#AYFA+gI=)5*C)Rbq^%>Y| zr5)0_wnBKw*@4^ZkXrx?i&L=f7!7r!TD%E~uK5-8`eoTMv7q6FcMB@-yo}m= zKbTn zL^IA5uaDTrc8B}sU@ zqgEuJ;$<~VON!t{_87^FC(2Y0BIBa1#Aa~DU1^Vay2V8~cD`AAhYV{EK07Q{-`zq; z*#@%ab+lmQvl{BZI;z|nf@U>j+vUU;gp8%hurEOq3bvAb?Oftr7fnTFweAKMEw~vb z)o)5{BpCEy(Wi+nVkUaC=TPDxQNlJ*@7%0$HxOm$v|mgn&JpG4e_fXnEkq4EO_E)n zc#d)8DW#xZv#k0*l<{Z;0Z~qj3DIa6?dKMw znNF>oO0nZ?(M%~EqGz_bOD9cvypg9<9j6;-yVV6F=`AETWobUq>Q>5k{tv4lpCV^Y z<#kF-g(>@jK%3h_j7||-vh!09eA|Zlo8O;vfZ?o7OW-qd+z5s8s+j+mw$D6$7 y+Ef+c&*(6dD{k26yC~NQXvu%Ec(Q?#wgh#jm6G#XWAVCQ40O2LZv_iGk)+(TMtXd&FLQDlhdDz;nOIj=n zK2X2fU0YGARku_t8awp~R9tu39bc`TZi}OIx^Cav2jgySr|dcRCfM1Xomu|46LRml z=XZX;-}m$V<+CooH^=$SSxNJP$7=5ewKm&pO!fBqv%L-jcQ>fgRcorMY_<<^zj8kp z{z#N2T$yJ?+i^YS23^H{*$S-B)S=<%B$RB9LE}DiU~e>$kE_ghKGO(WYAEK`xkwsa z6^n|!{`fjujwiN6LD(||nPvg+l}2Idi(etX&%i5_ab#C4(z|ct1%ER>P0Jzi7%J7n zwpRzol=B{gJdE(lO!28h11cOm_C3@)7x2m?@vHh-a+I#QDFn8-8lBY^^Kjuoym@Y? z%B|ozvc7OKu{YU5{S<`Yr7bJkLMj_7>sGZmtDEQAS2Yh8-YjYlZzmiV&2`kd9L|R3 zz%i5K?~}J0!c_7udsCCEso9d3l_QK5kB%8^8ts3p-ZC2kQnX_T8x3G`S4?}%!N;-W z{%#oZ1JTY$Lop+T-eG$+`UT)yJ`CeIG1#0vm88;Y#-cYv2K~}tG^ExcJY56%+Vy+g z83YEofcrM6u~{ZZs4fa;60eX9Z><&BhB0hPQX@HiEw4;L?=b5w8D5cTVePt%pLBY< zFc6Bxx5TutzPgYVO4G7{n8c@9&tBMeRlHl$!L|v+!A+G|U8096=6mSn3XIHCi$N>j zxP_!yi5RH(2sh>%vB+w`ZvSBNIlifTmMHQ4e!ckI?VJEK7JW|FCPMnGMY2wVH}fK} zQN9nSYI;2bbLwTRwd3Row9|DM%AADXo1^e$rhvW|)yS*q5Ou^NR=z>sw=o#yhZm3n znydtL=NBV8I3l{<)zGqBtrqJw=Khag-{GveTh$Jq9Tjc+@Q*;fL8YK7Z)&Klw_94BHR0jnOV|0DKu!=_p~ar0V=T{1kULAhL0hK6 zGcwPQcp7D4ge2fdx*FwiO7(w-WacrjES;@or0~_K^KDim0kK0;<`s)$kU2XV4=z?> z>1-8h7l)!`e}|{UFOHCOnk*x3@qy?)p+(n%t8namgjeN=O~u-oHWQjUjoy5fV^4 z@*nV>QNbX&HBE&_mz82uR+MZw-K?e0L}KOXr-)g6+7u%o-t-89Hl*T6kDh8whp&4y zxSSD+b!D%@P@zGieGOjSo`g#U0l40##S;BRm@Um&D&+(TEfV?kdfE~)Zj3u!tPz8v z0lFW(A_Yj0aMplXMTQBXUOI3EWUEeoy~riF=ozdqZv8;!&LqTRoGXWjt z8!@9hB8O zQa!`&Famdm0;g!VkMv%nm5`tk3U_Y3r|AR@j?Exxas%aN5}QBp{Bp_#Z%wSx@54I5Y&YB_ON5M$1jh-cc_%lJ;j>*)W zn5vj_v299KD!H@K(qyl;H?&Nj&iWGt=kh#vcEs@E$^gb3I)4;7iaI8DP({QZSw5F& z)!C+k{4BGnYFa^Vc5P+eG;^idIIcpepX6QFrl&Ha_Uv%3BrIt@48+#vP*IO#Fj7EC z$8&f#QJT6Gx^F~0F!5X}sPP>0*AwxJzTwq+k@3xSt&ab}_(SRXFfV?_+_KmNN#`(} zN`TcGjpnL&k15_pF!*>P?i@|VAFWc55P(n7+%xtwiA-~+(esuexbUAv)j~C`tOb90YjvAIrmb>6#044R$)i`? zgIusdAW8jhtwHePek@C{Rd9kqOI+3Ncy1E?aCp!?SSavKAt|=_LV;vFeK?xp zQ|X->*rd^&uc60{0z*#f>kN?3@v3l|^l;U15$6LnMZ5|!TzD%EpB!}5$FraX8oich zQ7;surU&|r3!y>L@C6!v{BOh0{EzS#{y*VAErw6q-bhEZG;ub~5<%RZufS#PE&NNT z@Wc+$LFB${mVT4Sgo`_95$QzqnD&v0W@J;uh*blZK2V$_+S~V00WfC@q>3Rtg7&B*I#N)>mv~_giFCBZ?BpjmC z;{#6|5H&bLN820Im*L{k6p>%XiQhkTE{T_fXK^*uIUDTv4F2Kg@>9G9&+u=ALKlsG z(-n_9c&UQEhKb!26A0Iw5){3b&A586`z5Y+P5wYM@^VKn!mtSL-)$F)+HL#BGM?80;CH2Oq?0|kl@F>+$QkUVoP)5!2IrsoCf60c*+>c$kl9l(&cQZ zsciX8_@k;bGAVpjffw06O|c(yaoA=%!7I~5yYmeg)@TiGEI)x+XJ5m~y6N)q4+mS# JV
- -
diff --git a/public/src/client/topic.js b/public/src/client/topic.js index 7e65cbeb4f..e786b1b0a0 100644 --- a/public/src/client/topic.js +++ b/public/src/client/topic.js @@ -73,10 +73,55 @@ define('forum/topic', [ $(window).on('scroll', utils.debounce(updateTopicTitle, 250)); handleTopicSearch(); + Topic.handleSearch(); hooks.fire('action:topic.loaded', ajaxify.data); }; + Topic.handleSearch = function (params) { + console.log('entered public/src/client/topics handleSearch'); + searchResultCount = params && params.resultCount; + $('#search-topic').on('keyup', utils.debounce(doSearch, 250)); + $('.search select, .search input[type="checkbox"]').on('change', doSearch); + }; + + function doSearch() { + console.log('entered public/src/client/topics doSearch'); + if (!ajaxify.data.template.users) { + return; + } + $('[component="topic/search/icon"]').removeClass('fa-search').addClass('fa-spinner fa-spin'); + const title = $('#search-topic').val(); + const activeSection = getActiveSection(); + + const query = { + section: activeSection, + page: 1, + }; + + if (!title) { + return loadPage(query); + } + + query.query = title; + query.sortBy = getSortBy(); + // const filters = []; + // if ($('.search .online-only').is(':checked') || (activeSection === 'online')) { + // filters.push('online'); + // } + // if (activeSection === 'banned') { + // filters.push('banned'); + // } + // if (activeSection === 'flagged') { + // filters.push('flagged'); + // } + // if (filters.length) { + // query.filters = filters; + // } + + loadPage(query); + } + function handleTopicSearch() { require(['mousetrap'], (mousetrap) => { if (config.topicSearchEnabled) { diff --git a/src/api/topics.js b/src/api/topics.js index 6609e5e1e5..b1ae829cd8 100644 --- a/src/api/topics.js +++ b/src/api/topics.js @@ -299,4 +299,21 @@ topicsAPI.bump = async (caller, { tid }) => { topics.pushUnreadCount(caller.uid); }; - +topicsAPI.search = async function (caller, data) { + console.log('entered src/api/topics.js'); + // console.log(caller); + // console.log(data); + if (!data) { + throw new Error('[[error:invalid-data]]'); + } + let filters = data.filters || []; + + return await topic.search({ + tid: caller.tid, + query: data.query, + searchBy: data.searchBy || 'title', + page: data.page || 1, + sortBy: data.sortBy || 'lastposttime', + filters: filters, + }); +}; diff --git a/src/api/users.js b/src/api/users.js index c4f4add772..edf5ba2f70 100644 --- a/src/api/users.js +++ b/src/api/users.js @@ -598,6 +598,9 @@ async function canDeleteUids(uids) { } usersAPI.search = async function (caller, data) { + console.log('entered src/api/users.js'); + // console.log(caller); + // console.log(data); if (!data) { throw new Error('[[error:invalid-data]]'); } diff --git a/src/controllers/topics.js b/src/controllers/topics.js index d83ce8e602..237fca0ba8 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -405,3 +405,16 @@ topicsController.pagination = async function (req, res, next) { res.json({ pagination: paginationData }); }; + +topicsController.search = async function (req, res) { + console.log('entered src/controllers/topics.js'); + // console.log(req); + const searchData = await api.topics.search(req, req.query); + + const section = req.query.section || 'joindate'; + + searchData.pagination = pagination.create(req.query.page, searchData.pageCount, req.query); + searchData[`section_${section}`] = true; + searchData.displayUserSearch = true; + await render(req, res, searchData); +}; \ No newline at end of file diff --git a/src/controllers/users.js b/src/controllers/users.js index 41194e6c82..f00fc432d9 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -33,6 +33,8 @@ usersController.index = async function (req, res, next) { }; usersController.search = async function (req, res) { + console.log('entered src/controllers/users.js'); + // console.log(req); const searchData = await api.users.search(req, req.query); const section = req.query.section || 'joindate'; diff --git a/src/topics/index.js b/src/topics/index.js index 456d0d5c36..4a2700f59b 100644 --- a/src/topics/index.js +++ b/src/topics/index.js @@ -20,7 +20,7 @@ require('./create')(Topics); require('./delete')(Topics); require('./sorted')(Topics); require('./unread')(Topics); -// require('./search')(Topics); +require('./search')(Topics); require('./recent')(Topics); require('./user')(Topics); require('./fork')(Topics); diff --git a/src/topics/search.js b/src/topics/search.js index d8ce02b80a..105db6c487 100644 --- a/src/topics/search.js +++ b/src/topics/search.js @@ -1,38 +1,153 @@ + 'use strict'; +const _ = require('lodash'); + +const meta = require('../meta'); +const plugins = require('../plugins'); const db = require('../database'); +const groups = require('../groups'); +const utils = require('../utils'); + +console.log('this was called'); +module.exports = function (Topic) { + Topic.search = async function (data) { + console.log('entered user.search in src/topics/search'); + const query = data.query || ''; + const searchBy = data.searchBy || 'title'; + const page = data.page || 1; + const uid = data.uid || 0; + const paginate = data.hasOwnProperty('paginate') ? data.paginate : true; + + const startTime = process.hrtime(); + + let uids = []; + if (searchBy === 'ip') { + uids = await searchByIP(query); + } else if (searchBy === 'uid') { + uids = [query]; + } else { + const searchMethod = data.findUids || findUids; + uids = await searchMethod(query, searchBy, data.hardCap); + } + + uids = await filterAndSortUids(uids, data); + const result = await plugins.hooks.fire('filter:users.search', { uids: uids, uid: uid }); + uids = result.uids; + + const searchResult = { + matchCount: uids.length, + }; + + if (paginate) { + const resultsPerPage = data.resultsPerPage || meta.config.userSearchResultsPerPage; + const start = Math.max(0, page - 1) * resultsPerPage; + const stop = start + resultsPerPage; + searchResult.pageCount = Math.ceil(uids.length / resultsPerPage); + uids = uids.slice(start, stop); + } + + const [userData, blocks] = await Promise.all([ + User.getUsers(uids, uid), + User.blocks.list(uid), + ]); -module.exports = function (Topics) { - Topics.search = async function (query, options) { - console.log('entered topic search'); - console.log(query); + if (blocks.length) { + userData.forEach((user) => { + if (user) { + user.isBlocked = blocks.includes(user.uid); + } + }); + } + + searchResult.timing = (process.elapsedTimeSince(startTime) / 1000).toFixed(2); + searchResult.users = userData.filter(user => user && user.uid > 0); + return searchResult; + }; + + async function findUids(query, searchBy, hardCap) { if (!query) { return []; } query = String(query).toLowerCase(); - let topicTitles = Object.values(await db.getObject('topicslug:topictitle')); - topicTitles = topicTitles.filter( - name => name.toLowerCase().includes(query) && name !== Topics.BANNED_USERS // hide banned-users in searches - ); - topicTitles = topicTitles.slice(0, 100); - return Topics.sort(options.sort, topicTitles); - }; + const min = query; + const max = query.substr(0, query.length - 1) + String.fromCharCode(query.charCodeAt(query.length - 1) + 1); - Topics.sort = function (strategy, topics) { - switch (strategy) { - case 'count': - topics.sort((a, b) => a.slug > b.slug) - .sort((a, b) => b.memberCount - a.memberCount); - break; + const resultsPerPage = meta.config.userSearchResultsPerPage; + hardCap = hardCap || resultsPerPage * 10; - case 'date': - topics.sort((a, b) => b.createtime - a.createtime); - break; + const data = await db.getSortedSetRangeByLex(`${searchBy}:sorted`, min, max, 0, hardCap); + const uids = data.map(data => data.split(':').pop()); + return uids; + } - case 'alpha': // intentional fall-through - default: - topics.sort((a, b) => (a.slug > b.slug ? 1 : -1)); + async function filterAndSortUids(uids, data) { + uids = uids.filter(uid => parseInt(uid, 10)); + let filters = data.filters || []; + filters = Array.isArray(filters) ? filters : [data.filters]; + const fields = []; + + if (data.sortBy) { + fields.push(data.sortBy); } - return topics; - }; + + filters.forEach((filter) => { + if (filterFieldMap[filter]) { + fields.push(...filterFieldMap[filter]); + } + }); + + if (data.groupName) { + const isMembers = await groups.isMembers(uids, data.groupName); + uids = uids.filter((uid, index) => isMembers[index]); + } + + if (!fields.length) { + return uids; + } + + if (filters.includes('banned') || filters.includes('notbanned')) { + const isMembersOfBanned = await groups.isMembers(uids, groups.BANNED_USERS); + const checkBanned = filters.includes('banned'); + uids = uids.filter((uid, index) => (checkBanned ? isMembersOfBanned[index] : !isMembersOfBanned[index])); + } + + fields.push('uid'); + let userData = await User.getUsersFields(uids, fields); + + filters.forEach((filter) => { + if (filterFnMap[filter]) { + userData = userData.filter(filterFnMap[filter]); + } + }); + + if (data.sortBy) { + sortUsers(userData, data.sortBy, data.sortDirection); + } + + return userData.map(user => user.uid); + } + + function sortUsers(userData, sortBy, sortDirection) { + if (!userData || !userData.length) { + return; + } + sortDirection = sortDirection || 'desc'; + const direction = sortDirection === 'desc' ? 1 : -1; + + const isNumeric = utils.isNumber(userData[0][sortBy]); + if (isNumeric) { + userData.sort((u1, u2) => direction * (u2[sortBy] - u1[sortBy])); + } else { + userData.sort((u1, u2) => { + if (u1[sortBy] < u2[sortBy]) { + return direction * -1; + } else if (u1[sortBy] > u2[sortBy]) { + return direction * 1; + } + return 0; + }); + } + } + }; From f59d48602f9a783c53f4d6720cd4bdbc43a4f61f Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Wed, 2 Oct 2024 11:57:42 +0300 Subject: [PATCH 05/20] moved client side handleSearch function from public/src/client/topic.js to public/src/client/category.js --- dump.rdb | Bin 50531 -> 50535 bytes public/src/client/categories.js | 2 ++ public/src/client/category.js | 46 ++++++++++++++++++++++++++++++++ public/src/client/topic.js | 45 +------------------------------ 4 files changed, 49 insertions(+), 44 deletions(-) diff --git a/dump.rdb b/dump.rdb index b0395ddf5f84a061e951952d84cac1015e3831a0..d50664c2a7750dc6895fe69951c76e9acacf5070 100644 GIT binary patch delta 491 zcmaFd#r(XBd4hr9S+2inzc@;ZQ&V(vQ*#d;c)ZckPLa`XbAw_jH>&{Se?h~^8|TSQ z)|KVntgO3Eh%tQgCHn|bW|O_0lXXM&7=P>x?gnQ{I8 zhW!rQOhvq!3Hl1$%nb!Iy$^6RG3Zq^WHSf=6^cD?h-Z)hGN#UN=x2~p&}TaNOFcoK zK^AD*t^*C58RQhWnQZKQ62uu4fvVy!Gz2rKE9f(_u*fyc-h5>3WR7~UwWonD;RZQL z9B2yz$VK{K7Xclj40MP%$RVep4pDaCW`sIG8RP(WWCyqtbii_m1LPW-nH+#ou=(1y ztsH{wM+KFjTQ{eUVTt+B|2!AS>gV$?J~Hk#68&Vq)xekYr3PO5kJWVPyRO N-=yrVlD?jM3;=HulF9%8 delta 487 zcmaFf#r(L7d4hppF~{GuUmT^ysVTa-skw(P{MhJdr^slwxk0g%o0W<2zo6k{#x<&& z<#jg+G1_mwWFH~QJnePkWZh6bMuEvOp$tO5My7gF28M>4SA?!-6l6CwG%ztX zF*H^d)^SwAOU1do!>BEti<1bqfspypi% z8ul~D0p;Q^G`KUU12wbAHS}*jwstZ{J;YvdpuNf { if (config.topicSearchEnabled) { From ceff7fd391c8c97de4a2f53b7e80042f20ec749a Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Wed, 2 Oct 2024 12:21:11 +0300 Subject: [PATCH 06/20] adding in missing functions that are needed in public/src/client/category.js and are found in public/src/client/users.js --- dump.rdb | Bin 50535 -> 50564 bytes public/src/client/category.js | 47 +++++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/dump.rdb b/dump.rdb index d50664c2a7750dc6895fe69951c76e9acacf5070..013fbfc8bcfc1446d4592203574db0efbb32f054 100644 GIT binary patch delta 399 zcmaFf#oW@(Ji$P)k^gVnFOJgU)D+#^)Z9Z1+c!GeDKchkZcy~$Hal!+E@sZaz`()q zrGZ6GWfCI;11BTn7l!x?-U-}nOpIR|v`T#vxEa_K#2Ibu8n~H+82<|zPG(%Ax>;U# zlMrL!=1cYwqRe|W=Wf;wH56lZjBebVm@T6WW;FE8W9IzfIG=ky&{&tr>XV*x91v#$ znz(>_v%uszlKjdrIfgF`f|FS$pWmuD`OccHw#rN(Ta^{KnHZ+dZr6A69@|Svo zID;(E9lH)R>}QZu;08HJp8=?fG5$hBJcGJ|J|l}#xD%<7reo2CLr6!&IimE*!)lDwh&|Z=3Dj=qRb|HJ2#t#8j3L=X3pE3 znJuHtd<4ko=$psP`N?rI_hg_+PLuT~J!fhV-z+zIjwGivT=ejoJEq)>Q|CAIGe{}u zGoAdUo}kYlt02y}>p;V11~~<8CZLrG;tYxk+>G%T8iE2y;aiJbB_T4DH3em diff --git a/public/src/client/category.js b/public/src/client/category.js index ed72be8e8b..a100b1e2be 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -19,6 +19,8 @@ define('forum/category', [ } }); + let searchResultCount = 0; + Category.init = function () { console.log('entered category public client'); const cid = ajaxify.data.cid; @@ -42,6 +44,7 @@ define('forum/category', [ handleIgnoreWatch(cid); handleLoadMoreSubcategories(); + Category.handleSearch(); categorySelector.init($('[component="category-selector"]'), { @@ -123,11 +126,12 @@ define('forum/category', [ function doSearch() { console.log('entered public/src/client/category doSearch'); - if (!ajaxify.data.template.users) { + if (!ajaxify.data.template.category) { return; } $('[component="topic/search/icon"]').removeClass('fa-search').addClass('fa-spinner fa-spin'); const title = $('#search-topic').val(); + console.log(title); const activeSection = getActiveSection(); const query = { @@ -158,6 +162,26 @@ define('forum/category', [ loadPage(query); } + function getSortBy() { + let sortBy; + const activeSection = getActiveSection(); + if (activeSection === 'sort-posts') { + sortBy = 'postcount'; + } else if (activeSection === 'sort-reputation') { + sortBy = 'reputation'; + } else if (activeSection === 'users') { + sortBy = 'joindate'; + } + return sortBy; + } + + function loadPage(query) { + console.log('entered load page'); + api.get('/api/topics', query) + .then(renderSearchResults) + .catch(alerts.error); + } + Category.toTop = function () { navigator.scrollTop(0); }; @@ -183,5 +207,26 @@ define('forum/category', [ }); } + function getActiveSection() { + return utils.param('section') || ''; + } + + function renderSearchResults(data) { + Benchpress.render('partials/paginator', { pagination: data.pagination }).then(function (html) { + $('.pagination-container').replaceWith(html); + }); + + if (searchResultCount) { + data.users = data.users.slice(0, searchResultCount); + } + + data.isAdminOrGlobalMod = app.user.isAdmin || app.user.isGlobalMod; + app.parseAndTranslate('topics', 'topics', data, function (html) { + $('#users-container').html(html); + html.find('.timeago').timeago(); + $('[component="topic/search/icon"]').addClass('fa-search').removeClass('fa-spinner fa-spin'); + }); + } + return Category; }); From ef8958144eeaf65a105edc6353c08a6825ba3529 Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Thu, 3 Oct 2024 06:27:05 +0300 Subject: [PATCH 07/20] editing the code mainly in public/src/client/category.js to try and render post results --- dump.rdb | Bin 50564 -> 50695 bytes .../templates/partials/posts_list.tpl | 2 +- .../nodebb-theme-harmony/templates/users.tpl | 2 +- public/src/client/category.js | 6 +++--- public/src/client/users.js | 1 + src/api/topics.js | 2 ++ 6 files changed, 8 insertions(+), 5 deletions(-) diff --git a/dump.rdb b/dump.rdb index 013fbfc8bcfc1446d4592203574db0efbb32f054..85a3c2913cebab3961a2c734e3b00f3ac79e76a3 100644 GIT binary patch delta 758 zcmaKpPe>GD7{=dkW>|OkOHHvIH_K)j!%cE$D-+bxSu7P4T(Rv`II(SHVlLWhdeBcu zL=p*ypy;2s4i*|8sU)#mb`h!Uw1Pvm@QXQcC`{`N_r)RX7&0DuG*n_4_ENdO#)5rGeTnrNjS(3@S&*xi9$ zsjw*BCB%ZZ)kcHb1Y)s`mSBPkKnfTIQIUm`Sd$?`2LE<2l2iO0RX* z;!P)5uyDw`jl@#IX(VI`8Wbc&CL1kCLZ(?g@P>O^Vw%-}6v9`d`S zl7+KDeyO8C{Z)-k+!dVxTVS5fV-yXhHu*Vg9jKVPx(=z6e2;nG?I`~}vGizUNER>$ zqY9OvqMx;b9mR`h)8ex5^;D6e0>!7McWeVP6-v6o*vnQ_G81PjIu*Jz4;Y$4MHao? zn2OVPmG!|+9K>AvK*qxLk##`6qNM}Yz>U{#K42VnW9G}=ls(vsZ_g4e357U+teR<{ zV$rsWi^YmYq(a8|+T+a(hc7Tqr_o)V`Qho%zBD;9ptM23hEQms4K1iC-lQ3uQ^UzE zMpdU|i%tE5trgko|H<}$wD>mK9sXsm!A>l*GG1X0$M+Z2+YaYir+bZ{aWpYtEAy98 tD|Bya7mTgLfaJ9LUq@Jp`8-}nesC$lCCP{XXfD2bVJBm2Z`io|;ZL!J-24Cl delta 641 zcmZqgVQ%SWo?sx@$p1I(7e{GvYKm@dYVIM1?He6+6@?WP7#J8>7``+t*zGcjk%56T zgK=|{q7S!*p}CkjP>KU6#UiHymSSZ5!VrJKJAs>xiSbK=R;f<{Hv`*d4&6{8&IE_8 z(p!PbxhALChcYuOFi$q%l90&F&nwBmu%VD~Gq1yGK{YKyN26qMy1!YF{4Gr83Tnge$pF>m~0-o2iIbGeKX0o4KK2ruPAECI-EVhHM4_phB_d4e<;T3d&5N5KvYC zN==>LFq=UNXe`k63E~X0Kx20uXxPsn2UKk%YS*C8093{pe*vgZT|u9bMXq7_X1{g6 z*g0h!Cv#5*y4`7V;I?{kphXGR3~WH%KnDi{9SnBe>B;Z6DaW6Nx=7i9n-S^~WspnU zfiAHo(j`a^*$i_?Ka&IFe?im9jSg~?C$O+@Ua(!3gYoO+efur>4j6Hm7?^N>3E5+# zksvzx`+imNST-Y}FC}U%J_)7_oevnQn7O`8ELk8j+2Md2 +
    {{{ each posts }}} {{{ end }}} diff --git a/node_modules/nodebb-theme-harmony/templates/users.tpl b/node_modules/nodebb-theme-harmony/templates/users.tpl index 8d3b04c9fd..b7ed28bf1d 100644 --- a/node_modules/nodebb-theme-harmony/templates/users.tpl +++ b/node_modules/nodebb-theme-harmony/templates/users.tpl @@ -36,4 +36,4 @@ - + \ No newline at end of file diff --git a/public/src/client/category.js b/public/src/client/category.js index a100b1e2be..e950d379eb 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -177,7 +177,7 @@ define('forum/category', [ function loadPage(query) { console.log('entered load page'); - api.get('/api/topics', query) + api.get('/categories', query) .then(renderSearchResults) .catch(alerts.error); } @@ -221,8 +221,8 @@ define('forum/category', [ } data.isAdminOrGlobalMod = app.user.isAdmin || app.user.isGlobalMod; - app.parseAndTranslate('topics', 'topics', data, function (html) { - $('#users-container').html(html); + app.parseAndTranslate('posts_list', 'topics', data, function (html) { + $('#category-container').html(html); html.find('.timeago').timeago(); $('[component="topic/search/icon"]').addClass('fa-search').removeClass('fa-spinner fa-spin'); }); diff --git a/public/src/client/users.js b/public/src/client/users.js index 8ea461ced1..678236fff2 100644 --- a/public/src/client/users.js +++ b/public/src/client/users.js @@ -84,6 +84,7 @@ define('forum/users', [ function loadPage(query) { + console.log('user load page then api?'); api.get('/api/users', query) .then(renderSearchResults) .catch(alerts.error); diff --git a/src/api/topics.js b/src/api/topics.js index b1ae829cd8..b3ed4d2dfa 100644 --- a/src/api/topics.js +++ b/src/api/topics.js @@ -17,6 +17,8 @@ const socketHelpers = require('../socket.io/helpers'); const topicsAPI = module.exports; + +console.log('trying ot gr here'); topicsAPI._checkThumbPrivileges = async function ({ tid, uid }) { // req.params.tid could be either a tid (pushing a new thumb to an existing topic) // or a post UUID (a new topic being composed) From c1f21834075e30ea6d2385bdf48c8b3cf1e89757 Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Thu, 3 Oct 2024 12:50:29 +0300 Subject: [PATCH 08/20] adding comments and console.logs to test --- dump.rdb | Bin 50695 -> 50975 bytes public/src/client/category.js | 10 +++++++--- public/src/modules/categorySearch.js | 2 ++ src/api/posts.js | 2 ++ src/api/topics.js | 1 - src/categories/search.js | 1 + 6 files changed, 12 insertions(+), 4 deletions(-) diff --git a/dump.rdb b/dump.rdb index 85a3c2913cebab3961a2c734e3b00f3ac79e76a3..6df4a8d6b4cba8ea6b590deb55f249192888300f 100644 GIT binary patch delta 999 zcmbV~T}TvB6vywKnRZvN--N5HZeuHGAM31}Vy>Z6P(8R=TUHdA`!(9;$8I~bXa#wd zQlf8%qO!1ps0b|?C@RRMFX*Xy5|Uz}phq8CdRRj{TlPWp)XU{??*E*7f9HP&kFz5u z+0(X?!acLC2}4Ad{MJsX^9h|SLJ5N>*lP89WGRYf(TwHso;et(WBVu`i&-Y^+f$4d`n9cXR|TU$mSlF zd;jv?1$A(%mCapKp$=bkWK~o**=ij26^^Rva+AGcg@(6{;#}%sYbvWNi;J+$#y{b2 z#!`z@S5|4!?U!_z)0%hRUQmz;qYFFi4*04P=xURniu=X>Mg4$~q1vVGX4B?iM3FKm zJ{}B7U0VWv$?FNr>HWbjb}p+-y*f~)K0IPnr-V#(L$68O=U=DiN*+9OX^+|qEI*>R zCoi)prqxqq3WnXN(xI7!F-#bkbJWP7^M05!LkEVngX-aY%ngm^r)>NsUOYP33qp4- zPyUcnf^@tQ*X*b5$N)jA@RGq?aMAi}wyXgA8M=PgXqa|_CczGp}1Br<{gWug?; zpa@bAqjUzDK@V#nAPWR7uc5G%7cgh06I$a~LZ7mJ^(*oU_?@cjUhiK>-~R&5bWl1l zoZK=70bBQXHs>2U4QwO{ncP40n-S0~fM!ghP0yoQM1tp$gnuKopuDyJg*5pS=>{X> zx$G*nPc*BiIlXq}evtuxQ6Eq2DvLH7Ds7b{uAB*Oa+k*p%{qHdylrgUVh$MEHd&Hg%{%avhXnnn%X1`Aoqi7H9^1I6|r%m{_dehWM*SYwnye5QD z28zp?qT&Y_p)`!+$h%c9&=i5=^3EkslqL`^kZD9RdZIkiAm~vlqsQlJWSY?7{al-} z?k-WA&8*Hk%Et;~@Lv{s&iNz3PzM)|_(Q<}Ck6U~;eLrZp3`OS6vYm|FVJndE-4?+ zkK$?dBEOf5(^dE7Au@ZZee`jX1C>akBsrDvT_$C-R#$6N#%7#3HhYV;+F9Xn+Nv!1 z4ttea)A}0g=6zIUwWG4iVdpoPm)jX8t%}>8QkYPmU0X;|-f|}u`Ho37h`p(r^3|&z zbuv`I9#*gJ&5~)9YlU8cnQq0S?5f^}w~Qa@DQHapilo zy>wf9fjXm$w+;v%p)xu`Rah(N_?6lD6KG-^jcC&2!=FXDTy0xVXfzgBv(oy0*+Ae) X-iXCMA&bnwcz+*H{P-eI8DIPcApQ4A diff --git a/public/src/client/category.js b/public/src/client/category.js index e950d379eb..9196cd2d61 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -10,7 +10,8 @@ define('forum/category', [ 'hooks', 'alerts', 'api', -], function (infinitescroll, share, navigator, topicList, sort, categorySelector, hooks, alerts, api) { + 'benchpress', +], function (infinitescroll, share, navigator, topicList, sort, categorySelector, hooks, alerts, api, Benchpress) { const Category = {}; $(window).on('action:ajaxify.start', function (ev, data) { @@ -211,7 +212,7 @@ define('forum/category', [ return utils.param('section') || ''; } - function renderSearchResults(data) { + function renderSearchResults(data, options) { Benchpress.render('partials/paginator', { pagination: data.pagination }).then(function (html) { $('.pagination-container').replaceWith(html); }); @@ -221,7 +222,10 @@ define('forum/category', [ } data.isAdminOrGlobalMod = app.user.isAdmin || app.user.isGlobalMod; - app.parseAndTranslate('posts_list', 'topics', data, function (html) { + app.parseAndTranslate(options.template, { + categoryItems: categories.slice(0, 200), + selectedCategory: ajaxify.data.selectedCategory, + allCategoriesUrl: ajaxify.data.allCategoriesUrl}, function (html) { $('#category-container').html(html); html.find('.timeago').timeago(); $('[component="topic/search/icon"]').addClass('fa-search').removeClass('fa-spinner fa-spin'); diff --git a/public/src/modules/categorySearch.js b/public/src/modules/categorySearch.js index 8c7461dcdf..6970e8e9a2 100644 --- a/public/src/modules/categorySearch.js +++ b/public/src/modules/categorySearch.js @@ -70,6 +70,8 @@ define('categorySearch', ['alerts', 'bootstrap', 'api'], function (alerts, boots }); function loadList(search, callback) { + console.log('caategories loadlist'); + console.log('did it call search??'); api.get('/search/categories', { search: search, query: utils.params(), diff --git a/src/api/posts.js b/src/api/posts.js index 4e3917a008..cf797fe940 100644 --- a/src/api/posts.js +++ b/src/api/posts.js @@ -20,6 +20,8 @@ const socketHelpers = require('../socket.io/helpers'); const postsAPI = module.exports; +console.log('posts api gets called'); + postsAPI.get = async function (caller, data) { const [userPrivileges, post, voted] = await Promise.all([ privileges.posts.get([data.pid], caller.uid), diff --git a/src/api/topics.js b/src/api/topics.js index b3ed4d2dfa..804636fd72 100644 --- a/src/api/topics.js +++ b/src/api/topics.js @@ -18,7 +18,6 @@ const socketHelpers = require('../socket.io/helpers'); const topicsAPI = module.exports; -console.log('trying ot gr here'); topicsAPI._checkThumbPrivileges = async function ({ tid, uid }) { // req.params.tid could be either a tid (pushing a new thumb to an existing topic) // or a post UUID (a new topic being composed) diff --git a/src/categories/search.js b/src/categories/search.js index 685628f32c..173b451ae6 100644 --- a/src/categories/search.js +++ b/src/categories/search.js @@ -8,6 +8,7 @@ const db = require('../database'); module.exports = function (Categories) { Categories.search = async function (data) { + console.log('it called categories search'); const query = data.query || ''; const page = data.page || 1; const uid = data.uid || 0; From dd8a81116b91dd603f8607104f5d18e3772d8b1c Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Mon, 14 Oct 2024 15:27:49 +0300 Subject: [PATCH 09/20] fixed routes so that they now call posts controller --- public/src/client/category.js | 3 ++- src/controllers/posts.js | 15 +++++++++++++++ src/controllers/write/posts.js | 1 + src/posts/index.js | 1 + src/routes/api.js | 2 ++ src/routes/write/posts.js | 3 +++ 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/public/src/client/category.js b/public/src/client/category.js index 9196cd2d61..548b9a8d47 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -178,7 +178,8 @@ define('forum/category', [ function loadPage(query) { console.log('entered load page'); - api.get('/categories', query) + console.log(query); + api.get('/api/posts', query) .then(renderSearchResults) .catch(alerts.error); } diff --git a/src/controllers/posts.js b/src/controllers/posts.js index 7865ba0af7..314f47f0c3 100644 --- a/src/controllers/posts.js +++ b/src/controllers/posts.js @@ -5,6 +5,7 @@ const querystring = require('querystring'); const posts = require('../posts'); const privileges = require('../privileges'); const helpers = require('./helpers'); +const api = require('../api'); const postsController = module.exports; @@ -37,3 +38,17 @@ postsController.getRecentPosts = async function (req, res) { const data = await posts.getRecentPosts(req.uid, start, stop, req.params.term); res.json(data); }; + +postsController.search = async function (req, res) { + console.log('got it'); + console.log('entered src/controllers/posts.js'); + // console.log(req); + const searchData = await api.posts.search(req, req.query); + + const section = req.query.section || 'joindate'; + + searchData.pagination = pagination.create(req.query.page, searchData.pageCount, req.query); + searchData[`section_${section}`] = true; + searchData.displayUserSearch = true; + await render(req, res, searchData); +}; \ No newline at end of file diff --git a/src/controllers/write/posts.js b/src/controllers/write/posts.js index 1dc8cf6800..30379dd94b 100644 --- a/src/controllers/write/posts.js +++ b/src/controllers/write/posts.js @@ -36,6 +36,7 @@ Posts.redirectByIndex = async (req, res, next) => { }; Posts.get = async (req, res) => { + console.log('got here'); const post = await api.posts.get(req, { pid: req.params.pid }); if (!post) { return helpers.formatApiResponse(404, res, new Error('[[error:no-post]]')); diff --git a/src/posts/index.js b/src/posts/index.js index 9db52c6b27..81bfa34c32 100644 --- a/src/posts/index.js +++ b/src/posts/index.js @@ -26,6 +26,7 @@ require('./bookmarks')(Posts); require('./queue')(Posts); require('./diffs')(Posts); require('./uploads')(Posts); +require('./search')(Posts); Posts.exists = async function (pids) { return await db.exists( diff --git a/src/routes/api.js b/src/routes/api.js index 0fe575a326..e2f8f048d3 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -23,6 +23,8 @@ module.exports = function (app, middleware, controllers) { router.get('/topic/teaser/:topic_id', [...middlewares], helpers.tryRoute(controllers.topics.teaser)); router.get('/topic/pagination/:topic_id', [...middlewares], helpers.tryRoute(controllers.topics.pagination)); + router.get('/posts', [...middlewares], helpers.tryRoute(controllers.posts.search)); + const multipart = require('connect-multiparty'); const multipartMiddleware = multipart(); const postMiddlewares = [ diff --git a/src/routes/write/posts.js b/src/routes/write/posts.js index e573bbb9b0..98bc643377 100644 --- a/src/routes/write/posts.js +++ b/src/routes/write/posts.js @@ -39,6 +39,9 @@ module.exports = function () { setupApiRoute(router, 'get', '/:pid/replies', [middleware.assert.post], controllers.write.posts.getReplies); + setupApiRoute(router, 'get', '/:title', [middleware.ensureLoggedIn], controllers.posts.search); + + // Shorthand route to access post routes by topic index router.all('/+byIndex/:index*?', [middleware.checkRequired.bind(null, ['tid'])], controllers.write.posts.redirectByIndex); From ade1e7df01dbde6ff8fa163d675a43561848a17a Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Sat, 19 Oct 2024 21:06:25 +0300 Subject: [PATCH 10/20] adding the same code to the topics folder because posts is not returning the correct thing --- public/src/client/category.js | 9 ++- src/api/posts.js | 33 ++++++++ src/api/topics.js | 26 ++++-- src/categories/topics.js | 4 + src/controllers/mods.js | 2 + src/controllers/posts.js | 62 ++++++++++++-- src/controllers/topics.js | 10 ++- src/controllers/users.js | 1 + src/routes/api.js | 1 + src/topics/index.js | 23 +++--- src/topics/search.js | 148 ++++++++++++++++++---------------- src/user/search.js | 3 + 12 files changed, 224 insertions(+), 98 deletions(-) diff --git a/public/src/client/category.js b/public/src/client/category.js index 548b9a8d47..2837787856 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -180,8 +180,8 @@ define('forum/category', [ console.log('entered load page'); console.log(query); api.get('/api/posts', query) - .then(renderSearchResults) - .catch(alerts.error); + .then(renderSearchResults) + .catch(alerts.error); } Category.toTop = function () { @@ -214,12 +214,15 @@ define('forum/category', [ } function renderSearchResults(data, options) { + + console.log('data)'); + console.log(data); Benchpress.render('partials/paginator', { pagination: data.pagination }).then(function (html) { $('.pagination-container').replaceWith(html); }); if (searchResultCount) { - data.users = data.users.slice(0, searchResultCount); + data.posts = data.posts.slice(0, searchResultCount); } data.isAdminOrGlobalMod = app.user.isAdmin || app.user.isGlobalMod; diff --git a/src/api/posts.js b/src/api/posts.js index cf797fe940..3518949758 100644 --- a/src/api/posts.js +++ b/src/api/posts.js @@ -514,3 +514,36 @@ postsAPI.getReplies = async (caller, { pid }) => { return postData; }; + +postsAPI.search = async function (caller, data) { + console.log('entered src/api/posts.js'); + // console.log(caller); + // console.log(data); + if (!data) { + throw new Error('[[error:invalid-data]]'); + } + const [allowed, isPrivileged] = await Promise.all([ + privileges.global.can('search:users', caller.uid), + user.isPrivileged(caller.uid), + ]); + let filters = data.filters || []; + filters = Array.isArray(filters) ? filters : [filters]; + if (!allowed || + (( + data.searchBy === 'ip' || + data.searchBy === 'email' || + filters.includes('banned') || + filters.includes('flagged') + ) && !isPrivileged) + ) { + throw new Error('[[error:no-privileges]]'); + } + return await posts.search({ + uid: caller.uid, + query: data.query, + searchBy: data.searchBy || 'title', + page: data.page || 1, + sortBy: data.sortBy || 'lastonline', + filters: filters, + }); +}; \ No newline at end of file diff --git a/src/api/topics.js b/src/api/topics.js index 804636fd72..9a48425d6a 100644 --- a/src/api/topics.js +++ b/src/api/topics.js @@ -301,20 +301,34 @@ topicsAPI.bump = async (caller, { tid }) => { }; topicsAPI.search = async function (caller, data) { - console.log('entered src/api/topics.js'); + console.log('entered src/api/posts.js'); // console.log(caller); // console.log(data); if (!data) { throw new Error('[[error:invalid-data]]'); } + const [allowed, isPrivileged] = await Promise.all([ + privileges.global.can('search:users', caller.uid), + user.isPrivileged(caller.uid), + ]); let filters = data.filters || []; - - return await topic.search({ - tid: caller.tid, + filters = Array.isArray(filters) ? filters : [filters]; + if (!allowed || + (( + data.searchBy === 'ip' || + data.searchBy === 'email' || + filters.includes('banned') || + filters.includes('flagged') + ) && !isPrivileged) + ) { + throw new Error('[[error:no-privileges]]'); + } + return await topics.search({ + uid: caller.uid, query: data.query, searchBy: data.searchBy || 'title', page: data.page || 1, - sortBy: data.sortBy || 'lastposttime', + sortBy: data.sortBy || 'lastonline', filters: filters, - }); + }) }; diff --git a/src/categories/topics.js b/src/categories/topics.js index 1a2a259f3d..07a6297246 100644 --- a/src/categories/topics.js +++ b/src/categories/topics.js @@ -12,7 +12,11 @@ const batch = require('../batch'); module.exports = function (Categories) { Categories.getCategoryTopics = async function (data) { + console.log('data'); + console.log(data); let results = await plugins.hooks.fire('filter:category.topics.prepare', data); + console.log('results'); + console.log(results); const tids = await Categories.getTopicIds(results); let topicsData = await topics.getTopicsByTids(tids, data.uid); topicsData = await user.blocks.filter(data.uid, topicsData); diff --git a/src/controllers/mods.js b/src/controllers/mods.js index 4976dd9e82..4b6f31e81a 100644 --- a/src/controllers/mods.js +++ b/src/controllers/mods.js @@ -211,6 +211,8 @@ modsController.flags.detail = async function (req, res, next) { }; modsController.postQueue = async function (req, res, next) { + + console.log('um is this mods called'); if (!req.loggedIn) { return next(); } diff --git a/src/controllers/posts.js b/src/controllers/posts.js index 314f47f0c3..76045c1c8f 100644 --- a/src/controllers/posts.js +++ b/src/controllers/posts.js @@ -6,6 +6,9 @@ const posts = require('../posts'); const privileges = require('../privileges'); const helpers = require('./helpers'); const api = require('../api'); +const pagination = require('../pagination'); +const user = require('../user'); +const meta = require('../meta'); const postsController = module.exports; @@ -42,13 +45,56 @@ postsController.getRecentPosts = async function (req, res) { postsController.search = async function (req, res) { console.log('got it'); console.log('entered src/controllers/posts.js'); - // console.log(req); - const searchData = await api.posts.search(req, req.query); + try { + // console.log(req); + const searchData = await api.posts.search(req, req.query); - const section = req.query.section || 'joindate'; + console.log('search data'); + console.log(searchData); - searchData.pagination = pagination.create(req.query.page, searchData.pageCount, req.query); - searchData[`section_${section}`] = true; - searchData.displayUserSearch = true; - await render(req, res, searchData); -}; \ No newline at end of file + const section = req.query.section || 'joindate'; + + searchData.pagination = pagination.create(req.query.page, searchData.pageCount, req.query); + searchData[`section_${section}`] = true; + searchData.displayUserSearch = true; + + const { id } = req.params; + const { cid } = req.query; + const page = parseInt(req.query.page, 10) || 1; + + let [isAdmin, isGlobalMod, categoriesData, _privileges] = await Promise.all([ + user.isAdministrator(req.uid), + user.isGlobalModerator(req.uid), + helpers.getSelectedCategory(cid), + Promise.all(['global', 'admin'].map(async type => privileges[type].get(req.uid))), + ]); + _privileges = { ..._privileges[0], ..._privileges[1] }; + + const crumbs = [{ text: '[[pages:post-queue]]', url: id ? '/post-queue' : undefined }]; + + const tempData = { + title: '[[pages:post-queue]]', + posts: searchData.posts, + isAdmin: isAdmin, + canAccept: isAdmin || isGlobalMod, + ...categoriesData, + allCategoriesUrl: `post-queue${helpers.buildQueryString(req.query, 'cid', '')}`, + pagination: pagination.create(page, searchData.pageCount), + breadcrumbs: helpers.buildBreadcrumbs(crumbs), + enabled: meta.config.postQueue, + singlePost: !!id, + privileges: _privileges, + } + + await render(req, res, tempData); } catch (error) { + console.log('errored'); + console.error('Error in search controller:', error); + } +}; + + +async function render(req, res, data) { + console.log('render is called'); + // res.append('X-Total-Count', data.pageCount); + res.render('post-queue', data); +} \ No newline at end of file diff --git a/src/controllers/topics.js b/src/controllers/topics.js index 237fca0ba8..9d463e54cf 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -22,6 +22,8 @@ const relative_path = nconf.get('relative_path'); const upload_url = nconf.get('upload_url'); const validSorts = ['oldest_to_newest', 'newest_to_oldest', 'most_votes']; +const api = require('../api'); + topicsController.get = async function getTopic(req, res, next) { const tid = req.params.topic_id; if ( @@ -417,4 +419,10 @@ topicsController.search = async function (req, res) { searchData[`section_${section}`] = true; searchData.displayUserSearch = true; await render(req, res, searchData); -}; \ No newline at end of file +}; + +async function render(req, res, data) { + console.log('render is called'); + // res.append('X-Total-Count', data.pageCount); + res.render('post-queue', data); +} \ No newline at end of file diff --git a/src/controllers/users.js b/src/controllers/users.js index f00fc432d9..2b941df26f 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -191,6 +191,7 @@ usersController.getUsersAndCount = async function (set, uid, start, stop) { }; async function render(req, res, data) { + console.log(data); const { registrationType } = meta.config; data.maximumInvites = meta.config.maximumInvites; diff --git a/src/routes/api.js b/src/routes/api.js index e2f8f048d3..1406125ba1 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -23,6 +23,7 @@ module.exports = function (app, middleware, controllers) { router.get('/topic/teaser/:topic_id', [...middlewares], helpers.tryRoute(controllers.topics.teaser)); router.get('/topic/pagination/:topic_id', [...middlewares], helpers.tryRoute(controllers.topics.pagination)); + router.get('/topics', [...middlewares], helpers.tryRoute(controllers.topics.search)); router.get('/posts', [...middlewares], helpers.tryRoute(controllers.posts.search)); const multipart = require('connect-multiparty'); diff --git a/src/topics/index.js b/src/topics/index.js index 4a2700f59b..6151160ebc 100644 --- a/src/topics/index.js +++ b/src/topics/index.js @@ -298,16 +298,17 @@ Topics.isLocked = async function (tid) { return locked === 1; }; -Topics.search = async function (tid, term) { - if (!tid || !term) { - throw new Error('[[error:invalid-data]]'); - } - const result = await plugins.hooks.fire('filter:topic.search', { - tid: tid, - term: term, - ids: [], - }); - return Array.isArray(result) ? result : result.ids; -}; +// Topics.search = async function (tid, term) { +// if (!tid || !term) { +// throw new Error('[[error:invalid-data]]'); +// } + +// const result = await plugins.hooks.fire('filter:topic.search', { +// tid: tid, +// term: term, +// ids: [], +// }); +// return Array.isArray(result) ? result : result.ids; +// }; require('../promisify')(Topics); diff --git a/src/topics/search.js b/src/topics/search.js index 105db6c487..b8524bfaae 100644 --- a/src/topics/search.js +++ b/src/topics/search.js @@ -1,71 +1,94 @@ - 'use strict'; const _ = require('lodash'); - const meta = require('../meta'); const plugins = require('../plugins'); const db = require('../database'); -const groups = require('../groups'); const utils = require('../utils'); -console.log('this was called'); module.exports = function (Topic) { + + // Topics.search = async function (tid, term) { + // if (!tid || !term) { + // throw new Error('[[error:invalid-data]]'); + // } + + // // Normalize the search term for case-insensitivity + // term = term.toLowerCase(); + + // // Fetch topics related to the provided tid + // const topics = await Topics.getTopicsByTid(tid); // Implement this method to fetch topics + + // // Filter topics based on the search term in the title + // const matchedTopics = topics.filter(topic => + // topic.title.toLowerCase().includes(term) + // ); + + // // Fire plugin hooks for additional processing, if needed + // const result = await plugins.hooks.fire('filter:topic.search', { + // tid: tid, + // term: term, + // ids: matchedTopics.map(topic => topic.tid), + // }); + + // return Array.isArray(result) ? result : result.ids; + // }; + + const filterFnMap = { + pinned: topic => topic.pinned > 0, + locked: topic => topic.locked > 0, + // Add other filters as needed + }; + + const filterFieldMap = { + pinned: ['pinned'], + locked: ['locked'], + // Map other relevant fields + }; + Topic.search = async function (data) { - console.log('entered user.search in src/topics/search'); + console.log('hit it'); + const query = data.query || ''; - const searchBy = data.searchBy || 'title'; + const searchBy = data.searchBy || 'title'; // Change this as needed const page = data.page || 1; - const uid = data.uid || 0; const paginate = data.hasOwnProperty('paginate') ? data.paginate : true; const startTime = process.hrtime(); - let uids = []; - if (searchBy === 'ip') { - uids = await searchByIP(query); - } else if (searchBy === 'uid') { - uids = [query]; + let tids = []; + if (searchBy === 'tid') { + tids = [query]; // Searching by topic ID } else { - const searchMethod = data.findUids || findUids; - uids = await searchMethod(query, searchBy, data.hardCap); + tids = await findTids(query, searchBy); } - uids = await filterAndSortUids(uids, data); - const result = await plugins.hooks.fire('filter:users.search', { uids: uids, uid: uid }); - uids = result.uids; + tids = await filterAndSortTids(tids, data); + const result = await plugins.hooks.fire('filter:topics.search', { tids }); + tids = result.tids; const searchResult = { - matchCount: uids.length, + matchCount: tids.length, }; if (paginate) { - const resultsPerPage = data.resultsPerPage || meta.config.userSearchResultsPerPage; + const resultsPerPage = data.resultsPerPage || meta.config.topicSearchResultsPerPage; const start = Math.max(0, page - 1) * resultsPerPage; const stop = start + resultsPerPage; - searchResult.pageCount = Math.ceil(uids.length / resultsPerPage); - uids = uids.slice(start, stop); - } - - const [userData, blocks] = await Promise.all([ - User.getUsers(uids, uid), - User.blocks.list(uid), - ]); - - if (blocks.length) { - userData.forEach((user) => { - if (user) { - user.isBlocked = blocks.includes(user.uid); - } - }); + searchResult.pageCount = Math.ceil(tids.length / resultsPerPage); + tids = tids.slice(start, stop); } + const topicData = await Topic.getTopics(tids); // You need to implement this + searchResult.topics = topicData.filter(topic => topic && topic.tid > 0); searchResult.timing = (process.elapsedTimeSince(startTime) / 1000).toFixed(2); - searchResult.users = userData.filter(user => user && user.uid > 0); + + console.log('topics search result)'); + console.log(searchResult); return searchResult; }; - async function findUids(query, searchBy, hardCap) { + async function findTids(query, searchBy) { if (!query) { return []; } @@ -73,16 +96,15 @@ module.exports = function (Topic) { const min = query; const max = query.substr(0, query.length - 1) + String.fromCharCode(query.charCodeAt(query.length - 1) + 1); - const resultsPerPage = meta.config.userSearchResultsPerPage; - hardCap = hardCap || resultsPerPage * 10; - - const data = await db.getSortedSetRangeByLex(`${searchBy}:sorted`, min, max, 0, hardCap); - const uids = data.map(data => data.split(':').pop()); - return uids; + const data = await db.getSortedSetRangeByLex(`${searchBy}:sorted`, min, max, 0, meta.config.topicSearchResultsPerPage * 10); + const tids = data.map(data => data.split(':').pop()); + console.log('dataaa'); + console.log(searchResult); + return tids; } - async function filterAndSortUids(uids, data) { - uids = uids.filter(uid => parseInt(uid, 10)); + async function filterAndSortTids(tids, data) { + tids = tids.filter(tid => parseInt(tid, 10)); let filters = data.filters || []; filters = Array.isArray(filters) ? filters : [data.filters]; const fields = []; @@ -97,57 +119,45 @@ module.exports = function (Topic) { } }); - if (data.groupName) { - const isMembers = await groups.isMembers(uids, data.groupName); - uids = uids.filter((uid, index) => isMembers[index]); - } - if (!fields.length) { - return uids; + return tids; } - if (filters.includes('banned') || filters.includes('notbanned')) { - const isMembersOfBanned = await groups.isMembers(uids, groups.BANNED_USERS); - const checkBanned = filters.includes('banned'); - uids = uids.filter((uid, index) => (checkBanned ? isMembersOfBanned[index] : !isMembersOfBanned[index])); - } - - fields.push('uid'); - let userData = await User.getUsersFields(uids, fields); + fields.push('tid'); + let topicData = await Topic.getTopicsFields(tids, fields); // You need to implement this filters.forEach((filter) => { if (filterFnMap[filter]) { - userData = userData.filter(filterFnMap[filter]); + topicData = topicData.filter(filterFnMap[filter]); } }); if (data.sortBy) { - sortUsers(userData, data.sortBy, data.sortDirection); + sortTopics(topicData, data.sortBy, data.sortDirection); } - return userData.map(user => user.uid); + return topicData.map(topic => topic.tid); } - function sortUsers(userData, sortBy, sortDirection) { - if (!userData || !userData.length) { + function sortTopics(topicData, sortBy, sortDirection) { + if (!topicData || !topicData.length) { return; } sortDirection = sortDirection || 'desc'; const direction = sortDirection === 'desc' ? 1 : -1; - const isNumeric = utils.isNumber(userData[0][sortBy]); + const isNumeric = utils.isNumber(topicData[0][sortBy]); if (isNumeric) { - userData.sort((u1, u2) => direction * (u2[sortBy] - u1[sortBy])); + topicData.sort((t1, t2) => direction * (t2[sortBy] - t1[sortBy])); } else { - userData.sort((u1, u2) => { - if (u1[sortBy] < u2[sortBy]) { + topicData.sort((t1, t2) => { + if (t1[sortBy] < t2[sortBy]) { return direction * -1; - } else if (u1[sortBy] > u2[sortBy]) { + } else if (t1[sortBy] > t2[sortBy]) { return direction * 1; } return 0; }); } } - }; diff --git a/src/user/search.js b/src/user/search.js index cbe1f35aab..b0169a21ff 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -26,6 +26,9 @@ module.exports = function (User) { User.search = async function (data) { + + console.log('data'); + console.log(data); console.log('entered user.search in src/user/search'); const query = data.query || ''; const searchBy = data.searchBy || 'username'; From d80cfcb0083163ee14306e4d204dbe6b223a4f1b Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Sat, 19 Oct 2024 21:50:54 +0300 Subject: [PATCH 11/20] adding console logs and trying to insert search function in src/categories/topics as implemented search function is not returning the correct thing --- public/src/client/category.js | 2 +- src/categories/topics.js | 23 +++++++++++++++++---- src/topics/search.js | 38 +++++++++++++++-------------------- 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/public/src/client/category.js b/public/src/client/category.js index 2837787856..83c5b97578 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -179,7 +179,7 @@ define('forum/category', [ function loadPage(query) { console.log('entered load page'); console.log(query); - api.get('/api/posts', query) + api.get('/api/topics', query) .then(renderSearchResults) .catch(alerts.error); } diff --git a/src/categories/topics.js b/src/categories/topics.js index 07a6297246..2449cc594c 100644 --- a/src/categories/topics.js +++ b/src/categories/topics.js @@ -11,13 +11,28 @@ const translator = require('../translator'); const batch = require('../batch'); module.exports = function (Categories) { + + Categories.search = async function (data) { + const query = data.query; + const searchFor = query.toLowerCase(); + let results = await plugins.hooks.fire('filter:category.topics.prepare', data); + const tids = await Categories.getTopicIds(results); + let topicsData = await topics.getTopicsByTids(tids, data.uid); + const matchedTopics = topicsData.filter(topic => topic.title.toLowerCase().includes(searchFor)); + return matchedTopics; + } + Categories.getCategoryTopics = async function (data) { - console.log('data'); - console.log(data); + // console.log('data'); + // console.log(data); let results = await plugins.hooks.fire('filter:category.topics.prepare', data); - console.log('results'); - console.log(results); + // console.log('results'); + // console.log(results); const tids = await Categories.getTopicIds(results); + + console.log(tids); + + let topicsData = await topics.getTopicsByTids(tids, data.uid); topicsData = await user.blocks.filter(data.uid, topicsData); diff --git a/src/topics/search.js b/src/topics/search.js index b8524bfaae..c0846bff30 100644 --- a/src/topics/search.js +++ b/src/topics/search.js @@ -5,8 +5,10 @@ const meta = require('../meta'); const plugins = require('../plugins'); const db = require('../database'); const utils = require('../utils'); +const { search } = require('../api/users'); +const categories = require ('../categories'); -module.exports = function (Topic) { +module.exports = function (Topics) { // Topics.search = async function (tid, term) { // if (!tid || !term) { @@ -33,20 +35,7 @@ module.exports = function (Topic) { // return Array.isArray(result) ? result : result.ids; // }; - - const filterFnMap = { - pinned: topic => topic.pinned > 0, - locked: topic => topic.locked > 0, - // Add other filters as needed - }; - - const filterFieldMap = { - pinned: ['pinned'], - locked: ['locked'], - // Map other relevant fields - }; - - Topic.search = async function (data) { + Topics.search = async function (data) { console.log('hit it'); const query = data.query || ''; @@ -56,11 +45,16 @@ module.exports = function (Topic) { const startTime = process.hrtime(); - let tids = []; + const tids = await categories.getTopicIds(data); + let topicsData = await Topics.getTopicsByTids(tids, data.uid); + console.log('testing;;g'); + console.log(tids); + console.log(topicsData); + if (searchBy === 'tid') { tids = [query]; // Searching by topic ID } else { - tids = await findTids(query, searchBy); + tids = await findTids(query, searchBy, data.hardCap); } tids = await filterAndSortTids(tids, data); @@ -88,18 +82,18 @@ module.exports = function (Topic) { return searchResult; }; - async function findTids(query, searchBy) { + async function findTids(query, searchBy, hardCap) { if (!query) { return []; } query = String(query).toLowerCase(); const min = query; const max = query.substr(0, query.length - 1) + String.fromCharCode(query.charCodeAt(query.length - 1) + 1); - - const data = await db.getSortedSetRangeByLex(`${searchBy}:sorted`, min, max, 0, meta.config.topicSearchResultsPerPage * 10); + console.log(searchBy); + const data = await db.getSortedSetRangeByLex(`${searchBy}:sorted`, min, max, 0, hardCap); const tids = data.map(data => data.split(':').pop()); - console.log('dataaa'); - console.log(searchResult); + console.log('dataaa tids'); + console.log(tids); return tids; } From eb02604062ab91043568f16f5ea1794f5e73961f Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Sat, 19 Oct 2024 22:13:41 +0300 Subject: [PATCH 12/20] copied search functions over to matching files for categories --- public/src/client/category.js | 2 +- src/api/categories.js | 105 ++++++++++++++++++++++++++++++++++ src/categories/topics.js | 11 +++- src/controllers/categories.js | 20 +++++++ src/routes/api.js | 1 + 5 files changed, 135 insertions(+), 4 deletions(-) diff --git a/public/src/client/category.js b/public/src/client/category.js index 83c5b97578..c0dda376c0 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -179,7 +179,7 @@ define('forum/category', [ function loadPage(query) { console.log('entered load page'); console.log(query); - api.get('/api/topics', query) + api.get('/api/categories', query) .then(renderSearchResults) .catch(alerts.error); } diff --git a/src/api/categories.js b/src/api/categories.js index 9a43a81526..762ae87687 100644 --- a/src/api/categories.js +++ b/src/api/categories.js @@ -45,6 +45,111 @@ categoriesAPI.get = async function (caller, data) { return category; }; +categoriesAPI.search = async function (caller, data) { + console.log('entered src/api/categories.js'); + // console.log(caller); + // console.log(data); + if (!data) { + throw new Error('[[error:invalid-data]]'); + } + const [allowed, isPrivileged] = await Promise.all([ + privileges.global.can('search:users', caller.uid), + user.isPrivileged(caller.uid), + ]); + let filters = data.filters || []; + filters = Array.isArray(filters) ? filters : [filters]; + if (!allowed || + (( + data.searchBy === 'ip' || + data.searchBy === 'email' || + filters.includes('banned') || + filters.includes('flagged') + ) && !isPrivileged) + ) { + throw new Error('[[error:no-privileges]]'); + } + return await categories.searchTopics({ + uid: caller.uid, + cid: '2', + start: 0, + stop: 19, + sort: data.sortBy, + settings: { + uid: 1, + showemail: false, + showfullname: false, + openOutgoingLinksInNewTab: false, + dailyDigestFreq: 'off', + usePagination: false, + topicsPerPage: 20, + postsPerPage: 20, + userLang: 'en-GB', + acpLang: 'en-GB', + topicPostSort: 'oldest_to_newest', + categoryTopicSort: 'recently_replied', + followTopicsOnCreate: true, + followTopicsOnReply: false, + upvoteNotifFreq: 'all', + restrictChat: false, + topicSearchEnabled: false, + updateUrlWithPostIndex: true, + bootswatchSkin: '', + homePageRoute: '', + scrollToMyPost: true, + categoryWatchState: 'tracking', + notificationType_upvote: 'notification', + 'notificationType_new-topic': 'notification', + 'notificationType_new-topic-with-tag': 'notification', + 'notificationType_new-topic-in-category': 'notification', + 'notificationType_new-reply': 'notification', + 'notificationType_post-edit': 'notification', + notificationType_follow: 'notification', + 'notificationType_new-chat': 'notification', + 'notificationType_new-group-chat': 'notification', + 'notificationType_new-public-chat': 'notification', + 'notificationType_group-invite': 'notification', + 'notificationType_group-leave': 'notification', + 'notificationType_group-request-membership': 'notification', + 'notificationType_new-reward': 'notification', + notificationType_mention: 'notification', + 'notificationType_new-register': 'notification', + 'notificationType_post-queue': 'notification', + 'notificationType_new-post-flag': 'notification', + 'notificationType_new-user-flag': 'notification' + }, + query: data.query, + tag: undefined, + targetUid: 0, + category: { + cid: 2, + name: 'General Discussion', + description: 'A place to talk about whatever you want', + descriptionParsed: '

    A place to talk about whatever you want

    \n', + icon: 'fa-comments-o', + bgColor: '#59b3d0', + color: '#ffffff', + slug: '2/general-discussion', + parentCid: 0, + topic_count: 5, + post_count: 7, + disabled: 0, + order: 2, + link: '', + numRecentReplies: 1, + class: 'col-md-3 col-6', + imageClass: 'cover', + isSection: 0, + subCategoriesPerPage: 10, + minTags: 0, + maxTags: 5, + postQueue: 0, + totalPostCount: 7, + totalTopicCount: 5, + tagWhitelist: [] + } + }) +}; + categoriesAPI.create = async function (caller, data) { await hasAdminPrivilege(caller.uid); diff --git a/src/categories/topics.js b/src/categories/topics.js index 2449cc594c..2dea6f45f5 100644 --- a/src/categories/topics.js +++ b/src/categories/topics.js @@ -12,16 +12,21 @@ const batch = require('../batch'); module.exports = function (Categories) { - Categories.search = async function (data) { + Categories.searchTopics = async function (data) { + console.log('was this called??/'); const query = data.query; const searchFor = query.toLowerCase(); let results = await plugins.hooks.fire('filter:category.topics.prepare', data); const tids = await Categories.getTopicIds(results); + + console.log(tids); + let topicsData = await topics.getTopicsByTids(tids, data.uid); const matchedTopics = topicsData.filter(topic => topic.title.toLowerCase().includes(searchFor)); + console.log(matchedTopics); return matchedTopics; } - + Categories.getCategoryTopics = async function (data) { // console.log('data'); // console.log(data); @@ -30,7 +35,7 @@ module.exports = function (Categories) { // console.log(results); const tids = await Categories.getTopicIds(results); - console.log(tids); + // console.log(tids); let topicsData = await topics.getTopicsByTids(tids, data.uid); diff --git a/src/controllers/categories.js b/src/controllers/categories.js index a169b49be5..790edecd6b 100644 --- a/src/controllers/categories.js +++ b/src/controllers/categories.js @@ -7,10 +7,30 @@ const categories = require('../categories'); const meta = require('../meta'); const pagination = require('../pagination'); const helpers = require('./helpers'); +const api = require('../api'); const privileges = require('../privileges'); const categoriesController = module.exports; +categoriesController.search = async function (req, res) { + console.log('entered src/controllers/categories.js'); + // console.log(req); + const searchData = await api.categories.search(req, req.query); + + const section = req.query.section || 'joindate'; + + searchData.pagination = pagination.create(req.query.page, searchData.pageCount, req.query); + searchData[`section_${section}`] = true; + searchData.displayUserSearch = true; + await render(req, res, searchData); +}; + +async function render(req, res, data) { + console.log('render is called'); + // res.append('X-Total-Count', data.pageCount); + res.render('post-queue', data); +} + categoriesController.list = async function (req, res) { res.locals.metaTags = [{ name: 'title', diff --git a/src/routes/api.js b/src/routes/api.js index 1406125ba1..581c650bc2 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -25,6 +25,7 @@ module.exports = function (app, middleware, controllers) { router.get('/topics', [...middlewares], helpers.tryRoute(controllers.topics.search)); router.get('/posts', [...middlewares], helpers.tryRoute(controllers.posts.search)); + router.get('/categories', [...middlewares], helpers.tryRoute(controllers.categories.search)); const multipart = require('connect-multiparty'); const multipartMiddleware = multipart(); From b6108e0b5f23f8e91a4c29a183d92e688aefeb83 Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Sat, 19 Oct 2024 22:51:18 +0300 Subject: [PATCH 13/20] fixed search functions and checked functionality --- public/src/client/category.js | 26 +++----------------------- src/categories/topics.js | 10 +++++----- src/controllers/categories.js | 2 +- 3 files changed, 9 insertions(+), 29 deletions(-) diff --git a/public/src/client/category.js b/public/src/client/category.js index c0dda376c0..b8631e0152 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -146,20 +146,6 @@ define('forum/category', [ query.query = title; query.sortBy = getSortBy(); - // const filters = []; - // if ($('.search .online-only').is(':checked') || (activeSection === 'online')) { - // filters.push('online'); - // } - // if (activeSection === 'banned') { - // filters.push('banned'); - // } - // if (activeSection === 'flagged') { - // filters.push('flagged'); - // } - // if (filters.length) { - // query.filters = filters; - // } - loadPage(query); } @@ -213,23 +199,17 @@ define('forum/category', [ return utils.param('section') || ''; } - function renderSearchResults(data, options) { - - console.log('data)'); - console.log(data); + function renderSearchResults(data) { Benchpress.render('partials/paginator', { pagination: data.pagination }).then(function (html) { $('.pagination-container').replaceWith(html); }); if (searchResultCount) { - data.posts = data.posts.slice(0, searchResultCount); + data.users = data.users.slice(0, searchResultCount); } data.isAdminOrGlobalMod = app.user.isAdmin || app.user.isGlobalMod; - app.parseAndTranslate(options.template, { - categoryItems: categories.slice(0, 200), - selectedCategory: ajaxify.data.selectedCategory, - allCategoriesUrl: ajaxify.data.allCategoriesUrl}, function (html) { + app.parseAndTranslate('post-queue', 'posts', data, function (html) { $('#category-container').html(html); html.find('.timeago').timeago(); $('[component="topic/search/icon"]').addClass('fa-search').removeClass('fa-spinner fa-spin'); diff --git a/src/categories/topics.js b/src/categories/topics.js index 2dea6f45f5..64586ff227 100644 --- a/src/categories/topics.js +++ b/src/categories/topics.js @@ -15,15 +15,15 @@ module.exports = function (Categories) { Categories.searchTopics = async function (data) { console.log('was this called??/'); const query = data.query; - const searchFor = query.toLowerCase(); let results = await plugins.hooks.fire('filter:category.topics.prepare', data); const tids = await Categories.getTopicIds(results); - - console.log(tids); - let topicsData = await topics.getTopicsByTids(tids, data.uid); + if (!query || query.trim() === ''){ + return topicsData; + } + const searchFor = query.toLowerCase(); const matchedTopics = topicsData.filter(topic => topic.title.toLowerCase().includes(searchFor)); - console.log(matchedTopics); + // console.log(matchedTopics); return matchedTopics; } diff --git a/src/controllers/categories.js b/src/controllers/categories.js index 790edecd6b..e8be352c41 100644 --- a/src/controllers/categories.js +++ b/src/controllers/categories.js @@ -28,7 +28,7 @@ categoriesController.search = async function (req, res) { async function render(req, res, data) { console.log('render is called'); // res.append('X-Total-Count', data.pageCount); - res.render('post-queue', data); + res.render('category', data); } categoriesController.list = async function (req, res) { From 6b2a9d5aa984217612dd6e4466831a4e73d3e9cd Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Sun, 20 Oct 2024 09:52:11 +0300 Subject: [PATCH 14/20] removing code that isnt used --- public/src/client/categories.js | 3 - public/src/client/category.js | 4 +- src/api/categories.js | 136 +++++++++++++-------------- src/api/posts.js | 2 +- src/api/topics.js | 2 +- src/categories/topics.js | 11 +-- src/controllers/mods.js | 2 - src/controllers/posts.js | 61 ------------- src/controllers/topics.js | 2 +- src/controllers/users.js | 2 +- src/controllers/write/posts.js | 2 +- src/groups/index.js | 7 +- src/groups/search.js | 2 +- src/posts/index.js | 1 - src/topics/index.js | 15 --- src/topics/search.js | 157 -------------------------------- src/user/search.js | 3 +- 17 files changed, 84 insertions(+), 328 deletions(-) delete mode 100644 src/topics/search.js diff --git a/public/src/client/categories.js b/public/src/client/categories.js index 674b757c62..461d720267 100644 --- a/public/src/client/categories.js +++ b/public/src/client/categories.js @@ -1,9 +1,6 @@ 'use strict'; - define('forum/categories', ['categorySelector'], function (categorySelector) { - - console.log('entered categories public client'); const categories = {}; categories.init = function () { diff --git a/public/src/client/category.js b/public/src/client/category.js index b8631e0152..f5d3da4fde 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -166,8 +166,8 @@ define('forum/category', [ console.log('entered load page'); console.log(query); api.get('/api/categories', query) - .then(renderSearchResults) - .catch(alerts.error); + .then(renderSearchResults) + .catch(alerts.error); } Category.toTop = function () { diff --git a/src/api/categories.js b/src/api/categories.js index 762ae87687..61814ab2ec 100644 --- a/src/api/categories.js +++ b/src/api/categories.js @@ -75,79 +75,79 @@ categoriesAPI.search = async function (caller, data) { stop: 19, sort: data.sortBy, settings: { - uid: 1, - showemail: false, - showfullname: false, - openOutgoingLinksInNewTab: false, - dailyDigestFreq: 'off', - usePagination: false, - topicsPerPage: 20, - postsPerPage: 20, - userLang: 'en-GB', - acpLang: 'en-GB', - topicPostSort: 'oldest_to_newest', - categoryTopicSort: 'recently_replied', - followTopicsOnCreate: true, - followTopicsOnReply: false, - upvoteNotifFreq: 'all', - restrictChat: false, - topicSearchEnabled: false, - updateUrlWithPostIndex: true, - bootswatchSkin: '', - homePageRoute: '', - scrollToMyPost: true, - categoryWatchState: 'tracking', - notificationType_upvote: 'notification', - 'notificationType_new-topic': 'notification', - 'notificationType_new-topic-with-tag': 'notification', - 'notificationType_new-topic-in-category': 'notification', - 'notificationType_new-reply': 'notification', - 'notificationType_post-edit': 'notification', - notificationType_follow: 'notification', - 'notificationType_new-chat': 'notification', - 'notificationType_new-group-chat': 'notification', - 'notificationType_new-public-chat': 'notification', - 'notificationType_group-invite': 'notification', - 'notificationType_group-leave': 'notification', - 'notificationType_group-request-membership': 'notification', - 'notificationType_new-reward': 'notification', - notificationType_mention: 'notification', - 'notificationType_new-register': 'notification', - 'notificationType_post-queue': 'notification', - 'notificationType_new-post-flag': 'notification', - 'notificationType_new-user-flag': 'notification' + uid: 1, + showemail: false, + showfullname: false, + openOutgoingLinksInNewTab: false, + dailyDigestFreq: 'off', + usePagination: false, + topicsPerPage: 20, + postsPerPage: 20, + userLang: 'en-GB', + acpLang: 'en-GB', + topicPostSort: 'oldest_to_newest', + categoryTopicSort: 'recently_replied', + followTopicsOnCreate: true, + followTopicsOnReply: false, + upvoteNotifFreq: 'all', + restrictChat: false, + topicSearchEnabled: false, + updateUrlWithPostIndex: true, + bootswatchSkin: '', + homePageRoute: '', + scrollToMyPost: true, + categoryWatchState: 'tracking', + notificationType_upvote: 'notification', + 'notificationType_new-topic': 'notification', + 'notificationType_new-topic-with-tag': 'notification', + 'notificationType_new-topic-in-category': 'notification', + 'notificationType_new-reply': 'notification', + 'notificationType_post-edit': 'notification', + notificationType_follow: 'notification', + 'notificationType_new-chat': 'notification', + 'notificationType_new-group-chat': 'notification', + 'notificationType_new-public-chat': 'notification', + 'notificationType_group-invite': 'notification', + 'notificationType_group-leave': 'notification', + 'notificationType_group-request-membership': 'notification', + 'notificationType_new-reward': 'notification', + notificationType_mention: 'notification', + 'notificationType_new-register': 'notification', + 'notificationType_post-queue': 'notification', + 'notificationType_new-post-flag': 'notification', + 'notificationType_new-user-flag': 'notification', }, query: data.query, tag: undefined, targetUid: 0, category: { - cid: 2, - name: 'General Discussion', - description: 'A place to talk about whatever you want', - descriptionParsed: '

    A place to talk about whatever you want

    \n', - icon: 'fa-comments-o', - bgColor: '#59b3d0', - color: '#ffffff', - slug: '2/general-discussion', - parentCid: 0, - topic_count: 5, - post_count: 7, - disabled: 0, - order: 2, - link: '', - numRecentReplies: 1, - class: 'col-md-3 col-6', - imageClass: 'cover', - isSection: 0, - subCategoriesPerPage: 10, - minTags: 0, - maxTags: 5, - postQueue: 0, - totalPostCount: 7, - totalTopicCount: 5, - tagWhitelist: [] - } - }) + cid: 2, + name: 'General Discussion', + description: 'A place to talk about whatever you want', + descriptionParsed: '

    A place to talk about whatever you want

    \n', + icon: 'fa-comments-o', + bgColor: '#59b3d0', + color: '#ffffff', + slug: '2/general-discussion', + parentCid: 0, + topic_count: 5, + post_count: 7, + disabled: 0, + order: 2, + link: '', + numRecentReplies: 1, + class: 'col-md-3 col-6', + imageClass: 'cover', + isSection: 0, + subCategoriesPerPage: 10, + minTags: 0, + maxTags: 5, + postQueue: 0, + totalPostCount: 7, + totalTopicCount: 5, + tagWhitelist: [], + }, + }); }; categoriesAPI.create = async function (caller, data) { diff --git a/src/api/posts.js b/src/api/posts.js index 3518949758..cc0f00f61a 100644 --- a/src/api/posts.js +++ b/src/api/posts.js @@ -546,4 +546,4 @@ postsAPI.search = async function (caller, data) { sortBy: data.sortBy || 'lastonline', filters: filters, }); -}; \ No newline at end of file +}; diff --git a/src/api/topics.js b/src/api/topics.js index 9a48425d6a..c27b8b128d 100644 --- a/src/api/topics.js +++ b/src/api/topics.js @@ -330,5 +330,5 @@ topicsAPI.search = async function (caller, data) { page: data.page || 1, sortBy: data.sortBy || 'lastonline', filters: filters, - }) + }); }; diff --git a/src/categories/topics.js b/src/categories/topics.js index 64586ff227..cd47413ae1 100644 --- a/src/categories/topics.js +++ b/src/categories/topics.js @@ -11,21 +11,20 @@ const translator = require('../translator'); const batch = require('../batch'); module.exports = function (Categories) { - Categories.searchTopics = async function (data) { console.log('was this called??/'); - const query = data.query; - let results = await plugins.hooks.fire('filter:category.topics.prepare', data); + const { query } = data; + const results = await plugins.hooks.fire('filter:category.topics.prepare', data); const tids = await Categories.getTopicIds(results); - let topicsData = await topics.getTopicsByTids(tids, data.uid); - if (!query || query.trim() === ''){ + const topicsData = await topics.getTopicsByTids(tids, data.uid); + if (!query || query.trim() === '') { return topicsData; } const searchFor = query.toLowerCase(); const matchedTopics = topicsData.filter(topic => topic.title.toLowerCase().includes(searchFor)); // console.log(matchedTopics); return matchedTopics; - } + }; Categories.getCategoryTopics = async function (data) { // console.log('data'); diff --git a/src/controllers/mods.js b/src/controllers/mods.js index 4b6f31e81a..4976dd9e82 100644 --- a/src/controllers/mods.js +++ b/src/controllers/mods.js @@ -211,8 +211,6 @@ modsController.flags.detail = async function (req, res, next) { }; modsController.postQueue = async function (req, res, next) { - - console.log('um is this mods called'); if (!req.loggedIn) { return next(); } diff --git a/src/controllers/posts.js b/src/controllers/posts.js index 76045c1c8f..7865ba0af7 100644 --- a/src/controllers/posts.js +++ b/src/controllers/posts.js @@ -5,10 +5,6 @@ const querystring = require('querystring'); const posts = require('../posts'); const privileges = require('../privileges'); const helpers = require('./helpers'); -const api = require('../api'); -const pagination = require('../pagination'); -const user = require('../user'); -const meta = require('../meta'); const postsController = module.exports; @@ -41,60 +37,3 @@ postsController.getRecentPosts = async function (req, res) { const data = await posts.getRecentPosts(req.uid, start, stop, req.params.term); res.json(data); }; - -postsController.search = async function (req, res) { - console.log('got it'); - console.log('entered src/controllers/posts.js'); - try { - // console.log(req); - const searchData = await api.posts.search(req, req.query); - - console.log('search data'); - console.log(searchData); - - const section = req.query.section || 'joindate'; - - searchData.pagination = pagination.create(req.query.page, searchData.pageCount, req.query); - searchData[`section_${section}`] = true; - searchData.displayUserSearch = true; - - const { id } = req.params; - const { cid } = req.query; - const page = parseInt(req.query.page, 10) || 1; - - let [isAdmin, isGlobalMod, categoriesData, _privileges] = await Promise.all([ - user.isAdministrator(req.uid), - user.isGlobalModerator(req.uid), - helpers.getSelectedCategory(cid), - Promise.all(['global', 'admin'].map(async type => privileges[type].get(req.uid))), - ]); - _privileges = { ..._privileges[0], ..._privileges[1] }; - - const crumbs = [{ text: '[[pages:post-queue]]', url: id ? '/post-queue' : undefined }]; - - const tempData = { - title: '[[pages:post-queue]]', - posts: searchData.posts, - isAdmin: isAdmin, - canAccept: isAdmin || isGlobalMod, - ...categoriesData, - allCategoriesUrl: `post-queue${helpers.buildQueryString(req.query, 'cid', '')}`, - pagination: pagination.create(page, searchData.pageCount), - breadcrumbs: helpers.buildBreadcrumbs(crumbs), - enabled: meta.config.postQueue, - singlePost: !!id, - privileges: _privileges, - } - - await render(req, res, tempData); } catch (error) { - console.log('errored'); - console.error('Error in search controller:', error); - } -}; - - -async function render(req, res, data) { - console.log('render is called'); - // res.append('X-Total-Count', data.pageCount); - res.render('post-queue', data); -} \ No newline at end of file diff --git a/src/controllers/topics.js b/src/controllers/topics.js index 9d463e54cf..f157b241fe 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -425,4 +425,4 @@ async function render(req, res, data) { console.log('render is called'); // res.append('X-Total-Count', data.pageCount); res.render('post-queue', data); -} \ No newline at end of file +} diff --git a/src/controllers/users.js b/src/controllers/users.js index 2b941df26f..f06ee433bf 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -191,7 +191,7 @@ usersController.getUsersAndCount = async function (set, uid, start, stop) { }; async function render(req, res, data) { - console.log(data); + // console.log(data); const { registrationType } = meta.config; data.maximumInvites = meta.config.maximumInvites; diff --git a/src/controllers/write/posts.js b/src/controllers/write/posts.js index 30379dd94b..617e41413d 100644 --- a/src/controllers/write/posts.js +++ b/src/controllers/write/posts.js @@ -36,7 +36,7 @@ Posts.redirectByIndex = async (req, res, next) => { }; Posts.get = async (req, res) => { - console.log('got here'); + // console.log('got here'); const post = await api.posts.get(req, { pid: req.params.pid }); if (!post) { return helpers.formatApiResponse(404, res, new Error('[[error:no-post]]')); diff --git a/src/groups/index.js b/src/groups/index.js index 1abc420f21..5d1fa6089c 100644 --- a/src/groups/index.js +++ b/src/groups/index.js @@ -103,10 +103,7 @@ Groups.getNonPrivilegeGroups = async function (set, start, stop, flags) { }; Groups.getGroups = async function (set, start, stop) { - console.log('entered src/groups/index getGroups'); - console.log(set); - console.log(start); - console.log(stop); + // console.log('entered src/groups/index getGroups'); return await db.getSortedSetRevRange(set, start, stop); }; @@ -126,7 +123,7 @@ Groups.getGroupsAndMembers = async function (groupNames) { Groups.get = async function (groupName, options) { console.log('hi'); - console.log(options); + // console.log(options); if (!groupName) { throw new Error('[[error:invalid-group]]'); } diff --git a/src/groups/search.js b/src/groups/search.js index 982f6a2c4c..267bd2741a 100644 --- a/src/groups/search.js +++ b/src/groups/search.js @@ -6,7 +6,7 @@ const db = require('../database'); module.exports = function (Groups) { Groups.search = async function (query, options) { console.log('entered group search'); - console.log(query); + // console.log(query); if (!query) { return []; } diff --git a/src/posts/index.js b/src/posts/index.js index 81bfa34c32..9db52c6b27 100644 --- a/src/posts/index.js +++ b/src/posts/index.js @@ -26,7 +26,6 @@ require('./bookmarks')(Posts); require('./queue')(Posts); require('./diffs')(Posts); require('./uploads')(Posts); -require('./search')(Posts); Posts.exists = async function (pids) { return await db.exists( diff --git a/src/topics/index.js b/src/topics/index.js index 6151160ebc..958b10cdf8 100644 --- a/src/topics/index.js +++ b/src/topics/index.js @@ -20,7 +20,6 @@ require('./create')(Topics); require('./delete')(Topics); require('./sorted')(Topics); require('./unread')(Topics); -require('./search')(Topics); require('./recent')(Topics); require('./user')(Topics); require('./fork')(Topics); @@ -297,18 +296,4 @@ Topics.isLocked = async function (tid) { const locked = await Topics.getTopicField(tid, 'locked'); return locked === 1; }; - -// Topics.search = async function (tid, term) { -// if (!tid || !term) { -// throw new Error('[[error:invalid-data]]'); -// } - -// const result = await plugins.hooks.fire('filter:topic.search', { -// tid: tid, -// term: term, -// ids: [], -// }); -// return Array.isArray(result) ? result : result.ids; -// }; - require('../promisify')(Topics); diff --git a/src/topics/search.js b/src/topics/search.js deleted file mode 100644 index c0846bff30..0000000000 --- a/src/topics/search.js +++ /dev/null @@ -1,157 +0,0 @@ -'use strict'; - -const _ = require('lodash'); -const meta = require('../meta'); -const plugins = require('../plugins'); -const db = require('../database'); -const utils = require('../utils'); -const { search } = require('../api/users'); -const categories = require ('../categories'); - -module.exports = function (Topics) { - - // Topics.search = async function (tid, term) { - // if (!tid || !term) { - // throw new Error('[[error:invalid-data]]'); - // } - - // // Normalize the search term for case-insensitivity - // term = term.toLowerCase(); - - // // Fetch topics related to the provided tid - // const topics = await Topics.getTopicsByTid(tid); // Implement this method to fetch topics - - // // Filter topics based on the search term in the title - // const matchedTopics = topics.filter(topic => - // topic.title.toLowerCase().includes(term) - // ); - - // // Fire plugin hooks for additional processing, if needed - // const result = await plugins.hooks.fire('filter:topic.search', { - // tid: tid, - // term: term, - // ids: matchedTopics.map(topic => topic.tid), - // }); - - // return Array.isArray(result) ? result : result.ids; - // }; - Topics.search = async function (data) { - console.log('hit it'); - - const query = data.query || ''; - const searchBy = data.searchBy || 'title'; // Change this as needed - const page = data.page || 1; - const paginate = data.hasOwnProperty('paginate') ? data.paginate : true; - - const startTime = process.hrtime(); - - const tids = await categories.getTopicIds(data); - let topicsData = await Topics.getTopicsByTids(tids, data.uid); - console.log('testing;;g'); - console.log(tids); - console.log(topicsData); - - if (searchBy === 'tid') { - tids = [query]; // Searching by topic ID - } else { - tids = await findTids(query, searchBy, data.hardCap); - } - - tids = await filterAndSortTids(tids, data); - const result = await plugins.hooks.fire('filter:topics.search', { tids }); - tids = result.tids; - - const searchResult = { - matchCount: tids.length, - }; - - if (paginate) { - const resultsPerPage = data.resultsPerPage || meta.config.topicSearchResultsPerPage; - const start = Math.max(0, page - 1) * resultsPerPage; - const stop = start + resultsPerPage; - searchResult.pageCount = Math.ceil(tids.length / resultsPerPage); - tids = tids.slice(start, stop); - } - - const topicData = await Topic.getTopics(tids); // You need to implement this - searchResult.topics = topicData.filter(topic => topic && topic.tid > 0); - searchResult.timing = (process.elapsedTimeSince(startTime) / 1000).toFixed(2); - - console.log('topics search result)'); - console.log(searchResult); - return searchResult; - }; - - async function findTids(query, searchBy, hardCap) { - if (!query) { - return []; - } - query = String(query).toLowerCase(); - const min = query; - const max = query.substr(0, query.length - 1) + String.fromCharCode(query.charCodeAt(query.length - 1) + 1); - console.log(searchBy); - const data = await db.getSortedSetRangeByLex(`${searchBy}:sorted`, min, max, 0, hardCap); - const tids = data.map(data => data.split(':').pop()); - console.log('dataaa tids'); - console.log(tids); - return tids; - } - - async function filterAndSortTids(tids, data) { - tids = tids.filter(tid => parseInt(tid, 10)); - let filters = data.filters || []; - filters = Array.isArray(filters) ? filters : [data.filters]; - const fields = []; - - if (data.sortBy) { - fields.push(data.sortBy); - } - - filters.forEach((filter) => { - if (filterFieldMap[filter]) { - fields.push(...filterFieldMap[filter]); - } - }); - - if (!fields.length) { - return tids; - } - - fields.push('tid'); - let topicData = await Topic.getTopicsFields(tids, fields); // You need to implement this - - filters.forEach((filter) => { - if (filterFnMap[filter]) { - topicData = topicData.filter(filterFnMap[filter]); - } - }); - - if (data.sortBy) { - sortTopics(topicData, data.sortBy, data.sortDirection); - } - - return topicData.map(topic => topic.tid); - } - - function sortTopics(topicData, sortBy, sortDirection) { - if (!topicData || !topicData.length) { - return; - } - sortDirection = sortDirection || 'desc'; - const direction = sortDirection === 'desc' ? 1 : -1; - - const isNumeric = utils.isNumber(topicData[0][sortBy]); - if (isNumeric) { - topicData.sort((t1, t2) => direction * (t2[sortBy] - t1[sortBy])); - } else { - topicData.sort((t1, t2) => { - if (t1[sortBy] < t2[sortBy]) { - return direction * -1; - } else if (t1[sortBy] > t2[sortBy]) { - return direction * 1; - } - return 0; - }); - } - } -}; diff --git a/src/user/search.js b/src/user/search.js index b0169a21ff..66a438128f 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -26,9 +26,8 @@ module.exports = function (User) { User.search = async function (data) { - console.log('data'); - console.log(data); + // console.log(data); console.log('entered user.search in src/user/search'); const query = data.query || ''; const searchBy = data.searchBy || 'username'; From 6891f0cdea3b6fdecb841b35822c25d9b01cceec Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Sun, 20 Oct 2024 16:11:15 +0300 Subject: [PATCH 15/20] removing most comsole.log messages --- public/src/client/category.js | 8 +++---- public/src/client/groups/list.js | 4 ++-- public/src/client/search.js | 2 +- public/src/client/topic.js | 2 +- public/src/client/users.js | 6 ++--- public/src/modules/categorySearch.js | 4 ++-- src/api/categories.js | 4 ++++ src/api/topics.js | 33 ---------------------------- src/batch.js | 4 ++-- src/categories/topics.js | 8 +++++-- src/routes/api.js | 4 +--- src/routes/write/posts.js | 1 - src/topics/create.js | 4 ++-- test/api.js | 1 + 14 files changed, 29 insertions(+), 56 deletions(-) diff --git a/public/src/client/category.js b/public/src/client/category.js index f5d3da4fde..5c563740a4 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -23,7 +23,7 @@ define('forum/category', [ let searchResultCount = 0; Category.init = function () { - console.log('entered category public client'); + // console.log('entered category public client'); const cid = ajaxify.data.cid; app.enterRoom('category_' + cid); @@ -119,20 +119,20 @@ define('forum/category', [ } Category.handleSearch = function (params) { - console.log('entered public/src/client/category handleSearch'); + // console.log('entered public/src/client/category handleSearch'); searchResultCount = params && params.resultCount; $('#search-topic').on('keyup', utils.debounce(doSearch, 250)); $('.search select, .search input[type="checkbox"]').on('change', doSearch); }; function doSearch() { - console.log('entered public/src/client/category doSearch'); + // console.log('entered public/src/client/category doSearch'); if (!ajaxify.data.template.category) { return; } $('[component="topic/search/icon"]').removeClass('fa-search').addClass('fa-spinner fa-spin'); const title = $('#search-topic').val(); - console.log(title); + // console.log(title); const activeSection = getActiveSection(); const query = { diff --git a/public/src/client/groups/list.js b/public/src/client/groups/list.js index d250697c7c..7a431cbc1c 100644 --- a/public/src/client/groups/list.js +++ b/public/src/client/groups/list.js @@ -62,8 +62,8 @@ define('forum/groups/list', [ const queryEl = $('#search-text'); const sortEl = $('#search-sort'); - console.log('entered public/src/client/groups/list groups.search'); - console.log(queryEl); + // console.log('entered public/src/client/groups/list groups.search'); + // console.log(queryEl); socket.emit('groups.search', { query: queryEl.val(), diff --git a/public/src/client/search.js b/public/src/client/search.js index 279d621904..122c26d13c 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -333,7 +333,7 @@ define('forum/search', [ } async function doSearch() { - console.log('mercy'); + // console.log('mercy'); let result = { tags: [] }; const query = el.find('[component="tag/filter/search"]').val(); if (query && query.length > 1) { diff --git a/public/src/client/topic.js b/public/src/client/topic.js index e51e3ed140..45a4c855b6 100644 --- a/public/src/client/topic.js +++ b/public/src/client/topic.js @@ -38,7 +38,7 @@ define('forum/topic', [ }); Topic.init = async function () { - console.log('public src client topic'); + // console.log('public src client topic'); const tidChanged = !tid || parseInt(tid, 10) !== parseInt(ajaxify.data.tid, 10); tid = ajaxify.data.tid; currentUrl = ajaxify.currentPage; diff --git a/public/src/client/users.js b/public/src/client/users.js index 678236fff2..6a544ee9d6 100644 --- a/public/src/client/users.js +++ b/public/src/client/users.js @@ -26,14 +26,14 @@ define('forum/users', [ }; Users.handleSearch = function (params) { - console.log('entered public/src/client/users handleSearch'); + // console.log('entered public/src/client/users handleSearch'); searchResultCount = params && params.resultCount; $('#search-user').on('keyup', utils.debounce(doSearch, 250)); $('.search select, .search input[type="checkbox"]').on('change', doSearch); }; function doSearch() { - console.log('entered public/src/client/users doSearch'); + // console.log('entered public/src/client/users doSearch'); if (!ajaxify.data.template.users) { return; } @@ -84,7 +84,7 @@ define('forum/users', [ function loadPage(query) { - console.log('user load page then api?'); + // console.log('user load page then api?'); api.get('/api/users', query) .then(renderSearchResults) .catch(alerts.error); diff --git a/public/src/modules/categorySearch.js b/public/src/modules/categorySearch.js index 6970e8e9a2..bb8421a2b8 100644 --- a/public/src/modules/categorySearch.js +++ b/public/src/modules/categorySearch.js @@ -70,8 +70,8 @@ define('categorySearch', ['alerts', 'bootstrap', 'api'], function (alerts, boots }); function loadList(search, callback) { - console.log('caategories loadlist'); - console.log('did it call search??'); + // console.log('caategories loadlist'); + // console.log('did it call search??'); api.get('/search/categories', { search: search, query: utils.params(), diff --git a/src/api/categories.js b/src/api/categories.js index 61814ab2ec..4f45f214fd 100644 --- a/src/api/categories.js +++ b/src/api/categories.js @@ -68,6 +68,10 @@ categoriesAPI.search = async function (caller, data) { ) { throw new Error('[[error:no-privileges]]'); } + + const testing = categories.getCategoryData(2); + // console.log('testingg'); + // console.log(testing); return await categories.searchTopics({ uid: caller.uid, cid: '2', diff --git a/src/api/topics.js b/src/api/topics.js index c27b8b128d..cb342982f9 100644 --- a/src/api/topics.js +++ b/src/api/topics.js @@ -299,36 +299,3 @@ topicsAPI.bump = async (caller, { tid }) => { await topics.markAsUnreadForAll(tid); topics.pushUnreadCount(caller.uid); }; - -topicsAPI.search = async function (caller, data) { - console.log('entered src/api/posts.js'); - // console.log(caller); - // console.log(data); - if (!data) { - throw new Error('[[error:invalid-data]]'); - } - const [allowed, isPrivileged] = await Promise.all([ - privileges.global.can('search:users', caller.uid), - user.isPrivileged(caller.uid), - ]); - let filters = data.filters || []; - filters = Array.isArray(filters) ? filters : [filters]; - if (!allowed || - (( - data.searchBy === 'ip' || - data.searchBy === 'email' || - filters.includes('banned') || - filters.includes('flagged') - ) && !isPrivileged) - ) { - throw new Error('[[error:no-privileges]]'); - } - return await topics.search({ - uid: caller.uid, - query: data.query, - searchBy: data.searchBy || 'title', - page: data.page || 1, - sortBy: data.sortBy || 'lastonline', - filters: filters, - }); -}; diff --git a/src/batch.js b/src/batch.js index 208371fca1..bb35437f17 100644 --- a/src/batch.js +++ b/src/batch.js @@ -23,7 +23,7 @@ function processIsFunction(process) { exports.processSortedSet = async function (setKey, process, options) { - console.log('Hakaabi: Refactored code is running!'); + // console.log('Hakaabi: Refactored code is running!'); options = options || {}; processIsFunction(process); @@ -79,7 +79,7 @@ exports.processSortedSet = async function (setKey, process, options) { stop = start + options.batch - 1; } }; -console.log('Hakaabi: Refactored code stopped running!'); +// console.log('Hakaabi: Refactored code stopped running!'); exports.processArray = async function (array, process, options) { options = options || {}; diff --git a/src/categories/topics.js b/src/categories/topics.js index cd47413ae1..e27953f62c 100644 --- a/src/categories/topics.js +++ b/src/categories/topics.js @@ -22,8 +22,12 @@ module.exports = function (Categories) { } const searchFor = query.toLowerCase(); const matchedTopics = topicsData.filter(topic => topic.title.toLowerCase().includes(searchFor)); - // console.log(matchedTopics); - return matchedTopics; + const finalTopics = matchedTopics.map(topic => topic.title); + const finalResults = { + title: '', + topics: finalTopics, + }; + return finalResults; }; Categories.getCategoryTopics = async function (data) { diff --git a/src/routes/api.js b/src/routes/api.js index 581c650bc2..da23256b3a 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -23,9 +23,7 @@ module.exports = function (app, middleware, controllers) { router.get('/topic/teaser/:topic_id', [...middlewares], helpers.tryRoute(controllers.topics.teaser)); router.get('/topic/pagination/:topic_id', [...middlewares], helpers.tryRoute(controllers.topics.pagination)); - router.get('/topics', [...middlewares], helpers.tryRoute(controllers.topics.search)); - router.get('/posts', [...middlewares], helpers.tryRoute(controllers.posts.search)); - router.get('/categories', [...middlewares], helpers.tryRoute(controllers.categories.search)); + // router.get('/categories', [...middlewares], helpers.tryRoute(controllers.categories.search)); const multipart = require('connect-multiparty'); const multipartMiddleware = multipart(); diff --git a/src/routes/write/posts.js b/src/routes/write/posts.js index 98bc643377..59480b1901 100644 --- a/src/routes/write/posts.js +++ b/src/routes/write/posts.js @@ -39,7 +39,6 @@ module.exports = function () { setupApiRoute(router, 'get', '/:pid/replies', [middleware.assert.post], controllers.write.posts.getReplies); - setupApiRoute(router, 'get', '/:title', [middleware.ensureLoggedIn], controllers.posts.search); // Shorthand route to access post routes by topic index diff --git a/src/topics/create.js b/src/topics/create.js index a141a2b722..91c40276a5 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -15,7 +15,7 @@ const privileges = require('../privileges'); const categories = require('../categories'); const translator = require('../translator'); -console.log('Al Anoud'); +// console.log('Al Anoud'); module.exports = function (Topics) { Topics.create = async function (data) { @@ -119,7 +119,7 @@ module.exports = function (Topics) { throw new Error('[[error:no-privileges]]'); } - console.log('Al Anoud: Refactored code executed'); + // console.log('Al Anoud: Refactored code executed'); await guestHandleValid(data); if (!data.fromQueue) { diff --git a/test/api.js b/test/api.js index 0ea9918953..1905069156 100644 --- a/test/api.js +++ b/test/api.js @@ -615,6 +615,7 @@ describe('API', async () => { // Compare the schema to the response required.forEach((prop) => { if (schema.hasOwnProperty(prop)) { + // console.log(response); assert(response.hasOwnProperty(prop), `"${prop}" is a required property (path: ${method} ${path}, context: ${context})`); // Don't proceed with type-check if the value could possibly be unset (nullable: true, in spec) From 0cd54905bba593c6b0e778f9ee44946dafcf19c8 Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Sun, 20 Oct 2024 20:30:37 +0300 Subject: [PATCH 16/20] adding console.logs to debug tests --- public/src/client/category.js | 2 +- src/api/categories.js | 3 --- src/categories/topics.js | 36 +++++++++++++++++++++++++++++------ src/controllers/categories.js | 12 +++++++----- src/controllers/users.js | 1 - src/routes/api.js | 2 +- src/socket.io/topics.js | 7 ------- test/api.js | 9 ++++++--- 8 files changed, 45 insertions(+), 27 deletions(-) diff --git a/public/src/client/category.js b/public/src/client/category.js index 5c563740a4..898a81cbdb 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -165,7 +165,7 @@ define('forum/category', [ function loadPage(query) { console.log('entered load page'); console.log(query); - api.get('/api/categories', query) + api.get('/api/categoriesss', query) .then(renderSearchResults) .catch(alerts.error); } diff --git a/src/api/categories.js b/src/api/categories.js index 4f45f214fd..3aea2bc349 100644 --- a/src/api/categories.js +++ b/src/api/categories.js @@ -69,9 +69,6 @@ categoriesAPI.search = async function (caller, data) { throw new Error('[[error:no-privileges]]'); } - const testing = categories.getCategoryData(2); - // console.log('testingg'); - // console.log(testing); return await categories.searchTopics({ uid: caller.uid, cid: '2', diff --git a/src/categories/topics.js b/src/categories/topics.js index e27953f62c..2f7a418a91 100644 --- a/src/categories/topics.js +++ b/src/categories/topics.js @@ -17,17 +17,41 @@ module.exports = function (Categories) { const results = await plugins.hooks.fire('filter:category.topics.prepare', data); const tids = await Categories.getTopicIds(results); const topicsData = await topics.getTopicsByTids(tids, data.uid); + console.log('topics'); + console.log(topicsData); if (!query || query.trim() === '') { - return topicsData; + return modifyResults(topicsData); } - const searchFor = query.toLowerCase(); + const searchFor = query.toLowerCase(); const matchedTopics = topicsData.filter(topic => topic.title.toLowerCase().includes(searchFor)); const finalTopics = matchedTopics.map(topic => topic.title); - const finalResults = { + return modifyResults(finalTopics); + }; + + function modifyResults (results) { + const modified = { title: '', - topics: finalTopics, - }; - return finalResults; + selectCategoryLabel: '', + categories: results, + pagination: results.hasOwnProperty('paginate') ? results.paginate : true, + loggedIn: true, + relative_path: '', + template: 'undefined', + url : '', + bodyClass: '', + _header: '', + widgets:[ + { + widget: 'html', + data: { + html: 'test', + title: '', + container: '', + }, + }, + ], + } + return modified; }; Categories.getCategoryTopics = async function (data) { diff --git a/src/controllers/categories.js b/src/controllers/categories.js index e8be352c41..035f634850 100644 --- a/src/controllers/categories.js +++ b/src/controllers/categories.js @@ -16,12 +16,14 @@ categoriesController.search = async function (req, res) { console.log('entered src/controllers/categories.js'); // console.log(req); const searchData = await api.categories.search(req, req.query); + console.log('searching data'); + console.log(searchData); + // return searchData + // const section = req.query.section || 'joindate'; - const section = req.query.section || 'joindate'; - - searchData.pagination = pagination.create(req.query.page, searchData.pageCount, req.query); - searchData[`section_${section}`] = true; - searchData.displayUserSearch = true; + // searchData.pagination = pagination.create(req.query.page, searchData.pageCount, req.query); + // searchData[`section_${section}`] = true; + // searchData.displayUserSearch = true; await render(req, res, searchData); }; diff --git a/src/controllers/users.js b/src/controllers/users.js index f06ee433bf..f170db4b75 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -33,7 +33,6 @@ usersController.index = async function (req, res, next) { }; usersController.search = async function (req, res) { - console.log('entered src/controllers/users.js'); // console.log(req); const searchData = await api.users.search(req, req.query); diff --git a/src/routes/api.js b/src/routes/api.js index da23256b3a..f2a5f27f5f 100644 --- a/src/routes/api.js +++ b/src/routes/api.js @@ -23,7 +23,7 @@ module.exports = function (app, middleware, controllers) { router.get('/topic/teaser/:topic_id', [...middlewares], helpers.tryRoute(controllers.topics.teaser)); router.get('/topic/pagination/:topic_id', [...middlewares], helpers.tryRoute(controllers.topics.pagination)); - // router.get('/categories', [...middlewares], helpers.tryRoute(controllers.categories.search)); + router.get('/categoriesss', [...middlewares], helpers.tryRoute(controllers.categories.search)); const multipart = require('connect-multiparty'); const multipartMiddleware = multipart(); diff --git a/src/socket.io/topics.js b/src/socket.io/topics.js index 31d9b806e5..3df9cdc1a2 100644 --- a/src/socket.io/topics.js +++ b/src/socket.io/topics.js @@ -62,13 +62,6 @@ SocketTopics.createTopicFromPosts = async function (socket, data) { return result; }; -SocketTopics.search = async (socket, data) => { - console.log('entered socket topics search'); - data.options = data.options || {}; - data.options.filterHidden = data.options.filterHidden || !await user.isAdministrator(socket.uid); - return await topics.search(data.query, data.options); -}; - SocketTopics.isFollowed = async function (socket, tid) { const isFollowing = await topics.isFollowing([tid], socket.uid); return isFollowing[0]; diff --git a/test/api.js b/test/api.js index 1905069156..6d34478e68 100644 --- a/test/api.js +++ b/test/api.js @@ -366,10 +366,11 @@ describe('API', async () => { }); const exclusionPrefixes = [ '/api/admin/plugins', '/api/compose', '/debug', - '/api/user/{userslug}/theme', // from persona + '/api/user/{userslug}/theme', '/api/categoriesss', // from persona ]; paths = paths.filter(path => path.method !== '_all' && !exclusionPrefixes.some(prefix => path.path.startsWith(prefix))); - + console.log('patjs'); + process.stdout.write(JSON.stringify(paths.filter(path => path.method === 'get')) + '\n'); // For each express path, query for existence in read and write api schemas paths.forEach((pathObj) => { @@ -454,7 +455,6 @@ describe('API', async () => { url = nconf.get('url') + (prefix || '') + testPath; }); - it('should contain a valid request body (if present) with application/json or multipart/form-data type if POST/PUT/DELETE', () => { if (['post', 'put', 'delete'].includes(method) && context[method].hasOwnProperty('requestBody')) { const failMessage = `${method.toUpperCase()} ${path} has a malformed request body`; @@ -615,6 +615,9 @@ describe('API', async () => { // Compare the schema to the response required.forEach((prop) => { if (schema.hasOwnProperty(prop)) { + // console.log(response); + // console.log('schema'); + // console.log(schema); // console.log(response); assert(response.hasOwnProperty(prop), `"${prop}" is a required property (path: ${method} ${path}, context: ${context})`); From b0008aa4ee620f6551a98b7cdfa08260de4eb3c1 Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Sun, 20 Oct 2024 20:52:38 +0300 Subject: [PATCH 17/20] adding function that was accidentally removed --- src/topics/index.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/topics/index.js b/src/topics/index.js index 958b10cdf8..5724d8a276 100644 --- a/src/topics/index.js +++ b/src/topics/index.js @@ -296,4 +296,17 @@ Topics.isLocked = async function (tid) { const locked = await Topics.getTopicField(tid, 'locked'); return locked === 1; }; + +Topics.search = async function (tid, term) { + if (!tid || !term) { + throw new Error('[[error:invalid-data]]'); + } + const result = await plugins.hooks.fire('filter:topic.search', { + tid: tid, + term: term, + ids: [], + }); + return Array.isArray(result) ? result : result.ids; +}; + require('../promisify')(Topics); From 0d3367f6e55e61d0dc5da413a8e775a987e4633a Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Sun, 20 Oct 2024 21:13:35 +0300 Subject: [PATCH 18/20] removing / commenting more console.log statements and other dead code --- public/src/admin/manage/groups.js | 2 -- public/src/client/category.js | 2 -- public/src/client/search.js | 2 -- src/api/categories.js | 3 --- src/api/users.js | 1 - src/categories/search.js | 1 - src/categories/topics.js | 33 ++----------------------------- src/controllers/categories.js | 13 ++++-------- src/controllers/topics.js | 4 ---- src/groups/index.js | 2 -- src/groups/search.js | 1 - src/socket.io/admin/rooms.js | 4 ---- src/socket.io/groups.js | 2 -- src/topics/events.js | 1 - src/user/search.js | 3 --- test/api.js | 6 ------ 16 files changed, 6 insertions(+), 74 deletions(-) diff --git a/public/src/admin/manage/groups.js b/public/src/admin/manage/groups.js index 0a31341fce..682dcadf21 100644 --- a/public/src/admin/manage/groups.js +++ b/public/src/admin/manage/groups.js @@ -82,8 +82,6 @@ define('admin/manage/groups', [ function handleSearch() { const queryEl = $('#group-search'); - console.log('public/src/admin/manage/groups handleSearch'); - console.log(queryEl); function doSearch() { if (!queryEl.val()) { diff --git a/public/src/client/category.js b/public/src/client/category.js index 898a81cbdb..87b589ece1 100644 --- a/public/src/client/category.js +++ b/public/src/client/category.js @@ -163,8 +163,6 @@ define('forum/category', [ } function loadPage(query) { - console.log('entered load page'); - console.log(query); api.get('/api/categoriesss', query) .then(renderSearchResults) .catch(alerts.error); diff --git a/public/src/client/search.js b/public/src/client/search.js index 122c26d13c..5bf52a1ef9 100644 --- a/public/src/client/search.js +++ b/public/src/client/search.js @@ -114,7 +114,6 @@ define('forum/search', [ } function getSearchDataFromDOM() { - console.log('testing'); const form = $('#advanced-search'); const searchData = { in: $('#search-in').val(), @@ -333,7 +332,6 @@ define('forum/search', [ } async function doSearch() { - // console.log('mercy'); let result = { tags: [] }; const query = el.find('[component="tag/filter/search"]').val(); if (query && query.length > 1) { diff --git a/src/api/categories.js b/src/api/categories.js index 3aea2bc349..23d7b51447 100644 --- a/src/api/categories.js +++ b/src/api/categories.js @@ -46,9 +46,6 @@ categoriesAPI.get = async function (caller, data) { }; categoriesAPI.search = async function (caller, data) { - console.log('entered src/api/categories.js'); - // console.log(caller); - // console.log(data); if (!data) { throw new Error('[[error:invalid-data]]'); } diff --git a/src/api/users.js b/src/api/users.js index edf5ba2f70..82c8c7b397 100644 --- a/src/api/users.js +++ b/src/api/users.js @@ -598,7 +598,6 @@ async function canDeleteUids(uids) { } usersAPI.search = async function (caller, data) { - console.log('entered src/api/users.js'); // console.log(caller); // console.log(data); if (!data) { diff --git a/src/categories/search.js b/src/categories/search.js index 173b451ae6..685628f32c 100644 --- a/src/categories/search.js +++ b/src/categories/search.js @@ -8,7 +8,6 @@ const db = require('../database'); module.exports = function (Categories) { Categories.search = async function (data) { - console.log('it called categories search'); const query = data.query || ''; const page = data.page || 1; const uid = data.uid || 0; diff --git a/src/categories/topics.js b/src/categories/topics.js index 2f7a418a91..243f23eefb 100644 --- a/src/categories/topics.js +++ b/src/categories/topics.js @@ -12,46 +12,17 @@ const batch = require('../batch'); module.exports = function (Categories) { Categories.searchTopics = async function (data) { - console.log('was this called??/'); const { query } = data; const results = await plugins.hooks.fire('filter:category.topics.prepare', data); const tids = await Categories.getTopicIds(results); const topicsData = await topics.getTopicsByTids(tids, data.uid); - console.log('topics'); - console.log(topicsData); if (!query || query.trim() === '') { - return modifyResults(topicsData); + return topicsData; } const searchFor = query.toLowerCase(); const matchedTopics = topicsData.filter(topic => topic.title.toLowerCase().includes(searchFor)); const finalTopics = matchedTopics.map(topic => topic.title); - return modifyResults(finalTopics); - }; - - function modifyResults (results) { - const modified = { - title: '', - selectCategoryLabel: '', - categories: results, - pagination: results.hasOwnProperty('paginate') ? results.paginate : true, - loggedIn: true, - relative_path: '', - template: 'undefined', - url : '', - bodyClass: '', - _header: '', - widgets:[ - { - widget: 'html', - data: { - html: 'test', - title: '', - container: '', - }, - }, - ], - } - return modified; + return finalTopics; }; Categories.getCategoryTopics = async function (data) { diff --git a/src/controllers/categories.js b/src/controllers/categories.js index 035f634850..ea14d39530 100644 --- a/src/controllers/categories.js +++ b/src/controllers/categories.js @@ -13,17 +13,12 @@ const privileges = require('../privileges'); const categoriesController = module.exports; categoriesController.search = async function (req, res) { - console.log('entered src/controllers/categories.js'); - // console.log(req); const searchData = await api.categories.search(req, req.query); - console.log('searching data'); - console.log(searchData); - // return searchData - // const section = req.query.section || 'joindate'; + const section = req.query.section || 'joindate'; - // searchData.pagination = pagination.create(req.query.page, searchData.pageCount, req.query); - // searchData[`section_${section}`] = true; - // searchData.displayUserSearch = true; + searchData.pagination = pagination.create(req.query.page, searchData.pageCount, req.query); + searchData[`section_${section}`] = true; + searchData.displayUserSearch = true; await render(req, res, searchData); }; diff --git a/src/controllers/topics.js b/src/controllers/topics.js index f157b241fe..dbb5f851ce 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -409,8 +409,6 @@ topicsController.pagination = async function (req, res, next) { }; topicsController.search = async function (req, res) { - console.log('entered src/controllers/topics.js'); - // console.log(req); const searchData = await api.topics.search(req, req.query); const section = req.query.section || 'joindate'; @@ -422,7 +420,5 @@ topicsController.search = async function (req, res) { }; async function render(req, res, data) { - console.log('render is called'); - // res.append('X-Total-Count', data.pageCount); res.render('post-queue', data); } diff --git a/src/groups/index.js b/src/groups/index.js index 5d1fa6089c..050843c766 100644 --- a/src/groups/index.js +++ b/src/groups/index.js @@ -122,8 +122,6 @@ Groups.getGroupsAndMembers = async function (groupNames) { }; Groups.get = async function (groupName, options) { - console.log('hi'); - // console.log(options); if (!groupName) { throw new Error('[[error:invalid-group]]'); } diff --git a/src/groups/search.js b/src/groups/search.js index 267bd2741a..56eb76f35c 100644 --- a/src/groups/search.js +++ b/src/groups/search.js @@ -5,7 +5,6 @@ const db = require('../database'); module.exports = function (Groups) { Groups.search = async function (query, options) { - console.log('entered group search'); // console.log(query); if (!query) { return []; diff --git a/src/socket.io/admin/rooms.js b/src/socket.io/admin/rooms.js index ae67ed9551..45afcae2ca 100644 --- a/src/socket.io/admin/rooms.js +++ b/src/socket.io/admin/rooms.js @@ -16,7 +16,6 @@ SocketRooms.getTotalGuestCount = async function () { }; SocketRooms.getAll = async function () { - console.log('GhalyaRefactoredCode'); const sockets = await io.server.fetchSockets(); totals.onlineGuestCount = 0; @@ -52,7 +51,6 @@ SocketRooms.getAll = async function () { }; function processSocket(s, totals, userRooms, topicData) { - console.log('GhalyaRefactoredCode1'); for (const key of s.rooms) { if (key === 'online_guests') { totals.onlineGuestCount += 1; @@ -73,7 +71,6 @@ function processSocket(s, totals, userRooms, topicData) { } function processTopicKey(key, totals, topicData) { - console.log('GhalyaRefactoredCode2'); const tid = key.match(/^topic_(\d+)/); if (tid) { totals.users.topics += 1; @@ -83,7 +80,6 @@ function processTopicKey(key, totals, topicData) { } function getTopTenTopics(topicData) { - console.log('GhalyaRefactoredCode3'); const topTenTopics = []; Object.keys(topicData).forEach((tid) => { topTenTopics.push({ tid: tid, count: topicData[tid].count }); diff --git a/src/socket.io/groups.js b/src/socket.io/groups.js index 19bbd1a6e4..789ac9941a 100644 --- a/src/socket.io/groups.js +++ b/src/socket.io/groups.js @@ -23,7 +23,6 @@ SocketGroups.before = async (socket, method, data) => { }; SocketGroups.search = async (socket, data) => { - console.log('entered socket search'); data.options = data.options || {}; if (!data.query) { @@ -47,7 +46,6 @@ SocketGroups.loadMore = async (socket, data) => { }; SocketGroups.searchMembers = async (socket, data) => { - console.log('entered socket search'); sockets.warnDeprecated(socket, 'GET /api/v3/groups/:groupName/members'); if (!data.groupName) { diff --git a/src/topics/events.js b/src/topics/events.js index 95407ed5ec..7f3c0b2397 100644 --- a/src/topics/events.js +++ b/src/topics/events.js @@ -27,7 +27,6 @@ const Events = module.exports; * the user avatar/username will be rendered as part of the event text * see https://github.com/NodeBB/nodebb-plugin-question-and-answer/blob/master/library.js#L288-L306 */ -console.log('entered topic events'); Events._types = { pin: { icon: 'fa-thumb-tack', diff --git a/src/user/search.js b/src/user/search.js index 66a438128f..ec0b81d025 100644 --- a/src/user/search.js +++ b/src/user/search.js @@ -26,9 +26,6 @@ module.exports = function (User) { User.search = async function (data) { - console.log('data'); - // console.log(data); - console.log('entered user.search in src/user/search'); const query = data.query || ''; const searchBy = data.searchBy || 'username'; const page = data.page || 1; diff --git a/test/api.js b/test/api.js index 6d34478e68..2214d50d3a 100644 --- a/test/api.js +++ b/test/api.js @@ -369,8 +369,6 @@ describe('API', async () => { '/api/user/{userslug}/theme', '/api/categoriesss', // from persona ]; paths = paths.filter(path => path.method !== '_all' && !exclusionPrefixes.some(prefix => path.path.startsWith(prefix))); - console.log('patjs'); - process.stdout.write(JSON.stringify(paths.filter(path => path.method === 'get')) + '\n'); // For each express path, query for existence in read and write api schemas paths.forEach((pathObj) => { @@ -615,10 +613,6 @@ describe('API', async () => { // Compare the schema to the response required.forEach((prop) => { if (schema.hasOwnProperty(prop)) { - // console.log(response); - // console.log('schema'); - // console.log(schema); - // console.log(response); assert(response.hasOwnProperty(prop), `"${prop}" is a required property (path: ${method} ${path}, context: ${context})`); // Don't proceed with type-check if the value could possibly be unset (nullable: true, in spec) From 2393d0be0ffaf2177b8cac0f4ebd41d3cc930eda Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Sun, 20 Oct 2024 21:21:25 +0300 Subject: [PATCH 19/20] removed trailing spaces --- src/categories/topics.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/categories/topics.js b/src/categories/topics.js index 243f23eefb..cb880e2564 100644 --- a/src/categories/topics.js +++ b/src/categories/topics.js @@ -19,23 +19,16 @@ module.exports = function (Categories) { if (!query || query.trim() === '') { return topicsData; } - const searchFor = query.toLowerCase(); + const searchFor = query.toLowerCase(); const matchedTopics = topicsData.filter(topic => topic.title.toLowerCase().includes(searchFor)); const finalTopics = matchedTopics.map(topic => topic.title); return finalTopics; }; Categories.getCategoryTopics = async function (data) { - // console.log('data'); - // console.log(data); let results = await plugins.hooks.fire('filter:category.topics.prepare', data); - // console.log('results'); - // console.log(results); const tids = await Categories.getTopicIds(results); - // console.log(tids); - - let topicsData = await topics.getTopicsByTids(tids, data.uid); topicsData = await user.blocks.filter(data.uid, topicsData); From 186a64ac4bd2ccab0b0917e2acab628a482cfb4f Mon Sep 17 00:00:00 2001 From: Zeina Halawa Date: Sun, 20 Oct 2024 23:17:11 +0300 Subject: [PATCH 20/20] adding automated tests --- test/categories.js | 84 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/test/categories.js b/test/categories.js index 5309bd1545..65d00ff843 100644 --- a/test/categories.js +++ b/test/categories.js @@ -175,6 +175,90 @@ describe('Categories', () => { }); }); + describe('.searchTopics()', () => { + let adminUid; + let uid; + before(async () => { + adminUid = await User.create({ username: 'noteadmin' }); + await groups.join('administrators', adminUid); + }); + + it('should return array of topics whose titles being with a', (done) => { + Categories.searchTopics({ query: 'a' }, (err, searchData) => { + assert.ifError(err); + assert.equal(Array.isArray(searchData.users) && searchData.users.length > 0, true); + assert.equal(searchData[0], 'africa'); + done(); + }); + }); + + it('should search topic', async () => { + const searchData = await apiCat.search({ uid: testUid }, { query: 'alrightyyy' }); + assert.equal(searchData[0], 'alrightyyy'); + }); + + it('should error for guest', async () => { + try { + await apiCat.search({ uid: 0 }, { query: 'john' }); + assert(false); + } catch (err) { + assert.equal(err.message, '[[error:no-privileges]]'); + } + }); + + it('should error with invalid data', async () => { + try { + await apiCat.search({ uid: testUid }, null); + assert(false); + } catch (err) { + assert.equal(err.message, '[[error:invalid-data]]'); + } + }); + + it('should error for unprivileged user', async () => { + try { + await apiCat.search({ uid: testUid }, { searchBy: 'ip', query: '123' }); + assert(false); + } catch (err) { + assert.equal(err.message, '[[error:no-privileges]]'); + } + }); + + it('should error for unprivileged user', async () => { + try { + await apiCat.search({ uid: testUid }, { filters: ['banned'], query: '123' }); + assert(false); + } catch (err) { + assert.equal(err.message, '[[error:no-privileges]]'); + } + }); + + it('should error for unprivileged user', async () => { + try { + await apiCat.search({ uid: testUid }, { filters: ['flagged'], query: '123' }); + assert(false); + } catch (err) { + assert.equal(err.message, '[[error:no-privileges]]'); + } + }); + + it('should return all topics if query is empty', async () => { + const data = await apiCat.search({ uid: testUid }, { query: '' }); + assert.isAbove(data.length, 0); + }); + + it('should sort results by username', async () => { + const data = await Categories.searchTopics({ + uid: testUid, + query: 'b', + sortBy: 'title', + paginate: false, + }); + assert.equal(data[0], 'africa'); + assert.equal(data[1], 'alrightyyy'); + }); + }); + describe('api/socket methods', () => { const socketCategories = require('../src/socket.io/categories'); const apiCategories = require('../src/api/categories');