forked from cadence/breezewiki
		
	Add support for File: pages
Fixes https://lists.sr.ht/~cadence/breezewiki-discuss/%3Cb2835a70-5118-4df0-90c9-4333486a4b69%40nixnetmail.com%3E
This commit is contained in:
		
							parent
							
								
									5813c49261
								
							
						
					
					
						commit
						07074dccfc
					
				
					 4 changed files with 171 additions and 0 deletions
				
			
		| 
						 | 
					@ -19,6 +19,7 @@
 | 
				
			||||||
(require-reloadable "src/page-static.rkt" static-dispatcher)
 | 
					(require-reloadable "src/page-static.rkt" static-dispatcher)
 | 
				
			||||||
(require-reloadable "src/page-subdomain.rkt" subdomain-dispatcher)
 | 
					(require-reloadable "src/page-subdomain.rkt" subdomain-dispatcher)
 | 
				
			||||||
(require-reloadable "src/page-wiki.rkt" page-wiki)
 | 
					(require-reloadable "src/page-wiki.rkt" page-wiki)
 | 
				
			||||||
 | 
					(require-reloadable "src/page-file.rkt" page-file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(reload!)
 | 
					(reload!)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +39,7 @@
 | 
				
			||||||
      page-proxy
 | 
					      page-proxy
 | 
				
			||||||
      page-search
 | 
					      page-search
 | 
				
			||||||
      page-wiki
 | 
					      page-wiki
 | 
				
			||||||
 | 
					      page-file
 | 
				
			||||||
      redirect-wiki-home
 | 
					      redirect-wiki-home
 | 
				
			||||||
      static-dispatcher
 | 
					      static-dispatcher
 | 
				
			||||||
      subdomain-dispatcher))))
 | 
					      subdomain-dispatcher))))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								dist.rkt
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								dist.rkt
									
										
									
									
									
								
							| 
						 | 
					@ -13,6 +13,7 @@
 | 
				
			||||||
(require (only-in "src/page-static.rkt" static-dispatcher))
 | 
					(require (only-in "src/page-static.rkt" static-dispatcher))
 | 
				
			||||||
(require (only-in "src/page-subdomain.rkt" subdomain-dispatcher))
 | 
					(require (only-in "src/page-subdomain.rkt" subdomain-dispatcher))
 | 
				
			||||||
(require (only-in "src/page-wiki.rkt" page-wiki))
 | 
					(require (only-in "src/page-wiki.rkt" page-wiki))
 | 
				
			||||||
 | 
					(require (only-in "src/page-file.rkt" page-file))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(serve/launch/wait
 | 
					(serve/launch/wait
 | 
				
			||||||
 #:listen-ip (if (config-true? 'debug) "127.0.0.1" #f)
 | 
					 #:listen-ip (if (config-true? 'debug) "127.0.0.1" #f)
 | 
				
			||||||
| 
						 | 
					@ -27,6 +28,7 @@
 | 
				
			||||||
    page-proxy
 | 
					    page-proxy
 | 
				
			||||||
    page-search
 | 
					    page-search
 | 
				
			||||||
    page-wiki
 | 
					    page-wiki
 | 
				
			||||||
 | 
					    page-file
 | 
				
			||||||
    redirect-wiki-home
 | 
					    redirect-wiki-home
 | 
				
			||||||
    static-dispatcher
 | 
					    static-dispatcher
 | 
				
			||||||
    subdomain-dispatcher)))
 | 
					    subdomain-dispatcher)))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,7 @@
 | 
				
			||||||
              (pathprocedure:make "/proxy" (hash-ref ds 'page-proxy))
 | 
					              (pathprocedure:make "/proxy" (hash-ref ds 'page-proxy))
 | 
				
			||||||
              (pathprocedure:make "/search" (hash-ref ds 'page-global-search))
 | 
					              (pathprocedure:make "/search" (hash-ref ds 'page-global-search))
 | 
				
			||||||
              (filter:make (pregexp (format "^/~a/wiki/Category:.+$" px-wikiname)) (lift:make (hash-ref ds 'page-category)))
 | 
					              (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/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/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)))
 | 
					              (filter:make (pregexp (format "^/~a(/(wiki(/)?)?)?$" px-wikiname)) (lift:make (hash-ref ds 'redirect-wiki-home)))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										166
									
								
								src/page-file.rkt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								src/page-file.rkt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,166 @@
 | 
				
			||||||
 | 
					#lang racket/base
 | 
				
			||||||
 | 
					(require racket/dict
 | 
				
			||||||
 | 
					         racket/list
 | 
				
			||||||
 | 
					         racket/match
 | 
				
			||||||
 | 
					         racket/string
 | 
				
			||||||
 | 
					         (prefix-in easy: net/http-easy)
 | 
				
			||||||
 | 
					         ; html libs
 | 
				
			||||||
 | 
					         html-parsing
 | 
				
			||||||
 | 
					         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"
 | 
				
			||||||
 | 
					         "config.rkt"
 | 
				
			||||||
 | 
					         "data.rkt"
 | 
				
			||||||
 | 
					         "page-wiki.rkt"
 | 
				
			||||||
 | 
					         "syntax.rkt"
 | 
				
			||||||
 | 
					         "url-utils.rkt"
 | 
				
			||||||
 | 
					         "xexpr-utils.rkt")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(provide page-file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(module+ test
 | 
				
			||||||
 | 
					  (require rackunit)
 | 
				
			||||||
 | 
					  (define test-media-detail
 | 
				
			||||||
 | 
					    '#hasheq((fileTitle . "Example file")
 | 
				
			||||||
 | 
					             (videoEmbedCode . "")
 | 
				
			||||||
 | 
					             (imageUrl . "https://static.wikia.nocookie.net/examplefile")
 | 
				
			||||||
 | 
					             (rawImageUrl . "https://static.wikia.nocookie.net/examplefile")
 | 
				
			||||||
 | 
					             (userName . "blankie")
 | 
				
			||||||
 | 
					             (isPostedIn . #t)
 | 
				
			||||||
 | 
					             (smallerArticleList . (#hasheq((title . "Example_article")
 | 
				
			||||||
 | 
					                                            (titleText . "Example article"))))
 | 
				
			||||||
 | 
					             (articleListIsSmaller . 0)
 | 
				
			||||||
 | 
					             (exists . #t)
 | 
				
			||||||
 | 
					             (imageDescription . #f))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (url-content-type url)
 | 
				
			||||||
 | 
					  (log-outgoing url)
 | 
				
			||||||
 | 
					  (define dest-res (easy:head url #:timeouts timeouts))
 | 
				
			||||||
 | 
					  (easy:response-headers-ref dest-res 'content-type))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (get-media-html url content-type)
 | 
				
			||||||
 | 
					  (define maybe-proxied-url (if (config-true? 'strict_proxy) (u-proxy-url url) url))
 | 
				
			||||||
 | 
					  (cond
 | 
				
			||||||
 | 
					    [(eq? content-type #f) `""]
 | 
				
			||||||
 | 
					    [(regexp-match? #rx"(?i:^image/)" content-type) `(img (@ (src ,maybe-proxied-url)))]
 | 
				
			||||||
 | 
					    [(regexp-match? #rx"(?i:^audio/|^application/ogg(;|$))" content-type)
 | 
				
			||||||
 | 
					     `(audio (@ (src ,maybe-proxied-url) (controls)))]
 | 
				
			||||||
 | 
					    [(regexp-match? #rx"(?i:^video/)" content-type) `(video (@ (src ,maybe-proxied-url) (controls)))]
 | 
				
			||||||
 | 
					    [else `""]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (generate-results-page #:source-url source-url
 | 
				
			||||||
 | 
					                               #:wikiname wikiname
 | 
				
			||||||
 | 
					                               #:title title
 | 
				
			||||||
 | 
					                               #:media-detail media-detail
 | 
				
			||||||
 | 
					                               #:image-content-type image-content-type
 | 
				
			||||||
 | 
					                               #:siteinfo [siteinfo #f])
 | 
				
			||||||
 | 
					  (define video-embed-code (jp "/videoEmbedCode" media-detail ""))
 | 
				
			||||||
 | 
					  (define raw-image-url (jp "/rawImageUrl" media-detail))
 | 
				
			||||||
 | 
					  (define image-url (jp "/imageUrl" media-detail raw-image-url))
 | 
				
			||||||
 | 
					  (define username (jp "/userName" media-detail))
 | 
				
			||||||
 | 
					  (define is-posted-in (jp "/isPostedIn" media-detail #f))
 | 
				
			||||||
 | 
					  (define smaller-article-list (jp "/smallerArticleList" media-detail))
 | 
				
			||||||
 | 
					  (define article-list-is-smaller (jp "/articleListIsSmaller" media-detail))
 | 
				
			||||||
 | 
					  (define image-description (jp "/imageDescription" media-detail #f))
 | 
				
			||||||
 | 
					  (define maybe-proxied-raw-image-url
 | 
				
			||||||
 | 
					    (if (config-true? 'strict_proxy) (u-proxy-url raw-image-url) raw-image-url))
 | 
				
			||||||
 | 
					  (generate-wiki-page
 | 
				
			||||||
 | 
					   #:source-url source-url
 | 
				
			||||||
 | 
					   #:wikiname wikiname
 | 
				
			||||||
 | 
					   #:title title
 | 
				
			||||||
 | 
					   #:siteinfo siteinfo
 | 
				
			||||||
 | 
					   `(div ,(if (non-empty-string? video-embed-code)
 | 
				
			||||||
 | 
					              (update-tree-wiki (html->xexp (preprocess-html-wiki video-embed-code)) wikiname)
 | 
				
			||||||
 | 
					              (get-media-html image-url image-content-type))
 | 
				
			||||||
 | 
					         (p ,(if (non-empty-string? video-embed-code)
 | 
				
			||||||
 | 
					                 `""
 | 
				
			||||||
 | 
					                 `(span (a (@ (href ,maybe-proxied-raw-image-url)) "View original file") ". "))
 | 
				
			||||||
 | 
					            "Added by "
 | 
				
			||||||
 | 
					            (a (@ (href ,(format "/~a/wiki/User:~a" wikiname username))) ,username)
 | 
				
			||||||
 | 
					            "."
 | 
				
			||||||
 | 
					            ,(if is-posted-in
 | 
				
			||||||
 | 
					                 `(span " Posted in "
 | 
				
			||||||
 | 
					                        ,@(map (λ (article)
 | 
				
			||||||
 | 
					                                 (define page-path (jp "/title" article))
 | 
				
			||||||
 | 
					                                 (define title (jp "/titleText" article page-path))
 | 
				
			||||||
 | 
					                                 `(span ,(if (eq? (car smaller-article-list) article) "" ", ")
 | 
				
			||||||
 | 
					                                        (a (@ (href ,(format "/~a/wiki/~a" wikiname page-path)))
 | 
				
			||||||
 | 
					                                           ,title)))
 | 
				
			||||||
 | 
					                               smaller-article-list)
 | 
				
			||||||
 | 
					                        ,(if (eq? article-list-is-smaller 1) "…" "."))
 | 
				
			||||||
 | 
					                 `""))
 | 
				
			||||||
 | 
					         ,(if (string? image-description)
 | 
				
			||||||
 | 
					              (update-tree-wiki (html->xexp (preprocess-html-wiki image-description)) wikiname)
 | 
				
			||||||
 | 
					              ""))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (page-file req)
 | 
				
			||||||
 | 
					  (define wikiname (path/param-path (first (url-path (request-uri req)))))
 | 
				
			||||||
 | 
					  (define prefixed-title (path/param-path (caddr (url-path (request-uri req)))))
 | 
				
			||||||
 | 
					  (define origin (format "https://~a.fandom.com" wikiname))
 | 
				
			||||||
 | 
					  (define source-url (format "~a/wiki/~a" origin prefixed-title))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (thread-let ([media-detail
 | 
				
			||||||
 | 
					                (define dest-url
 | 
				
			||||||
 | 
					                  (format "~a/wikia.php?~a"
 | 
				
			||||||
 | 
					                          origin
 | 
				
			||||||
 | 
					                          (params->query `(("format" . "json") ("controller" . "Lightbox")
 | 
				
			||||||
 | 
					                                                               ("method" . "getMediaDetail")
 | 
				
			||||||
 | 
					                                                               ("fileTitle" . ,prefixed-title)))))
 | 
				
			||||||
 | 
					                (log-outgoing dest-url)
 | 
				
			||||||
 | 
					                (define dest-res (easy:get dest-url #:timeouts timeouts))
 | 
				
			||||||
 | 
					                (easy:response-json dest-res)]
 | 
				
			||||||
 | 
					               [siteinfo (siteinfo-fetch wikiname)])
 | 
				
			||||||
 | 
					              (if (not (jp "/exists" media-detail #f))
 | 
				
			||||||
 | 
					                  (next-dispatcher)
 | 
				
			||||||
 | 
					                  (response-handler
 | 
				
			||||||
 | 
					                   (define file-title (jp "/fileTitle" media-detail ""))
 | 
				
			||||||
 | 
					                   (define title
 | 
				
			||||||
 | 
					                     (if (non-empty-string? file-title) (format "File:~a" file-title) prefixed-title))
 | 
				
			||||||
 | 
					                   (define image-content-type
 | 
				
			||||||
 | 
					                     (if (non-empty-string? (jp "/videoEmbedCode" media-detail ""))
 | 
				
			||||||
 | 
					                         #f
 | 
				
			||||||
 | 
					                         (url-content-type (jp "/imageUrl" media-detail))))
 | 
				
			||||||
 | 
					                   (define body
 | 
				
			||||||
 | 
					                     (generate-results-page #:source-url source-url
 | 
				
			||||||
 | 
					                                            #:wikiname wikiname
 | 
				
			||||||
 | 
					                                            #:title title
 | 
				
			||||||
 | 
					                                            #:media-detail media-detail
 | 
				
			||||||
 | 
					                                            #:image-content-type image-content-type
 | 
				
			||||||
 | 
					                                            #: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
 | 
				
			||||||
 | 
					                     (xexp->html body))
 | 
				
			||||||
 | 
					                   (response/output #:code 200
 | 
				
			||||||
 | 
					                                    #:headers (build-headers always-headers)
 | 
				
			||||||
 | 
					                                    (λ (out) (write-html body out)))))))
 | 
				
			||||||
 | 
					(module+ test
 | 
				
			||||||
 | 
					  (parameterize ([(config-parameter 'strict_proxy) "true"])
 | 
				
			||||||
 | 
					    (check-equal? (get-media-html "https://static.wikia.nocookie.net/a" "image/jpeg")
 | 
				
			||||||
 | 
					                  `(img (@ (src "/proxy?dest=https%3A%2F%2Fstatic.wikia.nocookie.net%2Fa"))))
 | 
				
			||||||
 | 
					    (check-equal? (get-media-html "https://static.wikia.nocookie.net/b" "audio/mp3")
 | 
				
			||||||
 | 
					                  `(audio (@ (src "/proxy?dest=https%3A%2F%2Fstatic.wikia.nocookie.net%2Fb")
 | 
				
			||||||
 | 
					                             (controls)))))
 | 
				
			||||||
 | 
					  (parameterize ([(config-parameter 'strict_proxy) "no"])
 | 
				
			||||||
 | 
					    (check-equal? (get-media-html "https://static.wikia.nocookie.net/c" "application/ogg")
 | 
				
			||||||
 | 
					                  `(audio (@ (src "/proxy?dest=https%3A%2F%2Fstatic.wikia.nocookie.net%2Fc")
 | 
				
			||||||
 | 
					                             (controls))))
 | 
				
			||||||
 | 
					    (check-equal? (get-media-html "https://static.wikia.nocookie.net/d" "video/mp4")
 | 
				
			||||||
 | 
					                  `(video (@ (src "/proxy?dest=https%3A%2F%2Fstatic.wikia.nocookie.net%2Fd")
 | 
				
			||||||
 | 
					                             (controls)))))
 | 
				
			||||||
 | 
					  (check-equal? (get-media-html "https://example.com" "who knows") `"")
 | 
				
			||||||
 | 
					  (check-equal? (get-media-html "https://example.com" #f) `""))
 | 
				
			||||||
 | 
					(module+ test
 | 
				
			||||||
 | 
					  (parameterize ([(config-parameter 'strict_proxy) "true"])
 | 
				
			||||||
 | 
					    (check-not-false
 | 
				
			||||||
 | 
					     ((query-selector
 | 
				
			||||||
 | 
					       (attribute-selector 'src "/proxy?dest=https%3A%2F%2Fstatic.wikia.nocookie.net%2Fexamplefile")
 | 
				
			||||||
 | 
					       (generate-results-page #:source-url ""
 | 
				
			||||||
 | 
					                              #:wikiname "test"
 | 
				
			||||||
 | 
					                              #:title "File:Example file"
 | 
				
			||||||
 | 
					                              #:media-detail test-media-detail
 | 
				
			||||||
 | 
					                              #:image-content-type "image/jpeg"))))))
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue