diff --git a/qml/components/LogLoader.qml b/qml/components/LogLoader.qml deleted file mode 100644 index 5b25a69..0000000 --- a/qml/components/LogLoader.qml +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2022,2023 Peter G. (nephros) -// SPDX-License-Identifier: Apache-2.0 - -import QtQuick 2.6 - -Item { - - property ListModel model: ListModel{} - - WorkerScript { id: worker - source: "../js/logworker.js" - } - - function reload() { - if (!model) return - worker.sendMessage({action: "reload", model: model}) - } -} - -// vim: expandtab ts=4 st=4 sw=4 filetype=javascript diff --git a/qml/components/LogPaster.qml b/qml/components/LogPaster.qml index 5a191f2..46505af 100644 --- a/qml/components/LogPaster.qml +++ b/qml/components/LogPaster.qml @@ -20,7 +20,7 @@ Item { if (m.event === "pasteOk") { successCount++ } if (m.event === "pasteError") { errorCount++ - app.popup(qsTr("Error uploading: %1 - %2", "%1: error code, %2: error message").arg(m.code).arg(m.text)); + app.popup(qsTr("Error uploading %1: %2 - %3", "%1: file name, %2 error code, %3: error message").arg(m.file).arg(m.code).arg(m.text)); } if (m.event === "uploading") { uploading = m.file } } @@ -28,18 +28,8 @@ Item { function upload() { if (!model) return - for (var i = 0; i < model.count; ++i) { - worker.sendMessage({ action: "pasteFile", model: model, index: i, url: postUrl, expire: config.expireDays }) - //delay(pasteFile(model.get(i))) - } - } - - Timer { id: delayTimer; interval: 1000 } - function delay(callback) { - delayTimer.triggered.connect(callback) - delayTimer.start(); + worker.sendMessage({ action: "loadAndPaste", model: model, url: postUrl, expire: config.expireDays }) } - } // vim: expandtab ts=4 st=4 sw=4 filetype=javascript diff --git a/qml/components/LogfileDelegate.qml b/qml/components/LogfileDelegate.qml index 882b0f3..a4bb271 100644 --- a/qml/components/LogfileDelegate.qml +++ b/qml/components/LogfileDelegate.qml @@ -45,7 +45,7 @@ GridItem { id: root Label { text: (model.fileSize > 0) ? Format.formatFileSize(model.fileSize) : "?"; truncationMode: TruncationMode.Fade; font.pixelSize: Theme.fontSizeTiny; color: Theme.secondaryColor } Label { text: (model.pastedUrl) ? qsTr("uploaded"): qsTr("not uploaded"); truncationMode: TruncationMode.Fade; font.pixelSize: Theme.fontSizeTiny; color: Theme.secondaryColor } } - Label { text: filePath; width: parent.width; truncationMode: TruncationMode.Fade; font.pixelSize: Theme.fontSizeTiny; color: Theme.secondaryColor } + //Label { text: (model.pastedUrl) ? model.pastedUrl : model.filePath; truncationMode: TruncationMode.Fade; font.pixelSize: Theme.fontSizeTiny; color: Theme.secondaryColor } //Label { text: fileNameOrig ? fileNameOrig : ""; width: parent.width; truncationMode: TruncationMode.Fade; font.pixelSize: Theme.fontSizeTiny; color: Theme.secondaryColor } } } diff --git a/qml/harbour-bugger.qml b/qml/harbour-bugger.qml index efa4e58..70f51fa 100644 --- a/qml/harbour-bugger.qml +++ b/qml/harbour-bugger.qml @@ -146,7 +146,8 @@ ApplicationWindow { Notification { id: smessage; isTransient: true; } function popup(s) { smessage.previewSummary = s - smessage.urgency = 0; + smessage.expireTimeout = Math.floor(1000 * s.length/20) + //smessage.urgency = 0; smessage.publish(); } diff --git a/qml/js/logworker.js b/qml/js/logworker.js index f270130..194f8e7 100644 --- a/qml/js/logworker.js +++ b/qml/js/logworker.js @@ -4,77 +4,67 @@ .pragma library WorkerScript.onMessage = function(m) { - if (m.action === "reload") reload(m.model) - if (m.action === "pasteFile") pasteFile(m.model, m.index, m.url, m.expire) + if (m.action === "pasteFile") pasteFile(m.model, m.index, m.url, m.expire) + if (m.action === "loadAndPaste") loadAndPaste(m.model, m.url, m.expire) - function reload(model) { + function loadAndPaste(model, url, expire) { if (!model) return for (var i = 0; i < model.count; ++i) { - getFile(model, i) + console.debug("Uploading %1/%2".arg(i+1).arg(model.count)) + loadAndPasteFile(model, i, url, expire) } } - - /* load files from URLs into data buffer */ - function getFile(model, index) { - var data = model.get(index) - var url = data.url - var r = new XMLHttpRequest() - r.open('GET', url); + /* get contents from name, upload */ + function loadAndPasteFile(model, index, url, expire) { + var fn = model.get(index).url + console.assert((fn.length > 0), "No filepath in element.") + var r = new XMLHttpRequest(); + r.open('GET', fn); r.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); r.send(); - r.onreadystatechange = function(event) { if (r.readyState == XMLHttpRequest.DONE) { - if (r.status === 200 || r.status == 0) { - console.debug("Filedata loaded: about", r.response.split("\n").length, "lines"); - if (r.response.length > 0) { - model.setProperty(index, "dataStr", r.response) - // FIXME: use response header for this? - //model.setProperty(index, "fileSize", r.response.length) - } else { - console.warn("File was empty, removing from list:", data.fileName); - model.remove(index) - } - model.sync() + if (r.status === 200) { + WorkerScript.sendMessage({ event: "readOk", count: r.response.length }) + uploadFile(r.response) } else { console.warn("Filedata load failed:", JSON.stringify(r.response)); + WorkerScript.sendMessage({ event: "readError", code: r.status, text: r.statusText }) } } } - } - function pasteFile(model, index, url, expire) { - var data = model.get(index) - WorkerScript.sendMessage({ event: "uploading", file: data.fileName}) - var r = new XMLHttpRequest() - r.open('POST', url); - r.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); - r.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - const fileContent = data["dataStr"] - console.assert( (fileContent.length>0), "Trying to upload empty log data") + function uploadFile(fileContent) { + console.assert( (fileContent.length>0), "Trying to upload empty log data"); + WorkerScript.sendMessage({ event: "uploading", file: model.get(index).fileName }) + console.debug("uploading %1 to %2, expiring in %3s".arg(model.get(index).fileName).arg(url).arg(expire)) + var r = new XMLHttpRequest(); + r.open('POST', url); + r.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + r.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - const payload = - 'expiry_days=' + expire - + '&title=' + data.fileName - + '&content=' + encodeURIComponent(fileContent) - r.send(payload); + const payload = + 'expiry_days=' + expire + + '&title=' + model.get(index).fileName + + '&content=' + encodeURIComponent(fileContent); + r.send(payload); - r.onreadystatechange = function(event) { - if (r.readyState == XMLHttpRequest.DONE) { - //if (r.status === 200 || r.status == 0) { - if (r.status === 200) { - console.info("upload successful:", data["fileName"], r.response); - model.setProperty(index, "pastedUrl", r.response.replace(/"/g, "")) - model.sync(); - WorkerScript.sendMessage({ event: "pasteOk"}) - } else { - console.warn("error in processing request.", r.status, r.statusText); - WorkerScript.sendMessage({ event: "pasteError", code: r.status, text: r.statusText }) + r.onreadystatechange = function(event) { + if (r.readyState == XMLHttpRequest.DONE) { + if (r.status === 200) { + console.info("upload successful:", r.response); + const ret = r.response.split('"').join(''); // remove quotes + model.setProperty(index, "pastedUrl", ret); + model.sync(); + WorkerScript.sendMessage({ event: "pasteOk", file: model.get(index).fileName, url: ret }) + } else { + WorkerScript.sendMessage({ event: "pasteError", file: model.get(index).fileName, code: r.status, text: r.statusText ? r.statusText : "Unknown Error" }) + console.warn("error in processing request.", r.status, r.statusText); + } } } } - WorkerScript.sendMessage({ event: "uploading", file: ""}) } } // vim: expandtab ts=4 st=4 sw=4 filetype=javascript diff --git a/qml/pages/FilePage.qml b/qml/pages/FilePage.qml index af7a765..f611f7a 100644 --- a/qml/pages/FilePage.qml +++ b/qml/pages/FilePage.qml @@ -38,11 +38,6 @@ Dialog { id: page } } } - - function loadFiles() { - loader.model = filesModel - loader.reload() - } function upload() { paster.model = filesModel paster.upload() @@ -135,40 +130,43 @@ Dialog { id: page //nameFilters: config.gather.postfixes nameFilters: [ '*.log', '*.txt', '*.json' ] onPopulatedChanged: { - console.debug("dirModel has", dirModel.count, "files"); + console.info("Detected", dirModel.count, "files."); //if (!populated || active) return if (!dirModel.populated) return + transformer.model = null + transformer.active = false filesModel.clear(); transformer.model = dirModel transformer.active = true } } - /* As we can't change elements of dirModel/FileModel, make an extended - * model here. + /* + * Since a FileModel does not have a get() method, and we can't extend its + elements, popuplate our own model with the extended data. + Actually we just really need the "pastedUrl" property. This is a FIXME. + + Use an Instantiator to generate the content, as it can use the model directly. */ Instantiator { id: transformer active: false - delegate: QtObject { - Component.onCompleted: { - const o = {} - o["title"] = ""; - o["mimeType"] = mimeType - o["fileName"] = fileName - o["filePath"] = page.cacheDir + o["fileName"]; - o["url"] = Qt.resolvedUrl(o["filePath"]); - //o["fileSize"] = -1; // prepare property so we don't need dynamicRoles - o["fileSize"] = size; - o["pastedUrl"] = ""; // prepare property so we don't need dynamicRoles - //console.debug("Adding:", JSON.stringify(o,null,2)) - filesModel.append(o) - } + delegate: ListElement { + property string title: "" + property string mimeType: model.mimeType + property string fileName: model.fileName + property string filePath: page.cacheDir + model.fileName + // do not specify an url type here, it will become an object... + property string url: Qt.resolvedUrl(filePath) + property int fileSize: model.size + property string pastedUrl: "" // create property so we don't need dynamicRoles } + // after we're done, add ourselves to the model: + onObjectAdded: function(i,o) { filesModel.set(i,o) } + onObjectRemoved: function(i,o) { filesModel.remove(i) } } LogMailer { id: mailer } // calls jolla-email, Issue #29 LogShare { id: sharer } // calls Share by Email, Issue #29 LogGatherer { id: gather } // executes systemd things - LogLoader { id: loader } // gets file contents LogPaster { id: paster } // uploads files to "pastebin" Connections {