adds technical foundation to just push tag updates

Fri, 02 Feb 2018 16:46:04 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Fri, 02 Feb 2018 16:46:04 +0100
changeset 366
5228b912c925
parent 365
f04ab0420512
child 367
4a6a59f89f9f

adds technical foundation to just push tag updates

dav/db.c file | annotate | diff | comparison | revisions
dav/db.h file | annotate | diff | comparison | revisions
dav/sync.c file | annotate | diff | comparison | revisions
--- a/dav/db.c	Thu Feb 01 18:25:23 2018 +0100
+++ b/dav/db.c	Fri Feb 02 16:46:04 2018 +0100
@@ -124,6 +124,8 @@
                 field = 3;
             } else if(xstreq(name, "skipped")) {
                 res->skipped = TRUE;
+            } else if(xstreq(name, "tags-updated")) {
+                res->tags_updated = TRUE;
             }
         } else if(type == XML_READER_TYPE_TEXT) {
             const xmlChar *value = xmlTextReaderConstValue(reader);
@@ -294,6 +296,16 @@
             }
         }
         
+        if(res->tags_updated) {
+            r = xmlTextWriterStartElement(writer, BAD_CAST "tags-updated");
+            r += xmlTextWriterEndElement(writer);
+            if(r < 0) {
+                fprintf(stderr, "Cannot write tags-updated\n");
+                xmlFreeTextWriter(writer);
+                return -1;
+            }
+        }
+        
         // </resource>
         xmlTextWriterEndElement(writer);
     }
--- a/dav/db.h	Thu Feb 01 18:25:23 2018 +0100
+++ b/dav/db.h	Fri Feb 02 16:46:04 2018 +0100
@@ -50,6 +50,7 @@
     off_t   size;
     DavBool isdirectory;
     DavBool skipped;
+    DavBool tags_updated;
 };
 
 struct SyncDatabase {
--- a/dav/sync.c	Thu Feb 01 18:25:23 2018 +0100
+++ b/dav/sync.c	Fri Feb 02 16:46:04 2018 +0100
@@ -583,6 +583,10 @@
                 local = calloc(1, sizeof(LocalResource));
                 local->path = util_concat_path(res->path, "/");
                 local->last_modified = 0;
+                if(local->etag) {
+                    free(local->etag);
+                }
+                local->etag = strdup(etag);
                 ucx_map_cstr_put(db->resources, local->path, local);
             }
             
@@ -933,7 +937,8 @@
                        
             // upload every changed file
             int error = 0;
-            if (local_resource_is_changed(dir, db, local_res)) {
+            int is_changed = local_resource_is_changed(dir, db, local_res);
+            if (is_changed || local_res->tags_updated) {
                 DavResource *res = dav_resource_new(sn, local_res->path);
                 if(!res) {
                     print_resource_error(sn, local_res->path);
@@ -941,10 +946,51 @@
                     sync_error++;
                 }
                 
-                if(local_res->isdirectory) {
-                    printf("mkcol: %s\n", local_res->path);
-                    if(sync_mkdir(dir, res, local_res) && sn->error != DAV_METHOD_NOT_ALLOWED) {
-                        print_resource_error(sn, res->path);
+                if(local_res->isdirectory || !is_changed) {
+                    // only check existence if the resource is supposed
+                    // to be a collection
+                    int exists = local_res->isdirectory ? dav_exists(res) : 1;
+                    
+                    // continue if the resource exists or is not found
+                    // because a 404 is not an unexpected error
+                    if(exists || sn->error == DAV_NOT_FOUND) {
+                        int abort = 0;
+                        if(!exists) {
+                            // make sure to store tags for newly created cols
+                            local_res->tags_updated = 1;
+                            // create collection
+                            // TODO: show 405
+                            printf("mkcol: %s\n", local_res->path);
+                            if(sync_mkdir(dir, res, local_res) && sn->error != DAV_METHOD_NOT_ALLOWED) {
+                                print_resource_error(sn, res->path);
+                                ret = -1;
+                                sync_error++;
+                                error = 1;
+                                abort = 1;
+                            }
+                        }
+                        
+                        if(dir->tagconfig && local_res->tags_updated && !abort) {
+                            // get tags from tagstore (xattr or something else)
+                            // and store it in resource property
+                            UcxList *tags = sync_get_file_tags(dir, local_res);
+                            DavXmlNode *prop = create_xml_taglist(tags);
+                            if(prop) {
+                                dav_set_property_ns(res, DAV_NS, "tags", prop);
+                                printf("update: %s\n", local_res->path);
+                                if(dav_store(res)) {
+                                    print_resource_error(sn, local_res->path);
+                                    ret = -1;
+                                    sync_error++;
+                                } else {
+                                    sync_success++;
+                                    local_res->tags_updated = 0;
+                                }
+                            }
+                        }
+                    } else {
+                        // dav_exists() failed
+                        print_resource_error(sn, local_res->path);
                         ret = -1;
                         sync_error++;
                         error = 1;
@@ -1194,7 +1240,9 @@
 
 int local_resource_is_changed(SyncDirectory *dir, SyncDatabase *db, LocalResource *res) {
     LocalResource *db_res = ucx_map_cstr_get(db->resources, res->path);
+    res->tags_updated = 0;
     if(db_res) {
+        res->tags_updated = db_res->tags_updated;
         if(db_res->etag) {
             res->etag = strdup(db_res->etag);
         }

mercurial