package classes import ( "time" "git.golem15.com/golem15/sm-sitemap-plugin/models" "git.golem15.com/golem15/summercms/modules/backpack" "gorm.io/gorm" ) // SitemapFile is one file of the sitemap index: its name, the number of // addresses (pages for an image file, articles for the News file) and the // newest lastmod of its addresses. type SitemapFile struct { Name string `json:"name"` Count int `json:"count"` LastMod *time.Time `json:"lastmod"` } // SitemapFiles lists the files the index links, in its order: the // per-group files, the image files while images_enabled is on, then // sitemap-news.xml while news_enabled is on and it lists an article. func SitemapFiles(db *gorm.DB, app *backpack.App, s models.Settings, now time.Time) ([]SitemapFile, error) { type fileRow struct { Grp string `gorm:"column:grp"` FileNo int `gorm:"column:file_no"` N int `gorm:"column:n"` LastMod *time.Time `gorm:"column:lastmod"` } var rows []fileRow if err := db.Raw(`SELECT grp, file_no, COUNT(*) AS n, MAX(lastmod) AS lastmod FROM golem15_sitemap_urls WHERE excluded_reason = '' AND file_no IS NOT NULL GROUP BY grp, file_no ORDER BY grp, file_no`).Scan(&rows).Error; err != nil { return nil, err } if s.ImagesEnabled { var images []fileRow if err := db.Raw(`SELECT image_file_no AS file_no, COUNT(*) AS n, MAX(lastmod) AS lastmod FROM golem15_sitemap_urls WHERE excluded_reason = '' AND image_file_no IS NOT NULL AND jsonb_array_length(images) > 0 GROUP BY image_file_no ORDER BY image_file_no`).Scan(&images).Error; err != nil { return nil, err } for i := range images { images[i].Grp = ImagesGroup } rows = append(rows, images...) } out := make([]SitemapFile, 0, len(rows)+1) for _, r := range rows { out = append(out, SitemapFile{Name: FileName(r.Grp, r.FileNo), Count: r.N, LastMod: r.LastMod}) } if s.NewsEnabled { news, err := NewsEntries(db, app, s, now) if err != nil { return nil, err } if len(news) > 0 { newest := news[0].Published out = append(out, SitemapFile{Name: NewsFile, Count: len(news), LastMod: &newest}) } } return out, nil } // LeftOut counts the addresses left out of the sitemaps by reason (a // Filter's or the type switch's; deleted and unpublished rows are holes, // not left out). func LeftOut(db *gorm.DB) (map[string]int, error) { var rows []struct { Reason string `gorm:"column:excluded_reason"` N int `gorm:"column:n"` } if err := db.Raw(`SELECT excluded_reason, COUNT(*) AS n FROM golem15_sitemap_urls WHERE excluded_reason NOT IN ('', ?, ?) GROUP BY excluded_reason`, models.ReasonDeleted, models.ReasonUnpublished).Scan(&rows).Error; err != nil { return nil, err } out := make(map[string]int, len(rows)) for _, r := range rows { out[r.Reason] = r.N } return out, nil }