parent
dcc46f679b
commit
b7923c9091
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "src/webui/translation-json"]
|
||||
path = src/webui/translation-json
|
||||
url = https://gitea.armuli.eu/museum-digital/translation-json.git
|
@ -398,9 +398,11 @@ func HandleUpload() {
|
||||
// Upload the files
|
||||
if len(uploadableMetadata) > 0 {
|
||||
webdavupload.UploadMetadataFiles(c, os.Stdout, uploadableMetadata)
|
||||
webdavupload.BatchUnlink(os.Stdout, uploadableMetadata)
|
||||
}
|
||||
if len(uploadableMedia) > 0 {
|
||||
webdavupload.UploadMediaFiles(c, os.Stdout, uploadableMedia)
|
||||
webdavupload.BatchUnlink(os.Stdout, uploadableMedia)
|
||||
}
|
||||
|
||||
// Generate the import config.
|
||||
|
@ -93,3 +93,40 @@ func UploadMediaFiles(c *gowebdav.Client, w io.Writer, files []string) {
|
||||
uploadFiles(c, w, files, "IMPORT_IMG", "Uploading media files")
|
||||
|
||||
}
|
||||
|
||||
// Removes a list of files.
|
||||
func BatchUnlink(w io.Writer, files []string) {
|
||||
|
||||
_, wImplementsHttpFlusher := interface{}(w).(http.Flusher)
|
||||
|
||||
maxConcTasks := min(10, runtime.NumCPU())
|
||||
|
||||
// Set a semaphore to restrict the number of concurrent upload tasks.
|
||||
semaphore := make(chan struct{}, maxConcTasks)
|
||||
wg := &sync.WaitGroup{}
|
||||
|
||||
for _, f := range(files) {
|
||||
|
||||
semaphore <- struct{}{} // acquire
|
||||
wg.Add(1)
|
||||
|
||||
go func() {
|
||||
|
||||
defer wg.Done()
|
||||
err := os.Remove(f)
|
||||
if err != nil {
|
||||
panic("Failed to delete file " + f)
|
||||
}
|
||||
fmt.Fprintf(w, "Delete file %s\n", f)
|
||||
<-semaphore // release
|
||||
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
if wImplementsHttpFlusher == true {
|
||||
w.(http.Flusher).Flush()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
:root {
|
||||
--color-bg: #FFF;
|
||||
--color-bg2: #F5F5F5;
|
||||
--color-bg-transparent: rgba(255,255,255,.4);
|
||||
--color-bg-transparent-stronger: rgba(255,255,255,.7);
|
||||
--color-bg-transparent-dark: rgba(0,0,0,.4);
|
||||
--color-fg: #000;
|
||||
--color-fg2: #212121;
|
||||
--color-bg-dark: #212121;
|
||||
@ -24,9 +21,6 @@
|
||||
:root {
|
||||
--color-bg: #000;
|
||||
--color-bg2: #2685AF;
|
||||
--color-bg-transparent: rgba(0,0,0,.4);
|
||||
--color-bg-transparent-stronger: rgba(0,0,0,.7);
|
||||
--color-bg-transparent-dark: rgba(0,0,0,.4);
|
||||
--color-fg: #FFF;
|
||||
--color-fg2: #D6D6D6;
|
||||
--color-bg-dark: #212121;
|
||||
@ -52,18 +46,32 @@ html {
|
||||
|
||||
body { margin: 0; padding: 0; }
|
||||
|
||||
header { display: block; background: var(--color-bg); font-size: 1.5em; padding: .4em 2rem;
|
||||
box-shadow: 0 4px 2px -2px var(--color-borders); }
|
||||
header { display: grid; grid-template-columns: auto auto 100fr auto;
|
||||
align-items: center;
|
||||
background: var(--color-bg); font-size: 1.5em; padding: .4em 2rem;
|
||||
box-shadow: 0 4px 2px -2px var(--color-borders); }
|
||||
header * { margin: 0; padding: 0; vertical-align: middle; }
|
||||
header img { height: 1em; }
|
||||
|
||||
header #actions { grid-column: 4; font-size: .85rem; font-weight: bold; }
|
||||
header #actions > * { padding: .2em .5em;
|
||||
border-radius: .2em; color: var(--color-fg2); transition: .2s; }
|
||||
header #actions > :hover { background: var(--color-accent-hover); color: var(--color-bg); }
|
||||
|
||||
h1 { display: inline-block; margin-left: 1em; font-size: .8em; }
|
||||
|
||||
#wrap { display: grid; grid-template-columns: 450px 1fr; margin: 1em 2rem; grid-gap: 2em; }
|
||||
#wrap { display: grid;
|
||||
grid-template-columns: 450px 1fr; grid-template-rows: auto auto;
|
||||
margin: 1em 2rem; grid-gap: 2em; }
|
||||
#wrap > * { vertical-align: top; }
|
||||
|
||||
main,
|
||||
aside { background: var(--color-bg); border-radius: 1px solid var(--color-borders); box-shadow: 0 0 6px var(--color-borders); border-radius: 2px; }
|
||||
aside,
|
||||
.sec-aside { background: var(--color-bg); border-radius: 1px solid var(--color-borders); box-shadow: 0 0 6px var(--color-borders); border-radius: 2px; }
|
||||
|
||||
aside,
|
||||
.sec-aside { grid-column: 1; }
|
||||
main { grid-column: 2; grid-row: 1 / span 2; }
|
||||
|
||||
h2 { margin: 0; padding: .8rem; font-size: 1.4em;
|
||||
border-bottom: .15em solid var(--color-borders); }
|
||||
@ -72,18 +80,22 @@ h3 { margin: 0; padding: .8rem; border-bottom: .15em solid var(--color-borders);
|
||||
input { background: var(--color-bg); color: var(--color-fg); }
|
||||
|
||||
aside .label-input { display: grid;
|
||||
grid-template-columns: 150px 2fr; border-bottom: 1px solid var(--color-borders); }
|
||||
grid-template-columns: 150px auto 2em; border-bottom: 1px solid var(--color-borders); }
|
||||
aside .label-input:hover { border-color: var(--color-accent); }
|
||||
aside .label-input > * { display: inline-block;
|
||||
font-size: .9em;
|
||||
padding: .5rem .8rem; border: 0; outline: 0; }
|
||||
aside label { font-weight: bold; color: var(--color-fg-medium); }
|
||||
|
||||
aside .label-input3 { grid-template-columns: 150px auto 2em; }
|
||||
aside .label-input3 button { background: none; transition: background .2s; }
|
||||
aside .label-input3 button:hover { background: var(--color-accent); }
|
||||
aside .label-input button { background: none; transition: background .2s; }
|
||||
aside .label-input button:hover { background: var(--color-accent); }
|
||||
|
||||
select { background: var(--color-bg); color: var(--color-fg); }
|
||||
.icon-help:before { content: " ? "; font-weight: bold; font-size: .8em;
|
||||
text-align: center; color: var(--color-fg2); transition: background .2s; }
|
||||
.icon-help { transition: background .2s; }
|
||||
.icon-help:hover { background: var(--color-accent); }
|
||||
|
||||
select { width: 100%; background: var(--color-bg); color: var(--color-fg); }
|
||||
|
||||
.updateB { display: block; width: calc(100% - 1em); background: var(--color-bg);
|
||||
margin: .5em; padding: .5em;
|
||||
@ -98,6 +110,11 @@ select { background: var(--color-bg); color: var(--color-fg); }
|
||||
border-bottom: 1px solid var(--color-borders); transition: border .2s, background .2s; }
|
||||
.upload-file-list > span:hover { background: var(--color-bg2); border-color: var(--color-accent-hover); }
|
||||
|
||||
.upload-file-list:empty { display: block; position: relative; height: 5em; }
|
||||
.upload-file-list:empty:before { content: " - - - - - ";
|
||||
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
|
||||
font-weight: bold; font-size: 3em; color: var(--color-borders); }
|
||||
|
||||
main { position: relative; }
|
||||
main h3 { position: sticky; top: 0; background: var(--color-bg); }
|
||||
|
||||
@ -107,6 +124,17 @@ main h3 { position: sticky; top: 0; background: var(--color-bg); }
|
||||
border: 2px solid var(--color-accent-hover); border-bottom-width: 0;
|
||||
box-shadow: 0 0 6px var(--color-borders);
|
||||
z-index: 10; animation: slide-up .4s ease-out; }
|
||||
.transfer-overlay h3 { border-bottom: none; }
|
||||
.transfer-overlay-hl { display: grid; grid-template-columns: auto 1fr auto;
|
||||
padding-right: .8em;
|
||||
align-items: center; border-bottom: .15em solid var(--color-borders); }
|
||||
.transfer-overlay-hl .overlay-close { display: inline-block;
|
||||
color: var(--color-fg2);
|
||||
padding: .5em; border-radius: 2px;
|
||||
grid-column: 3;
|
||||
transition: .2s; }
|
||||
.transfer-overlay-hl .overlay-close:hover { background: var(--color-accent-hover); color: var(--color-bg); }
|
||||
.transfer-overlay-hl .overlay-close:before { display: inline-block; content: " x ";}
|
||||
|
||||
.transfer-msgs { font-size: .9em; }
|
||||
.transfer-msgs > * { display: block; border-bottom: 1px solid var(--color-borders); transition: .2s; }
|
||||
@ -119,6 +147,8 @@ main h3 { position: sticky; top: 0; background: var(--color-bg); }
|
||||
}
|
||||
|
||||
iframe { display: block; width: 100%; border: none; height: 60vh; }
|
||||
.parser-desc { display: block; padding: 0 .8rem;
|
||||
font-size: .85em; white-space: pre-wrap; }
|
||||
|
||||
/***
|
||||
* Slider
|
||||
|
@ -18,7 +18,7 @@ class App {
|
||||
return elem;
|
||||
}
|
||||
|
||||
generateLabelInput(id, labelText, type, value) {
|
||||
generateLabelInput(id, labelText, explanationText, type, value) {
|
||||
|
||||
const output = document.createElement("div");
|
||||
output.classList.add("label-input");
|
||||
@ -34,33 +34,38 @@ class App {
|
||||
input.value = value;
|
||||
output.appendChild(input);
|
||||
|
||||
const help = document.createElement("span");
|
||||
help.classList.add("icon-help");
|
||||
help.title = explanationText;
|
||||
output.appendChild(help);
|
||||
|
||||
return {'wrap': output, 'input': input};
|
||||
|
||||
}
|
||||
|
||||
async generateSidebar() {
|
||||
|
||||
this.aside.appendChild(this.generateTextElement("h2", "Settings")); // TODO
|
||||
this.aside.appendChild(this.generateTextElement("h2", this.tls.settings)); // TODO
|
||||
|
||||
// Set up fields
|
||||
const instanceLinkArea = this.generateLabelInput("instance-link",
|
||||
"Instance link", "url", this.config.settings.instance);
|
||||
this.tls.instance_link, this.tls.instance_link_explica, "url", this.config.settings.instance);
|
||||
this.aside.appendChild(instanceLinkArea.wrap);
|
||||
|
||||
const usernameArea = this.generateLabelInput("username",
|
||||
"Username", "text", this.config.settings.username);
|
||||
this.tls.username, this.tls.username_explica, "text", this.config.settings.username);
|
||||
this.aside.appendChild(usernameArea.wrap);
|
||||
|
||||
const mailArea = this.generateLabelInput("mail",
|
||||
"Mail", "email", this.config.settings.mail);
|
||||
this.tls.mail, this.tls.mail_explica, "email", this.config.settings.mail);
|
||||
this.aside.appendChild(mailArea.wrap);
|
||||
|
||||
const institutionIdArea = this.generateLabelInput("institutionId",
|
||||
"Institution ID", "number", this.config.settings.institution_id);
|
||||
this.tls.institution_id, this.tls.institution_id_explica, "number", this.config.settings.institution_id);
|
||||
this.aside.appendChild(institutionIdArea.wrap);
|
||||
|
||||
const tokenArea = this.generateLabelInput("token",
|
||||
"Token", "text", this.config.settings.token);
|
||||
this.tls.token, this.tls.token_explica, "text", this.config.settings.token);
|
||||
this.aside.appendChild(tokenArea.wrap);
|
||||
|
||||
const parserDiv = document.createElement("div");
|
||||
@ -68,7 +73,7 @@ class App {
|
||||
|
||||
const parserLabel = document.createElement("label");
|
||||
parserLabel.setAttribute("for", "parserSelect");
|
||||
parserLabel.textContent = "Parser";
|
||||
parserLabel.textContent = this.tls.parser;
|
||||
parserDiv.appendChild(parserLabel);
|
||||
const parserSelect = document.createElement("select");
|
||||
parserSelect.id = "parserSelect";
|
||||
@ -84,17 +89,23 @@ class App {
|
||||
}
|
||||
|
||||
parserDiv.appendChild(parserSelect);
|
||||
|
||||
const parserHelp = document.createElement("span");
|
||||
parserHelp.classList.add("icon-help");
|
||||
parserHelp.title = this.tls.parser_explica;
|
||||
parserDiv.appendChild(parserHelp);
|
||||
|
||||
this.aside.appendChild(parserDiv);
|
||||
|
||||
const uploadFolderArea = this.generateLabelInput("upload-folder",
|
||||
"Upload directory", "text", this.config.settings.upload_directory);
|
||||
this.tls.upload_directory, this.tls.upload_directory_explica, "text", this.config.settings.upload_directory);
|
||||
this.aside.appendChild(uploadFolderArea.wrap);
|
||||
|
||||
const visibleDivOuter = document.createElement("div");
|
||||
visibleDivOuter.classList.add("label-input");
|
||||
const visibleLabel = document.createElement("label");
|
||||
visibleLabel.setAttribute("for", "visible");
|
||||
visibleLabel.textContent = "Publish immediately?";
|
||||
visibleLabel.textContent = this.tls.publish_immediately;
|
||||
visibleDivOuter.appendChild(visibleLabel);
|
||||
|
||||
const visibleDiv = document.createElement("div");
|
||||
@ -119,32 +130,40 @@ class App {
|
||||
|
||||
visibleDiv.appendChild(visibleSwitch);
|
||||
visibleDivOuter.appendChild(visibleDiv);
|
||||
|
||||
const visibleHelp = document.createElement("span");
|
||||
visibleHelp.classList.add("icon-help");
|
||||
visibleHelp.title = this.tls.publish_immediately_explica;
|
||||
visibleDivOuter.appendChild(visibleHelp);
|
||||
|
||||
this.aside.appendChild(visibleDivOuter);
|
||||
|
||||
// Additional settings
|
||||
this.aside.appendChild(this.generateTextElement("h3", "Additional settings"));
|
||||
this.aside.appendChild(this.generateTextElement("h3", this.tls.additional_settings));
|
||||
|
||||
const addSettingsArea = document.createElement("div");
|
||||
|
||||
const app = this;
|
||||
function generateAdditionalSettingsField(key, value) {
|
||||
|
||||
const line = document.createElement("div");
|
||||
line.classList.add("label-input", "label-input3");
|
||||
line.classList.add("label-input");
|
||||
|
||||
const newKey = document.createElement("input");
|
||||
newKey.placeholder = "Key (aspect to set)";
|
||||
newKey.placeholder = app.tls.add_settings_key;
|
||||
newKey.required = "required";
|
||||
newKey.value = key;
|
||||
line.appendChild(newKey);
|
||||
|
||||
const newVal = document.createElement("input");
|
||||
newVal.placeholder = "Value (what to set it to?)";
|
||||
newVal.placeholder = app.tls.add_settings_value;
|
||||
newVal.required = "required";
|
||||
newVal.value = value;
|
||||
line.appendChild(newVal);
|
||||
|
||||
const removeB = document.createElement("button");
|
||||
removeB.textContent = " x ";
|
||||
removeB.title = app.tls.remove;
|
||||
line.appendChild(removeB);
|
||||
|
||||
removeB.addEventListener('click', function() {
|
||||
@ -164,21 +183,22 @@ class App {
|
||||
this.aside.appendChild(addSettingsArea);
|
||||
|
||||
const newSettingLine = document.createElement("form");
|
||||
newSettingLine.classList.add("label-input", "label-input3");
|
||||
newSettingLine.classList.add("label-input");
|
||||
|
||||
const newKey = document.createElement("input");
|
||||
newKey.placeholder = "Key (aspect to set)";
|
||||
newKey.placeholder = this.tls.add_settings_key;
|
||||
newKey.required = "required";
|
||||
newSettingLine.appendChild(newKey);
|
||||
|
||||
const newVal = document.createElement("input");
|
||||
newVal.placeholder = "Value (what to set it to?)";
|
||||
newVal.placeholder = this.tls.add_settings_value;
|
||||
newVal.required = "required";
|
||||
newSettingLine.appendChild(newVal);
|
||||
|
||||
const newSubmitB = document.createElement("button");
|
||||
newSubmitB.type = "submit";
|
||||
newSubmitB.textContent = " > ";
|
||||
newSubmitB.title = app.tls.add;
|
||||
newSettingLine.appendChild(newSubmitB);
|
||||
|
||||
newSettingLine.addEventListener('submit', function(e) {
|
||||
@ -194,7 +214,7 @@ class App {
|
||||
this.aside.appendChild(newSettingLine)
|
||||
|
||||
const updateB = document.createElement("button");
|
||||
updateB.textContent = "Save / Update settings";
|
||||
updateB.textContent = this.tls.save_update;
|
||||
updateB.classList.add("updateB");
|
||||
this.aside.appendChild(updateB);
|
||||
|
||||
@ -245,12 +265,12 @@ class App {
|
||||
|
||||
generateMain() {
|
||||
|
||||
this.main.appendChild(this.generateTextElement("h2", "Uploadable files"));
|
||||
this.main.appendChild(this.generateTextElement("h2", this.tls.uploadable_files));
|
||||
|
||||
// Metadata
|
||||
const metadataSec = document.createElement("section");
|
||||
|
||||
metadataSec.appendChild(this.generateTextElement("h3", "Metadata files"));
|
||||
metadataSec.appendChild(this.generateTextElement("h3", this.tls.metadata_files));
|
||||
const metadataList = document.createElement("div");
|
||||
metadataList.classList.add("upload-file-list");
|
||||
|
||||
@ -268,7 +288,7 @@ class App {
|
||||
// Media
|
||||
const mediaSec = document.createElement("section");
|
||||
|
||||
mediaSec.appendChild(this.generateTextElement("h3", "Media files"));
|
||||
mediaSec.appendChild(this.generateTextElement("h3", this.tls.media_files));
|
||||
const mediaList = document.createElement("div");
|
||||
mediaList.classList.add("upload-file-list");
|
||||
|
||||
@ -282,7 +302,6 @@ class App {
|
||||
mediaSec.appendChild(mediaList);
|
||||
this.main.appendChild(mediaSec);
|
||||
|
||||
|
||||
}
|
||||
|
||||
generateActionsMenu() {
|
||||
@ -292,7 +311,7 @@ class App {
|
||||
}
|
||||
|
||||
const uploadTrigger = document.createElement("span");
|
||||
uploadTrigger.textContent = "Upload";
|
||||
uploadTrigger.textContent = this.tls.upload;
|
||||
this.actionsArea.appendChild(uploadTrigger);
|
||||
|
||||
const app = this;
|
||||
@ -302,7 +321,16 @@ class App {
|
||||
transferOverlay.id = "transfer-overlay";
|
||||
transferOverlay.classList.add("transfer-overlay");
|
||||
const hl = document.createElement("div");
|
||||
hl.appendChild(app.generateTextElement("h3", "Transfer"));
|
||||
hl.classList.add("transfer-overlay-hl");
|
||||
hl.appendChild(app.generateTextElement("h3", app.tls.upload));
|
||||
|
||||
const closeB = document.createElement("span");
|
||||
closeB.classList.add("overlay-close");
|
||||
hl.appendChild(closeB);
|
||||
|
||||
closeB.addEventListener('click', function() { location.reload(); });
|
||||
// closeB.addEventListener('click', function() { transferOverlay.parentElement.removeChild(transferOverlay); });
|
||||
|
||||
transferOverlay.appendChild(hl);
|
||||
|
||||
const transferMsgs = document.createElement("div");
|
||||
@ -320,6 +348,32 @@ class App {
|
||||
|
||||
}
|
||||
|
||||
// Provides a sidebar entry for describing the parser
|
||||
generateParserDesc() {
|
||||
|
||||
for (const parser of this.parserList) {
|
||||
if (parser.title == this.config.settings.parser) {
|
||||
|
||||
const aside = document.createElement("div");
|
||||
aside.classList.add("sec-aside");
|
||||
|
||||
aside.appendChild(this.generateTextElement("h3", this.tls.parser));
|
||||
const div = document.createElement("div");
|
||||
div.classList.add("parser-desc");
|
||||
|
||||
const desc = document.createElement("p");
|
||||
desc.textContent = parser.comment;
|
||||
div.appendChild(desc);
|
||||
|
||||
aside.appendChild(div);
|
||||
|
||||
this.wrap.appendChild(aside);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
if (this.config.setup_required === true) {
|
||||
@ -330,6 +384,9 @@ class App {
|
||||
this.generateSidebar();
|
||||
this.generateMain();
|
||||
this.generateActionsMenu();
|
||||
|
||||
this.generateParserDesc();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -341,7 +398,7 @@ class App {
|
||||
let done = 0;
|
||||
|
||||
function wrapFinish() {
|
||||
if (done === 3) {
|
||||
if (done === 4) {
|
||||
app.render();
|
||||
}
|
||||
}
|
||||
@ -367,12 +424,22 @@ class App {
|
||||
done++;
|
||||
wrapFinish();
|
||||
});
|
||||
window.fetch('/get-translations?lang=' + encodeURIComponent(this.lang), {method: 'GET', cache: 'no-cache', credentials: 'same-origin'})
|
||||
.then(function(response) { return response.json(); })
|
||||
.then(function(elements) {
|
||||
app.tls = elements.webdav_uploader;
|
||||
done++;
|
||||
wrapFinish();
|
||||
});
|
||||
}
|
||||
|
||||
constructor() {
|
||||
|
||||
this.wrap = document.getElementById("wrap");
|
||||
this.lang = navigator.language.substring(0, 2)
|
||||
if (["de", "en"].includes(this.lang) === false) {
|
||||
this.lang = "en";
|
||||
}
|
||||
|
||||
this.aside = document.createElement("aside");
|
||||
this.main = document.createElement("main");
|
||||
|
32
src/webui/serveApiGetTranslations.go
Normal file
32
src/webui/serveApiGetTranslations.go
Normal file
@ -0,0 +1,32 @@
|
||||
package webui
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type tlRaw struct {
|
||||
webdav_uploader map[string]string `json:"webdav_uploader"`
|
||||
}
|
||||
|
||||
//go:embed translation-json/webdav-uploader/de/webdav_uploader.json
|
||||
var rawTlsDe string
|
||||
//go:embed translation-json/webdav-uploader/en/webdav_uploader.json
|
||||
var rawTlsEn string
|
||||
|
||||
// Retrieves translation variables in the given language.
|
||||
func serveApiGetTranslations(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var rawTls string
|
||||
if r.URL.Query().Get("lang") == "de" {
|
||||
rawTls = rawTlsDe
|
||||
} else {
|
||||
rawTls = rawTlsEn
|
||||
}
|
||||
|
||||
setHeadersForJson(w)
|
||||
|
||||
fmt.Fprint(w, rawTls)
|
||||
|
||||
}
|
@ -39,14 +39,17 @@ func serveApiTriggerUpload(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprint(w, "Uploading metadata files\n")
|
||||
w.(http.Flusher).Flush()
|
||||
webdavupload.UploadMetadataFiles(c, w, uploadableMetadata)
|
||||
webdavupload.BatchUnlink(w, uploadableMetadata)
|
||||
}
|
||||
if len(uploadableMedia) > 0 {
|
||||
fmt.Fprint(w, "Uploading media files\n")
|
||||
webdavupload.UploadMediaFiles(c, w, uploadableMedia)
|
||||
webdavupload.BatchUnlink(w, uploadableMedia)
|
||||
}
|
||||
|
||||
fmt.Fprint(w, "Generating and uploading import configuration\n")
|
||||
webdavupload.SetImportConfigToTheRemote(c, config)
|
||||
fmt.Fprint(w, "DONE\n")
|
||||
w.(http.Flusher).Flush()
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ func Run() {
|
||||
// Bind callable URLs
|
||||
http.HandleFunc("/", serveAppShell) // Serve app shell
|
||||
http.HandleFunc("/get-settings", serveApiGetSettings) // API for listing current settings
|
||||
http.HandleFunc("/get-translations", serveApiGetTranslations) // API for listing current settings
|
||||
http.HandleFunc("/list-uploadable", serveApiListUploadable) // API to list uploadable files
|
||||
http.HandleFunc("/list-parsers", serveApiListParsers) // API to list available parsers.
|
||||
http.HandleFunc("/update-settings", serveApiUpdateSettings) // API for updating settings
|
||||
|
1
src/webui/translation-json
Submodule
1
src/webui/translation-json
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 6803016b709dcc0bf92ddfc29c6bf7bd9bd29cf7
|
Loading…
x
Reference in New Issue
Block a user