Move the location of the chat files to the model download directory and add a magic+version.

This commit is contained in:
Adam Treat 2023-05-06 18:51:30 -04:00
parent 7a8f437f8f
commit eb7b61a76d

View File

@ -1,8 +1,12 @@
#include "chatlistmodel.h" #include "chatlistmodel.h"
#include "download.h"
#include <QFile> #include <QFile>
#include <QDataStream> #include <QDataStream>
#define CHAT_FORMAT_MAGIC 0xF5D553CC
#define CHAT_FORMAT_VERSION 100
bool ChatListModel::shouldSaveChats() const bool ChatListModel::shouldSaveChats() const
{ {
return m_shouldSaveChats; return m_shouldSaveChats;
@ -18,10 +22,8 @@ void ChatListModel::setShouldSaveChats(bool b)
void ChatListModel::removeChatFile(Chat *chat) const void ChatListModel::removeChatFile(Chat *chat) const
{ {
QSettings settings; const QString savePath = Download::globalInstance()->downloadLocalModelsPath();
QFileInfo settingsInfo(settings.fileName()); QFile file(savePath + "/gpt4all-" + chat->id() + ".chat");
QString settingsPath = settingsInfo.absolutePath();
QFile file(settingsPath + "/gpt4all-" + chat->id() + ".chat");
if (!file.exists()) if (!file.exists())
return; return;
bool success = file.remove(); bool success = file.remove();
@ -34,18 +36,21 @@ void ChatListModel::saveChats() const
if (!m_shouldSaveChats) if (!m_shouldSaveChats)
return; return;
QSettings settings; const QString savePath = Download::globalInstance()->downloadLocalModelsPath();
QFileInfo settingsInfo(settings.fileName());
QString settingsPath = settingsInfo.absolutePath();
for (Chat *chat : m_chats) { for (Chat *chat : m_chats) {
QString fileName = "gpt4all-" + chat->id() + ".chat"; QString fileName = "gpt4all-" + chat->id() + ".chat";
QFile file(settingsPath + "/" + fileName); QFile file(savePath + "/" + fileName);
bool success = file.open(QIODevice::WriteOnly); bool success = file.open(QIODevice::WriteOnly);
if (!success) { if (!success) {
qWarning() << "ERROR: Couldn't save chat to file:" << file.fileName(); qWarning() << "ERROR: Couldn't save chat to file:" << file.fileName();
continue; continue;
} }
QDataStream out(&file); QDataStream out(&file);
out << (quint32)CHAT_FORMAT_MAGIC;
out << (qint32)CHAT_FORMAT_VERSION;
out.setVersion(QDataStream::Qt_6_5);
qDebug() << "serializing chat" << fileName; qDebug() << "serializing chat" << fileName;
if (!chat->serialize(out)) { if (!chat->serialize(out)) {
qWarning() << "ERROR: Couldn't serialize chat to file:" << file.fileName(); qWarning() << "ERROR: Couldn't serialize chat to file:" << file.fileName();
@ -57,32 +62,81 @@ void ChatListModel::saveChats() const
void ChatListModel::restoreChats() void ChatListModel::restoreChats()
{ {
QSettings settings;
QFileInfo settingsInfo(settings.fileName());
QString settingsPath = settingsInfo.absolutePath();
QDir dir(settingsPath);
dir.setNameFilters(QStringList() << "gpt4all-*.chat");
QStringList fileNames = dir.entryList();
beginResetModel(); beginResetModel();
for (QString f : fileNames) { {
QString filePath = settingsPath + "/" + f; // Look for any files in the original spot which was the settings config directory
QFile file(filePath); QSettings settings;
bool success = file.open(QIODevice::ReadOnly); QFileInfo settingsInfo(settings.fileName());
if (!success) { QString settingsPath = settingsInfo.absolutePath();
qWarning() << "ERROR: Couldn't restore chat from file:" << file.fileName(); QDir dir(settingsPath);
continue; dir.setNameFilters(QStringList() << "gpt4all-*.chat");
QStringList fileNames = dir.entryList();
for (QString f : fileNames) {
QString filePath = settingsPath + "/" + f;
QFile file(filePath);
bool success = file.open(QIODevice::ReadOnly);
if (!success) {
qWarning() << "ERROR: Couldn't restore chat from file:" << file.fileName();
continue;
}
QDataStream in(&file);
Chat *chat = new Chat(this);
if (!chat->deserialize(in)) {
qWarning() << "ERROR: Couldn't deserialize chat from file:" << file.fileName();
file.remove();
} else {
connect(chat, &Chat::nameChanged, this, &ChatListModel::nameChanged);
m_chats.append(chat);
}
qDebug() << "deserializing chat" << f;
file.remove(); // No longer storing in this directory
file.close();
} }
QDataStream in(&file); }
Chat *chat = new Chat(this); {
if (!chat->deserialize(in)) { const QString savePath = Download::globalInstance()->downloadLocalModelsPath();
qWarning() << "ERROR: Couldn't deserialize chat from file:" << file.fileName(); QDir dir(savePath);
file.remove(); dir.setNameFilters(QStringList() << "gpt4all-*.chat");
} else { QStringList fileNames = dir.entryList();
connect(chat, &Chat::nameChanged, this, &ChatListModel::nameChanged); for (QString f : fileNames) {
m_chats.append(chat); QString filePath = savePath + "/" + f;
QFile file(filePath);
bool success = file.open(QIODevice::ReadOnly);
if (!success) {
qWarning() << "ERROR: Couldn't restore chat from file:" << file.fileName();
continue;
}
QDataStream in(&file);
// Read and check the header
quint32 magic;
in >> magic;
if (magic != CHAT_FORMAT_MAGIC) {
qWarning() << "ERROR: Chat file has bad magic:" << file.fileName();
continue;
}
// Read the version
qint32 version;
in >> version;
if (version < 100) {
qWarning() << "ERROR: Chat file has non supported version:" << file.fileName();
continue;
}
if (version <= 100)
in.setVersion(QDataStream::Qt_6_5);
Chat *chat = new Chat(this);
if (!chat->deserialize(in)) {
qWarning() << "ERROR: Couldn't deserialize chat from file:" << file.fileName();
file.remove();
} else {
connect(chat, &Chat::nameChanged, this, &ChatListModel::nameChanged);
m_chats.append(chat);
}
qDebug() << "deserializing chat" << f;
file.close();
} }
qDebug() << "deserializing chat" << f;
file.close();
} }
std::sort(m_chats.begin(), m_chats.end(), [](const Chat* a, const Chat* b) { std::sort(m_chats.begin(), m_chats.end(), [](const Chat* a, const Chat* b) {
return a->creationDate() > b->creationDate(); return a->creationDate() > b->creationDate();