1/*
2 * Copyright © 2018-2019 A Bunch Tell LLC.
3 *
4 * This file is part of WriteFreely.
5 *
6 * WriteFreely is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License, included
8 * in the LICENSE file in this source code package.
9 */
10
11package writefreely
12
13import (
14	"fmt"
15	"net/http"
16	"time"
17
18	"github.com/gorilla/mux"
19	"github.com/ikeikeikeike/go-sitemap-generator/v2/stm"
20	"github.com/writeas/web-core/log"
21)
22
23func buildSitemap(host, alias string) *stm.Sitemap {
24	sm := stm.NewSitemap(0)
25	sm.SetDefaultHost(host)
26	if alias != "/" {
27		sm.SetSitemapsPath(alias)
28	}
29
30	sm.Create()
31
32	// Note: Do not call `sm.Finalize()` because it flushes
33	// the underlying datastructure from memory to disk.
34
35	return sm
36}
37
38func handleViewSitemap(app *App, w http.ResponseWriter, r *http.Request) error {
39	vars := mux.Vars(r)
40
41	// Determine canonical blog URL
42	alias := vars["collection"]
43	subdomain := vars["subdomain"]
44	isSubdomain := subdomain != ""
45	if isSubdomain {
46		alias = subdomain
47	}
48
49	host := fmt.Sprintf("%s/%s/", app.cfg.App.Host, alias)
50	var c *Collection
51	var err error
52	pre := "/"
53	if app.cfg.App.SingleUser {
54		c, err = app.db.GetCollectionByID(1)
55	} else {
56		c, err = app.db.GetCollection(alias)
57	}
58	if err != nil {
59		return err
60	}
61	c.hostName = app.cfg.App.Host
62
63	if !isSubdomain {
64		pre += alias + "/"
65	}
66	host = c.CanonicalURL()
67
68	sm := buildSitemap(host, pre)
69	posts, err := app.db.GetPosts(app.cfg, c, 0, false, false, false)
70	if err != nil {
71		log.Error("Error getting posts: %v", err)
72		return err
73	}
74	lastSiteMod := time.Now()
75	for i, p := range *posts {
76		if i == 0 {
77			lastSiteMod = p.Updated
78		}
79		u := stm.URL{
80			{"loc", p.Slug.String},
81			{"changefreq", "weekly"},
82			{"mobile", true},
83			{"lastmod", p.Updated},
84		}
85		if len(p.Images) > 0 {
86			imgs := []stm.URL{}
87			for _, i := range p.Images {
88				imgs = append(imgs, stm.URL{
89					{"loc", i},
90					{"title", ""},
91				})
92			}
93			u = append(u, []interface{}{"image", imgs})
94		}
95		sm.Add(u)
96	}
97
98	// Add top URL
99	sm.Add(stm.URL{
100		{"loc", pre},
101		{"changefreq", "daily"},
102		{"priority", "1.0"},
103		{"lastmod", lastSiteMod},
104	})
105
106	w.Write(sm.XMLContent())
107
108	return nil
109}
110