From 221354f73b2bc6fba0a116d208e1bf05e6b13610 Mon Sep 17 00:00:00 2001 From: eleith Date: Fri, 12 Sep 2025 17:22:54 -0700 Subject: [PATCH] opengraph tag support 1. add og tags to html templates 2. add og image 3. support serving static files from web/static 4. fix minify to not strip header and closing tags 5. default digest host to localhost:8080 --- .gitignore | 5 ++--- internal/app/app_test.go | 2 +- internal/app/services/digest.go | 2 +- internal/archive/archive.go | 6 +++++- internal/config/config.go | 1 + internal/digest/digest.go | 4 ++-- internal/digest/digest_test.go | 10 +++++----- internal/digest/view/view.go | 3 ++- internal/models/models.go | 4 +++- internal/processor/processor.go | 1 + internal/processor/processor_test.go | 8 ++++---- internal/templates/grouped-entries.gohtml | 5 +++++ internal/templates/overview.gohtml | 5 +++++ internal/webserver/webserver.go | 6 +++++- scripts/preview/main.go | 2 ++ web/static/images/opengraph.png | Bin 0 -> 42562 bytes 16 files changed, 44 insertions(+), 20 deletions(-) create mode 100644 web/static/images/opengraph.png diff --git a/.gitignore b/.gitignore index f224fad..f2e73b1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,10 +10,9 @@ /vendor # Web archive -/web/miniflux-archive -/web/preview.html +/web/archive # Gemini CLI state /.gemini/ -PROJECT.md \ No newline at end of file +PROJECT.md diff --git a/internal/app/app_test.go b/internal/app/app_test.go index 26581ce..86e4b13 100644 --- a/internal/app/app_test.go +++ b/internal/app/app_test.go @@ -39,7 +39,7 @@ func (m *mockMinifluxClientService) UpdateEntries(entryIDs []int64, status strin type mockDigestService struct{} -func (m *mockDigestService) BuildDigestData(entries []*models.Entry, icons map[int64]*models.FeedIcon, view string, minifluxHost string) *models.OverviewTemplateData { +func (m *mockDigestService) BuildDigestData(entries []*models.Entry, icons map[int64]*models.FeedIcon, view string, minifluxHost string, digestHost string) *models.OverviewTemplateData { return nil } diff --git a/internal/app/services/digest.go b/internal/app/services/digest.go index 05229d2..4c45f83 100644 --- a/internal/app/services/digest.go +++ b/internal/app/services/digest.go @@ -5,5 +5,5 @@ import ( ) type DigestService interface { - BuildDigestData(entries []*models.Entry, icons map[int64]*models.FeedIcon, view string, minifluxHost string) *models.OverviewTemplateData + BuildDigestData(entries []*models.Entry, icons map[int64]*models.FeedIcon, view string, minifluxHost string, digestHost string) *models.OverviewTemplateData } diff --git a/internal/archive/archive.go b/internal/archive/archive.go index a158d20..905b4ba 100644 --- a/internal/archive/archive.go +++ b/internal/archive/archive.go @@ -46,7 +46,10 @@ func (s *ArchiveServiceImpl) minifyHTML(data []byte, compress bool) ([]byte, err } m := minify.New() - m.AddFunc("text/html", html.Minify) + m.Add("text/html", &html.Minifier{ + KeepDocumentTags: true, + KeepEndTags: true, + }) return m.Bytes("text/html", data) } @@ -129,6 +132,7 @@ func (s *ArchiveServiceImpl) MakeArchiveHTML(data *models.OverviewTemplateData, MinifluxHost: data.MinifluxHost, GeneratedDate: data.GeneratedDate, TotalEntries: totalEntriesInPrimaryGroup, + DigestHost: data.DigestHost, } groupedEntriesFile, err := s.makeGroupedEntriesArchiveFile(primaryGroup, dateFolderPath) if err != nil { diff --git a/internal/config/config.go b/internal/config/config.go index 2a65344..27f1a0e 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -118,6 +118,7 @@ func setDefaultValues(k *koanf.Koanf) error { return k.Load(confmap.Provider(map[string]any{ "digest.compress": true, "digest.view": "date", + "digest.host": "http://localhost:8080", "digest.schedule": "@weekly", "digest.mark_as_read": true, "digest.run_on_startup": false, diff --git a/internal/digest/digest.go b/internal/digest/digest.go index 12ffe9c..3ab30af 100644 --- a/internal/digest/digest.go +++ b/internal/digest/digest.go @@ -14,6 +14,6 @@ type digestServiceImpl struct { llmService services.LLMService } -func (s *digestServiceImpl) BuildDigestData(entries []*models.Entry, icons map[int64]*models.FeedIcon, viewType string, minifluxHost string) *models.OverviewTemplateData { - return view.BuildDigestDataForView(entries, icons, viewType, minifluxHost, s.llmService) +func (s *digestServiceImpl) BuildDigestData(entries []*models.Entry, icons map[int64]*models.FeedIcon, viewType string, minifluxHost string, digestHost string) *models.OverviewTemplateData { + return view.BuildDigestDataForView(entries, icons, viewType, minifluxHost, digestHost, s.llmService) } \ No newline at end of file diff --git a/internal/digest/digest_test.go b/internal/digest/digest_test.go index bc27d2c..b88f163 100644 --- a/internal/digest/digest_test.go +++ b/internal/digest/digest_test.go @@ -71,7 +71,7 @@ func TestDigestService_BuildDigestData(t *testing.T) { } t.Run("view=date", func(t *testing.T) { - overviewData := digestService.BuildDigestData(entries, icons, "date", "http://miniflux.test") + overviewData := digestService.BuildDigestData(entries, icons, "date", "http://miniflux.test", "") if overviewData == nil { t.Fatal("overviewData is nil") } @@ -94,7 +94,7 @@ func TestDigestService_BuildDigestData(t *testing.T) { }) t.Run("view=category", func(t *testing.T) { - overviewData := digestService.BuildDigestData(entries, icons, "category", "http://miniflux.test") + overviewData := digestService.BuildDigestData(entries, icons, "category", "http://miniflux.test", "") if overviewData == nil { t.Fatal("overviewData is nil") } @@ -115,7 +115,7 @@ func TestDigestService_BuildDigestData(t *testing.T) { t.Run("view=ai", func(t *testing.T) { aiEntries := createLLMGrouperMockEntries() - overviewData := digestService.BuildDigestData(aiEntries, icons, "ai", "http://miniflux.test") + overviewData := digestService.BuildDigestData(aiEntries, icons, "ai", "http://miniflux.test", "") if overviewData == nil { t.Fatal("overviewData is nil") } @@ -138,7 +138,7 @@ func TestDigestService_BuildDigestData(t *testing.T) { } digestService := NewDigestService(mockLLM) aiEntries := createLLMGrouperMockEntries() - overviewData := digestService.BuildDigestData(aiEntries, icons, "ai", "http://miniflux.test") + overviewData := digestService.BuildDigestData(aiEntries, icons, "ai", "http://miniflux.test", "") if overviewData == nil { t.Fatal("overviewData is nil") @@ -176,7 +176,7 @@ func TestDigestService_BuildDigestData(t *testing.T) { } digestService := NewDigestService(mockLLM) aiEntries := createLLMGrouperMockEntries() - overviewData := digestService.BuildDigestData(aiEntries, icons, "ai", "http://miniflux.test") + overviewData := digestService.BuildDigestData(aiEntries, icons, "ai", "http://miniflux.test", "") if overviewData == nil { t.Fatal("overviewData is nil") diff --git a/internal/digest/view/view.go b/internal/digest/view/view.go index 8d22beb..47f3171 100644 --- a/internal/digest/view/view.go +++ b/internal/digest/view/view.go @@ -8,7 +8,7 @@ import ( "time" ) -func BuildDigestDataForView(entries []*models.Entry, icons map[int64]*models.FeedIcon, viewType string, minifluxHost string, llmService services.LLMService) *models.OverviewTemplateData { +func BuildDigestDataForView(entries []*models.Entry, icons map[int64]*models.FeedIcon, viewType string, minifluxHost string, digestHost string, llmService services.LLMService) *models.OverviewTemplateData { iconsSlice := make([]*models.FeedIcon, 0, len(icons)) for _, icon := range icons { iconsSlice = append(iconsSlice, icon) @@ -69,6 +69,7 @@ func BuildDigestDataForView(entries []*models.Entry, icons map[int64]*models.Fee TotalEntries: len(entries), TotalFeeds: len(uniqueFeedIDs), MinifluxHost: minifluxHost, + DigestHost: digestHost, } } diff --git a/internal/models/models.go b/internal/models/models.go index 7b5018e..64e1dc7 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -49,6 +49,7 @@ type OverviewTemplateData struct { TotalEntries int TotalFeeds int MinifluxHost string + DigestHost string } type EntryGroup struct { @@ -93,4 +94,5 @@ type GroupedDigestPageData struct { GeneratedDate time.Time TotalEntries int TotalFeeds int -} + DigestHost string +} \ No newline at end of file diff --git a/internal/processor/processor.go b/internal/processor/processor.go index 77cb4ad..da7d266 100644 --- a/internal/processor/processor.go +++ b/internal/processor/processor.go @@ -37,6 +37,7 @@ func ProcessDigest(application *app.App) (*os.File, []*os.File, *models.Overview icons, application.Config.Digest.View, application.Config.Miniflux.Host, + application.Config.Digest.Host, ) overviewFile, groupedEntryFiles, err := application.ArchiveService.MakeArchiveHTML(data, application.Config.Digest.Compress) diff --git a/internal/processor/processor_test.go b/internal/processor/processor_test.go index 895fccd..3c6399b 100644 --- a/internal/processor/processor_test.go +++ b/internal/processor/processor_test.go @@ -30,11 +30,11 @@ func (m *mockMinifluxClientService) UpdateEntries(entryIDs []int64, status strin } type mockDigestService struct { - buildDigestDataFunc func(entries []*models.Entry, icons map[int64]*models.FeedIcon, view string, minifluxHost string) *models.OverviewTemplateData + buildDigestDataFunc func(entries []*models.Entry, icons map[int64]*models.FeedIcon, view string, minifluxHost string, digestHost string) *models.OverviewTemplateData } -func (m *mockDigestService) BuildDigestData(entries []*models.Entry, icons map[int64]*models.FeedIcon, view string, minifluxHost string) *models.OverviewTemplateData { - return m.buildDigestDataFunc(entries, icons, view, minifluxHost) +func (m *mockDigestService) BuildDigestData(entries []*models.Entry, icons map[int64]*models.FeedIcon, view string, minifluxHost string, digestHost string) *models.OverviewTemplateData { + return m.buildDigestDataFunc(entries, icons, view, minifluxHost, digestHost) } type mockArchiveService struct { @@ -78,7 +78,7 @@ func TestProcessDigest_Success(t *testing.T) { }, } mockDigestService := &mockDigestService{ - buildDigestDataFunc: func(entries []*models.Entry, icons map[int64]*models.FeedIcon, view string, minifluxHost string) *models.OverviewTemplateData { + buildDigestDataFunc: func(entries []*models.Entry, icons map[int64]*models.FeedIcon, view string, minifluxHost string, digestHost string) *models.OverviewTemplateData { return expectedOverviewData }, } diff --git a/internal/templates/grouped-entries.gohtml b/internal/templates/grouped-entries.gohtml index 58b5709..d4df502 100644 --- a/internal/templates/grouped-entries.gohtml +++ b/internal/templates/grouped-entries.gohtml @@ -5,6 +5,11 @@ {{.PrimaryGroup.Title}} + + + + + diff --git a/internal/webserver/webserver.go b/internal/webserver/webserver.go index fa28fec..7997dfb 100644 --- a/internal/webserver/webserver.go +++ b/internal/webserver/webserver.go @@ -11,7 +11,8 @@ import ( ) const ( - ArchiveBasePath = "web/miniflux-archive" + ArchiveBasePath = "web/archive" + StaticBasePath = "web/static" Port = ":8080" ) @@ -45,6 +46,9 @@ func SetupServer(archiveBasePath string) *http.ServeMux { } }) + staticFs := http.FileServer(http.Dir(StaticBasePath)) + mux.Handle("/static/", http.StripPrefix("/static/", staticFs)) + fs := http.FileServer(noDirListingFileSystem{http.Dir(archiveBasePath)}) mux.Handle("/archive/", http.StripPrefix("/archive/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/scripts/preview/main.go b/scripts/preview/main.go index 5e67200..5136f54 100644 --- a/scripts/preview/main.go +++ b/scripts/preview/main.go @@ -84,6 +84,7 @@ func generateMockDigest(cfg *config.Config) *models.OverviewTemplateData { icons, cfg.Digest.View, cfg.Miniflux.Host, + cfg.Digest.Host, ) if len(data.PrimaryGroups) > 0 { @@ -135,6 +136,7 @@ func generateMinifluxDigest(cfg *config.Config, minifluxClientService services.M icons, cfg.Digest.View, cfg.Miniflux.Host, + cfg.Digest.Host, ) } diff --git a/web/static/images/opengraph.png b/web/static/images/opengraph.png new file mode 100644 index 0000000000000000000000000000000000000000..fd9febf7de2e1334b05ee3de743c55e7ebf3aecd GIT binary patch literal 42562 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