From 694ec7c2c513c815c2ef7b300d722630392cb27f Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Wed, 31 Oct 2018 18:57:28 +0900 Subject: [PATCH] Enforce avatar image dimensions --- jobs/mal-parse/mal-parse.go | 40 +++++++++------- scripts/Actions/Upload.ts | 94 +++++++++++++++++++++++++++---------- 2 files changed, 94 insertions(+), 40 deletions(-) diff --git a/jobs/mal-parse/mal-parse.go b/jobs/mal-parse/mal-parse.go index b9a5613c..72ea4f17 100644 --- a/jobs/mal-parse/mal-parse.go +++ b/jobs/mal-parse/mal-parse.go @@ -28,23 +28,31 @@ func main() { } if objectType == "all" || objectType == "anime" { - filepath.Walk(path.Join(arn.Root, "jobs/mal-download/anime"), func(name string, info os.FileInfo, err error) error { - if err != nil { - fmt.Println(err) - return err - } - - if info.IsDir() { - return nil - } - - if !strings.HasSuffix(name, ".html.gz") { - return nil - } - - return readAnimeFile(name) - }) + readFiles(path.Join(arn.Root, "jobs", "mal-download", "anime"), readAnimeFile) } + + if objectType == "all" || objectType == "character" { + readFiles(path.Join(arn.Root, "jobs", "mal-download", "character"), readCharacterFile) + } +} + +func readFiles(root string, onFile func(string) error) { + filepath.Walk(root, func(name string, info os.FileInfo, err error) error { + if err != nil { + fmt.Println(err) + return err + } + + if info.IsDir() { + return nil + } + + if !strings.HasSuffix(name, ".html.gz") { + return nil + } + + return onFile(name) + }) } func readAnimeFile(name string) error { diff --git a/scripts/Actions/Upload.ts b/scripts/Actions/Upload.ts index 77201bda..a63868b0 100644 --- a/scripts/Actions/Upload.ts +++ b/scripts/Actions/Upload.ts @@ -17,7 +17,7 @@ export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) { input.setAttribute("type", "file") input.value = null - input.onchange = () => { + input.onchange = async () => { let file = input.files[0] if(!file) { @@ -39,7 +39,26 @@ export function selectFile(arn: AnimeNotifier, button: HTMLButtonElement) { // Preview image if(fileType === "image") { let previews = document.getElementsByClassName(button.id + "-preview") - previewImage(file, endpoint, previews) + let dataURL = await readImageAsDataURL(file) + let img = await loadImage(dataURL) + + switch(endpoint) { + case "/api/upload/avatar": + if(img.naturalWidth <= 280 || img.naturalHeight < 280) { + arn.statusMessage.showError(`Your image has a resolution of ${img.naturalWidth} x ${img.naturalHeight} pixels which is too small. Recommended: 560 x 560. Minimum: 280 x 280.`, 8000) + return + } + break + + case "/api/upload/cover": + if(img.naturalWidth <= 960 || img.naturalHeight < 225) { + arn.statusMessage.showError(`Your image has a resolution of ${img.naturalWidth} x ${img.naturalHeight} pixels which is too small. Recommended: 1920 x 450. Minimum: 960 x 225.`, 8000) + return + } + break + } + + previewImage(dataURL, endpoint, previews) } uploadFile(file, fileType, endpoint, arn) @@ -92,36 +111,63 @@ function uploadFile(file: File, fileType: string, endpoint: string, arn: AnimeNo reader.readAsArrayBuffer(file) } -// Preview image -function previewImage(file: File, endpoint: string, previews: HTMLCollectionOf) { - let reader = new FileReader() +// Read image as data URL +function readImageAsDataURL(file: File): Promise { + return new Promise((resolve, reject) => { + let reader = new FileReader() - reader.onloadend = () => { - let dataURL = reader.result as string - - if(endpoint === "/api/upload/avatar") { - let svgPreview = document.getElementById("avatar-input-preview-svg") as HTMLImageElement - - if(svgPreview) { - svgPreview.classList.add("hidden") - } + reader.onloadend = () => { + let dataURL = reader.result as string + resolve(dataURL) } - for(let preview of previews) { - let img = preview as HTMLImageElement - img.classList.remove("hidden") + reader.onerror = event => { + reader.abort() + reject(event) + } - // Make not found images visible again - if(img.classList.contains("lazy")) { - img.classList.remove("element-not-found") - img.classList.add("element-found") - } + reader.readAsDataURL(file) + }) +} - img.src = dataURL +// Load image and resolve when loading has finished +function loadImage(url: string): Promise { + return new Promise((resolve, reject) => { + let img = new Image() + img.src = url + + img.onload = () => { + resolve(img) + } + + img.onerror = error => { + reject(error) + } + }) +} + +// Preview image +function previewImage(dataURL: string, endpoint: string, previews: HTMLCollectionOf) { + if(endpoint === "/api/upload/avatar") { + let svgPreview = document.getElementById("avatar-input-preview-svg") as HTMLImageElement + + if(svgPreview) { + svgPreview.classList.add("hidden") } } - reader.readAsDataURL(file) + for(let preview of previews) { + let img = preview as HTMLImageElement + img.classList.remove("hidden") + + // Make not found images visible again + if(img.classList.contains("lazy")) { + img.classList.remove("element-not-found") + img.classList.add("element-found") + } + + img.src = dataURL + } } // Update sidebar avatar