Skip to content

Commit 8695b84

Browse files
[DC-53] feat: remove suffix plugin (#12174)
Suffix VFS was deprecated in late 2023 for desktop client 6.0. Now with 7.0 we finally remove it. #11365
1 parent a21beff commit 8695b84

32 files changed

+103
-2025
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ add_feature_info(AppImageUpdate WITH_APPIMAGEUPDATER "Built-in libappimageupdate
101101
option(WITH_EXTERNAL_BRANDING "A URL to an external branding repo" "")
102102

103103
# specify additional vfs plugins
104-
set(VIRTUAL_FILE_SYSTEM_PLUGINS off suffix win CACHE STRING "Name of internal plugin in src/libsync/vfs or the locations of virtual file plugins")
104+
set(VIRTUAL_FILE_SYSTEM_PLUGINS off win CACHE STRING "Name of internal plugin in src/libsync/vfs or the locations of virtual file plugins")
105105

106106
if(APPLE)
107107
set( SOCKETAPI_TEAM_IDENTIFIER_PREFIX "" CACHE STRING "SocketApi prefix (including a following dot) that must match the codesign key's TeamIdentifier/Organizational Unit" )

THEME.cmake

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@ endif()
2929

3030
message(STATUS "Branding: ${APPLICATION_NAME}")
3131

32-
# Default suffix if the theme doesn't define one
33-
if(NOT DEFINED APPLICATION_VIRTUALFILE_SUFFIX)
34-
set(APPLICATION_VIRTUALFILE_SUFFIX "${APPLICATION_SHORTNAME}_virtual" CACHE STRING "Virtual file suffix (not including the .)")
35-
endif()
32+
set(APPLICATION_REV_DOMAIN_INSTALLER ${APPLICATION_REV_DOMAIN})
3633

3734
# need this logic to not mess with re/uninstallations via macosx.pkgproj
3835
if(${APPLICATION_REV_DOMAIN} STREQUAL "com.owncloud.desktopclient")

src/common/vfs.cpp

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,14 @@ Vfs::Vfs(QObject* parent)
4040
{
4141
}
4242

43-
QString Vfs::underlyingFileName(const QString &fileName) const
44-
{
45-
return fileName;
46-
}
47-
4843
Vfs::~Vfs() = default;
4944

5045
Vfs::Mode Vfs::modeFromString(const QString &str)
5146
{
5247
// Note: Strings are used for config and must be stable
5348
// keep in sync with: QString Utility::enumToString(Vfs::Mode mode)
54-
// which is defined BELOW
55-
if (str == QLatin1String("suffix")) {
56-
return WithSuffix;
49+
if (str == QLatin1String("off")) {
50+
return Off;
5751
} else if (str == QLatin1String("wincfapi")) {
5852
return WindowsCfApi;
5953
}
@@ -66,8 +60,6 @@ QString Utility::enumToString(Vfs::Mode mode)
6660
// Note: Strings are used for config and must be stable
6761
// keep in sync with: Optional<Vfs::Mode> Vfs::modeFromString(const QString &str)
6862
switch (mode) {
69-
case Vfs::Mode::WithSuffix:
70-
return QStringLiteral("suffix");
7163
case Vfs::Mode::WindowsCfApi:
7264
return QStringLiteral("wincfapi");
7365
case Vfs::Mode::Off:
@@ -162,7 +154,7 @@ void Vfs::wipeDehydratedVirtualFiles()
162154
_setupParams->journal->deleteFileRecord(relativePath);
163155

164156
// If the local file is a dehydrated placeholder, wipe it too.
165-
// Otherwise leave it to allow the next sync to have a new-new conflict.
157+
// Otherwise, leave it to allow the next sync to have a new-new conflict.
166158
const QString absolutePath = _setupParams->filesystemPath + relativePath;
167159
if (QFile::exists(absolutePath)) {
168160
// according to our db this is a dehydrated file, check it to be sure
@@ -199,17 +191,17 @@ bool OCC::VfsPluginManager::isVfsPluginAvailable(Vfs::Mode mode) const
199191
auto pluginPath = pluginFileName(QStringLiteral("vfs"), name);
200192
QPluginLoader loader(pluginPath);
201193

202-
auto basemeta = loader.metaData();
203-
if (basemeta.isEmpty() || !basemeta.contains(QStringLiteral("IID"))) {
194+
auto baseMetaData = loader.metaData();
195+
if (baseMetaData.isEmpty() || !baseMetaData.contains(QStringLiteral("IID"))) {
204196
qCDebug(lcPlugin) << "Plugin doesn't exist:" << loader.fileName() << "LibraryPath:" << QCoreApplication::libraryPaths();
205197
return false;
206198
}
207-
if (basemeta[QStringLiteral("IID")].toString() != QLatin1String("org.owncloud.PluginFactory")) {
208-
qCWarning(lcPlugin) << "Plugin has wrong IID" << loader.fileName() << basemeta[QStringLiteral("IID")];
199+
if (baseMetaData[QStringLiteral("IID")].toString() != QLatin1String("org.owncloud.PluginFactory")) {
200+
qCWarning(lcPlugin) << "Plugin has wrong IID" << loader.fileName() << baseMetaData[QStringLiteral("IID")];
209201
return false;
210202
}
211203

212-
auto metadata = basemeta[QStringLiteral("MetaData")].toObject();
204+
auto metadata = baseMetaData[QStringLiteral("MetaData")].toObject();
213205
if (metadata[QStringLiteral("type")].toString() != QLatin1String("vfs")) {
214206
qCWarning(lcPlugin) << "Plugin has wrong type" << loader.fileName() << metadata[QStringLiteral("type")];
215207
return false;
@@ -236,10 +228,6 @@ Vfs::Mode OCC::VfsPluginManager::bestAvailableVfsMode() const
236228
{
237229
if (isVfsPluginAvailable(Vfs::WindowsCfApi)) {
238230
return Vfs::WindowsCfApi;
239-
} else if (isVfsPluginAvailable(Vfs::WithSuffix)) {
240-
return Vfs::WithSuffix;
241-
} else if (isVfsPluginAvailable(Vfs::Off)) {
242-
return Vfs::Off;
243231
}
244232

245233
return Vfs::Off;
@@ -253,7 +241,7 @@ std::unique_ptr<Vfs> OCC::VfsPluginManager::createVfsFromPlugin(Vfs::Mode mode)
253241
auto pluginPath = pluginFileName(QStringLiteral("vfs"), name);
254242

255243
if (!isVfsPluginAvailable(mode)) {
256-
qCCritical(lcPlugin) << "Could not load plugin: not existant or bad metadata" << pluginPath;
244+
qCCritical(lcPlugin) << "Could not load plugin: not existent or bad metadata" << pluginPath;
257245
return nullptr;
258246
}
259247

src/common/vfs.h

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include "utility.h"
2424

2525
#include <QObject>
26-
#include <QScopedPointer>
2726
#include <QSharedPointer>
2827
#include <QUrl>
2928
#include <QVersionNumber>
@@ -53,7 +52,7 @@ struct OCSYNC_EXPORT VfsSetupParams
5352
*/
5453
QString remotePath;
5554

56-
/// Account url, credentials etc for network calls
55+
/// Account url, credentials etc. for network calls
5756
AccountPtr account;
5857

5958
/** Access to the sync folder's database.
@@ -68,7 +67,7 @@ struct OCSYNC_EXPORT VfsSetupParams
6867
QVersionNumber providerVersion;
6968

7069
/** when registering with the system we might use
71-
* a different presentaton to identify the accounts
70+
* a different presentation to identify the accounts
7271
*/
7372
bool multipleAccountsRegistered = false;
7473

@@ -111,11 +110,7 @@ class OCSYNC_EXPORT Vfs : public QObject
111110
*
112111
* Currently plugins and modes are one-to-one but that's not required.
113112
*/
114-
enum Mode {
115-
Off,
116-
WithSuffix,
117-
WindowsCfApi
118-
};
113+
enum Mode { Off, WindowsCfApi };
119114
Q_ENUM(Mode)
120115
enum class ConvertToPlaceholderResult {
121116
Ok,
@@ -142,13 +137,6 @@ class OCSYNC_EXPORT Vfs : public QObject
142137

143138
virtual Mode mode() const = 0;
144139

145-
/// For WithSuffix modes: the suffix (including the dot)
146-
virtual QString fileSuffix() const = 0;
147-
148-
/// The fileName without fileSuffix
149-
/// TODO: better naming welcome
150-
virtual QString underlyingFileName(const QString &fileName) const;
151-
152140
/// Access to the parameters the instance was start()ed with.
153141
const VfsSetupParams &params() const { return *_setupParams.get(); }
154142

@@ -251,7 +239,7 @@ public Q_SLOTS:
251239
/// we encountered an error
252240
void error(const QString &error);
253241

254-
/// The vfs plugin detected that the meta data are out of sync and requests a sync with the server
242+
/// The vfs plugin detected that the metadata are out of sync and requests a sync with the server
255243
void needSync();
256244

257245
protected:
@@ -262,7 +250,7 @@ public Q_SLOTS:
262250
*/
263251
[[nodiscard]] virtual Result<ConvertToPlaceholderResult, QString> updateMetadata(const SyncFileItem &item, const QString &filePath, const QString &replacesFile) = 0;
264252

265-
/** Setup the plugin for the folder.
253+
/** Set up the plugin for the folder.
266254
*
267255
* For example, the VFS provider might monitor files to be able to start a file
268256
* hydration (download of a file's remote contents) when the user wants to open

src/csync/config.h.in

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
#cmakedefine APPLICATION_EXECUTABLE "@APPLICATION_EXECUTABLE@"
1818
#cmakedefine APPLICATION_UPDATE_URL "@APPLICATION_UPDATE_URL@"
1919
#cmakedefine APPLICATION_ICON_NAME "@APPLICATION_ICON_NAME@"
20-
#cmakedefine APPLICATION_VIRTUALFILE_SUFFIX "@APPLICATION_VIRTUALFILE_SUFFIX@"
21-
#define APPLICATION_DOTVIRTUALFILE_SUFFIX "." APPLICATION_VIRTUALFILE_SUFFIX
2220

2321
#cmakedefine SYSCONFDIR "@SYSCONFDIR@"
2422

src/csync/csync_exclude.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ OCSYNC_EXPORT bool csync_is_windows_reserved_word(QStringView filename)
120120
if (static_cast<size_t>(word.size()) > len_filename) {
121121
break;
122122
}
123-
// until windows 11, not only the device names where illegal file names
123+
// until Windows 11, not only the device names where illegal file names
124124
// also COM9.png was illegal
125125
if ((static_cast<size_t>(word.size()) == len_filename || filename.at(word.size()) == QLatin1Char('.')) && filename.startsWith(word, Qt::CaseInsensitive)) {
126126
return true;
@@ -165,10 +165,6 @@ static CSYNC_EXCLUDE_TYPE _csync_excluded_common(QStringView path, bool excludeC
165165
}
166166
}
167167

168-
if (bname.endsWith(QLatin1String(APPLICATION_DOTVIRTUALFILE_SUFFIX), Qt::CaseInsensitive)) { // ".owncloud" placeholder
169-
return CSYNC_FILE_EXCLUDE_RESERVED;
170-
}
171-
172168
// check the strlen and ignore the file if its name is longer than 254 chars.
173169
// whenever changing this also check createDownloadTmpFileName
174170
if (blen > 254) {
@@ -397,32 +393,33 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::traversalPatternMatch(QStringView path, ItemTy
397393
bnameStr = path.mid(lastSlash + 1);
398394
}
399395

400-
QRegularExpressionMatch m;
396+
QRegularExpressionMatch regularExpressionMatch;
401397
if (filetype == ItemTypeDirectory) {
402-
m = _bnameTraversalRegexDir.match(bnameStr);
398+
regularExpressionMatch = _bnameTraversalRegexDir.matchView(bnameStr);
403399
} else {
404-
m = _bnameTraversalRegexFile.match(bnameStr);
400+
regularExpressionMatch = _bnameTraversalRegexFile.matchView(bnameStr);
405401
}
406-
if (!m.hasMatch())
402+
if (!regularExpressionMatch.hasMatch())
407403
return CSYNC_NOT_EXCLUDED;
408-
if (m.capturedStart(QStringLiteral("exclude")) != -1) {
404+
if (regularExpressionMatch.capturedStart(QStringLiteral("exclude")) != -1) {
409405
return CSYNC_FILE_EXCLUDE_LIST;
410-
} else if (m.capturedStart(QStringLiteral("excluderemove")) != -1) {
406+
} else if (regularExpressionMatch.capturedStart(QStringLiteral("excluderemove")) != -1) {
411407
return CSYNC_FILE_EXCLUDE_AND_REMOVE;
412408
}
413409

414410
// third capture: full path matching is triggered
415411
QStringView pathStr = path;
416412

417413
if (filetype == ItemTypeDirectory) {
418-
m = _fullTraversalRegexDir.match(pathStr);
414+
regularExpressionMatch = _fullTraversalRegexDir.matchView(pathStr);
419415
} else {
420-
m = _fullTraversalRegexFile.match(pathStr);
416+
regularExpressionMatch = _fullTraversalRegexFile.matchView(pathStr);
421417
}
422-
if (m.hasMatch()) {
423-
if (m.capturedStart(QStringLiteral("exclude")) != -1) {
418+
if (regularExpressionMatch.hasMatch()) {
419+
if (regularExpressionMatch.capturedStart(QStringLiteral("exclude")) != -1) {
424420
return CSYNC_FILE_EXCLUDE_LIST;
425-
} else if (m.capturedStart(QStringLiteral("excluderemove")) != -1) {
421+
}
422+
if (regularExpressionMatch.capturedStart(QStringLiteral("excluderemove")) != -1) {
426423
return CSYNC_FILE_EXCLUDE_AND_REMOVE;
427424
}
428425
}
@@ -439,9 +436,9 @@ CSYNC_EXCLUDE_TYPE ExcludedFiles::fullPatternMatch(QStringView p, ItemType filet
439436

440437
QRegularExpressionMatch m;
441438
if (filetype == ItemTypeDirectory) {
442-
m = _fullRegexDir.match(p);
439+
m = _fullRegexDir.matchView(p);
443440
} else {
444-
m = _fullRegexFile.match(p);
441+
m = _fullRegexFile.matchView(p);
445442
}
446443
if (m.hasMatch()) {
447444
if (m.capturedStart(QStringLiteral("exclude")) != -1) {

src/gui/MacOSXBundleInfo.plist

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -38,42 +38,5 @@
3838
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
3939
<key>CFBundleAllowMixedLocalizations</key>
4040
<true/>
41-
42-
<key>UTExportedTypeDeclarations</key>
43-
<array>
44-
<dict>
45-
<key>UTTypeIdentifier</key>
46-
<string>${APPLICATION_REV_DOMAIN}.VIRTUALFILE</string>
47-
<key>UTTypeTagSpecification</key>
48-
<dict>
49-
<key>public.filename-extension</key>
50-
<string>${APPLICATION_VIRTUALFILE_SUFFIX}</string>
51-
<key>public.mime-type</key>
52-
<string>application/octet-stream</string>
53-
</dict>
54-
<key>UTTypeConformsTo</key>
55-
<array>
56-
<string>public.data</string>
57-
</array>
58-
</dict>
59-
</array>
60-
61-
<key>CFBundleDocumentTypes</key>
62-
<array>
63-
<dict>
64-
<key>CFBundleTypeName</key>
65-
<string>${APPLICATION_EXECUTABLE} Download Virtual File</string>
66-
<key>CFBundleTypeRole</key>
67-
<string>Editor</string>
68-
<key>LSHandlerRank</key>
69-
<string>Owner</string>
70-
<key>LSItemContentTypes</key>
71-
<array>
72-
<string>${APPLICATION_REV_DOMAIN}.VIRTUALFILE</string>
73-
</array>
74-
</dict>
75-
</array>
76-
77-
7841
</dict>
7942
</plist>

src/gui/application.cpp

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@ Application::Application(Platform *platform, const QString &displayLanguage, boo
7373
}
7474
if (VfsPluginManager::instance().isVfsPluginAvailable(Vfs::WindowsCfApi))
7575
qCInfo(lcApplication) << "VFS windows plugin is available";
76-
if (VfsPluginManager::instance().isVfsPluginAvailable(Vfs::WithSuffix))
77-
qCInfo(lcApplication) << "VFS suffix plugin is available";
7876

7977
ConfigFile cfg;
8078

@@ -105,7 +103,7 @@ Application::Application(Platform *platform, const QString &displayLanguage, boo
105103

106104
// Refactoring example: this is oversimplified and really belongs in a dedicated app builder impl but the idea is illustrated:
107105
// don't handling everything "locally" -> request that the best entity for the job do it. Then make the proper connections between
108-
// requestor and responsible handler in a clearly defined, central location (eg an app builder, but for now, this will do)
106+
// requestor and responsible handler in a clearly defined, central location (e.g. an app builder, but for now, this will do)
109107
connect(_gui, &ownCloudGui::requestSetUpSyncFoldersForAccount, FolderMan::instance(), &FolderMan::setUpInitialSyncFolders);
110108

111109
#ifdef WITH_AUTO_UPDATER
@@ -131,7 +129,7 @@ void Application::slotAccountStateRemoved() const
131129
{
132130
// if there is no more account, show the wizard.
133131
if (_gui && AccountManager::instance()->accounts().isEmpty()) {
134-
// allow to add a new account if there is non any more. Always think
132+
// allow to add a new account if there is none anymore. Always think
135133
// about single account theming!
136134
gui()->runNewAccountWizard();
137135
}
@@ -204,45 +202,6 @@ bool Application::debugMode()
204202
return _debugMode;
205203
}
206204

207-
void Application::openVirtualFile(const QString &filename)
208-
{
209-
QString virtualFileExt = Theme::instance()->appDotVirtualFileSuffix();
210-
if (!filename.endsWith(virtualFileExt)) {
211-
qWarning(lcApplication) << "Can only handle file ending in .owncloud. Unable to open" << filename;
212-
return;
213-
}
214-
QString relativePath;
215-
auto folder = FolderMan::instance()->folderForPath(filename, &relativePath);
216-
if (!folder) {
217-
qWarning(lcApplication) << "Can't find sync folder for" << filename;
218-
// TODO: show a QMessageBox for errors
219-
return;
220-
}
221-
folder->implicitlyHydrateFile(relativePath);
222-
QString normalName = filename.left(filename.size() - virtualFileExt.size());
223-
auto con = QSharedPointer<QMetaObject::Connection>::create();
224-
*con = connect(folder, &Folder::syncFinished, folder, [folder, con, normalName] {
225-
folder->disconnect(*con);
226-
if (QFile::exists(normalName)) {
227-
QDesktopServices::openUrl(QUrl::fromLocalFile(normalName));
228-
}
229-
});
230-
}
231-
232-
bool Application::eventFilter(QObject *obj, QEvent *event)
233-
{
234-
#ifdef Q_OS_MAC
235-
if (event->type() == QEvent::FileOpen) {
236-
QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
237-
qCDebug(lcApplication) << "QFileOpenEvent" << openEvent->file();
238-
// virtual file, open it after the Folder were created (if the app is not terminated)
239-
QString fn = openEvent->file();
240-
QTimer::singleShot(0, this, [this, fn] { openVirtualFile(fn); });
241-
}
242-
#endif
243-
return QObject::eventFilter(obj, event);
244-
}
245-
246205
std::unique_ptr<Application> Application::createInstance(Platform *platform, const QString &displayLanguage, bool debugMode)
247206
{
248207
Q_ASSERT(!_instance);

0 commit comments

Comments
 (0)