dav/sync.c

changeset 361
b6f2462ee055
parent 347
b6ff6be7aa91
child 363
e9ed8e130ccf
--- a/dav/sync.c	Mon Dec 18 16:24:32 2017 +0100
+++ b/dav/sync.c	Mon Jan 01 19:53:36 2018 +0100
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2016 Olaf Wintermann. All rights reserved.
+ * Copyright 2018 Olaf Wintermann. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -49,7 +49,8 @@
 #include "db.h"
 #include "error.h"
 #include "assistant.h"
-
+#include "libxattr.h"
+#include "tags.h"
 #include "sync.h"
 #include "libidav/session.h"
 
@@ -344,7 +345,7 @@
     }
     
     int ret = 0;
-    DavResource *ls = dav_query(sn, "select D:getetag,idav:status from / with depth = infinity");
+    DavResource *ls = dav_query(sn, "select D:getetag,idav:status,idav:tags from / with depth = infinity");
     if(!ls) {
         print_resource_error(sn, "/");
         if(locked) {
@@ -584,6 +585,8 @@
                 local->last_modified = 0;
                 ucx_map_cstr_put(db->resources, local->path, local);
             }
+            
+            sync_store_tags(dir, local_path, local, res);
         }
     } else {
         if(!tmp_path) {
@@ -604,6 +607,8 @@
         }
         fclose(out);
         
+        sync_store_tags(dir, tmp_path, local, res);
+        
         if(ret == 0) {
             (*counter)++;
             
@@ -1234,7 +1239,7 @@
 
 int sync_set_status(DavResource *res, char *status) {
     DavResource *resource = dav_resource_new(res->session, res->path);
-    dav_set_property(resource, "idav:status", status);
+    dav_set_string_property(resource, "idav:status", status);
     int ret = dav_store(resource);
     dav_resource_free(resource);
     return ret;
@@ -1248,6 +1253,81 @@
     return ret;
 }
 
+int sync_store_tags(SyncDirectory *dir, const char *path, LocalResource *local, DavResource *res) {
+    if(!dir->tagconfig) {
+        return 0;
+    }
+    
+    UcxList *tags = NULL;
+    if(dir->tagconfig) {
+        DavXmlNode *tagsprop = dav_get_property_ns(res, DAV_NS, "tags");
+        if(tagsprop) {
+            tags = parse_dav_xml_taglist(tagsprop);
+        }
+    }
+    
+    if(!tags) {
+        return 0;
+    }
+    
+    int ret = 0;
+    if(dir->tagconfig->store == TAG_STORE_XATTR) {
+        UcxBuffer *data = NULL;
+        switch(dir->tagconfig->local_format) {
+            default: break;
+            case TAG_FORMAT_TEXT: {
+                data = create_text_taglist(tags);
+                break;
+            }
+            case TAG_FORMAT_CSV: {
+                data = create_csv_taglist(tags);
+                break;
+            }
+        }
+        
+        if(data) {
+            ret = xattr_set(path, "tags", data->space, data->pos);
+            ucx_buffer_free(data);
+        } else {
+            ret = -1;
+        }
+    }
+    
+    // TODO: free stuff
+    
+    return ret;
+}
+
+UcxList* sync_get_file_tags(SyncDirectory *dir, LocalResource *res) {
+    UcxList *tags = NULL;
+    
+    if(!dir->tagconfig) {
+        return NULL;
+    }
+    if(dir->tagconfig->store == TAG_STORE_XATTR) {
+        ssize_t tag_length = 0;
+        char *local_path = util_concat_path(dir->path, res->path);
+        char* tag_data = xattr_get(local_path, "tags", &tag_length);
+        free(local_path);
+        
+        if(tag_length > 0) {
+            switch(dir->tagconfig->local_format) {
+                default: break;
+                case TAG_FORMAT_TEXT: {
+                    tags = parse_text_taglist(tag_data, tag_length);
+                    break;
+                }
+                case TAG_FORMAT_CSV: {
+                    tags = parse_csv_taglist(tag_data, tag_length);
+                    break;
+                }
+            }
+        }
+    }
+    
+    return tags;
+}
+
 int sync_put_resource(
         SyncDirectory *dir,
         DavResource *res,
@@ -1273,6 +1353,14 @@
     
     dav_set_content(res, in, (dav_read_func)fread);
     
+    if(dir->tagconfig) {
+        UcxList *tags = sync_get_file_tags(dir, local);
+        DavXmlNode *prop = create_xml_taglist(tags);
+        if(prop) {
+            dav_set_property_ns(res, DAV_NS, "tags", prop);
+        }
+    }
+    
     int ret = -1;
     int created = 0;
     for(int i=0;i<=dir->max_retry;i++) {

mercurial