diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-12 22:24:08 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-12 22:24:08 +0200 |
| commit | cfddc5696f4956081630e3d394ef3d8c652af02e (patch) | |
| tree | 30dc6e7de7fe28d6733c485adaddea1129533cfb | |
| parent | 914d3fb1c0839f3a25c42769ea42cf424ae340c4 (diff) | |
release v1.2.5v1.2.5
| -rwxr-xr-x | gos | bin | 10792292 -> 10791252 bytes | |||
| -rwxr-xr-x | gosc | bin | 10792292 -> 10791252 bytes | |||
| -rw-r--r-- | internal/main.go | 2 | ||||
| -rw-r--r-- | internal/platforms/linkedin/preview.go | 9 | ||||
| -rw-r--r-- | internal/platforms/linkedin/preview_test.go | 92 | ||||
| -rw-r--r-- | internal/version.go | 2 |
6 files changed, 100 insertions, 5 deletions
| Binary files differBinary files differ diff --git a/internal/main.go b/internal/main.go index 372c305..198a584 100644 --- a/internal/main.go +++ b/internal/main.go @@ -26,7 +26,7 @@ func Main(composeModeDefault bool) { target := flag.Int("target", 2, "How many posts per week are the target?") minQueued := flag.Int("minQueued", 42, "Minimum of queued items until printing a warn message!") maxDaysQueued := flag.Int("maxDaysQueued", 365*2, "Maximum days worth of queued posts until target++ and pauseDays--") - pauseDays := flag.Int("pauseDays", 1, "How many days until next post can be posted?") + pauseDays := flag.Int("pauseDays", 2, "How many days until next post can be posted?") runInterval := flag.Int("runInterval", 6, "How many hours to wait for the next run.") lookback := flag.Int("lookback", 42, "How many days look back in time for posting history") geminiSummaryFor := flag.String("geminiSummaryFor", "", "Generate a summary in Gemini Gemtext format, format is coma separated string of months, e.g. 202410,202411") diff --git a/internal/platforms/linkedin/preview.go b/internal/platforms/linkedin/preview.go index 125a4bf..b7387c9 100644 --- a/internal/platforms/linkedin/preview.go +++ b/internal/platforms/linkedin/preview.go @@ -44,13 +44,16 @@ func NewPreview(ctx context.Context, args config.Args, urls []string) (preview, colour.Infoln("URL", urls[0], "is without any image, that's fine, though.") } if !errors.Is(err, errNoTitleElementFound) && !errors.Is(err, errNoImageElementFound) { - return p, err + colour.Infoln("Skipping LinkedIn preview metadata for", urls[0], "due to", err) + return p, nil } } if p.thumbnailURL != "" { if p.thumbnailDownloadPath, err = p.DownloadImage(args.CacheDir); err != nil { - return p, err + colour.Infoln("Skipping LinkedIn preview image for", urls[0], "due to", err) + p.thumbnailDownloadPath = "" + return p, nil } colour.Infoln("Downloaded preview image to ", p.thumbnailDownloadPath) } @@ -65,7 +68,7 @@ func (p preview) String() string { } func (p preview) TitleAndURL() (string, string, bool) { - return p.title, p.url, p.url != "" + return p.title, p.url, p.url != "" && p.title != "" } func (p preview) Thumbnail() (string, bool) { diff --git a/internal/platforms/linkedin/preview_test.go b/internal/platforms/linkedin/preview_test.go index 1df969b..f65da63 100644 --- a/internal/platforms/linkedin/preview_test.go +++ b/internal/platforms/linkedin/preview_test.go @@ -1,8 +1,14 @@ package linkedin import ( + "context" + "net/http" + "net/http/httptest" + "path/filepath" "strings" "testing" + + "codeberg.org/snonux/gos/internal/config" ) func TestPreviewExtract(t *testing.T) { @@ -33,3 +39,89 @@ func TestPreviewExtract(t *testing.T) { t.Errorf("expected imageURL '%s' but got '%s'", expectedImageURL, imageURL) } } + +func TestNewPreviewIgnoresForbiddenPage(t *testing.T) { + t.Parallel() + + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.Error(w, "blocked", http.StatusForbidden) + })) + defer srv.Close() + + prev, err := NewPreview(context.Background(), config.Args{ + CacheDir: t.TempDir(), + }, []string{srv.URL}) + if err != nil { + t.Fatalf("expected preview fetch failure to be non-fatal, got %v", err) + } + + title, sourceURL, ok := prev.TitleAndURL() + if !ok { + t.Fatal("expected preview to keep URL fallback") + } + if title != srv.URL { + t.Fatalf("expected fallback title %q, got %q", srv.URL, title) + } + if sourceURL != srv.URL { + t.Fatalf("expected source URL %q, got %q", srv.URL, sourceURL) + } + if _, ok := prev.Thumbnail(); ok { + t.Fatal("expected no thumbnail for forbidden preview page") + } +} + +func TestNewPreviewIgnoresForbiddenImage(t *testing.T) { + t.Parallel() + + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/": + _, _ = w.Write([]byte(` +<!DOCTYPE html> +<html> +<head> + <title>Blocked image</title> +</head> +<body> + <img src="/blocked.jpg" alt="blocked"> +</body> +</html> +`)) + case "/blocked.jpg": + http.Error(w, "blocked", http.StatusForbidden) + default: + http.NotFound(w, r) + } + })) + defer srv.Close() + + cacheDir := t.TempDir() + prev, err := NewPreview(context.Background(), config.Args{ + CacheDir: cacheDir, + }, []string{srv.URL}) + if err != nil { + t.Fatalf("expected image download failure to be non-fatal, got %v", err) + } + + title, sourceURL, ok := prev.TitleAndURL() + if !ok { + t.Fatal("expected preview title and URL to be preserved") + } + if title != "Blocked image" { + t.Fatalf("expected title %q, got %q", "Blocked image", title) + } + if sourceURL != srv.URL { + t.Fatalf("expected source URL %q, got %q", srv.URL, sourceURL) + } + if thumbnailPath, ok := prev.Thumbnail(); ok { + t.Fatalf("expected no thumbnail after blocked download, got %q", thumbnailPath) + } + + matches, err := filepath.Glob(filepath.Join(cacheDir, "*")) + if err != nil { + t.Fatalf("glob failed: %v", err) + } + if len(matches) != 0 { + t.Fatalf("expected cache dir to stay empty, got %v", matches) + } +} diff --git a/internal/version.go b/internal/version.go index 3980280..3f9eb70 100644 --- a/internal/version.go +++ b/internal/version.go @@ -6,7 +6,7 @@ import ( "codeberg.org/snonux/gos/internal/table" ) -const versionStr = "v1.2.4" +const versionStr = "v1.2.5" func printVersion() { table.New(). |
