summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xgosbin10792292 -> 10791252 bytes
-rwxr-xr-xgoscbin10792292 -> 10791252 bytes
-rw-r--r--internal/main.go2
-rw-r--r--internal/platforms/linkedin/preview.go9
-rw-r--r--internal/platforms/linkedin/preview_test.go92
-rw-r--r--internal/version.go2
6 files changed, 100 insertions, 5 deletions
diff --git a/gos b/gos
index e2420c7..664c73c 100755
--- a/gos
+++ b/gos
Binary files differ
diff --git a/gosc b/gosc
index 9678007..8e0dbc4 100755
--- a/gosc
+++ b/gosc
Binary 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().