downloaded files now stored with squawk:// prefix, that way I can move downloads folder without messing up the database

This commit is contained in:
Blue 2022-02-19 00:27:09 +03:00
parent 243edff8bd
commit d8b5ccb2da
Signed by untrusted user: blue
GPG Key ID: 9B203B252A63EE38
14 changed files with 75 additions and 44 deletions

View File

@ -32,4 +32,3 @@ target_include_directories(squawk PRIVATE ${LMDB_INCLUDE_DIRS})
add_subdirectory(handlers) add_subdirectory(handlers)
add_subdirectory(passwordStorageEngines) add_subdirectory(passwordStorageEngines)
add_subdirectory(utils)

View File

@ -299,6 +299,14 @@ void Core::MessageHandler::performSending(Shared::Message data, bool newMessage)
} }
changes.insert("stamp", sendTime); changes.insert("stamp", sendTime);
//sometimes (when the image is pasted with ctrl+v)
//I start sending message with one path, then copy it to downloads directory
//so, the final path changes. Let's assume it changes always since it costs me close to nothing
QString attachPath = data.getAttachPath();
if (attachPath.size() > 0) {
changes.insert("attachPath", attachPath);
}
if (ri != 0) { if (ri != 0) {
if (newMessage) { if (newMessage) {
ri->appendMessageToArchive(data); ri->appendMessageToArchive(data);
@ -439,14 +447,15 @@ void Core::MessageHandler::handleUploadError(const QString& jid, const QString&
}); });
} }
void Core::MessageHandler::onUploadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& path) void Core::MessageHandler::onUploadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& url, const QString& path)
{ {
for (const Shared::MessageInfo& info : msgs) { for (const Shared::MessageInfo& info : msgs) {
if (info.account == acc->getName()) { if (info.account == acc->getName()) {
RosterItem* ri = acc->rh->getRosterItem(info.jid); RosterItem* ri = acc->rh->getRosterItem(info.jid);
if (ri != 0) { if (ri != 0) {
Shared::Message msg = ri->getMessage(info.messageId); Shared::Message msg = ri->getMessage(info.messageId);
sendMessageWithLocalUploadedFile(msg, path, false); msg.setAttachPath(path);
sendMessageWithLocalUploadedFile(msg, url, false);
} else { } else {
qDebug() << "A signal received about complete upload to" << acc->name << "for pal" << info.jid << "but the object for this pal wasn't found, something went terrebly wrong, skipping send"; qDebug() << "A signal received about complete upload to" << acc->name << "for pal" << info.jid << "but the object for this pal wasn't found, something went terrebly wrong, skipping send";
} }

View File

@ -57,7 +57,7 @@ public slots:
void onUploadSlotReceived(const QXmppHttpUploadSlotIq& slot); void onUploadSlotReceived(const QXmppHttpUploadSlotIq& slot);
void onUploadSlotRequestFailed(const QXmppHttpUploadRequestIq& request); void onUploadSlotRequestFailed(const QXmppHttpUploadRequestIq& request);
void onDownloadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& path); void onDownloadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& path);
void onUploadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& path); void onUploadFileComplete(const std::list<Shared::MessageInfo>& msgs, const QString& url, const QString& path);
void onLoadFileError(const std::list<Shared::MessageInfo>& msgs, const QString& path, bool up); void onLoadFileError(const std::list<Shared::MessageInfo>& msgs, const QString& path, bool up);
void requestChangeMessage(const QString& jid, const QString& messageId, const QMap<QString, QVariant>& data); void requestChangeMessage(const QString& jid, const QString& messageId, const QMap<QString, QVariant>& data);

View File

@ -18,10 +18,10 @@
#include "../shared/global.h" #include "../shared/global.h"
#include "../shared/messageinfo.h" #include "../shared/messageinfo.h"
#include "../shared/pathcheck.h"
#include "../ui/squawk.h" #include "../ui/squawk.h"
#include "signalcatcher.h" #include "signalcatcher.h"
#include "squawk.h" #include "squawk.h"
#include "utils/pathcheck.h"
#include <QLibraryInfo> #include <QLibraryInfo>
#include <QSettings> #include <QSettings>
@ -109,7 +109,7 @@ int main(int argc, char *argv[])
} }
} }
} }
QString path = Utils::downloadsPathCheck(); QString path = Shared::downloadsPathCheck();
if (path.size() > 0) { if (path.size() > 0) {
settings.setValue("downloadsPath", path); settings.setValue("downloadsPath", path);
} else { } else {

View File

@ -305,7 +305,7 @@ void Core::NetworkAccess::onDownloadFinished()
if (path.size() > 0) { if (path.size() > 0) {
path = checkFileName(fileName, path); path = checkFileName(fileName, path);
QFile file(path); QFile file(Shared::resolvePath(path));
if (file.open(QIODevice::WriteOnly)) { if (file.open(QIODevice::WriteOnly)) {
file.write(dwn->reply->readAll()); file.write(dwn->reply->readAll());
file.close(); file.close();
@ -380,22 +380,19 @@ void Core::NetworkAccess::onUploadFinished()
if (upl->success) { if (upl->success) {
qDebug() << "upload success for" << url; qDebug() << "upload success for" << url;
storage.addFile(upl->messages, upl->url, upl->path);
emit uploadFileComplete(upl->messages, upl->url, upl->path);
// Copy file to Download folder if it is a temp file. See Conversation::onImagePasted. // Copy file to Download folder if it is a temp file. See Conversation::onImagePasted.
if (upl->path.startsWith(QDir::tempPath() + QStringLiteral("/squawk_img_attach_")) && upl->path.endsWith(".png")) { if (upl->path.startsWith(QDir::tempPath() + QDir::separator() + QStringLiteral("squawk_img_attach_")) && upl->path.endsWith(".png")) {
QString err = ""; QString err = "";
QString downloadDirPath = prepareDirectory(upl->messages.front().jid); QString downloadDirPath = prepareDirectory(upl->messages.front().jid);
if (downloadDirPath.size() > 0) { if (downloadDirPath.size() > 0) {
QString newPath = downloadDirPath + "/" + upl->path.mid(QDir::tempPath().length() + 1); QString newPath = downloadDirPath + QDir::separator() + upl->path.mid(QDir::tempPath().length() + 1);
// Copy {TEMPDIR}/squawk_img_attach_XXXXXX.png to Download folder // Copy {TEMPDIR}/squawk_img_attach_XXXXXX.png to Download folder
bool copyResult = QFile::copy(upl->path, newPath); bool copyResult = QFile::copy(upl->path, Shared::resolvePath(newPath));
if (copyResult) { if (copyResult) {
// Change storage // Change storage
storage.setPath(upl->url, newPath); upl->path = newPath;
} else { } else {
err = "copying to " + newPath + " failed"; err = "copying to " + newPath + " failed";
} }
@ -407,6 +404,9 @@ void Core::NetworkAccess::onUploadFinished()
qDebug() << "failed to copy temporary upload file " << upl->path << " to download folder:" << err; qDebug() << "failed to copy temporary upload file " << upl->path << " to download folder:" << err;
} }
} }
storage.addFile(upl->messages, upl->url, upl->path);
emit uploadFileComplete(upl->messages, upl->url, upl->path);
} }
upl->reply->deleteLater(); upl->reply->deleteLater();
@ -519,9 +519,12 @@ bool Core::NetworkAccess::checkAndAddToUploading(const QString& acc, const QStri
QString Core::NetworkAccess::prepareDirectory(const QString& jid) QString Core::NetworkAccess::prepareDirectory(const QString& jid)
{ {
QString path = currentPath; QString path = currentPath;
QString addition;
if (jid.size() > 0) { if (jid.size() > 0) {
path += "/" + jid; addition = jid;
path += QDir::separator() + jid;
} }
QDir location(path); QDir location(path);
if (!location.exists()) { if (!location.exists()) {
@ -529,10 +532,10 @@ QString Core::NetworkAccess::prepareDirectory(const QString& jid)
if (!res) { if (!res) {
return ""; return "";
} else { } else {
return path; return "squawk://" + addition;
} }
} }
return path; return "squawk://" + addition;
} }
QString Core::NetworkAccess::checkFileName(const QString& name, const QString& path) QString Core::NetworkAccess::checkFileName(const QString& name, const QString& path)
@ -546,14 +549,17 @@ QString Core::NetworkAccess::checkFileName(const QString& name, const QString& p
suffix += "." + (*sItr); suffix += "." + (*sItr);
} }
QString postfix(""); QString postfix("");
QFileInfo proposedName(path + "/" + realName + suffix); QString resolvedPath = Shared::resolvePath(path);
QString count("");
QFileInfo proposedName(resolvedPath + QDir::separator() + realName + count + suffix);
int counter = 0; int counter = 0;
while (proposedName.exists()) { while (proposedName.exists()) {
QString count = QString("(") + std::to_string(++counter).c_str() + ")"; count = QString("(") + std::to_string(++counter).c_str() + ")";
proposedName = QFileInfo(path + "/" + realName + count + suffix); proposedName = QFileInfo(resolvedPath + QDir::separator() + realName + count + suffix);
} }
return proposedName.absoluteFilePath(); return path + QDir::separator() + realName + count + suffix;
} }
QString Core::NetworkAccess::addMessageAndCheckForPath(const QString& url, const QString& account, const QString& jid, const QString& id) QString Core::NetworkAccess::addMessageAndCheckForPath(const QString& url, const QString& account, const QString& jid, const QString& id)
@ -568,5 +574,10 @@ std::list<Shared::MessageInfo> Core::NetworkAccess::reportPathInvalid(const QStr
void Core::NetworkAccess::moveFilesDirectory(const QString& newPath) void Core::NetworkAccess::moveFilesDirectory(const QString& newPath)
{ {
QDir dir;
if (dir.rename(currentPath, newPath)) {
currentPath = newPath;
} else {
qDebug() << "couldn't move downloads directory, most probably downloads will be broken";
}
} }

View File

@ -31,6 +31,7 @@
#include <set> #include <set>
#include "urlstorage.h" #include "urlstorage.h"
#include "shared/pathcheck.h"
namespace Core { namespace Core {

View File

@ -1,4 +0,0 @@
target_sources(squawk PRIVATE
pathcheck.h
pathcheck.cpp
)

View File

@ -16,4 +16,6 @@ target_sources(squawk PRIVATE
utils.h utils.h
vcard.cpp vcard.cpp
vcard.h vcard.h
pathcheck.cpp
pathcheck.h
) )

View File

@ -1,6 +1,7 @@
#include "pathcheck.h" #include "pathcheck.h"
QString Utils::downloadsPathCheck() QRegularExpression squawk("^squawk:\\/\\/");
QString Shared::downloadsPathCheck()
{ {
QSettings settings; QSettings settings;
QVariant dpv = settings.value("downloadsPath"); QVariant dpv = settings.value("downloadsPath");
@ -8,40 +9,47 @@ QString Utils::downloadsPathCheck()
if (!dpv.isValid()) { if (!dpv.isValid()) {
path = defaultDownloadsPath(); path = defaultDownloadsPath();
qDebug() << "no downloadsPath variable in config, using default" << path; qDebug() << "no downloadsPath variable in config, using default" << path;
path = getCanonicalWritablePath(path); path = getAbsoluteWritablePath(path);
return path; return path;
} else { } else {
path = dpv.toString(); path = dpv.toString();
path = getCanonicalWritablePath(path); path = getAbsoluteWritablePath(path);
if (path.size() == 0) { if (path.size() == 0) {
path = defaultDownloadsPath(); path = defaultDownloadsPath();
qDebug() << "falling back to the default downloads path" << path; qDebug() << "falling back to the default downloads path" << path;
path = getCanonicalWritablePath(path); path = getAbsoluteWritablePath(path);
} }
return path; return path;
} }
} }
QString Utils::defaultDownloadsPath() QString Shared::defaultDownloadsPath()
{ {
return QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + "/" + QApplication::applicationName(); return QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + "/" + QApplication::applicationName();
} }
QString Utils::getCanonicalWritablePath(const QString& path) QString Shared::getAbsoluteWritablePath(const QString& path)
{ {
QDir location(path); QDir location(path);
if (!location.exists()) { if (!location.exists()) {
bool res = location.mkpath(location.canonicalPath()); bool res = location.mkpath(location.absolutePath());
if (!res) { if (!res) {
qDebug() << "couldn't create directory" << path; qDebug() << "couldn't create directory" << path;
return ""; return "";
} }
} }
QFileInfo info(location.canonicalPath()); QFileInfo info(location.absolutePath());
if (info.isWritable()) { if (info.isWritable()) {
return location.canonicalPath(); return location.absolutePath();
} else { } else {
qDebug() << "directory" << path << "is not writable"; qDebug() << "directory" << path << "is not writable";
return ""; return "";
} }
} }
QString Shared::resolvePath(QString path)
{
QSettings settings;
QVariant dpv = settings.value("downloadsPath");
return path.replace(squawk, dpv.toString() + "/");
}

View File

@ -8,13 +8,15 @@
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QDebug> #include <QDebug>
#include <QRegularExpression>
namespace Utils { namespace Shared {
QString downloadsPathCheck(); QString downloadsPathCheck();
QString defaultDownloadsPath(); QString defaultDownloadsPath();
QString getCanonicalWritablePath(const QString& path); QString getAbsoluteWritablePath(const QString& path);
QString resolvePath(QString path);
} }

View File

@ -483,7 +483,7 @@ void Conversation::onFeedContext(const QPoint& pos)
}); });
} }
QString path = item->getAttachPath(); QString path = Shared::resolvePath(item->getAttachPath());
if (path.size() > 0) { if (path.size() > 0) {
showMenu = true; showMenu = true;
QAction* open = contextMenu->addAction(Shared::icon("document-preview"), tr("Open")); QAction* open = contextMenu->addAction(Shared::icon("document-preview"), tr("Open"));

View File

@ -33,6 +33,7 @@
#include "shared/order.h" #include "shared/order.h"
#include "shared/icons.h" #include "shared/icons.h"
#include "shared/utils.h" #include "shared/utils.h"
#include "shared/pathcheck.h"
#include "ui/models/account.h" #include "ui/models/account.h"
#include "ui/models/roster.h" #include "ui/models/roster.h"

View File

@ -314,7 +314,7 @@ QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel
case Models::none: case Models::none:
break; break;
case Models::uploading: case Models::uploading:
messageSize.rheight() += Preview::calculateAttachSize(data.attach.localPath, messageRect).height() + textMargin; messageSize.rheight() += Preview::calculateAttachSize(Shared::resolvePath(data.attach.localPath), messageRect).height() + textMargin;
[[fallthrough]]; [[fallthrough]];
case Models::downloading: case Models::downloading:
messageSize.rheight() += barHeight + textMargin; messageSize.rheight() += barHeight + textMargin;
@ -326,7 +326,7 @@ QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel
break; break;
case Models::ready: case Models::ready:
case Models::local: { case Models::local: {
QSize aSize = Preview::calculateAttachSize(data.attach.localPath, messageRect); QSize aSize = Preview::calculateAttachSize(Shared::resolvePath(data.attach.localPath), messageRect);
messageSize.rheight() += aSize.height() + textMargin; messageSize.rheight() += aSize.height() + textMargin;
messageSize.setWidth(std::max(messageSize.width(), aSize.width())); messageSize.setWidth(std::max(messageSize.width(), aSize.width()));
} }
@ -338,7 +338,7 @@ QSize MessageDelegate::sizeHint(const QStyleOptionViewItem& option, const QModel
} }
break; break;
case Models::errorUpload: { case Models::errorUpload: {
QSize aSize = Preview::calculateAttachSize(data.attach.localPath, messageRect); QSize aSize = Preview::calculateAttachSize(Shared::resolvePath(data.attach.localPath), messageRect);
QSize commentSize = dateMetrics.boundingRect(messageRect, Qt::TextWordWrap, data.attach.error).size(); QSize commentSize = dateMetrics.boundingRect(messageRect, Qt::TextWordWrap, data.attach.error).size();
messageSize.rheight() += aSize.height() + commentSize.height() + textMargin * 2; messageSize.rheight() += aSize.height() + commentSize.height() + textMargin * 2;
messageSize.setWidth(std::max(messageSize.width(), std::max(commentSize.width(), aSize.width()))); messageSize.setWidth(std::max(messageSize.width(), std::max(commentSize.width(), aSize.width())));
@ -455,12 +455,13 @@ int MessageDelegate::paintPreview(const Models::FeedItem& data, QPainter* painte
std::map<QString, Preview*>::iterator itr = previews->find(data.id); std::map<QString, Preview*>::iterator itr = previews->find(data.id);
QSize size = option.rect.size(); QSize size = option.rect.size();
QString path = Shared::resolvePath(data.attach.localPath);
if (itr != previews->end()) { if (itr != previews->end()) {
preview = itr->second; preview = itr->second;
preview->actualize(data.attach.localPath, size, option.rect.topLeft()); preview->actualize(path, size, option.rect.topLeft());
} else { } else {
QWidget* vp = static_cast<QWidget*>(painter->device()); QWidget* vp = static_cast<QWidget*>(painter->device());
preview = new Preview(data.attach.localPath, size, option.rect.topLeft(), vp); preview = new Preview(path, size, option.rect.topLeft(), vp);
previews->insert(std::make_pair(data.id, preview)); previews->insert(std::make_pair(data.id, preview));
} }

View File

@ -33,6 +33,7 @@
#include "shared/icons.h" #include "shared/icons.h"
#include "shared/global.h" #include "shared/global.h"
#include "shared/utils.h" #include "shared/utils.h"
#include "shared/pathcheck.h"
#include "preview.h" #include "preview.h"