2022-08-23 09:57:42 +00:00
#lang racket/base
( require racket/dict
racket/list
racket/string
( prefix-in easy: net/http-easy )
; html libs
html-writing
; web server libs
net/url
web-server/http
( only-in web-server/dispatchers/dispatch next-dispatcher )
#; ( only-in web-server/http/redirect redirect-to )
" application-globals.rkt "
2022-09-16 13:56:03 +00:00
" config.rkt "
" data.rkt "
2023-02-05 04:56:15 +00:00
" ../lib/syntax.rkt "
" ../lib/url-utils.rkt "
" whole-utils.rkt "
" ../lib/xexpr-utils.rkt " )
2022-08-23 09:57:42 +00:00
( provide
page-search )
( module+ test
2022-11-29 11:36:53 +00:00
( require rackunit
" test-utils.rkt " )
2022-08-23 09:57:42 +00:00
( define search-json-data
' #hasheq ( ( batchcomplete . #t ) ( query . #hasheq ( ( search . ( #hasheq ( ( ns . 0 ) ( pageid . 219 ) ( size . 1482 ) ( snippet . " " ) ( timestamp . " 2022-08-21T08:54:23Z " ) ( title . " Gacha Capsule " ) ( wordcount . 214 ) ) #hasheq ( ( ns . 0 ) ( pageid . 201 ) ( size . 1198 ) ( snippet . " " ) ( timestamp . " 2022-07-11T17:52:47Z " ) ( title . " Badges " ) ( wordcount . 181 ) ) ) ) ) ) ) ) )
2022-11-29 11:03:54 +00:00
( define ( generate-results-page req dest-url wikiname query data #:siteinfo [ siteinfo #f ] )
2022-08-23 09:57:42 +00:00
( define search-results ( jp " /query/search " data ) )
( generate-wiki-page
2022-11-29 11:03:54 +00:00
#:req req
2022-09-16 12:56:05 +00:00
#:source-url dest-url
#:wikiname wikiname
2022-10-30 11:03:13 +00:00
#:title query
2022-10-09 09:50:50 +00:00
#:siteinfo siteinfo
2022-08-23 09:57:42 +00:00
` ( div ( @ ( class " mw-parser-output " ) )
( p , ( format " ~a results found for " ( length search-results ) )
( strong , query ) )
( ul ,@ ( map
( λ ( result )
( let* ( [ title ( jp " /title " result ) ]
2022-11-17 10:25:06 +00:00
[ page-path ( page-title->path title ) ]
2022-08-23 09:57:42 +00:00
[ timestamp ( jp " /timestamp " result ) ]
[ wordcount ( jp " /wordcount " result ) ]
[ size ( jp " /size " result ) ] )
` ( li ( @ ( class " my-result " ) )
( a ( @ ( class " my-result__link " ) ( href , ( format " /~a/wiki/~a " wikiname page-path ) ) )
, title )
( div ( @ ( class " my-result__info " ) )
" last edited "
( time ( @ ( datetime , timestamp ) ) , ( list-ref ( string-split timestamp " T " ) 0 ) )
, ( format " , ~a words, ~a kb "
wordcount
( exact->inexact ( / ( round ( / size 100 ) ) 10 ) ) ) ) ) ) )
search-results ) ) ) ) )
( define ( page-search req )
( response-handler
( define wikiname ( path/param-path ( first ( url-path ( request-uri req ) ) ) ) )
( define query ( dict-ref ( url-query ( request-uri req ) ) ' q #f ) )
( define origin ( format " https://~a.fandom.com " wikiname ) )
2023-02-05 04:56:15 +00:00
( when ( config-true? ' feature_offline::only )
( raise-user-error " Full search is currently not available on breezewiki.com - for now, please use the pop-up search suggestions or wait for me to fix it! Thanks <3 " ) )
2022-09-16 13:56:03 +00:00
( define dest-url
( format " ~a/api.php?~a "
origin
( params->query ` ( ( " action " . " query " )
( " list " . " search " )
( " srsearch " . , query )
( " formatversion " . " 2 " )
( " format " . " json " ) ) ) ) )
( thread-let
2022-10-04 08:13:07 +00:00
( [ dest-res ( log-outgoing dest-url )
2022-09-16 13:56:03 +00:00
( easy:get dest-url #:timeouts timeouts ) ]
2022-10-09 09:50:50 +00:00
[ siteinfo ( siteinfo-fetch wikiname ) ] )
2022-08-23 09:57:42 +00:00
2022-09-16 13:56:03 +00:00
( define data ( easy:response-json dest-res ) )
2022-08-23 09:57:42 +00:00
2022-11-29 11:03:54 +00:00
( define body ( generate-results-page req dest-url wikiname query data #:siteinfo siteinfo ) )
2022-09-16 13:56:03 +00:00
( when ( config-true? ' debug )
; used for its side effects
; convert to string with error checking, error will be raised if xexp is invalid
( xexp->html body ) )
( response/output
#:code 200
2022-10-09 10:43:21 +00:00
#:headers ( build-headers always-headers )
2022-09-16 13:56:03 +00:00
( λ ( out )
( write-html body out ) ) ) ) ) )
2022-08-23 09:57:42 +00:00
( module+ test
2023-02-05 04:56:15 +00:00
( parameterize ( [ ( config-parameter ' feature_offline::only ) " false " ] )
( check-not-false ( ( query-selector ( attribute-selector ' href " /test/wiki/Gacha_Capsule " )
( generate-results-page test-req " " " test " " Gacha " search-json-data ) ) ) ) ) )