opengraph tag support #59

Merged
eleith merged 1 commits from gemini/feature/opengraph-tags into main 2025-09-13 00:30:21 +00:00
16 changed files with 44 additions and 20 deletions

No files matched your search

+2 -3
View File
@@ -10,10 +10,9 @@
/vendor
# Web archive
/web/miniflux-archive
/web/preview.html
/web/archive
# Gemini CLI state
/.gemini/
PROJECT.md
PROJECT.md
+1 -1
View File
@@ -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
}
+1 -1
View File
@@ -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
}
+5 -1
View File
@@ -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 {
+1
View File
@@ -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,
+2 -2
View File
@@ -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)
}
+5 -5
View File
@@ -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")
+2 -1
View File
@@ -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,
}
}
+3 -1
View File
@@ -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
}
+1
View File
@@ -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)
+4 -4
View File
@@ -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
},
}
@@ -5,6 +5,11 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{.PrimaryGroup.Title}}</title>
<meta property="og:title" content="{{.PrimaryGroup.Title}}">
<meta property="og:description" content="{{.PrimaryGroup.Summary}}">
<meta property="og:type" content="website">
<meta property="og:url" content="{{.DigestHost}}/digests/{{.PrimaryGroup.Slug}}.html">
<meta property="og:image" content="{{.DigestHost}}/static/images/opengraph.png">
<style>
{{include "static/style.css"}}
+5
View File
@@ -4,6 +4,11 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Miniflux Digest Overview</title>
<meta property="og:title" content="Miniflux Digest">
<meta property="og:description" content="Miniflux digests, an antidote to my doom scrolling.">
<meta property="og:type" content="website">
<meta property="og:url" content="{{.DigestHost}}">
<meta property="og:image" content="{{.DigestHost}}/static/images/opengraph.png">
<style>
{{include "static/style.css"}}
</style>
+5 -1
View File
@@ -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) {
+2
View File
@@ -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,
)
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB