rdf.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Copyright 2017 Frédéric Guillot. All rights reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. package rdf // import "miniflux.app/reader/rdf"
  5. import (
  6. "encoding/xml"
  7. "strings"
  8. "time"
  9. "miniflux.app/crypto"
  10. "miniflux.app/logger"
  11. "miniflux.app/model"
  12. "miniflux.app/reader/date"
  13. "miniflux.app/reader/sanitizer"
  14. "miniflux.app/url"
  15. )
  16. type rdfFeed struct {
  17. XMLName xml.Name `xml:"RDF"`
  18. Title string `xml:"channel>title"`
  19. Link string `xml:"channel>link"`
  20. Items []rdfItem `xml:"item"`
  21. DublinCoreFeedElement
  22. }
  23. func (r *rdfFeed) Transform() *model.Feed {
  24. feed := new(model.Feed)
  25. feed.Title = sanitizer.StripTags(r.Title)
  26. feed.SiteURL = r.Link
  27. for _, item := range r.Items {
  28. entry := item.Transform()
  29. if entry.Author == "" && r.DublinCoreCreator != "" {
  30. entry.Author = strings.TrimSpace(r.DublinCoreCreator)
  31. }
  32. entry.Author = sanitizer.StripTags(entry.Author)
  33. if entry.URL == "" {
  34. entry.URL = feed.SiteURL
  35. } else {
  36. entryURL, err := url.AbsoluteURL(feed.SiteURL, entry.URL)
  37. if err == nil {
  38. entry.URL = entryURL
  39. }
  40. }
  41. feed.Entries = append(feed.Entries, entry)
  42. }
  43. return feed
  44. }
  45. type rdfItem struct {
  46. Title string `xml:"title"`
  47. Link string `xml:"link"`
  48. Description string `xml:"description"`
  49. DublinCoreEntryElement
  50. }
  51. func (r *rdfItem) Transform() *model.Entry {
  52. entry := new(model.Entry)
  53. entry.Title = r.entryTitle()
  54. entry.Author = r.entryAuthor()
  55. entry.URL = r.entryURL()
  56. entry.Content = r.entryContent()
  57. entry.Hash = r.entryHash()
  58. entry.Date = r.entryDate()
  59. return entry
  60. }
  61. func (r *rdfItem) entryTitle() string {
  62. return strings.TrimSpace(r.Title)
  63. }
  64. func (r *rdfItem) entryContent() string {
  65. switch {
  66. case r.DublinCoreContent != "":
  67. return r.DublinCoreContent
  68. default:
  69. return r.Description
  70. }
  71. }
  72. func (r *rdfItem) entryAuthor() string {
  73. return strings.TrimSpace(r.DublinCoreCreator)
  74. }
  75. func (r *rdfItem) entryURL() string {
  76. return strings.TrimSpace(r.Link)
  77. }
  78. func (r *rdfItem) entryDate() time.Time {
  79. if r.DublinCoreDate != "" {
  80. result, err := date.Parse(r.DublinCoreDate)
  81. if err != nil {
  82. logger.Error("rdf: %v", err)
  83. return time.Now()
  84. }
  85. return result
  86. }
  87. return time.Now()
  88. }
  89. func (r *rdfItem) entryHash() string {
  90. value := r.Link
  91. if value == "" {
  92. value = r.Title + r.Description
  93. }
  94. return crypto.Hash(value)
  95. }