diff --git a/breezewiki.rkt b/breezewiki.rkt index 44d6771..a8b8c28 100644 --- a/breezewiki.rkt +++ b/breezewiki.rkt @@ -17,7 +17,6 @@ (require-reloadable "src/page-proxy.rkt" page-proxy) (require-reloadable "src/page-redirect-wiki-home.rkt" redirect-wiki-home) (require-reloadable "src/page-search.rkt" page-search) -(require-reloadable "src/page-set-user-settings.rkt" page-set-user-settings) (require-reloadable "src/page-static.rkt" static-dispatcher) (require-reloadable "src/page-subdomain.rkt" subdomain-dispatcher) (require-reloadable "src/page-wiki.rkt" page-wiki) @@ -41,7 +40,6 @@ page-not-found page-proxy page-search - page-set-user-settings page-wiki page-file redirect-wiki-home diff --git a/dist.rkt b/dist.rkt index 35e1824..777e81a 100644 --- a/dist.rkt +++ b/dist.rkt @@ -11,7 +11,6 @@ (require (only-in "src/page-proxy.rkt" page-proxy)) (require (only-in "src/page-redirect-wiki-home.rkt" redirect-wiki-home)) (require (only-in "src/page-search.rkt" page-search)) -(require (only-in "src/page-set-user-settings.rkt" page-set-user-settings)) (require (only-in "src/page-static.rkt" static-dispatcher)) (require (only-in "src/page-subdomain.rkt" subdomain-dispatcher)) (require (only-in "src/page-wiki.rkt" page-wiki)) @@ -30,7 +29,6 @@ page-not-found page-proxy page-search - page-set-user-settings page-wiki page-file redirect-wiki-home diff --git a/info.rkt b/info.rkt index dd34d49..46512df 100644 --- a/info.rkt +++ b/info.rkt @@ -1,3 +1,3 @@ #lang info -(define build-deps '("rackunit-lib" "web-server-lib" "http-easy-lib" "html-parsing" "html-writing" "json-pointer" "ini-lib" "memo" "net-cookies-lib")) +(define build-deps '("rackunit-lib" "web-server-lib" "http-easy-lib" "html-parsing" "html-writing" "json-pointer" "ini-lib" "memo")) diff --git a/misc/download-wiki-names.rkt b/misc/download-wiki-names.rkt deleted file mode 100644 index 96a8f9a..0000000 --- a/misc/download-wiki-names.rkt +++ /dev/null @@ -1,45 +0,0 @@ -#lang racket/base -(require racket/generator - racket/list - racket/string - json - net/http-easy - html-parsing - "../src/xexpr-utils.rkt" - "../src/url-utils.rkt") - -(define output-file "wiki-names.json") -(define limit "5000") - -(define (get-page offset) - (define res (get (format "https://community.fandom.com/wiki/Special:NewWikis?~a" - (params->query `(("offset" . ,offset) - ("limit" . ,limit)))))) - (html->xexp (bytes->string/utf-8 (response-body res)))) - -(define (convert-list-items gen) - (for/list ([item (in-producer gen #f)]) - ; '(li "\n" "\t" (a (@ (href "http://terra-hexalis.fandom.com/")) "Terra Hexalis Wiki") "\n" "\t\t\ten\t") - (hasheq 'title (third (fourth item)) - 'link (second (second (second (fourth item)))) - 'lang (string-trim (sixth item))))) - -(define (get-items-recursive [offset ""] [items null]) - (define page (get-page offset)) - (define page-content ((query-selector (attribute-selector 'class "mw-spcontent") page))) - (define next ((query-selector (attribute-selector 'class "mw-nextlink") page-content))) - (define next-offset - (if next - (second (regexp-match #rx"offset=([0-9]*)" (get-attribute 'href (bits->attributes next)))) - #f)) - (define list-item-generator (query-selector (λ (e a c) (eq? e 'li)) page-content)) - (define these-items (convert-list-items list-item-generator)) - (define all-items (append items these-items)) - (printf "page offset \"~a\" has ~a items (~a so far)~n" offset (length these-items) (length all-items)) - (if next - (get-items-recursive next-offset all-items) - all-items)) - -(call-with-output-file output-file #:exists 'truncate/replace - (λ (out) - (write-json (get-items-recursive) out))) diff --git a/src/application-globals.rkt b/src/application-globals.rkt index e6feaaf..f2d83e9 100644 --- a/src/application-globals.rkt +++ b/src/application-globals.rkt @@ -1,18 +1,11 @@ #lang racket/base -(require racket/file - racket/list - racket/runtime-path - racket/string +(require racket/string json (prefix-in easy: net/http-easy) - html-parsing html-writing web-server/http "config.rkt" "data.rkt" - "niwa-data.rkt" - "static-data.rkt" - "pure-utils.rkt" "xexpr-utils.rkt" "url-utils.rkt") @@ -30,26 +23,18 @@ (module+ test (require rackunit - html-writing - "test-utils.rkt")) + html-writing)) (define always-headers - (list (header #"Referrer-Policy" #"same-origin") ; header to not send referers to fandom - (header #"Link" (string->bytes/latin-1 link-header)))) + (list (header #"Referrer-Policy" #"same-origin"))) ; header to not send referers to fandom (define timeouts (easy:make-timeout-config #:lease 5 #:connect 5)) -(define-runtime-path path-static "../static") -(define theme-icons - (for/hasheq ([theme '(default light dark)]) - (values theme - (html->xexp (file->string (build-path path-static (format "icon-theme-~a.svg" theme)) #:mode 'binary))))) - (define (application-footer source-url #:license [license-in #f]) (define license (or license-in license-default)) `(footer (@ (class "custom-footer")) (div (@ (class ,(if source-url "custom-footer__cols" "internal-footer"))) (div (p - (img (@ (class "my-logo") (src ,(get-static-url "breezewiki.svg"))))) + (img (@ (class "my-logo") (src "/static/breezewiki.svg")))) (p (a (@ (href "https://gitdab.com/cadence/breezewiki")) ,(format "~a source code" (config-get 'application_name)))) @@ -77,123 +62,69 @@ " Media files and official Fandom documents have different copying restrictions.") (p ,(format "Fandom is a trademark of Fandom, Inc. ~a is not affiliated with Fandom." (config-get 'application_name)))))))) -;; generate a notice with a link if a fandom wiki has a replacement as part of NIWA or similar -;; if the wiki has no replacement, display nothing -(define (niwa-notice wikiname title) - (define ind (findf (λ (item) (member wikiname (first item))) niwa-data)) - (if ind - (let* ([search-page (format "/Special:Search?~a" - (params->query `(("search" . ,title) - ("go" . "Go"))))] - [go (if (string-suffix? (third ind) "/") - (regexp-replace #rx"/$" (third ind) (λ (_) search-page)) - (let* ([joiner (second (regexp-match #rx"/(w[^./]*)/" (third ind)))]) - (regexp-replace #rx"/w[^./]*/.*$" (third ind) (λ (_) (format "/~a~a" joiner search-page)))))]) - `(aside (@ (class "niwa__notice")) - (h1 (@ (class "niwa__header")) ,(second ind) " has its own website separate from Fandom.") - (a (@ (class "niwa__go") (href ,go)) "Read " ,title " on " ,(second ind) " →") - (div (@ (class "niwa__cols")) - (div (@ (class "niwa__left")) - (p "Most major Nintendo wikis are part of the " - (a (@ (href "https://www.niwanetwork.org/about/")) "Nintendo Independent Wiki Alliance") - " and have their own wikis off Fandom. You can help this wiki by " - (a (@ (href ,go)) "visiting it directly.")) - (p ,(fifth ind)) - (div (@ (class "niwa__divider"))) - (p "Why are you seeing this message? Fandom refuses to delete or archive their copy of this wiki, so that means their pages will appear high up in search results. Fandom hopes to get clicks from readers who don't know any better.") - (p (@ (class "niwa__feedback")) "This notice brought to you by BreezeWiki / " (a (@ (href "https://www.kotaku.com.au/2022/10/massive-zelda-wiki-reclaims-independence-six-months-before-tears-of-the-kingdom/")) "Info & Context") " / " (a (@ (href "https://docs.breezewiki.com/Reporting_Bugs.html")) "Feedback?"))) - (div (@ (class "niwa__right")) - (img (@ (class "niwa__logo") (src ,(format "https://www.niwanetwork.org~a" (fourth ind))))))))) - "")) - (define (generate-wiki-page content - #:req req #:source-url source-url #:wikiname wikiname #:title title - #:head-data [head-data-in #f] - #:siteinfo [siteinfo-in #f] - #:user-cookies [user-cookies-in #f]) + #:body-class [body-class-in #f] + #:siteinfo [siteinfo-in #f]) (define siteinfo (or siteinfo-in siteinfo-default)) - (define head-data (or head-data-in ((head-data-getter wikiname)))) - (define user-cookies (or user-cookies-in (user-cookies-getter req))) + (define body-class (if (not body-class-in) + "skin-fandomdesktop" + body-class-in)) (define (required-styles origin) (map (λ (dest-path) (define url (format dest-path origin)) (if (config-true? 'strict_proxy) (u-proxy-url url) url)) - `(#;"~a/load.php?lang=en&modules=skin.fandomdesktop.styles&only=styles&skin=fandomdesktop" + '(#;"~a/load.php?lang=en&modules=skin.fandomdesktop.styles&only=styles&skin=fandomdesktop" #;"~a/load.php?lang=en&modules=ext.gadget.dungeonsWiki%2CearthWiki%2Csite-styles%2Csound-styles&only=styles&skin=fandomdesktop" #;"~a/load.php?lang=en&modules=site.styles&only=styles&skin=fandomdesktop" ; combine the above entries into a single request for potentially extra speed - fandom.com doesn't even do this! - ,(format "~~a/wikia.php?controller=ThemeApi&method=themeVariables&variant=~a" (user-cookies^-theme user-cookies)) + "~a/wikia.php?controller=ThemeApi&method=themeVariables" "~a/load.php?lang=en&modules=skin.fandomdesktop.styles%7Cext.fandom.PortableInfoboxFandomDesktop.css%7Cext.fandom.GlobalComponents.CommunityHeaderBackground.css%7Cext.gadget.site-styles%2Csound-styles%7Csite.styles&only=styles&skin=fandomdesktop"))) - `(*TOP* - (*DECL* DOCTYPE html) - (html - (head - (meta (@ (name "viewport") (content "width=device-width, initial-scale=1"))) - (title ,(format "~a | ~a+~a" - title - (regexp-replace #rx" ?Wiki$" (siteinfo^-sitename siteinfo) "") - (config-get 'application_name))) - ,@(map (λ (url) - `(link (@ (rel "stylesheet") (type "text/css") (href ,url)))) - (required-styles (format "https://~a.fandom.com" wikiname))) - (link (@ (rel "stylesheet") (type "text/css") (href ,(get-static-url "main.css")))) - (script "const BWData = " - ,(jsexpr->string (hasheq 'wikiname wikiname - 'strict_proxy (config-true? 'strict_proxy)))) - ,(if (config-true? 'feature_search_suggestions) - `(script (@ (type "module") (src ,(get-static-url "search-suggestions.js")))) - "") - (script (@ (type "module") (src ,(get-static-url "countdown.js")))) - (link (@ (rel "icon") (href ,(u (λ (v) (config-true? 'strict_proxy)) - (λ (v) (u-proxy-url v)) - (head-data^-icon-url head-data)))))) - (body (@ (class ,(head-data^-body-class head-data))) - (div (@ (class "main-container")) - (div (@ (class "fandom-community-header__background tileHorizontally header"))) - (div (@ (class "page")) - (main (@ (class "page__main")) - ,(niwa-notice wikiname title) - (div (@ (class "custom-top")) - (h1 (@ (class "page-title")) ,title) - (nav (@ (class "sitesearch")) - (form (@ (action ,(format "/~a/search" wikiname)) - (class "bw-search-form") - (id "bw-pr-search-form")) - (label (@ (for "bw-search-input")) "Search ") - (div (@ (id "bw-pr-search-input")) - (input (@ (type "text") (name "q") (id "bw-search-input") (autocomplete "off")))) - (div (@ (class "bw-ss__container") (id "bw-pr-search-suggestions")))) - (div (@ (class "bw-theme__select")) - (span (@ (class "bw-theme__main-label")) "Page theme") - (div (@ (class "bw-theme__items")) - ,@(for/list ([theme '(default light dark)]) - (define class - (if (equal? theme (user-cookies^-theme user-cookies)) - "bw-theme__item bw-theme__item--selected" - "bw-theme__item")) - `(a (@ (href ,(user-cookies-setter-url - req - (struct-copy user-cookies^ user-cookies - [theme theme]))) (class ,class)) - (div (@ (class "bw-theme__icon-container")) - ,(hash-ref theme-icons theme)) - ,(format "~a" theme))))))) - (div (@ (id "content") #;(class "page-content")) - (div (@ (id "mw-content-text")) - ,content)) - ,(application-footer source-url #:license (siteinfo^-license siteinfo))))))))) + `(html + (head + (meta (@ (name "viewport") (content "width=device-width, initial-scale=1"))) + (title ,(format "~a | ~a+~a" + title + (regexp-replace #rx" ?Wiki$" (siteinfo^-sitename siteinfo) "") + (config-get 'application_name))) + ,@(map (λ (url) + `(link (@ (rel "stylesheet") (type "text/css") (href ,url)))) + (required-styles (format "https://~a.fandom.com" wikiname))) + (link (@ (rel "stylesheet") (type "text/css") (href "/static/main.css"))) + (script "const BWData = " + ,(jsexpr->string (hasheq 'wikiname wikiname + 'strict_proxy (config-true? 'strict_proxy)))) + ,(if (config-true? 'feature_search_suggestions) + '(script (@ (type "module") (src "/static/search-suggestions.js"))) + "")) + (body (@ (class ,body-class)) + (div (@ (class "main-container")) + (div (@ (class "fandom-community-header__background tileHorizontally header"))) + (div (@ (class "page")) + (main (@ (class "page__main")) + (div (@ (class "custom-top")) + (h1 (@ (class "page-title")) ,title) + (nav (@ (class "sitesearch")) + (form (@ (action ,(format "/~a/search" wikiname)) + (class "bw-search-form") + (id "bw-pr-search")) + (label (@ (for "bw-search-input")) "Search ") + (input (@ (type "text") (name "q") (id "bw-search-input") (autocomplete "off"))) + (div (@ (class "bw-ss__container")))))) + (div (@ (id "content") #;(class "page-content")) + (div (@ (id "mw-content-text")) + ,content)) + ,(application-footer source-url #:license (siteinfo^-license siteinfo)))))))) (module+ test (define page (parameterize ([(config-parameter 'strict_proxy) "true"]) (generate-wiki-page '(template) - #:req test-req #:source-url "" #:title "test" #:wikiname "test"))) @@ -208,11 +139,11 @@ page)))) "/proxy?dest=https%3A%2F%2Ftest.fandom.com"))) -(define (generate-redirect dest #:headers [headers-in '()]) +(define (generate-redirect dest) (define dest-bytes (string->bytes/utf-8 dest)) (response/output #:code 302 - #:headers (append (list (header #"Location" dest-bytes)) headers-in) + #:headers (list (header #"Location" dest-bytes)) (λ (out) (write-html `(html diff --git a/src/data.rkt b/src/data.rkt index cdd8c39..6673e4c 100644 --- a/src/data.rkt +++ b/src/data.rkt @@ -1,37 +1,22 @@ #lang racket/base (require racket/list - racket/match - web-server/http/request-structs - net/url-string - (only-in net/cookies/server cookie-header->alist cookie->set-cookie-header make-cookie) (prefix-in easy: net/http-easy) memo - "static-data.rkt" "url-utils.rkt" "xexpr-utils.rkt") (provide (struct-out siteinfo^) (struct-out license^) - (struct-out head-data^) - (struct-out user-cookies^) siteinfo-fetch siteinfo-default - license-default - head-data-getter - head-data-default - user-cookies-getter - user-cookies-default - user-cookies-setter - user-cookies-setter-url) + license-default) (struct siteinfo^ (sitename basepage license) #:transparent) (struct license^ (text url) #:transparent) -(struct head-data^ (body-class icon-url) #:transparent) (define license-default (license^ "CC-BY-SA" "https://www.fandom.com/licensing")) (define siteinfo-default (siteinfo^ "Test Wiki" "Main_Page" license-default)) -(define head-data-default (head-data^ "skin-fandomdesktop" (get-static-url "breezewiki-favicon.svg"))) (define/memoize (siteinfo-fetch wikiname) #:hash hash (define dest-url @@ -49,47 +34,3 @@ (second (regexp-match #rx"/wiki/(.*)" (jp "/query/general/base" data))) (license^ (jp "/query/rightsinfo/text" data) (jp "/query/rightsinfo/url" data)))) - -(define/memoize (head-data-getter wikiname) #:hash hash - ;; data will be stored here, can be referenced by the memoized closure - (define this-data head-data-default) - ;; returns the getter - (λ ([res-in #f]) - (when res-in - ;; when actual information is provided, parse it into the struct and store it for the future - (define head-html (jp "/parse/headhtml" res-in "")) - (define data - (head-data^ - (match (regexp-match #rx"]*class=\"([^\"]*)" head-html) - [(list _ classes) classes] - [_ (head-data^-body-class head-data-default)]) - (match (regexp-match #rx"alist (header-value cookie-header) bytes->string/utf-8) null)) - (define cookies-hash - (for/hasheq ([pair cookies-alist]) - (match pair - [(cons "theme" (and theme (or "light" "dark" "default"))) - (values 'theme (string->symbol theme))] - [_ (values #f #f)]))) - (user-cookies^ - (hash-ref cookies-hash 'theme (user-cookies^-theme user-cookies-default)))) - -(define (user-cookies-setter user-cookies) - (map (λ (c) (header #"Set-Cookie" (cookie->set-cookie-header c))) - (list (make-cookie "theme" (symbol->string (user-cookies^-theme user-cookies)) - #:path "/" - #:max-age (* 60 60 24 365 10))))) - -(define (user-cookies-setter-url req new-settings) - (format "/set-user-settings?~a" (params->query `(("next_location" . ,(url->string (request-uri req))) - ("new_settings" . ,(format "~a" new-settings)))))) diff --git a/src/dispatcher-tree.rkt b/src/dispatcher-tree.rkt index 251aa43..9e072bc 100644 --- a/src/dispatcher-tree.rkt +++ b/src/dispatcher-tree.rkt @@ -3,7 +3,6 @@ (for-syntax racket/base) racket/string net/url - web-server/http (prefix-in host: web-server/dispatchers/dispatch-host) (prefix-in pathprocedure: web-server/dispatchers/dispatch-pathprocedure) (prefix-in sequencer: web-server/dispatchers/dispatch-sequencer) @@ -33,18 +32,23 @@ (datum->syntax stx `(make-dispatcher-tree ,ds))) (define (make-dispatcher-tree ds) - (define subdomain-dispatcher (hash-ref ds 'subdomain-dispatcher)) - (sequencer:make - subdomain-dispatcher - (pathprocedure:make "/" (hash-ref ds 'page-home)) - (pathprocedure:make "/proxy" (hash-ref ds 'page-proxy)) - (pathprocedure:make "/search" (hash-ref ds 'page-global-search)) - (pathprocedure:make "/set-user-settings" (hash-ref ds 'page-set-user-settings)) - (pathprocedure:make "/buddyfight/wiki/It_Doesn't_Work!!" (hash-ref ds 'page-it-works)) - (filter:make (pregexp (format "^/~a/wiki/Category:.+$" px-wikiname)) (lift:make (hash-ref ds 'page-category))) - (filter:make (pregexp (format "^/~a/wiki/File:.+$" px-wikiname)) (lift:make (hash-ref ds 'page-file))) - (filter:make (pregexp (format "^/~a/wiki/.+$" px-wikiname)) (lift:make (hash-ref ds 'page-wiki))) - (filter:make (pregexp (format "^/~a/search$" px-wikiname)) (lift:make (hash-ref ds 'page-search))) - (filter:make (pregexp (format "^/~a(/(wiki(/)?)?)?$" px-wikiname)) (lift:make (hash-ref ds 'redirect-wiki-home))) - (hash-ref ds 'static-dispatcher) - (lift:make (hash-ref ds 'page-not-found)))) + (host:make + (λ (host-sym) + (if/out (config-true? 'canonical_origin) + (let* ([host-header (symbol->string host-sym)] + [splitter (string-append "." (url-host (string->url (config-get 'canonical_origin))))] + [s (string-split host-header splitter #:trim? #f)]) + (if/in (and (eq? 2 (length s)) (equal? "" (cadr s))) + ((hash-ref ds 'subdomain-dispatcher) (car s)))) + (sequencer:make + (pathprocedure:make "/" (hash-ref ds 'page-home)) + (pathprocedure:make "/proxy" (hash-ref ds 'page-proxy)) + (pathprocedure:make "/search" (hash-ref ds 'page-global-search)) + (pathprocedure:make "/buddyfight/wiki/It_Doesn't_Work!!" (hash-ref ds 'page-it-works)) + (filter:make (pregexp (format "^/~a/wiki/Category:.+$" px-wikiname)) (lift:make (hash-ref ds 'page-category))) + (filter:make (pregexp (format "^/~a/wiki/File:.+$" px-wikiname)) (lift:make (hash-ref ds 'page-file))) + (filter:make (pregexp (format "^/~a/wiki/.+$" px-wikiname)) (lift:make (hash-ref ds 'page-wiki))) + (filter:make (pregexp (format "^/~a/search$" px-wikiname)) (lift:make (hash-ref ds 'page-search))) + (filter:make (pregexp (format "^/~a(/(wiki(/)?)?)?$" px-wikiname)) (lift:make (hash-ref ds 'redirect-wiki-home))) + (hash-ref ds 'static-dispatcher) + (lift:make (hash-ref ds 'page-not-found))))))) diff --git a/src/niwa-data.rkt b/src/niwa-data.rkt deleted file mode 100644 index a1036af..0000000 --- a/src/niwa-data.rkt +++ /dev/null @@ -1,156 +0,0 @@ -#lang racket/base - -(provide - niwa-data) - -;; wikiname, niwa-name, url, logo-url -(define niwa-data - '((("arms" "armsgame") - "ARMS Institute" - "https://armswiki.org/wiki/Home" - "/images/logos/armswiki.png" - "ARMS Institute is a comprehensive resource for information about the Nintendo Switch game, ARMS. Founded on May 1, 2017 and growing rapidly, the wiki strives to offer in-depth coverage of ARMS from both a competitive and casual perspective. Join us and ARM yourself with knowledge!") - (("pokemon" "monster") - "Bulbapedia" - "https://bulbapedia.bulbagarden.net/wiki/Main_Page" - "/images/logos/bulbapedia.png" - "A part of the Bulbagarden community, Bulbapedia was founded on December 21, 2004 by Liam Pomfret. Everything you need to know about Pokémon can be found at Bulbapedia, whether about the games, the anime, the manga, or something else entirely. With its Bulbanews section and the Bulbagarden forums, it's your one-stop online place for Pokémon.") - (("dragalialost") - "Dragalia Lost Wiki" - "https://dragalialost.wiki/w/Dragalia_Lost_Wiki" - "/images/logos/dragalialost.png" - "The Dragalia Lost Wiki was originally founded in September 2018 on the Gamepedia platform but went independent in January 2021. The Wiki aims to document anything and everything Dragalia Lost, from in-game data to mechanics, story, guides, and more!") - (("dragonquest") - "Dragon Quest Wiki" - "https://dragon-quest.org/wiki/Main_Page" - "/images/logos/dragonquestwiki.png" - "Originally founded on Wikia, the Dragon Quest Wiki was largely inactive until FlyingRagnar became an admin in late 2009. The wiki went independent about a year later when it merged with the Dragon Quest Dictionary/Encyclopedia which was run by Zenithian and supported by the Dragon's Den. The Dragon Quest Wiki aims to be the most complete resource for Dragon Quest information on the web. It continues to grow in the hope that one day the series will be as popular in the rest of the world as it is in Japan.") - (("fireemblem") - "Fire Emblem Wiki" - "https://fireemblemwiki.org/wiki/Main_Page" - "/images/logos/fireemblemwiki.png" - "Growing since August 26, 2010, Fire Emblem Wiki is a project whose goal is to cover all information pertaining to the Fire Emblem series. It aspires to become the most complete and accurate independent source of information on this series.") - (("fzero" "f-zero") - "F-Zero Wiki" - "https://mutecity.org/wiki/F-Zero_Wiki" - "/images/logos/fzerowiki.png" - "Founded on Wikia in November 2007, F-Zero Wiki became independent with NIWA's help in 2011. F-Zero Wiki is quickly growing into the Internet's definitive source for the world of 2200 km/h+, from pilots to machines, and is the founding part of MuteCity.org, the web's first major F-Zero community.") - (("goldensun") - "Golden Sun Universe" - "https://www.goldensunwiki.net/wiki/Main_Page" - "/images/logos/goldensununiverse.png" - "Originally founded on Wikia in late 2006, Golden Sun Universe has always worked hard to meet one particular goal: to be the single most comprehensive yet accessible resource on the Internet for Nintendo's RPG series Golden Sun. It became an independent wiki four years later. Covering characters and plot, documenting all aspects of the gameplay, featuring walkthroughs both thorough and bare-bones, and packed with all manner of odd and fascinating minutiae, Golden Sun Universe leaves no stone unturned!") - (("tetris") - "Hard Drop - Tetris Wiki" - "https://harddrop.com/wiki/Main_Page" - "/images/logos/harddrop.png" - "The Tetris Wiki was founded by Tetris fans for Tetris fans on tetrisconcept.com in March 2006. The Tetris Wiki torch was passed to harddrop.com in July 2009. Hard Drop is a Tetris community for all Tetris players, regardless of skill or what version of Tetris you play.") - (("kidicarus") - "Icaruspedia" - "https://www.kidicaruswiki.org/wiki/Main_Page" - "/images/logos/icaruspedia.png" - "Icaruspedia is the Kid Icarus wiki that keeps flying to new heights. After going independent on January 8, 2012, Icaruspedia has worked to become the largest and most trusted independent source of Kid Icarus information. Just like Pit, they'll keep on fighting until the job is done.") - (("splatoon" "uk-splatoon" "splatoon3" "splatoon2") - "Inkipedia" - "https://splatoonwiki.org/wiki/Main_Page" - "/images/logos/inkipedia.png" - "Inkipedia is your ever-growing go-to source for all things Splatoon related. Though founded on Wikia on June 10, 2014, Inkipedia went independent on May 18, 2015, just days before Splatoon's release. Our aim is to cover all aspects of the series, both high and low. Come splat with us now!") - (("starfox") - "Lylat Wiki" - "https://starfoxwiki.info/wiki/Lylat_Wiki" - "/images/logos/lylatwiki.png" - "Out of seemingly nowhere, Lylat Wiki sprung up one day in early 2010. Led by creator, Justin Folvarcik, and project head, Tacopill, the wiki has reached stability since the move to its own domain. The staff of Lylat Wiki are glad to help out the NIWA wikis and are even prouder to join NIWA's ranks as the source for information on the Star Fox series.") - (("metroid" "themetroid") - "Metroid Wiki" - "https://www.metroidwiki.org/wiki/Main_Page" - "/images/logos/metroidwiki.png" - "Metroid Wiki, founded on January 27, 2010 by Nathanial Rumphol-Janc and Zelda Informer, is a rapidly expanding wiki that covers everything Metroid, from the games, to every suit, vehicle and weapon.") - (("nintendo" "nintendoseries" "nintendogames") - "Nintendo Wiki" - "http://niwanetwork.org/wiki/Main_Page" - "/images/logos/nintendowiki.png" - "Created on May 12, 2010, NintendoWiki (N-Wiki) is a collaborative project by the NIWA team to create an encyclopedia dedicated to Nintendo, being the company around which all other NIWA content is focused. It ranges from mainstream information such as the games and people who work for the company, to the most obscure info like patents and interesting trivia.") - (("animalcrossing" "animalcrossingcf" "acnh") - "Nookipedia" - "https://nookipedia.com/wiki/Main_Page" - "/images/logos/nookipedia.png" - "Founded in August 2005 on Wikia, Nookipedia was originally known as Animal Crossing City. Shortly after its five-year anniversary, Animal Crossing City decided to merge with the independent Animal Crossing Wiki, which in January 2011 was renamed to Nookipedia. Covering everything from the series including characters, items, critters, and much more, Nookipedia is your number one resource for everything Animal Crossing!") - (("pikmin") - "Pikipedia" - "https://www.pikminwiki.com/" - "/images/logos/pikipedia.png" - "Pikipedia, also known as Pikmin Wiki, was founded by Dark Lord Revan on Wikia in December 2005. In September 2010, with NIWA's help, Pikipedia moved away from Wikia to become independent. Pikipedia is working towards their goal of being the foremost source for everything Pikmin.") - (("pikmin-fan" "pikpikpedia") - "Pimkin Fanon" - "https://www.pikminfanon.com/wiki/Main_Page" - "/images/logos/pikifanon.png" - "Pikmin Fanon is a Pikmin wiki for fan stories (fanon). Founded back on November 1, 2008 by Rocky0718 as a part of Wikia, Pikmin Fanon has been independent since September 14, 2010. Check them out for fan created stories based around the Pikmin series.") - (("supersmashbros") - "SmashWiki" - "https://www.ssbwiki.com/" - "/images/logos/smashwiki.png" - "Originally two separate wikis (one on SmashBoards, the other on Wikia), SmashWiki as we know it was formed out of a merge on February 29th, 2008, becoming independent on September 28th, 2010. SmashWiki is the premier source of Smash Bros. information, from simple tidbits to detailed mechanics, and also touches on the origins of its wealth of content from its sibling franchises.") - (("starfy") - "Starfy Wiki" - "https://www.starfywiki.org/wiki/Main_Page" - "/images/logos/starfywiki.png" - "Founded on May 30, 2009, Starfy Wiki's one goal is to become the best source on Nintendo's elusive game series The Legendary Starfy. After gaining independence in 2011 with the help of Tappy and the wiki's original administrative team, the wiki still hopes to achieve its goal and be the best source of Starfy info for all present and future fans.") - (() - "StrategyWiki" - "https://www.strategywiki.org/wiki/Main_Page" - "/images/logos/strategywiki.png" - "StrategyWiki was founded in December 2005 by former member Brandon Suit with the idea that the existing strategy guides on the Internet could be improved. Three years later, in December 2008, Scott Jacobi officially established Abxy LLC for the purpose of owning and operating StrategyWiki as a community. Their vision is to bring free, collaborative video game strategy guides to the masses, including Nintendo franchise strategy guides.") - (("mario" "themario" "imario" "supermarionintendo" "mariokart" "luigi-kart" "mario3") - "Super Mario Wiki" - "https://www.mariowiki.com/" - "/images/logos/mariowiki.png" - "Online since August 12, 2005, when it was founded by Steve Shinn, Super Mario Wiki has you covered for anything Mario, Donkey Kong, Wario, Luigi, Yoshi—the whole gang, in fact. With its own large community in its accompanying forum, Super Mario Wiki is not only a great encyclopedia, but a fansite for you to talk anything Mario.") - (("mario64") - "Ukikipedia" - "https://ukikipedia.net/wiki/Main_Page" - "/images/logos/ukikipedia.png" - "Founded in 2018, Ukikipedia is a wiki focused on expert level knowledge of Super Mario 64, including detailed coverage of game mechanics, glitches, speedrunning, and challenges.") - (("advancewars") - "Wars Wiki" - "https://www.warswiki.org/wiki/Main_Page" - "/images/logos/warswiki.png" - "Created in February 2009, Wars Wiki is a small wiki community with a large heart. Founded by JoJo and Wars Central, Wars Wiki is going strong on one of Nintendo's lesser known franchises. Wars Wiki is keen to contribute to NIWA, and we're proud to be able to support them. With the Wars Central community, including forums, it's definitely worth checking out.") - (("earthbound") - "WikiBound" - "https://www.wikibound.info/wiki/WikiBound" - "/images/logos/wikibound.png" - "Founded in early 2010 by Tacopill, WikiBound strives to create a detailed database on the Mother/EarthBound games, a quaint series only having two games officially released outside of Japan. Help spread the PK Love by editing WikiBound!") - (("kirby") - "WiKirby" - "https://wikirby.com/wiki/Kirby_Wiki" - "/images/logos/wikirby.png" - "WiKirby. It's a wiki. About Kirby! Amidst the excitement of NIWA being founded, Josh LeJeune decided to create a Kirby Wiki, due to lack of a strong independent one online. Coming online on January 24, 2010, WiKirby continues its strong launch with a dedicated community and a daily growing source of Kirby based knowledge.") - (("xenoblade" "xenoseries" "xenogears" "xenosaga") - "Xeno Series Wiki" - "https://www.xenoserieswiki.org/wiki/Main_Page" - "/images/logos/xenoserieswiki.png" - "Xeno Series Wiki was created February 4, 2020 by Sir Teatei Moonlight. While founded by the desire to have an independent wiki for Xenoblade, there was an interest in including the Xenogears and Xenosaga games within its focus as well. This wide range of coverage means it's always in need of new editors to help bolster its many subjects.") - (("zelda" "zelda-archive") - "Zeldapedia" - "https://zeldapedia.wiki/wiki/Main_Page" - "/images/logos/zeldapedia.png" - "Founded on April 23, 2005 as Zelda Wiki, today's Zeldapedia is your definitive source for encyclopedic information on The Legend of Zelda series, as well as all of the latest Zelda news."))) - -;; get the current dataset so it can be stored above -(module+ fetch - (require racket/generator - racket/list - net/http-easy - html-parsing - "xexpr-utils.rkt") - (define r (get "https://www.niwanetwork.org/members/")) - (define x (html->xexp (bytes->string/utf-8 (response-body r)))) - (define english ((query-selector (λ (e a c) (equal? (get-attribute 'id a) "content1")) x))) - (define gen (query-selector (λ (e a c) (has-class? "member" a)) english)) - (for/list ([item (in-producer gen #f)]) - (define links (query-selector (λ (e a c) (eq? e 'a)) item)) - (define url (get-attribute 'href (bits->attributes (links)))) - (define title (third (links))) - (define icon (get-attribute 'src (bits->attributes ((query-selector (λ (e a c) (eq? e 'img)) item))))) - (define description (second ((query-selector (λ (e a c) (eq? e 'p)) item)))) - (list '() title url icon description))) diff --git a/src/page-category.rkt b/src/page-category.rkt index 62b7f38..6c0a733 100644 --- a/src/page-category.rkt +++ b/src/page-category.rkt @@ -24,27 +24,24 @@ page-category) (module+ test - (require rackunit - "test-utils.rkt") + (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"))))))))) (define (generate-results-page - #:req req #:source-url source-url #:wikiname wikiname #:title title #:members-data members-data #:page page - #:head-data [head-data #f] + #:body-class [body-class #f] #:siteinfo [siteinfo #f]) (define members (jp "/query/categorymembers" members-data)) (generate-wiki-page - #:req req #:source-url source-url #:wikiname wikiname #:title title - #:head-data head-data + #:body-class body-class #:siteinfo siteinfo `(div ,(update-tree-wiki page wikiname) @@ -55,7 +52,7 @@ ,@(map (λ (result) (define title (jp "/title" result)) - (define page-path (page-title->path title)) + (define page-path (regexp-replace* #rx" " title "_")) `(li (a (@ (href ,(format "/~a/wiki/~a" wikiname page-path))) ,title))) @@ -97,15 +94,17 @@ (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 head-html (jp "/parse/headhtml" page-data "")) + (define body-class (match (regexp-match #rx"]*class=\"([^\"]*)" head-html) + [(list _ classes) classes] + [_ ""])) (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 + #:body-class body-class #:siteinfo siteinfo)) (when (config-true? 'debug) @@ -120,7 +119,6 @@ (module+ test (check-not-false ((query-selector (attribute-selector 'href "/test/wiki/Ankle_Monitor") (generate-results-page - #:req test-req #:source-url "" #:wikiname "test" #:title "Category:Items" diff --git a/src/page-file.rkt b/src/page-file.rkt index d999ba4..1802568 100644 --- a/src/page-file.rkt +++ b/src/page-file.rkt @@ -23,8 +23,7 @@ (provide page-file) (module+ test - (require rackunit - "test-utils.rkt") + (require rackunit) (define test-media-detail '#hasheq((fileTitle . "Example file") (videoEmbedCode . "") @@ -52,8 +51,7 @@ [(regexp-match? #rx"(?i:^video/)" content-type) `(video (@ (src ,maybe-proxied-url) (controls)))] [else `""])) -(define (generate-results-page #:req req - #:source-url source-url +(define (generate-results-page #:source-url source-url #:wikiname wikiname #:title title #:media-detail media-detail @@ -70,7 +68,6 @@ (define maybe-proxied-raw-image-url (if (config-true? 'strict_proxy) (u-proxy-url raw-image-url) raw-image-url)) (generate-wiki-page - #:req req #:source-url source-url #:wikiname wikiname #:title title @@ -128,8 +125,7 @@ #f (url-content-type (jp "/imageUrl" media-detail)))) (define body - (generate-results-page #:req req - #:source-url source-url + (generate-results-page #:source-url source-url #:wikiname wikiname #:title title #:media-detail media-detail @@ -163,8 +159,7 @@ (check-not-false ((query-selector (attribute-selector 'src "/proxy?dest=https%3A%2F%2Fstatic.wikia.nocookie.net%2Fexamplefile") - (generate-results-page #:req test-req - #:source-url "" + (generate-results-page #:source-url "" #:wikiname "test" #:title "File:Example file" #:media-detail test-media-detail diff --git a/src/page-global-search.rkt b/src/page-global-search.rkt index a9c79bb..4364dea 100644 --- a/src/page-global-search.rkt +++ b/src/page-global-search.rkt @@ -4,7 +4,6 @@ net/url web-server/http "application-globals.rkt" - "data.rkt" "url-utils.rkt" "xexpr-utils.rkt") @@ -15,18 +14,12 @@ (define wikiname (dict-ref (url-query (request-uri req)) 'wikiname #f)) (define q (dict-ref (url-query (request-uri req)) 'q #f)) (response-handler - (cond - [(not wikiname) - (response/output - #:code 400 - #:mime-type "text/plain" - (λ (out) - (displayln "Requires wikiname and q parameters." out)))] - [(or (not q) (equal? q "")) - (define siteinfo (siteinfo-fetch wikiname)) - (define dest (format "/~a/wiki/~a" wikiname (or (siteinfo^-basepage siteinfo) "Main_Page"))) - (generate-redirect dest)] - [#t - (generate-redirect (format "/~a/search?~a" - wikiname - (params->query `(("q" . ,q)))))]))) + (if (not (and wikiname q)) + (response/output + #:code 400 + #:mime-type "text/plain" + (λ (out) + (displayln "Requires wikiname and q parameters." out))) + (generate-redirect (format "/~a/search?~a" + wikiname + (params->query `(("q" . ,q)))))))) diff --git a/src/page-home.rkt b/src/page-home.rkt index 23ede8b..86c316d 100644 --- a/src/page-home.rkt +++ b/src/page-home.rkt @@ -4,8 +4,6 @@ html-writing web-server/http "application-globals.rkt" - "data.rkt" - "static-data.rkt" "url-utils.rkt" "xexpr-utils.rkt" "config.rkt") @@ -17,11 +15,13 @@ (require rackunit)) (define examples - '(("minecraft" "Bricks") - ("crosscode" "CrossCode Wiki") - ("undertale" "Hot Dog...?") - ("tardis" "Eleanor Blake") - ("zelda" "Boomerang"))) + '(("crosscode" "CrossCode_Wiki") + ("pokemon" "Eevee") + ("minecraft" "Bricks") + ("undertale" "Hot_Dog...%3F") + ("tardis" "Eleanor_Blake") + ("fireemblem" "God-Shattering_Star") + ("fallout" "Pip-Boy_3000"))) (define content `((h2 "BreezeWiki makes wiki pages on Fandom readable") @@ -40,12 +40,12 @@ (input (@ (name "wikiname") (class "paired__input") (type "text") (placeholder "pokemon") (required)))) (label (@ (class "paired__label")) "Search query" - (input (@ (name "q") (class "paired__input") (type "text") (placeholder "Eevee")))) + (input (@ (name "q") (class "paired__input") (type "text") (placeholder "Eevee") (required)))) (button "Search")) (h2 "Example pages") (ul ,@(map (λ (x) - `(li (a (@ (href ,(format "/~a/wiki/~a" (car x) (page-title->path (cadr x))))) + `(li (a (@ (href ,(apply format "/~a/wiki/~a" x))) ,(apply format "~a: ~a" x)))) examples)) (h2 "Testimonials") @@ -53,34 +53,29 @@ (p (@ (class "testimonial")) ">you are so right that fandom still sucks even with adblock somehow. even zapping all the stupid padding it still sucks —Minimus") (p (@ (class "testimonial")) ">attempting to go to a wiki's forum page with breezewiki doesn't work, which is based honestly —Tom Skeleton") (p (@ (class "testimonial")) ">Fandom pages crashing and closing, taking forever to load and locking up as they load the ads on the site... they are causing the site to crash because they are trying to load video ads both at the top and bottom of the site as well as two or three banner ads, then a massive top of site ad and eventually my anti-virus shuts the whole site down because it's literally pulling more resources than WoW in ultra settings... —Anonymous") - (p (@ (class "testimonial")) ">reblogs EXTREMELY appreciated I want that twink* (*fandom wiki) obliterated —footlong") - (h2 "What BreezeWiki isn't") (p "BreezeWiki isn't an \"alternative\" to Fandom, and it doesn't let you edit or write new pages.") (p "If you want to create your own wiki, try Miraheze!"))) (define body - `(*TOP* - (*DECL* DOCTYPE html) - (html - (head - (meta (@ (name "viewport") (content "width=device-width, initial-scale=1"))) - (title "About | BreezeWiki") - (link (@ (rel "stylesheet") (type "text/css") (href ,(get-static-url "internal.css")))) - (link (@ (rel "stylesheet") (type "text/css") (href ,(get-static-url "main.css")))) - (link (@ (rel "icon") (href ,(head-data^-icon-url head-data-default))))) - (body (@ (class "skin-fandomdesktop theme-fandomdesktop-light internal")) - (div (@ (class "main-container")) - (div (@ (class "fandom-community-header__background tileBoth header"))) - (div (@ (class "page")) - (main (@ (class "page__main")) - (div (@ (class "custom-top")) - (h1 (@ (class "page-title")) - "About BreezeWiki")) - (div (@ (id "content") #;(class "page-content")) - (div (@ (id "mw-content-text")) - ,@content)) - ,(application-footer #f)))))))) + `(html + (head + (meta (@ (name "viewport") (content "width=device-width, initial-scale=1"))) + (title "About | BreezeWiki") + (link (@ (rel "stylesheet") (type "text/css") (href "/static/internal.css"))) + (link (@ (rel "stylesheet") (type "text/css") (href "/static/main.css")))) + (body (@ (class "skin-fandomdesktop theme-fandomdesktop-light internal")) + (div (@ (class "main-container")) + (div (@ (class "fandom-community-header__background tileBoth header"))) + (div (@ (class "page")) + (main (@ (class "page__main")) + (div (@ (class "custom-top")) + (h1 (@ (class "page-title")) + "About BreezeWiki")) + (div (@ (id "content") #;(class "page-content")) + (div (@ (id "mw-content-text")) + ,@content)) + ,(application-footer #f))))))) (module+ test (check-not-false (xexp->html body))) diff --git a/src/page-search.rkt b/src/page-search.rkt index 10ff66c..81a88b2 100644 --- a/src/page-search.rkt +++ b/src/page-search.rkt @@ -21,18 +21,16 @@ page-search) (module+ test - (require rackunit - "test-utils.rkt") + (require rackunit) (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))))))))) -(define (generate-results-page req dest-url wikiname query data #:siteinfo [siteinfo #f]) +(define (generate-results-page dest-url wikiname query data #:siteinfo [siteinfo #f]) (define search-results (jp "/query/search" data)) (generate-wiki-page - #:req req #:source-url dest-url #:wikiname wikiname - #:title query + #:title "Search Results" #:siteinfo siteinfo `(div (@ (class "mw-parser-output")) (p ,(format "~a results found for " (length search-results)) @@ -40,7 +38,7 @@ (ul ,@(map (λ (result) (let* ([title (jp "/title" result)] - [page-path (page-title->path title)] + [page-path (regexp-replace* #rx" " title "_")] [timestamp (jp "/timestamp" result)] [wordcount (jp "/wordcount" result)] [size (jp "/size" result)]) @@ -76,7 +74,7 @@ (define data (easy:response-json dest-res)) - (define body (generate-results-page req dest-url wikiname query data #:siteinfo siteinfo)) + (define body (generate-results-page dest-url wikiname query data #:siteinfo siteinfo)) (when (config-true? 'debug) ; used for its side effects ; convert to string with error checking, error will be raised if xexp is invalid @@ -88,4 +86,4 @@ (write-html body out)))))) (module+ test (check-not-false ((query-selector (attribute-selector 'href "/test/wiki/Gacha_Capsule") - (generate-results-page test-req "" "test" "Gacha" search-json-data))))) + (generate-results-page "" "test" "Gacha" search-json-data))))) diff --git a/src/page-set-user-settings.rkt b/src/page-set-user-settings.rkt deleted file mode 100644 index 2fbc573..0000000 --- a/src/page-set-user-settings.rkt +++ /dev/null @@ -1,18 +0,0 @@ -#lang racket/base -(require racket/dict - net/url - web-server/http - "application-globals.rkt" - "data.rkt" - "url-utils.rkt" - "xexpr-utils.rkt") - -(provide - page-set-user-settings) - -(define (page-set-user-settings req) - (response-handler - (define next-location (dict-ref (url-query (request-uri req)) 'next_location)) - (define new-settings (read (open-input-string (dict-ref (url-query (request-uri req)) 'new_settings)))) - (define headers (user-cookies-setter new-settings)) - (generate-redirect next-location #:headers headers))) diff --git a/src/page-static.rkt b/src/page-static.rkt index 2bf684c..353a0f8 100644 --- a/src/page-static.rkt +++ b/src/page-static.rkt @@ -22,7 +22,6 @@ #".js" #"text/javascript" #".png" #"image/png" #".svg" #"image/svg+xml" - #".woff2" #"font/woff2" #".txt" #"text/plain")) (define (ext->mime-type ext) @@ -65,7 +64,5 @@ ((files:make #:url->path (lambda (u) ((make-url->path path-static) u)) #:path->mime-type (lambda (u) (ext->mime-type (path-get-extension u))) - #:cache-no-cache (config-true? 'debug) - #:cache-immutable (not (config-true? 'debug)) - #:cache-max-age (if (config-true? 'debug) #f 604800)) + #:cache-no-cache (config-true? 'debug) #;"browser applies heuristics if unset") conn new-req)) diff --git a/src/page-subdomain.rkt b/src/page-subdomain.rkt index c254236..dededfb 100644 --- a/src/page-subdomain.rkt +++ b/src/page-subdomain.rkt @@ -1,65 +1,22 @@ #lang racket/base -(require racket/match - racket/path +(require racket/path racket/string net/url web-server/http - web-server/dispatchers/dispatch - (only-in racket/promise delay) (prefix-in lift: web-server/dispatchers/dispatch-lift) "application-globals.rkt" "config.rkt" - "syntax.rkt" "xexpr-utils.rkt") (provide subdomain-dispatcher) -(module+ test - (require rackunit)) - -(define (do-redirect:make subdomain canonical-origin) +(define (subdomain-dispatcher subdomain) (lift:make (λ (req) (response-handler (define uri (request-uri req)) (define path (url-path uri)) (define path-string (string-join (map (λ (p) (path/param-path p)) path) "/")) - (define dest (format "~a/~a/~a" canonical-origin subdomain path-string)) + (define dest (format "~a/~a/~a" (config-get 'canonical_origin) subdomain path-string)) (generate-redirect dest))))) - -(define (router req) - (define host (bytes->string/utf-8 (header-value (headers-assq* #"host" (request-headers/raw req))))) - (define x-canonical-origin (headers-assq* #"x-canonical-origin" (request-headers/raw req))) - (define canonical-origin - (cond - [x-canonical-origin (bytes->string/utf-8 (header-value x-canonical-origin))] - [(config-true? 'canonical_origin) (config-get 'canonical_origin)] - [#t #f])) - (if/out canonical-origin - (let* ([canonical-origin-host (url-host (string->url canonical-origin))]) - (if/in canonical-origin-host - (let* ([splitter (string-append "." (url-host (string->url canonical-origin)))] - [s (string-split host splitter #:trim? #f)]) - (if/in (and (eq? 2 (length s)) (equal? "" (cadr s))) - (list 'redirect (car s) canonical-origin))))) - 'next-dispatcher)) -(module+ test - (define (qr url headers) - (request #"GET" (string->url url) (map (λ (h) (header (car h) (cadr h))) headers) (delay '()) #f "127.0.0.1" 10416 "127.0.0.1")) - (parameterize ([(config-parameter 'canonical_origin) "https://breezewiki.com"]) - (check-equal? (router (qr "/" '((#"Host" #"breezewiki.com")))) - 'next-dispatcher) - (check-equal? (router (qr "/wiki/Spell" '((#"Host" #"magic.breezewiki.com")))) - '(redirect "magic" "https://breezewiki.com")) - (check-equal? (router (qr "/" '((#"Host" #"magic.bw.breezewiki.com") - (#"X-Canonical-Origin" #"https://bw.breezewiki.com")))) - '(redirect "magic" "https://bw.breezewiki.com")) - (check-equal? (router (qr "/" '((#"Host" #"magic.bwxxxxx.onion") - (#"X-Canonical-Origin" #"http://bwxxxxx.onion")))) - '(redirect "magic" "http://bwxxxxx.onion")))) - -(define (subdomain-dispatcher conn req) - (match (router req) - [(list 'redirect subdomain canonical-origin) ((do-redirect:make subdomain canonical-origin) conn req)] - [_ (next-dispatcher)])) diff --git a/src/page-wiki.rkt b/src/page-wiki.rkt index e41b093..c16153b 100644 --- a/src/page-wiki.rkt +++ b/src/page-wiki.rkt @@ -19,7 +19,6 @@ "data.rkt" "pure-utils.rkt" "syntax.rkt" - "tree-updater.rkt" "xexpr-utils.rkt" "url-utils.rkt") @@ -31,19 +30,56 @@ preprocess-html-wiki) (module+ test - (require rackunit)) + (require rackunit) + (define wiki-document + '(*TOP* + (div (@ (class "mw-parser-output")) + (aside (@ (role "region") (class "portable-infobox pi-theme-wikia pi-layout-default")) + (h2 (@ (class "pi-item pi-title") (data-source "title")) + "Infobox Title") + (figure (@ (class "pi-item pi-image") (data-source "image")) + (a (@ (href "https://static.wikia.nocookie.net/nice-image.png") (class "image image-thumbnail") (title "")) + (img (@ (src "https://static.wikia.nocookie.net/nice-image-thumbnail.png") (class "pi-image-thumbnail"))))) + (div (@ (class "pi-item pi-data") (data-source "description")) + (h3 (@ (class "pi-data-label")) + "Description") + (div (@ (class "pi-data-value")) + "Mystery infobox!"))) + (div (@ (data-test-collapsesection) (class "collapsible collapsetoggle-inline collapsed")) + (i (b "This section is hidden for dramatic effect.")) + (div (@ (class "collapsible-content")) + (p "Another page link: " + (a (@ (data-test-wikilink) (href "https://test.fandom.com/wiki/Another_Page") (title "Another Page")) + "Another Page")))) + (figure (@ (class "thumb tnone")) + (a (@ (href "https://static.wikia.nocookie.net/nice-image.png") (class "image") (data-test-figure-a)) + (img (@ (src "data:image/gif;base64,R0lGODlhAQABAIABAAAAAP///yH5BAEAAAEALAAAAAABAAEAQAICTAEAOw%3D%3D") + (data-src "https://static.wikia.nocookie.net/nice-image-thumbnail.png") + (class "thumbimage lazyload")))) + (noscript + (a (@ (href "https://static.wikia.nocookie.net/nice-image.png") (title "a nice image") (three-attribs)) + (img (@ (src "https://static.wikia.nocookie.net/nice-image-thumbnail.png") + (data-src "https://static.wikia.nocookie.net/nice-image-thumbnail.png") + (class "thumbimage"))))) + (noscript + (a (@ (href "https://static.wikia.nocookie.net/nice-image.png")) + (img (@ (src "https://static.wikia.nocookie.net/nice-image-thumbnail.png") + (data-src "https://static.wikia.nocookie.net/nice-image-thumbnail.png") + (class "thumbimage"))))) + (figcaption "Test figure!")) + (iframe (@ (src "https://example.com/iframe-src"))))))) (define (preprocess-html-wiki html) - (define ((rr* find replace) contents) + (define (rr* find replace contents) (regexp-replace* find contents replace)) ((compose1 ; fix navbox list nesting ; navbox on right of page has incorrect html "
  • " and the xexpr parser puts the
  • much further up the tree ; add a