package backend import ( "fmt" "io" "os" "git.streifling.com/jason/atom" ) func GenerateAtomFeed(c *Config, db *DB) (*string, error) { feed := atom.NewFeed(c.Title) feed.ID = atom.NewID("urn:feed:1") feed.Subtitle = atom.NewText("text", c.Description) linkID := feed.AddLink(atom.NewLink(c.Link)) feed.Links[linkID].Rel = "self" feed.Generator = atom.NewGenerator("cpolis") feed.Generator.URI = "https://git.streifling.com/jason/cpolis" feed.Generator.Version = c.Version articles, err := db.GetCertainArticles("published", true) if err != nil { return nil, fmt.Errorf("error getting published articles for Atom feed: %v", err) } for _, article := range articles { articleTitle, err := ConvertToPlain(article.Title) if err != nil { return nil, fmt.Errorf("error converting title to plain text for Atom feed: %v", err) } entry := atom.NewEntry(articleTitle) entry.ID = atom.NewID(fmt.Sprint("urn:entry:", article.ID)) entry.Published = atom.NewDate(article.Created) entry.Content = atom.NewContent(atom.OutOfLine, "text/html", fmt.Sprint(c.Domain, "/article/serve/", article.UUID)) if article.AutoGenerated { entry.Summary = atom.NewText("text", "automatically generated") } else { articleSummary, err := ConvertToPlain(article.Summary) if err != nil { return nil, fmt.Errorf("error converting description to plain text for Atom feed: %v", err) } entry.Summary = atom.NewText("text", articleSummary) } if len(article.BannerLink) > 0 { linkID := entry.AddLink(atom.NewLink(c.Domain + "/image/serve/" + article.BannerLink)) entry.Links[linkID].Rel = "enclosure" entry.Links[linkID].Type = "image/webp" } authors, err := db.GetArticleAuthors(c, article.ID) if err != nil { return nil, fmt.Errorf("error getting article's authors for Atom feed: %v", err) } for _, author := range authors { user, err := db.GetUser(c, author.ID) if err != nil { return nil, fmt.Errorf("error getting user info for Atom feed: %v", err) } authorID := entry.AddAuthor(atom.NewPerson(user.FirstName + " " + user.LastName)) entry.Authors[authorID].URI = c.Domain + "/image/serve/" + user.ProfilePicLink } contributors, err := db.GetArticleContributors(c, article.ID) if err != nil { return nil, fmt.Errorf("error getting article's contributors for Atom feed: %v", err) } for _, contributor := range contributors { user, err := db.GetUser(c, contributor.ID) if err != nil { return nil, fmt.Errorf("error getting user info for Atom feed: %v", err) } contributorID := entry.AddContributor(atom.NewPerson(user.FirstName + " " + user.LastName)) entry.Contributors[contributorID].URI = c.Domain + "/image/serve/" + user.ProfilePicLink } tags, err := db.GetArticleTags(article.ID) if err != nil { return nil, fmt.Errorf("error getting tags for articles for Atom feed: %v", err) } for _, tag := range tags { entry.AddCategory(atom.NewCategory(tag.Name)) } if article.IsInIssue || article.AutoGenerated { entry.AddCategory(atom.NewCategory(fmt.Sprint("Orient Express ", article.IssueID))) } if article.AutoGenerated { entry.AddCategory(atom.NewCategory("autogenerated")) } entry.Updated = atom.NewDate(article.Created) feed.AddEntry(entry) } if err = feed.Check(); err != nil { return nil, fmt.Errorf("error checking Atom feed: %v", err) } atom, err := feed.ToXML("UTF-8") if err != nil { return nil, fmt.Errorf("error converting Atom feed to XML: %v", err) } return &atom, nil } func SaveAtomFeed(filename string, feed *string) error { file, err := os.Create(filename) if err != nil { return fmt.Errorf("error creating file for Atom feed: %v", err) } defer file.Close() if err = file.Chmod(0644); err != nil { return fmt.Errorf("error setting permissions for Atom file: %v", err) } if _, err = io.WriteString(file, *feed); err != nil { return fmt.Errorf("error writing to Atom file: %v", err) } return nil }