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 tag support in sync process #6400

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

Conversation

Runtemund
Copy link

@Runtemund Runtemund commented Jan 30, 2024

I added basic support for file tags to the desktop client. Actually it is a draft, as long as also some of my todos also are already open. But I am welcome for early feedback about the integration.

So finally this shall fix #206

@Runtemund Runtemund marked this pull request as draft January 30, 2024 23:45
@claucambra claucambra requested review from mgallien, claucambra, allexzander and camilasan and removed request for mgallien and claucambra February 5, 2024 10:19
Uwe Runtemund and others added 21 commits February 14, 2024 12:38
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Nextcloud bot <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Nextcloud bot <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Matthieu Gallien <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: rakekniven <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Reported at Transifex

Signed-off-by: rakekniven <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: John Molakvoæ <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](codecov/codecov-action@v3...v4)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
is needed to avoid failing builds due to warnings

unclear when we will tackle the work of removing the use of deprectaed
APIs

Signed-off-by: Matthieu Gallien <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Claudio Cambra <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Claudio Cambra <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Claudio Cambra <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Nextcloud bot <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Camila Ayres <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
…ingBody.

- Add const auto.
- Remove extra error message information to make it more user friendly.

Signed-off-by: Camila Ayres <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Camila Ayres <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Nextcloud bot <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Camila Ayres <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
nextcloud-bot and others added 16 commits February 14, 2024 12:38
Signed-off-by: Nextcloud bot <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Nextcloud bot <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Nextcloud bot <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Nextcloud bot <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Josh Richards <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Claudio Cambra <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Claudio Cambra <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Matthieu Gallien <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
we are defining a component, by definition there will be no parent

setting the size if the responsibility of the stack view, not of the
component (or even its definition)

Signed-off-by: Matthieu Gallien <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Matthieu Gallien <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
Signed-off-by: Nextcloud bot <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
… Windows. Prevents signature verification failure.

Signed-off-by: alex-z <[email protected]>
Signed-off-by: Uwe Runtemund <[email protected]>
@Runtemund
Copy link
Author

On client side, everything should be done for Mac and Linux. Tags will be synced, as good as possible with current server side implementation. For the following points a change on server side is also necessary:

  • Full down sync of server side tag changes. Currently the client is not informed, if a tag to file is changed on the server side. Probably this could be done, by finally implementing the metadata_etag property to inform the client about that. Actually the synchronisation is done by coincidence or if the file was changed.
  • Full up sync is not possible, because system tags cannot updated via PROPPATCH. We actually safe client side tags via the oc:tags property. Later, if also system tags can be updated via PROPPATCH it should automatically handle tags as system tags, if present and as oc:tags, if not as system tag present. That means actually in practice: system-tags cannot be changed on client side. They will be overridden with the server side data frequently. Client side assigned tags which are no system tags are fully synchronised.

Following client side improvements cloud be done in the future:

  • implementation in windows client. Maybe the IPropertySet is the right way, but I have to investigate a bit more.. So that this could be a new pull request and finish this one as soon as possible.

@Runtemund Runtemund marked this pull request as ready for review February 14, 2024 11:58
@jancborchardt
Copy link
Member

@tobiasKaminsky @mgallien are you aware of this nice pull request? :)

@joecomo67
Copy link

this sounds great - is there a way to use this already?

@Runtemund
Copy link
Author

@joecomo67

this sounds great - is there a way to use this already?

Actually I am awaiting review from the nextcloud staff. I don't know their priorities, so I have to wait.

Even if I am confident, that the pull request will solve the issue, I recommend to wait for their review, because I am not so deep into the nexcloud logic then they will be.

Copy link
Collaborator

@claucambra claucambra left a comment

Choose a reason for hiding this comment

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

Again, huge thanks for this PR and apologies for the late review. From me, some comments -- two small ones, and one bigger request before we can merge:

  1. Your code style varies quite a lot from what we use in the desktop client, it would be great if you could run something like clang-format to format your changes in the same style as the rest of the app's code
  2. Use of const for variables that are not changed after definition would be great
  3. Most importantly, since this is a big PR that directly affects sync behaviour, it would be a requirement to see some unit tests for the additions here so that we can feel safer in including this in the next release

Thanks a ton for your time and effort in writing this PR

Comment on lines +132 to +190

#ifdef __APPLE__

// Create necessary system related objects
CFStringRef cfstr = CFStringCreateWithCString(kCFAllocatorDefault,
fullPath.constData(),
kCFStringEncodingUTF8);
CFURLRef urlref = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
cfstr,
kCFURLPOSIXPathStyle,
dirent->d_type == DT_DIR);

// Query tags
CFArrayRef labels=NULL;
Boolean result = CFURLCopyResourcePropertyForKey(urlref,
kCFURLTagNamesKey,
&labels,
NULL);

if(result==true && labels != NULL){
// Extract the labels to our array
int count = (int) CFArrayGetCount(labels);

if(count>0){
QStringList tagarray;

for(int index=0;index<count;index++){
CFStringRef str = (CFStringRef)CFArrayGetValueAtIndex(labels,index);
if(CFStringGetLength(str)>0)tagarray << QString::fromCFString(str);
}
tagarray.sort(Qt::CaseInsensitive);
QString tagList = tagarray.join(QChar(0x000A));
file_stat->tagList=tagList.toUtf8();
}
}

// Clean up
CFRelease(cfstr);
CFRelease(urlref);
if(labels!=NULL)CFRelease(labels);

#endif

#ifdef __linux__
const int sz=4096;
char buffer[sz];
int result = getxattr(fullPath.constData(),"user.xdg.tags",buffer,sz);

if(result>0)
{
// Data is store usually as comma(,) separated list.
// So we just need to replace ',' by '\n'.
QByteArray tagList = QByteArray(buffer,result);
tagList.replace(',','\n');
printf("%s\n",buffer);
file_stat->tagList= tagList;
}
#endif

Copy link
Collaborator

Choose a reason for hiding this comment

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

nitpick: the formatting of the code here does not match the rest of the code, please use 4-space indentation and leave spaces in between operators, as well as if statements and their parenthesis :)

@@ -610,7 +609,7 @@ void Folder::slotWatchedPathChanged(const QString &path, ChangeReason reason)
// an attribute change (pin state) that caused the notification
bool spurious = false;
if (record.isValid()
&& !FileSystem::fileChanged(path, record._fileSize, record._modtime)) {
&& !FileSystem::fileChanged(path, record._fileSize, record._modtime,record._tagList)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
&& !FileSystem::fileChanged(path, record._fileSize, record._modtime,record._tagList)) {
&& !FileSystem::fileChanged(path, record._fileSize, record._modtime, record._tagList)) {

Comment on lines +496 to +497
if(localEntry.isValid()
&& dbEntry.isValid()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if(localEntry.isValid()
&& dbEntry.isValid()) {
if(localEntry.isValid() && dbEntry.isValid()) {

@@ -344,6 +345,7 @@ void DiscoverySingleLocalDirectoryJob::run() {
i.isVirtualFile = dirent->type == ItemTypeVirtualFile || dirent->type == ItemTypeVirtualFileDownload;
i.isMetadataMissing = dirent->is_metadata_missing;
i.type = dirent->type;
i.tagList=dirent->tagList;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
i.tagList=dirent->tagList;
i.tagList = dirent->tagList;

Comment on lines +546 to +551
if(property == "system-tags" || property == "tags"){
FileTagManager::fromPropertiesToTagList(result.tagList,value);
}
if(property == "metadata_etag"){
//TODO: RMD Handle metadata etag for tag synchronization
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if(property == "system-tags" || property == "tags"){
FileTagManager::fromPropertiesToTagList(result.tagList,value);
}
if(property == "metadata_etag"){
//TODO: RMD Handle metadata etag for tag synchronization
}
if (property == "system-tags" || property == "tags") {
FileTagManager::fromPropertiesToTagList(result.tagList,value);
}
if (property == "metadata_etag") {
//TODO: RMD Handle metadata etag for tag synchronization
}

Comment on lines +41 to +42
if(gFileTagManger==NULL)gFileTagManger=new FileTagManager();
return gFileTagManger;
Copy link
Collaborator

Choose a reason for hiding this comment

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

nitpick: again, some small complaints about formatting in this file vs. the rest of the application code


if(result==true && labels != NULL){
// Extract the labels to our array
int count = (int) CFArrayGetCount(labels);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would use c++-style static casts here rather than c-style casts


while (!reader.atEnd()){
QXmlStreamReader::TokenType type = reader.readNext();
QString name = reader.name().toString();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
QString name = reader.name().toString();
const QString name = reader.name().toString();

Could also use const auto


if(count>0){
for(int index=0;index<count;index++){
CFStringRef str = (CFStringRef)CFArrayGetValueAtIndex(labels,index);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
CFStringRef str = (CFStringRef)CFArrayGetValueAtIndex(labels,index);
const CFStringRef str = (CFStringRef)CFArrayGetValueAtIndex(labels, index);

Also would be good to use c++ casts

@Runtemund
Copy link
Author

H, thanks for replay. I will work on that soon. Unfortunately I have much to do at work, so I will need some time.

@joshtrichards joshtrichards added 3. to review enhancement enhancement of a already implemented feature/code labels Aug 13, 2024
@claucambra claucambra added this to the 3.15.0 milestone Oct 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3. to review enhancement enhancement of a already implemented feature/code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Synchronize tags as well