2022-08-23 09:57:42 +00:00
#lang racket/base
( require racket/dict
racket/list
2022-09-16 12:56:05 +00:00
racket/match
2022-08-23 09:57:42 +00:00
racket/string
( prefix-in easy: net/http-easy )
; html libs
2022-09-11 11:21:37 +00:00
html-parsing
2022-08-23 09:57:42 +00:00
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-11 11:21:37 +00:00
" config.rkt "
2022-09-16 13:56:03 +00:00
" data.rkt "
2022-09-11 11:21:37 +00:00
" page-wiki.rkt "
2023-02-05 04:56:15 +00:00
" ../lib/syntax.rkt "
2023-02-12 00:55:33 +00:00
" ../lib/thread-utils.rkt "
2023-02-05 04:56:15 +00:00
" ../lib/url-utils.rkt "
" whole-utils.rkt "
" ../lib/xexpr-utils.rkt " )
2022-08-23 09:57:42 +00:00
( provide
page-category )
( module+ test
2022-11-29 11:36:53 +00:00
( require rackunit
" test-utils.rkt " )
2022-08-23 09:57:42 +00:00
( define category-json-data
' #hasheq ( ( batchcomplete . #t ) ( continue . #hasheq ( ( cmcontinue . " page|4150504c45|41473 " ) ( continue . " -|| " ) ) ) ( query . #hasheq ( ( categorymembers . ( #hasheq ( ( ns . 0 ) ( pageid . 25049 ) ( title . " Item (entity) " ) ) #hasheq ( ( ns . 0 ) ( pageid . 128911 ) ( title . " 3D " ) ) #hasheq ( ( ns . 0 ) ( pageid . 124018 ) ( title . " A Very Fine Item " ) ) #hasheq ( ( ns . 0 ) ( pageid . 142208 ) ( title . " Amethyst Shard " ) ) #hasheq ( ( ns . 0 ) ( pageid . 121612 ) ( title . " Ankle Monitor " ) ) ) ) ) ) ) ) )
2022-09-16 12:56:05 +00:00
( define ( generate-results-page
2022-11-29 11:03:54 +00:00
#:req req
2022-09-16 12:56:05 +00:00
#:source-url source-url
#:wikiname wikiname
2022-09-25 09:45:07 +00:00
#:title title
2022-09-16 12:56:05 +00:00
#:members-data members-data
#:page page
2022-10-31 06:39:19 +00:00
#:head-data [ head-data #f ]
2022-10-09 09:50:50 +00:00
#:siteinfo [ siteinfo #f ] )
2022-09-11 11:21:37 +00:00
( define members ( jp " /query/categorymembers " members-data ) )
2022-08-23 09:57:42 +00:00
( generate-wiki-page
2022-11-29 11:03:54 +00:00
#:req req
2022-09-16 12:56:05 +00:00
#:source-url source-url
#:wikiname wikiname
2022-09-25 09:45:07 +00:00
#:title title
2022-10-31 06:39:19 +00:00
#:head-data head-data
2022-10-09 09:50:50 +00:00
#:siteinfo siteinfo
2022-09-11 11:21:37 +00:00
` ( div
, ( update-tree-wiki page wikiname )
( hr )
2022-09-25 09:45:07 +00:00
( h2 , ( format " All Pages in ~a " title ) )
2022-09-11 11:21:37 +00:00
( div ( @ ( class " mw-parser-output " ) )
( ul ( @ ( class " my-category-list " ) )
,@ ( map
( λ ( result )
( define title ( jp " /title " result ) )
2022-11-17 10:25:06 +00:00
( define page-path ( page-title->path title ) )
2022-09-11 11:21:37 +00:00
` ( li
( a ( @ ( href , ( format " /~a/wiki/~a " wikiname page-path ) ) )
, title ) ) )
members ) ) ) ) ) )
2022-08-23 09:57:42 +00:00
( define ( page-category req )
( response-handler
( define wikiname ( path/param-path ( first ( url-path ( request-uri req ) ) ) ) )
( define prefixed-category ( path/param-path ( caddr ( url-path ( request-uri req ) ) ) ) )
( define origin ( format " https://~a.fandom.com " wikiname ) )
2022-09-11 11:21:37 +00:00
( define source-url ( format " ~a/wiki/~a " origin prefixed-category ) )
2023-02-12 00:55:33 +00:00
( define-values ( members-data page-data siteinfo )
( thread-values
( λ ( )
( define dest-url
( format " ~a/api.php?~a "
origin
( params->query ` ( ( " action " . " query " )
( " list " . " categorymembers " )
( " cmtitle " . , prefixed-category )
( " cmlimit " . " max " )
( " formatversion " . " 2 " )
( " format " . " json " ) ) ) ) )
( log-outgoing dest-url )
( define dest-res ( easy:get dest-url #:timeouts timeouts ) )
( easy:response-json dest-res ) )
( λ ( )
( define dest-url
( format " ~a/api.php?~a "
origin
( params->query ` ( ( " action " . " parse " )
( " page " . , prefixed-category )
( " prop " . " text|headhtml|langlinks " )
( " formatversion " . " 2 " )
( " format " . " json " ) ) ) ) )
( log-outgoing dest-url )
( define dest-res ( easy:get dest-url #:timeouts timeouts ) )
( easy:response-json dest-res ) )
( λ ( )
( siteinfo-fetch wikiname ) ) ) )
2022-09-11 11:21:37 +00:00
2023-02-12 00:55:33 +00:00
( define title ( preprocess-html-wiki ( jp " /parse/title " page-data prefixed-category ) ) )
( define page-html ( preprocess-html-wiki ( jp " /parse/text " page-data " " ) ) )
( define page ( html->xexp page-html ) )
( define head-data ( ( head-data-getter wikiname ) page-data ) )
( define body ( generate-results-page
#:req req
#:source-url source-url
#:wikiname wikiname
#:title title
#:members-data members-data
#:page page
#:head-data head-data
#:siteinfo siteinfo ) )
2022-08-23 09:57:42 +00:00
2023-02-12 00:55:33 +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
#:headers ( build-headers always-headers )
( λ ( out )
( write-html body out ) ) ) ) )
2022-08-23 09:57:42 +00:00
( module+ test
( check-not-false ( ( query-selector ( attribute-selector ' href " /test/wiki/Ankle_Monitor " )
2022-09-16 12:56:05 +00:00
( generate-results-page
2022-11-29 11:36:53 +00:00
#:req test-req
2022-09-16 12:56:05 +00:00
#:source-url " "
#:wikiname " test "
2022-09-25 09:45:07 +00:00
#:title " Category:Items "
2022-09-16 13:56:03 +00:00
#:members-data category-json-data
2022-09-16 12:56:05 +00:00
#:page ' ( div " page text " ) ) ) ) ) )