json.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package json // import "miniflux.app/v2/internal/reader/json"
  4. import (
  5. "encoding/json"
  6. "strings"
  7. )
  8. // JSON Feed specs:
  9. // https://www.jsonfeed.org/version/1.1/
  10. // https://www.jsonfeed.org/version/1/
  11. type JSONFeed struct {
  12. // Version is the URL of the version of the format the feed uses.
  13. // This should appear at the very top, though we recognize that not all JSON generators allow for ordering.
  14. Version string `json:"version"`
  15. // Title is the name of the feed, which will often correspond to the name of the website.
  16. Title string `json:"title"`
  17. // HomePageURL is the URL of the resource that the feed describes.
  18. // This resource may or may not actually be a “home” page, but it should be an HTML page.
  19. HomePageURL string `json:"home_page_url"`
  20. // FeedURL is the URL of the feed, and serves as the unique identifier for the feed.
  21. FeedURL string `json:"feed_url"`
  22. // Description provides more detail, beyond the title, on what the feed is about.
  23. Description string `json:"description"`
  24. // IconURL is the URL of an image for the feed suitable to be used in a timeline, much the way an avatar might be used.
  25. IconURL string `json:"icon"`
  26. // FaviconURL is the URL of an image for the feed suitable to be used in a source list. It should be square and relatively small.
  27. FaviconURL string `json:"favicon"`
  28. // Authors specifies one or more feed authors. The author object has several members.
  29. Authors JSONAuthors `json:"authors"` // JSON Feed v1.1
  30. // Author specifies the feed author. The author object has several members.
  31. // JSON Feed v1 (deprecated)
  32. Author JSONAuthor `json:"author"`
  33. // Language is the primary language for the feed in the format specified in RFC 5646.
  34. // The value is usually a 2-letter language tag from ISO 639-1, optionally followed by a region tag. (Examples: en or en-US.)
  35. Language string `json:"language"`
  36. // Expired is a boolean value that specifies whether or not the feed is finished.
  37. Expired bool `json:"expired"`
  38. // Items is an array, each representing an individual item in the feed.
  39. Items []JSONItem `json:"items"`
  40. // Hubs describes endpoints that can be used to subscribe to real-time notifications from the publisher of this feed.
  41. Hubs []JSONHub `json:"hubs"`
  42. }
  43. type JSONAuthor struct {
  44. // Author's name.
  45. Name string `json:"name"`
  46. // Author's website URL (Blog or micro-blog).
  47. WebsiteURL string `json:"url"`
  48. // Author's avatar URL.
  49. AvatarURL string `json:"avatar"`
  50. }
  51. func (a JSONAuthor) name() string {
  52. return strings.TrimSpace(a.Name)
  53. }
  54. // JSONAuthors unmarshals either an array or a single author object.
  55. // Some feeds incorrectly use an object for "authors"; we accept it to avoid failing the whole feed.
  56. type JSONAuthors []JSONAuthor
  57. func (a *JSONAuthors) UnmarshalJSON(data []byte) error {
  58. var authors []JSONAuthor
  59. if err := json.Unmarshal(data, &authors); err == nil {
  60. *a = authors
  61. return nil
  62. }
  63. var author JSONAuthor
  64. if err := json.Unmarshal(data, &author); err == nil {
  65. *a = []JSONAuthor{author}
  66. return nil
  67. }
  68. // Ignore invalid formats silently; the caller can still use other fields.
  69. return nil
  70. }
  71. type JSONHub struct {
  72. // Type defines the protocol used to talk with the hub: "rssCloud" or "WebSub".
  73. Type string `json:"type"`
  74. // URL is the location of the hub.
  75. URL string `json:"url"`
  76. }
  77. type JSONItem struct {
  78. // Unique identifier for the item.
  79. // Ideally, the id is the full URL of the resource described by the item, since URLs make great unique identifiers.
  80. ID string `json:"id"`
  81. // URL of the resource described by the item.
  82. URL string `json:"url"`
  83. // ExternalURL is the URL of a page elsewhere.
  84. // This is especially useful for linkblogs.
  85. // If url links to where you’re talking about a thing, then external_url links to the thing you’re talking about.
  86. ExternalURL string `json:"external_url"`
  87. // Title of the item (optional).
  88. // Microblog items in particular may omit titles.
  89. Title string `json:"title"`
  90. // ContentHTML is the HTML body of the item.
  91. ContentHTML string `json:"content_html"`
  92. // ContentText is the text body of the item.
  93. ContentText string `json:"content_text"`
  94. // Summary is a plain text sentence or two describing the item.
  95. Summary string `json:"summary"`
  96. // ImageURL is the URL of the main image for the item.
  97. ImageURL string `json:"image"`
  98. // BannerImageURL is the URL of an image to use as a banner.
  99. BannerImageURL string `json:"banner_image"`
  100. // DatePublished is the date the item was published.
  101. DatePublished string `json:"date_published"`
  102. // DateModified is the date the item was modified.
  103. DateModified string `json:"date_modified"`
  104. // Language is the language of the item.
  105. Language string `json:"language"`
  106. // Authors is an array of JSONAuthor.
  107. Authors JSONAuthors `json:"authors"`
  108. // Author is a JSONAuthor.
  109. // JSON Feed v1 (deprecated)
  110. Author JSONAuthor `json:"author"`
  111. // Tags is an array of strings.
  112. Tags []string `json:"tags"`
  113. // Attachments is an array of JSONAttachment.
  114. Attachments []JSONAttachment `json:"attachments"`
  115. }
  116. type JSONAttachment struct {
  117. // URL of the attachment.
  118. URL string `json:"url"`
  119. // MIME type of the attachment.
  120. MimeType string `json:"mime_type"`
  121. // Title of the attachment.
  122. Title string `json:"title"`
  123. // Size of the attachment in bytes.
  124. Size int64 `json:"size_in_bytes"`
  125. // Duration of the attachment in seconds.
  126. Duration int `json:"duration_in_seconds"`
  127. }