Recently Written · git

sbm-sync

Sync server for sbm bookmark files: one small Go program, plain files, AGPL

git clone https://github.com/equwal/sbm-sync

Log | Files | Refs


commit 6ef6be91bccde37b3611a99914f746208accd806
equwal <truex@equwal.com>
2026-09-25 02:22:23 -0700

Fetch a feed without -z while its item file is empty

sfeed_update 1.7 touches the item file before the first fetch. With -z on
that empty file, curl skips the whole feed as not newer than the file, so
the first fetch of each feed gave no items. The fetch now uses -z only
when the item file has items in it.

 feedjob.go      | 8 +++++++-
 feedjob_test.go | 4 +++-
 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/feedjob.go b/feedjob.go
index cc56e78..2f991fe 100644
--- a/feedjob.go
+++ b/feedjob.go
@@ -104,12 +104,18 @@ func (s *server) runFeeds() {
 // sfeedrc gives the sfeed_update settings for the feeds: the item files go
 // to itemsDir. Each URL passed feedURL, and each file name has only safe
 // characters, so the single quotes hold.
+//
+// The fetch asks only for a feed that changed since the item file was
+// written (-z), but not when that file is empty: sfeed_update touches the
+// file before the first fetch, and curl would then skip the whole feed as
+// not newer than the file.
 func sfeedrc(itemsDir string, feeds []Feed) string {
+	const curl = "curl --proto '=http,https' -L --max-redirs 3 -A 'sbm-sync (+https://github.com/equwal/sbm-sync)' -f -s -m 20 --max-filesize 5242880"
 	var b strings.Builder
 	b.WriteString("# sbm-sync makes this file from feeds.txt. Do not edit it.\n")
 	b.WriteString("sfeedpath='" + itemsDir + "'\n")
 	b.WriteString("maxjobs=4\n")
-	b.WriteString("fetch() {\n\tcurl --proto '=http,https' -L --max-redirs 3 -A 'sbm-sync (+https://github.com/equwal/sbm-sync)' -f -s -m 20 --max-filesize 5242880 -z \"$3\" \"$2\" 2>/dev/null\n}\n")
+	b.WriteString("fetch() {\n\tif [ -s \"$3\" ]; then\n\t\t" + curl + " -z \"$3\" \"$2\" 2>/dev/null\n\telse\n\t\t" + curl + " \"$2\" 2>/dev/null\n\tfi\n}\n")
 	b.WriteString("feeds() {\n")
 	for _, f := range feeds {
 		b.WriteString("\tfeed '" + f.File + "' '" + f.URL + "'\n")
diff --git a/feedjob_test.go b/feedjob_test.go
index c5bcf22..c109207 100644
--- a/feedjob_test.go
+++ b/feedjob_test.go
@@ -99,7 +99,9 @@ func TestJobFetchesTheFeeds(t *testing.T) {
 	e.s.runFeeds()
 	rc := e.feedFile(a, "sfeedrc")
 	itemsDir := filepath.Join(e.s.store.feedDir(a.ID), "items")
-	for _, want := range []string{"sfeedpath='" + itemsDir + "'\n", "\tfeed 'Alpha' 'https://a.org/rss.xml'\n", "curl --proto '=http,https'"} {
+	// The conditional fetch (-z) is only for an item file with items in it.
+	for _, want := range []string{"sfeedpath='" + itemsDir + "'\n", "\tfeed 'Alpha' 'https://a.org/rss.xml'\n",
+		"\tif [ -s \"$3\" ]; then\n\t\tcurl --proto '=http,https'", ` -z "$3" "$2" 2>/dev/null` + "\n\telse\n\t\tcurl "} {
 		if !strings.Contains(rc, want) {
 			t.Errorf("the sfeedrc lacks %q:\n%s", want, rc)
 		}