Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Checksum Verification and Directory Upload Support for QFieldCloud #6114

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

mohsenD98
Copy link
Collaborator

@mohsenD98 mohsenD98 commented Mar 18, 2025

Pull Request Description

Overview:

This pull request introduces several improvements to the file upload functionality, specifically for enhancing efficiency and extending support for pushing entire directories to QFieldCloud. The changes introduced include checksum verification to ensure that unchanged files are not uploaded again, reducing unnecessary data transfer, as well as enabling directory uploads.

Changes:

  1. Checksum Verification for File Uploads:
    The file upload process has been optimized by introducing checksum verification. This ensures that files that have not been modified are not uploaded again, leading to significant efficiency improvements and reduced data transfer. The checksum verification mechanism is implemented using ETags for file comparison.

  2. Support for Uploading Entire Directories:
    A new functionality has been added to allow uploading entire directories to QFieldCloud. The new code recursively scans a directory and processes its files, ensuring that all files within the directory are correctly handled and uploaded if necessary.

  3. Refactor of the addPendingAttachments Function:
    The existing addPendingAttachments function has been refactored and renamed to writeToAttachmentsFile. The new function allows both individual files and directories to be handled, and integrates the checksum verification logic.

    void QFieldCloudUtils::writeToAttachmentsFile( const QString &projectId, const QStringList &fileNames, const QHash<QString, QString> *fileChecksumMap, const bool &checkSumCheck )
    {
      // New implementation that processes files and directories, including checksum verification.
    }
  4. New Helper Functions:

    • writeFilesFromDirectory: A recursive function to process all files within a directory and push them to QFieldCloud.
    • writeFileDetails: This function writes the file details to the attachments file and checks the checksum for file comparison before uploading.
    void QFieldCloudUtils::writeFilesFromDirectory( const QString &dirPath, const QString &projectId, const QHash<QString, QString> *fileChecksumMap, const bool &checkSumCheck, QTextStream &attachmentsStream );
    
    void QFieldCloudUtils::writeFileDetails( const QString &fileName, const QString &projectId, const QHash<QString, QString> *fileChecksumMap, const bool &checkSumCheck, QTextStream &attachmentsStream );
  5. New QML Property for Detecting Project Folder:
    A new QML property itemWithinQFieldCloudProjectFolder has been added to check if the item is within the QFieldCloud project folder. This property ensures that only items within the project folder are considered for upload.

    property bool itemWithinQFieldCloudProjectFolder: cloudProjectsModel.currentProjectId !== "" && itemPath.search(cloudProjectsModel.currentProjectId) !== -1

    It is now used in the following conditional logic to determine whether a folder is part of the project:

    || (item.itemMetaType == LocalFilesModel.Folder && item.itemWithinQFieldCloudProjectFolder);

Certainly! Here’s a revised version of your test description, formatted for clarity and professionalism. You can append this text to your pull request.


Test Scenario:

  1. Created a PDF file.
  2. Uploaded the folder containing the PDF.
  3. Verified that one version of the PDF appears in QFieldCloud.
  4. Created multiple PDF files within the folder.
  5. Uploaded the entire folder again.
  6. Confirmed that all PDFs within the folder still show as version 1.
  7. Uploaded the entire folder once more.
  8. Verified that all PDFs remain on their original version (version 1).
  9. Added a single new PDF file to the folder.
  10. Uploaded the folder again.
  11. Confirmed that all files still remain on their original version (version 1).

Conclusion:

Both checksum verification and directory upload functionalities are working as intended. The checksum verification is successfully preventing unnecessary uploads of unchanged files, ensuring efficient data transfer.

@mohsenD98 mohsenD98 requested a review from nirvn March 18, 2025 09:35
@mohsenD98 mohsenD98 self-assigned this Mar 18, 2025
@qfield-fairy
Copy link
Collaborator

qfield-fairy commented Mar 18, 2025

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

harmonize with every variable name around.
@mohsenD98 mohsenD98 changed the title WIP: Add Checksum Verification and Directory Upload Support for QFieldCloud Add Checksum Verification and Directory Upload Support for QFieldCloud Mar 19, 2025
@mohsenD98 mohsenD98 marked this pull request as ready for review March 19, 2025 08:08
@@ -150,23 +152,107 @@ const QMultiMap<QString, QString> QFieldCloudUtils::getPendingAttachments()
return std::move( files );
}

void QFieldCloudUtils::addPendingAttachments( const QString &projectId, const QStringList &fileNames )
void QFieldCloudUtils::addPendingAttachments( const QString &projectId, const QStringList &fileNames, QFieldCloudConnection *cloudConnection, const bool &checkSumCheck )
{
QLockFile attachmentsLock( QStringLiteral( "%1/attachments.lock" ).arg( QFieldCloudUtils::localCloudDirectory() ) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the lock file into writeToAttachmentsFile.

//! Adds an array of \a fileNames for a given \a projectId to the pending attachments list
Q_INVOKABLE static void addPendingAttachments( const QString &projectId, const QStringList &fileNames );
/**
* Adds an array of \a fileNames for a given \a projectId to the pending attachments list.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Adds an array of \a fileNames for a given \a projectId to the pending attachments list.
* Adds an array of files and/or folders for a given cloud project to the pending upload attachments list.

* If \a checkSumCheck is true, checks file checksums with the server; otherwise, adds all files without validation.
*
* @param projectId The project ID for which files are added.
* @param fileNames The list of file names to be added.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param fileNames The list of file names to be added.
* @param fileNames The list of file and/or folder path(s) to be added.

QFileInfo fi( attachmentsFile );
if ( checkSumCheck )
{
QVariantMap params;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd do a null check for the cloud connection here, just in case.

* @param cloudConnection The cloud connection used to fetch file data.
* @param checkSumCheck Whether to validate files by comparing checksums with the server.
*/
Q_INVOKABLE static void addPendingAttachments( const QString &projectId, const QStringList &fileNames, QFieldCloudConnection *cloudConnection, const bool &checkSumCheck );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Q_INVOKABLE static void addPendingAttachments( const QString &projectId, const QStringList &fileNames, QFieldCloudConnection *cloudConnection, const bool &checkSumCheck );
Q_INVOKABLE static void addPendingAttachments( const QString &projectId, const QStringList &fileNames, QFieldCloudConnection *cloudConnection = nullptr, const bool &checkSumCheck = false );

// ? should we also check the checksums of the files being uploaded? they are available at deltaFile->attachmentFileNames()->values()
QFieldCloudUtils::addPendingAttachments( project->id, { absoluteFilePath } );
// ? should we also check the checksums of the files being uploaded? they are available at deltaFile->attachmentFileNames()->values() || Or just send true instead of false!
QFieldCloudUtils::addPendingAttachments( project->id, { absoluteFilePath }, mCloudConnection, false );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
QFieldCloudUtils::addPendingAttachments( project->id, { absoluteFilePath }, mCloudConnection, false );
QFieldCloudUtils::addPendingAttachments( project->id, { absoluteFilePath } );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants