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 "
" syntax.rkt "
2022-08-23 09:57:42 +00:00
" url-utils.rkt "
" xexpr-utils.rkt " )
( provide
page-category )
( module+ test
( require rackunit )
( 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
#: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-09-16 13:56:03 +00:00
#:body-class [ body-class #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-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
#:body-class body-class
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 ) )
( define page-path ( regexp-replace* #rx" " title " _ " ) )
` ( 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 ) )
( thread-let
2022-09-16 12:56:05 +00:00
( [ members-data ( define dest-url
( format " ~a/api.php?~a "
origin
( params->query ` ( ( " action " . " query " )
( " list " . " categorymembers " )
( " cmtitle " . , prefixed-category )
( " cmlimit " . " max " )
( " formatversion " . " 2 " )
( " format " . " json " ) ) ) ) )
2022-10-04 08:13:07 +00:00
( log-outgoing dest-url )
2022-09-16 12:56:05 +00:00
( define dest-res ( easy:get dest-url #:timeouts timeouts ) )
( easy:response-json dest-res ) ]
[ page-data ( define dest-url
( format " ~a/api.php?~a "
origin
( params->query ` ( ( " action " . " parse " )
( " page " . , prefixed-category )
( " prop " . " text|headhtml|langlinks " )
( " formatversion " . " 2 " )
( " format " . " json " ) ) ) ) )
2022-10-04 08:13:07 +00:00
( log-outgoing dest-url )
2022-09-16 12:56:05 +00:00
( define dest-res ( easy:get dest-url #:timeouts timeouts ) )
2022-09-16 13:56:03 +00:00
( easy:response-json dest-res ) ]
2022-10-09 09:50:50 +00:00
[ siteinfo ( siteinfo-fetch wikiname ) ] )
2022-09-11 11:21:37 +00:00
2022-09-25 09:45:07 +00:00
( define title ( preprocess-html-wiki ( jp " /parse/title " page-data prefixed-category ) ) )
2022-09-11 11:21:37 +00:00
( define page-html ( preprocess-html-wiki ( jp " /parse/text " page-data " " ) ) )
( define page ( html->xexp page-html ) )
2022-09-16 12:56:05 +00:00
( define head-html ( jp " /parse/headhtml " page-data " " ) )
( define body-class ( match ( regexp-match #rx"<body [^>]*class=\"([^\"]*)" head-html )
[ ( list _ classes ) classes ]
[ _ " " ] ) )
( define body ( generate-results-page
#: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-09-16 13:56:03 +00:00
#:body-class body-class
2022-10-09 09:50:50 +00:00
#:siteinfo siteinfo ) )
2022-08-23 09:57:42 +00:00
2022-09-11 11:21:37 +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 03:53:02 +00:00
#:headers ( list referrer-policy )
2022-09-11 11:21:37 +00:00
( λ ( 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
#: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 " ) ) ) ) ) )