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-subdomain.rkt" subdomain-dispatcher) | ||||
| (require-reloadable "src/page-wiki.rkt" page-wiki) | ||||
| (require-reloadable "src/page-file.rkt" page-file) | ||||
| 
 | ||||
| (reload!) | ||||
| 
 | ||||
|  | @ -38,6 +39,7 @@ | |||
|       page-proxy | ||||
|       page-search | ||||
|       page-wiki | ||||
|       page-file | ||||
|       redirect-wiki-home | ||||
|       static-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-subdomain.rkt" subdomain-dispatcher)) | ||||
| (require (only-in "src/page-wiki.rkt" page-wiki)) | ||||
| (require (only-in "src/page-file.rkt" page-file)) | ||||
| 
 | ||||
| (serve/launch/wait | ||||
|  #:listen-ip (if (config-true? 'debug) "127.0.0.1" #f) | ||||
|  | @ -27,6 +28,7 @@ | |||
|     page-proxy | ||||
|     page-search | ||||
|     page-wiki | ||||
|     page-file | ||||
|     redirect-wiki-home | ||||
|     static-dispatcher | ||||
|     subdomain-dispatcher))) | ||||
|  |  | |||
|  | @ -45,6 +45,7 @@ | |||
|               (pathprocedure:make "/proxy" (hash-ref ds 'page-proxy)) | ||||
|               (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/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))) | ||||
|  |  | |||
							
								
								
									
										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