Skip to content

Commit 9f74b0a

Browse files
committed
#3383 note: add method to get nextcloud files link
Signed-off-by: Patrizio Bekerle <patrizio@bekerle.com>
1 parent 490d356 commit 9f74b0a

File tree

4 files changed

+140
-0
lines changed

4 files changed

+140
-0
lines changed

src/entities/note.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <utility>
2424

2525
#include "api/noteapi.h"
26+
#include "cloudconnection.h"
2627
#include "entities/bookmark.h"
2728
#include "entities/commandsnippet.h"
2829
#include "helpers/codetohtmlconverter.h"
@@ -119,6 +120,54 @@ void Note::setShareId(int id) { this->_shareId = id; }
119120

120121
void Note::setSharePermissions(unsigned int permissions) { this->_sharePermissions = permissions; }
121122

123+
/**
124+
* Gets the Nextcloud file link for this note
125+
*
126+
* @return the Nextcloud file link URL, empty if not available
127+
*/
128+
QString Note::getNextcloudFileLink() const {
129+
if (!OwnCloudService::isOwnCloudSupportEnabled()) {
130+
return QString();
131+
}
132+
133+
// Get the OwnCloud service instance
134+
OwnCloudService *ownCloudService = OwnCloudService::instance();
135+
if (ownCloudService == nullptr) {
136+
return QString();
137+
}
138+
139+
// Fetch the file ID from Nextcloud
140+
QString fileId = ownCloudService->fetchNoteFileId(*this);
141+
if (fileId.isEmpty()) {
142+
return QString();
143+
}
144+
145+
// Get the server URL and construct the file link
146+
auto cloudConnection = CloudConnection::currentCloudConnection();
147+
QString serverUrl = cloudConnection.getServerUrlWithoutPath();
148+
149+
if (serverUrl.isEmpty()) {
150+
return QString();
151+
}
152+
153+
// Get the directory path for the "dir" parameter
154+
QString noteRelativePath = relativeNoteFilePath(QStringLiteral("/"));
155+
QString notesPath = NoteFolder::currentRemotePath();
156+
QString fullPath = notesPath + QStringLiteral("/") + noteRelativePath;
157+
158+
// Extract the directory part
159+
QFileInfo fileInfo(fullPath);
160+
QString dirPath = fileInfo.dir().path();
161+
162+
// Construct the Nextcloud file link
163+
// Format: https://server/apps/files/files/FILEID?dir=/path&opendetails=true
164+
QString fileLink = serverUrl % QStringLiteral("/apps/files/files/") % fileId %
165+
QStringLiteral("?dir=") % QUrl::toPercentEncoding(dirPath) %
166+
QStringLiteral("&opendetails=true");
167+
168+
return fileLink;
169+
}
170+
122171
void Note::setCryptoKey(const qint64 cryptoKey) { this->_cryptoKey = cryptoKey; }
123172

124173
void Note::setNoteText(QString text) { this->_noteText = std::move(text); }

src/entities/note.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,8 @@ class Note {
395395

396396
static QString parseEncryptedNoteText(const QString &noteText);
397397

398+
QString getNextcloudFileLink() const;
399+
398400
protected:
399401
int _id;
400402
int _noteSubFolderId;

src/services/owncloudservice.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2369,3 +2369,90 @@ QString OwnCloudService::fetchNextcloudAccountId(const QString &serverUrl, const
23692369
}
23702370

23712371
void OwnCloudService::unsetShareDialog() { shareDialog = nullptr; }
2372+
2373+
/**
2374+
* Fetches the file ID for a note from Nextcloud
2375+
*
2376+
* @param note
2377+
* @return the file ID as a QString, empty if not found
2378+
*/
2379+
QString OwnCloudService::fetchNoteFileId(const Note &note) {
2380+
if (!isOwnCloudSupportEnabled()) {
2381+
return {};
2382+
}
2383+
2384+
auto *manager = new QNetworkAccessManager(this);
2385+
QEventLoop loop;
2386+
QTimer timer;
2387+
2388+
timer.setSingleShot(true);
2389+
QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
2390+
QObject::connect(manager, SIGNAL(finished(QNetworkReply *)), &loop, SLOT(quit()));
2391+
2392+
// 10 sec timeout for the request
2393+
timer.start(10000);
2394+
2395+
// Get the relative path of the note file on the server
2396+
QString noteRelativePath = note.relativeNoteFilePath(QStringLiteral("/"));
2397+
QString notesPath = NoteFolder::currentRemotePath();
2398+
QString filePath = notesPath + QStringLiteral("/") + noteRelativePath;
2399+
2400+
QUrl url(serverUrl % webdavPath() % QStringLiteral("/") % filePath);
2401+
QNetworkRequest r(url);
2402+
addAuthHeader(&r);
2403+
2404+
// Build the PROPFIND request body to get the file ID
2405+
QString body = QStringLiteral(
2406+
"<?xml version=\"1.0\"?>"
2407+
"<d:propfind xmlns:d=\"DAV:\" xmlns:oc=\"http://owncloud.org/ns\">"
2408+
"<d:prop>"
2409+
"<oc:fileid />"
2410+
"</d:prop>"
2411+
"</d:propfind>");
2412+
2413+
auto dataToSend = new QByteArray(body.toUtf8());
2414+
r.setHeader(QNetworkRequest::ContentLengthHeader, dataToSend->size());
2415+
r.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/xml"));
2416+
auto *buffer = new QBuffer(dataToSend);
2417+
2418+
QNetworkReply *reply = manager->sendCustomRequest(r, "PROPFIND", buffer);
2419+
ignoreSslErrorsIfAllowed(reply);
2420+
loop.exec();
2421+
2422+
QString fileId;
2423+
2424+
// if we didn't get a timeout let us parse the response
2425+
if (timer.isActive()) {
2426+
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
2427+
2428+
// only get the data if the status code was "success"
2429+
if (statusCode >= 200 && statusCode < 300) {
2430+
QString data = QString(reply->readAll());
2431+
2432+
QDomDocument doc;
2433+
doc.setContent(data, true);
2434+
2435+
// Parse the WebDAV XML response to get the file ID
2436+
QDomNodeList responseNodes =
2437+
doc.elementsByTagNameNS(NS_DAV, QStringLiteral("response"));
2438+
2439+
if (responseNodes.count() > 0) {
2440+
QDomNode responseNode = responseNodes.at(0);
2441+
if (responseNode.isElement()) {
2442+
QDomElement elem = responseNode.toElement();
2443+
QDomNodeList fileIdNodes = elem.elementsByTagNameNS(
2444+
QStringLiteral("http://owncloud.org/ns"), QStringLiteral("fileid"));
2445+
2446+
if (fileIdNodes.length() > 0) {
2447+
fileId = fileIdNodes.at(0).toElement().text();
2448+
}
2449+
}
2450+
}
2451+
}
2452+
}
2453+
2454+
reply->deleteLater();
2455+
delete (manager);
2456+
2457+
return fileId;
2458+
}

src/services/owncloudservice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ class OwnCloudService : public QObject {
9696

9797
void unsetShareDialog();
9898

99+
QString fetchNoteFileId(const Note &note);
100+
99101
private:
100102
QString serverUrl;
101103
QString todoCalendarServerUrl;

0 commit comments

Comments
 (0)