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