Merge remote-tracking branch 'origin/master' into robo/og-tags
This commit is contained in:
commit
2637a4c207
11 changed files with 78 additions and 42 deletions
|
@ -13,8 +13,10 @@ $cancel-button-color = tomato
|
|||
|
||||
&.inactive input[type=submit],
|
||||
&.inactive .skip-duplicates
|
||||
&.inactive .always-upload-similar
|
||||
&.uploading input[type=submit],
|
||||
&.uploading .skip-duplicates,
|
||||
&.uploading .always-upload-similar
|
||||
&:not(.uploading) .cancel
|
||||
display: none
|
||||
|
||||
|
@ -39,6 +41,9 @@ $cancel-button-color = tomato
|
|||
.skip-duplicates
|
||||
margin-left: 1em
|
||||
|
||||
.always-upload-similar
|
||||
margin-left: 1em
|
||||
|
||||
form>.messages
|
||||
margin-top: 1em
|
||||
|
||||
|
|
|
@ -13,6 +13,14 @@
|
|||
}) %>
|
||||
</span>
|
||||
|
||||
<span class='always-upload-similar'>
|
||||
<%= ctx.makeCheckbox({
|
||||
text: 'Always upload similar',
|
||||
name: 'always-upload-similar',
|
||||
checked: false,
|
||||
}) %>
|
||||
</span>
|
||||
|
||||
<input type='button' value='Cancel' class='cancel'/>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
text: 'Upload anonymously',
|
||||
name: 'anonymous',
|
||||
checked: ctx.uploadable.anonymous,
|
||||
readonly: ctx.uploadable.forceAnonymous,
|
||||
}) %>
|
||||
</div>
|
||||
<% } %>
|
||||
|
|
|
@ -17,7 +17,7 @@ class HomeController {
|
|||
buildDate: config.meta.buildDate,
|
||||
canListSnapshots: api.hasPrivilege("snapshots:list"),
|
||||
canListPosts: api.hasPrivilege("posts:list"),
|
||||
isDevelopmentMode: config.environment == "development"
|
||||
isDevelopmentMode: config.environment == "development",
|
||||
});
|
||||
|
||||
Info.get().then(
|
||||
|
|
|
@ -12,7 +12,7 @@ const PostUploadView = require("../views/post_upload_view.js");
|
|||
const EmptyView = require("../views/empty_view.js");
|
||||
|
||||
const genericErrorMessage =
|
||||
"One of the posts needs your attention; " +
|
||||
"One or more posts needs your attention; " +
|
||||
'click "resume upload" when you\'re ready.';
|
||||
|
||||
class PostUploadController {
|
||||
|
@ -55,6 +55,7 @@ class PostUploadController {
|
|||
_evtSubmit(e) {
|
||||
this._view.disableForm();
|
||||
this._view.clearMessages();
|
||||
let anyFailures = false;
|
||||
|
||||
e.detail.uploadables
|
||||
.reduce(
|
||||
|
@ -62,44 +63,51 @@ class PostUploadController {
|
|||
promise.then(() =>
|
||||
this._uploadSinglePost(
|
||||
uploadable,
|
||||
e.detail.skipDuplicates
|
||||
)
|
||||
e.detail.skipDuplicates,
|
||||
e.detail.alwaysUploadSimilar
|
||||
).catch((error) => {
|
||||
anyFailures = true;
|
||||
if (error.uploadable) {
|
||||
if (error.similarPosts) {
|
||||
error.uploadable.lookalikes =
|
||||
error.similarPosts;
|
||||
this._view.updateUploadable(
|
||||
error.uploadable
|
||||
);
|
||||
this._view.showInfo(
|
||||
error.message,
|
||||
error.uploadable
|
||||
);
|
||||
} else {
|
||||
this._view.showError(
|
||||
error.message,
|
||||
error.uploadable
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this._view.showError(
|
||||
error.message,
|
||||
uploadable
|
||||
);
|
||||
}
|
||||
})
|
||||
),
|
||||
Promise.resolve()
|
||||
)
|
||||
.then(
|
||||
() => {
|
||||
.then(() => {
|
||||
if (anyFailures) {
|
||||
this._view.showError(genericErrorMessage);
|
||||
this._view.enableForm();
|
||||
} else {
|
||||
this._view.clearMessages();
|
||||
misc.disableExitConfirmation();
|
||||
const ctx = router.show(uri.formatClientLink("posts"));
|
||||
ctx.controller.showSuccess("Posts uploaded.");
|
||||
},
|
||||
(error) => {
|
||||
if (error.uploadable) {
|
||||
if (error.similarPosts) {
|
||||
error.uploadable.lookalikes = error.similarPosts;
|
||||
this._view.updateUploadable(error.uploadable);
|
||||
this._view.showInfo(genericErrorMessage);
|
||||
this._view.showInfo(
|
||||
error.message,
|
||||
error.uploadable
|
||||
);
|
||||
} else {
|
||||
this._view.showError(genericErrorMessage);
|
||||
this._view.showError(
|
||||
error.message,
|
||||
error.uploadable
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this._view.showError(error.message);
|
||||
}
|
||||
this._view.enableForm();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
_uploadSinglePost(uploadable, skipDuplicates) {
|
||||
_uploadSinglePost(uploadable, skipDuplicates, alwaysUploadSimilar) {
|
||||
progress.start();
|
||||
let reverseSearchPromise = Promise.resolve();
|
||||
if (!uploadable.lookalikesConfirmed) {
|
||||
|
@ -128,7 +136,10 @@ class PostUploadController {
|
|||
}
|
||||
|
||||
// notify about similar posts
|
||||
if (searchResult.similarPosts.length) {
|
||||
if (
|
||||
searchResult.similarPosts.length &&
|
||||
!alwaysUploadSimilar
|
||||
) {
|
||||
let error = new Error(
|
||||
`Found ${searchResult.similarPosts.length} similar ` +
|
||||
"posts.\nYou can resume or discard this upload."
|
||||
|
|
|
@ -196,11 +196,9 @@ class TagInputControl extends events.EventTarget {
|
|||
const listItemNode = this._createListItemNode(tag);
|
||||
if (!tag.category) {
|
||||
listItemNode.classList.add("new");
|
||||
}
|
||||
else if (source === SOURCE_IMPLICATION) {
|
||||
} else if (source === SOURCE_IMPLICATION) {
|
||||
listItemNode.classList.add("implication");
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
listItemNode.classList.add("added");
|
||||
}
|
||||
this._tagListNode.prependChild(listItemNode);
|
||||
|
|
|
@ -4,12 +4,12 @@ const config = require("./config.js");
|
|||
|
||||
if (config.environment == "development") {
|
||||
var ws = new WebSocket("ws://" + location.hostname + ":8080");
|
||||
ws.addEventListener('open', function (event) {
|
||||
ws.addEventListener("open", function (event) {
|
||||
console.log("Live-reloading websocket connected.");
|
||||
});
|
||||
ws.addEventListener('message', (event) => {
|
||||
ws.addEventListener("message", (event) => {
|
||||
console.log(event);
|
||||
if (event.data == 'reload'){
|
||||
if (event.data == "reload") {
|
||||
location.reload();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
const events = require("../events.js");
|
||||
const api = require("../api.js");
|
||||
const views = require("../util/views.js");
|
||||
const FileDropperControl = require("../controls/file_dropper_control.js");
|
||||
|
||||
|
@ -34,7 +35,8 @@ class Uploadable extends events.EventTarget {
|
|||
this.flags = [];
|
||||
this.tags = [];
|
||||
this.relations = [];
|
||||
this.anonymous = false;
|
||||
this.anonymous = !api.isLoggedIn();
|
||||
this.forceAnonymous = !api.isLoggedIn();
|
||||
}
|
||||
|
||||
destroy() {}
|
||||
|
@ -358,6 +360,8 @@ class PostUploadView extends events.EventTarget {
|
|||
detail: {
|
||||
uploadables: this._uploadables,
|
||||
skipDuplicates: this._skipDuplicatesCheckboxNode.checked,
|
||||
alwaysUploadSimilar: this._alwaysUploadSimilarCheckboxNode
|
||||
.checked,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
@ -421,6 +425,12 @@ class PostUploadView extends events.EventTarget {
|
|||
return this._hostNode.querySelector("form [name=skip-duplicates]");
|
||||
}
|
||||
|
||||
get _alwaysUploadSimilarCheckboxNode() {
|
||||
return this._hostNode.querySelector(
|
||||
"form [name=always-upload-similar]"
|
||||
);
|
||||
}
|
||||
|
||||
get _submitButtonNode() {
|
||||
return this._hostNode.querySelector("form [type=submit]");
|
||||
}
|
||||
|
|
|
@ -5,14 +5,15 @@ from io import BytesIO
|
|||
from typing import Any, Callable, List, Optional, Set, Tuple
|
||||
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
import pillow_avif
|
||||
import pyheif
|
||||
from PIL import Image
|
||||
from pyheif_pillow_opener import register_heif_opener
|
||||
register_heif_opener()
|
||||
|
||||
from szurubooru import config, errors
|
||||
|
||||
register_heif_opener()
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Math based on paper from H. Chi Wong, Marshall Bern and David Goldberg
|
||||
|
|
|
@ -6,6 +6,7 @@ import shlex
|
|||
import subprocess
|
||||
from io import BytesIO
|
||||
from typing import List
|
||||
|
||||
from PIL import Image as PILImage
|
||||
|
||||
from szurubooru import errors
|
||||
|
@ -17,7 +18,7 @@ logger = logging.getLogger(__name__)
|
|||
def convert_heif_to_png(content: bytes) -> bytes:
|
||||
img = PILImage.open(BytesIO(content))
|
||||
img_byte_arr = BytesIO()
|
||||
img.save(img_byte_arr, format='PNG')
|
||||
img.save(img_byte_arr, format="PNG")
|
||||
return img_byte_arr.getvalue()
|
||||
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ def is_animated_gif(content: bytes) -> bool:
|
|||
and len(re.findall(pattern, content)) > 1
|
||||
)
|
||||
|
||||
|
||||
def is_heif(mime_type: str) -> bool:
|
||||
return mime_type.lower() in (
|
||||
"image/heif",
|
||||
|
|
Loading…
Reference in a new issue