2727#include < QSettings>
2828#include < QSslConfiguration>
2929#include < QSslSocket>
30+ #include < QStandardPaths>
3031#include < QStringList>
3132#include < QTextStream>
3233#include < QTimer>
3637#include < algorithm>
3738#include < cstddef>
3839#include < iterator>
40+ #include < optional>
3941#include < string>
4042#include < utility>
4143
4244using namespace Qt ::Literals::StringLiterals;
4345
4446// #define USE_LOCAL_MODELSJSON
4547
48+ #define MODELS_JSON_VERSION " 3"
49+
4650static const QStringList FILENAME_BLACKLIST { u" gpt4all-nomic-embed-text-v1.rmodel" _s };
4751
4852QString ModelInfo::id () const
@@ -1331,15 +1335,32 @@ void ModelList::updateModelsFromDirectory()
13311335 }
13321336}
13331337
1334- #define MODELS_VERSION 3
1338+ static QString modelsJsonFilename ()
1339+ {
1340+ return QStringLiteral (" models" MODELS_JSON_VERSION " .json" );
1341+ }
1342+
1343+ static std::optional<QFile> modelsJsonCacheFile ()
1344+ {
1345+ constexpr auto loc = QStandardPaths::CacheLocation;
1346+ QString modelsJsonFname = modelsJsonFilename ();
1347+ if (auto path = QStandardPaths::locate (loc, modelsJsonFname); !path.isEmpty ())
1348+ return std::make_optional<QFile>(path);
1349+ if (auto path = QStandardPaths::writableLocation (loc); !path.isEmpty ())
1350+ return std::make_optional<QFile>(path);
1351+ return std::nullopt ;
1352+ }
13351353
13361354void ModelList::updateModelsFromJson ()
13371355{
1356+ QString modelsJsonFname = modelsJsonFilename ();
1357+
13381358#if defined(USE_LOCAL_MODELSJSON)
1339- QUrl jsonUrl (" file://" + QDir::homePath () + u" /dev/large_language_models/gpt4all/gpt4all-chat/metadata/models%1.json " _s.arg (MODELS_VERSION ));
1359+ QUrl jsonUrl (u " file://%1 /dev/large_language_models/gpt4all/gpt4all-chat/metadata/%2 " _s.arg (QDir::homePath (), modelsJsonFname ));
13401360#else
1341- QUrl jsonUrl (u" http://gpt4all.io/models/models%1.json " _s.arg (MODELS_VERSION ));
1361+ QUrl jsonUrl (u" http://gpt4all.io/models/%1 " _s.arg (modelsJsonFname ));
13421362#endif
1363+
13431364 QNetworkRequest request (jsonUrl);
13441365 QSslConfiguration conf = request.sslConfiguration ();
13451366 conf.setPeerVerifyMode (QSslSocket::VerifyNone);
@@ -1358,18 +1379,15 @@ void ModelList::updateModelsFromJson()
13581379 qWarning () << " WARNING: Could not download models.json synchronously" ;
13591380 updateModelsFromJsonAsync ();
13601381
1361- QSettings settings;
1362- QFileInfo info (settings.fileName ());
1363- QString dirPath = info.canonicalPath ();
1364- const QString modelsConfig = dirPath + " /models.json" ;
1365- QFile file (modelsConfig);
1366- if (!file.open (QIODeviceBase::ReadOnly)) {
1367- qWarning () << " ERROR: Couldn't read models config file: " << modelsConfig;
1368- } else {
1369- QByteArray jsonData = file.readAll ();
1370- file.close ();
1382+ auto cacheFile = modelsJsonCacheFile ();
1383+ if (!cacheFile) {
1384+ // no known location
1385+ } else if (cacheFile->open (QIODeviceBase::ReadOnly)) {
1386+ QByteArray jsonData = cacheFile->readAll ();
1387+ cacheFile->close ();
13711388 parseModelsJsonFile (jsonData, false );
1372- }
1389+ } else if (cacheFile->exists ())
1390+ qWarning () << " ERROR: Couldn't read models.json cache file: " << cacheFile->fileName ();
13731391 }
13741392 delete jsonReply;
13751393}
@@ -1378,12 +1396,14 @@ void ModelList::updateModelsFromJsonAsync()
13781396{
13791397 m_asyncModelRequestOngoing = true ;
13801398 emit asyncModelRequestOngoingChanged ();
1399+ QString modelsJsonFname = modelsJsonFilename ();
13811400
13821401#if defined(USE_LOCAL_MODELSJSON)
1383- QUrl jsonUrl (" file://" + QDir::homePath () + u" /dev/large_language_models/gpt4all/gpt4all-chat/metadata/models%1.json " _s.arg (MODELS_VERSION ));
1402+ QUrl jsonUrl (u " file://%1 /dev/large_language_models/gpt4all/gpt4all-chat/metadata/%2 " _s.arg (QDir::homePath (), modelsJsonFname ));
13841403#else
1385- QUrl jsonUrl (u" http://gpt4all.io/models/models%1.json " _s.arg (MODELS_VERSION ));
1404+ QUrl jsonUrl (u" http://gpt4all.io/models/%1 " _s.arg (modelsJsonFname ));
13861405#endif
1406+
13871407 QNetworkRequest request (jsonUrl);
13881408 QSslConfiguration conf = request.sslConfiguration ();
13891409 conf.setPeerVerifyMode (QSslSocket::VerifyNone);
@@ -1446,17 +1466,14 @@ void ModelList::parseModelsJsonFile(const QByteArray &jsonData, bool save)
14461466 }
14471467
14481468 if (save) {
1449- QSettings settings;
1450- QFileInfo info (settings.fileName ());
1451- QString dirPath = info.canonicalPath ();
1452- const QString modelsConfig = dirPath + " /models.json" ;
1453- QFile file (modelsConfig);
1454- if (!file.open (QIODeviceBase::WriteOnly)) {
1455- qWarning () << " ERROR: Couldn't write models config file: " << modelsConfig;
1456- } else {
1457- file.write (jsonData);
1458- file.close ();
1459- }
1469+ auto cacheFile = modelsJsonCacheFile ();
1470+ if (!cacheFile) {
1471+ // no known location
1472+ } else if (QFileInfo (*cacheFile).dir ().mkpath (u" ." _s) && cacheFile->open (QIODeviceBase::WriteOnly)) {
1473+ cacheFile->write (jsonData);
1474+ cacheFile->close ();
1475+ } else
1476+ qWarning () << " ERROR: Couldn't write models config file: " << cacheFile->fileName ();
14601477 }
14611478
14621479 QJsonArray jsonArray = document.array ();
0 commit comments