| 1017 | } |
| 1018 | |
| 1019 | bool cleanUpOldDesktopIntegrationResources(bool verbose) { |
| 1020 | auto dirPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/applications"; |
| 1021 | |
| 1022 | auto directory = QDir(dirPath); |
| 1023 | |
| 1024 | QStringList filters; |
| 1025 | filters << "appimagekit_*.desktop"; |
| 1026 | |
| 1027 | directory.setNameFilters(filters); |
| 1028 | |
| 1029 | for (auto desktopFilePath : directory.entryList()) { |
| 1030 | desktopFilePath = dirPath + "/" + desktopFilePath; |
| 1031 | |
| 1032 | std::shared_ptr<GKeyFile> desktopFile(g_key_file_new(), [](GKeyFile* p) { |
| 1033 | g_key_file_free(p); |
| 1034 | }); |
| 1035 | |
| 1036 | if (!g_key_file_load_from_file(desktopFile.get(), desktopFilePath.toStdString().c_str(), G_KEY_FILE_NONE, nullptr)) { |
| 1037 | continue; |
| 1038 | } |
| 1039 | |
| 1040 | std::shared_ptr<char> execValue(g_key_file_get_string(desktopFile.get(), G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_EXEC, nullptr), [](char* p) { |
| 1041 | free(p); |
| 1042 | }); |
| 1043 | |
| 1044 | // if there is no Exec value in the file, the desktop file is apparently broken, therefore we skip the file |
| 1045 | if (execValue == nullptr) { |
| 1046 | continue; |
| 1047 | } |
| 1048 | |
| 1049 | std::shared_ptr<char> tryExecValue(g_key_file_get_string(desktopFile.get(), G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_TRY_EXEC, nullptr), [](char* p) { |
| 1050 | free(p); |
| 1051 | }); |
| 1052 | |
| 1053 | // TryExec is optional, although recently the desktop integration functions started to force add such keys |
| 1054 | // with a path to the desktop file |
| 1055 | // (before, if it existed, the key was replaced with the AppImage's path) |
| 1056 | // If it exists, we assume its value is the full path to the AppImage, which can be used to check the existence |
| 1057 | // of the AppImage |
| 1058 | QString appImagePath; |
| 1059 | |
| 1060 | if (tryExecValue != nullptr) { |
| 1061 | appImagePath = QString(tryExecValue.get()); |
| 1062 | } else { |
| 1063 | appImagePath = QString(execValue.get()).split(" ").first(); |
| 1064 | } |
| 1065 | |
| 1066 | // now, check whether AppImage exists |
| 1067 | // FIXME: the split command for the Exec value might not work if there's a space in the filename |
| 1068 | // we really need a parser that understands the desktop file escaping |
| 1069 | if (!QFile(appImagePath).exists()) { |
| 1070 | if (verbose) |
| 1071 | std::cout << "AppImage no longer exists, cleaning up resources: " << appImagePath.toStdString() << std::endl; |
| 1072 | |
| 1073 | if (verbose) |
| 1074 | std::cout << "Removing desktop file: " << desktopFilePath.toStdString() << std::endl; |
| 1075 | |
| 1076 | QFile(desktopFilePath).remove(); |
no outgoing calls
no test coverage detected