Sfoglia il codice sorgente

Ignore enclosures without URL

Frédéric Guillot 6 anni fa
parent
commit
997e9422eb

+ 4 - 0
reader/atom/atom_10.go

@@ -161,6 +161,10 @@ func (a *atom10Entry) entryEnclosures() model.EnclosureList {
 
 	for _, link := range a.Links {
 		if strings.ToLower(link.Rel) == "enclosure" {
+			if link.URL == "" {
+				continue
+			}
+
 			if _, found := duplicates[link.URL]; !found {
 				duplicates[link.URL] = true
 				length, _ := strconv.ParseInt(link.Length, 10, 0)

+ 37 - 0
reader/atom/atom_10_test.go

@@ -503,6 +503,43 @@ func TestParseEntryWithEnclosures(t *testing.T) {
 	}
 }
 
+func TestParseEntryWithoutEnclosureURL(t *testing.T) {
+	data := `<?xml version="1.0" encoding="utf-8"?>
+	<feed xmlns="http://www.w3.org/2005/Atom">
+		<id>http://www.example.org/myfeed</id>
+		<title>My Podcast Feed</title>
+		<updated>2005-07-15T12:00:00Z</updated>
+		<link href="http://example.org" />
+		<link rel="self" href="http://example.org/myfeed" />
+		<entry>
+			<id>http://www.example.org/entries/1</id>
+			<title>Atom 1.0</title>
+			<updated>2005-07-15T12:00:00Z</updated>
+			<link href="http://www.example.org/entries/1" />
+			<summary>An overview of Atom 1.0</summary>
+			<link rel="enclosure" href="" length="0" />
+			<content type="xhtml">Test</content>
+		</entry>
+  	</feed>`
+
+	feed, err := Parse(bytes.NewBufferString(data))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(feed.Entries) != 1 {
+		t.Errorf("Incorrect number of entries, got: %d", len(feed.Entries))
+	}
+
+	if feed.Entries[0].URL != "http://www.example.org/entries/1" {
+		t.Errorf("Incorrect entry URL, got: %s", feed.Entries[0].URL)
+	}
+
+	if len(feed.Entries[0].Enclosures) != 0 {
+		t.Fatalf("Incorrect number of enclosures, got: %d", len(feed.Entries[0].Enclosures))
+	}
+}
+
 func TestParseEntryWithPublished(t *testing.T) {
 	data := `<?xml version="1.0" encoding="utf-8"?>
 	<feed xmlns="http://www.w3.org/2005/Atom">

+ 4 - 0
reader/json/json.go

@@ -136,6 +136,10 @@ func (j *jsonItem) GetEnclosures() model.EnclosureList {
 	enclosures := make(model.EnclosureList, 0)
 
 	for _, attachment := range j.Attachments {
+		if attachment.URL == "" {
+			continue
+		}
+
 		enclosures = append(enclosures, &model.Enclosure{
 			URL:      attachment.URL,
 			MimeType: attachment.MimeType,

+ 50 - 11
reader/json/parser_test.go

@@ -33,7 +33,7 @@ func TestParseJsonFeed(t *testing.T) {
 
 	feed, err := Parse(bytes.NewBufferString(data))
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 
 	if feed.Title != "My Example Feed" {
@@ -115,7 +115,7 @@ func TestParsePodcast(t *testing.T) {
 
 	feed, err := Parse(bytes.NewBufferString(data))
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 
 	if feed.Title != "The Record" {
@@ -131,7 +131,7 @@ func TestParsePodcast(t *testing.T) {
 	}
 
 	if len(feed.Entries) != 1 {
-		t.Errorf("Incorrect number of entries, got: %d", len(feed.Entries))
+		t.Fatalf("Incorrect number of entries, got: %d", len(feed.Entries))
 	}
 
 	if feed.Entries[0].Hash != "6b678e57962a1b001e4e873756563cdc08bbd06ca561e764e0baa9a382485797" {
@@ -156,7 +156,7 @@ func TestParsePodcast(t *testing.T) {
 	}
 
 	if len(feed.Entries[0].Enclosures) != 1 {
-		t.Errorf("Incorrect number of enclosures, got: %d", len(feed.Entries[0].Enclosures))
+		t.Fatalf("Incorrect number of enclosures, got: %d", len(feed.Entries[0].Enclosures))
 	}
 
 	if feed.Entries[0].Enclosures[0].URL != "http://therecord.co/downloads/The-Record-sp1e1-ChrisParrish.m4a" {
@@ -172,6 +172,45 @@ func TestParsePodcast(t *testing.T) {
 	}
 }
 
+func TestParseEntryWithoutAttachmentURL(t *testing.T) {
+	data := `{
+		"version": "https://jsonfeed.org/version/1",
+		"user_comment": "This is a podcast feed. You can add this feed to your podcast client using the following URL: http://therecord.co/feed.json",
+		"title": "The Record",
+		"home_page_url": "http://therecord.co/",
+		"feed_url": "http://therecord.co/feed.json",
+		"items": [
+			{
+				"id": "http://therecord.co/chris-parrish",
+				"title": "Special #1 - Chris Parrish",
+				"url": "http://therecord.co/chris-parrish",
+				"content_text": "Chris has worked at Adobe and as a founder of Rogue Sheep, which won an Apple Design Award for Postage. Chris’s new company is Aged & Distilled with Guy English — which shipped Napkin, a Mac app for visual collaboration. Chris is also the co-host of The Record. He lives on Bainbridge Island, a quick ferry ride from Seattle.",
+				"date_published": "2014-05-09T14:04:00-07:00",
+				"attachments": [
+					{
+						"url": "",
+						"mime_type": "audio/x-m4a",
+						"size_in_bytes": 0
+					}
+				]
+			}
+		]
+	}`
+
+	feed, err := Parse(bytes.NewBufferString(data))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(feed.Entries) != 1 {
+		t.Fatalf("Incorrect number of entries, got: %d", len(feed.Entries))
+	}
+
+	if len(feed.Entries[0].Enclosures) != 0 {
+		t.Errorf("Incorrect number of enclosures, got: %d", len(feed.Entries[0].Enclosures))
+	}
+}
+
 func TestParseFeedWithRelativeURL(t *testing.T) {
 	data := `{
 		"version": "https://jsonfeed.org/version/1",
@@ -189,7 +228,7 @@ func TestParseFeedWithRelativeURL(t *testing.T) {
 
 	feed, err := Parse(bytes.NewBufferString(data))
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 
 	if feed.Entries[0].URL != "https://example.org/something.html" {
@@ -221,7 +260,7 @@ func TestParseAuthor(t *testing.T) {
 
 	feed, err := Parse(bytes.NewBufferString(data))
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 
 	if len(feed.Entries) != 1 {
@@ -250,7 +289,7 @@ func TestParseFeedWithoutTitle(t *testing.T) {
 
 	feed, err := Parse(bytes.NewBufferString(data))
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 
 	if feed.Title != "https://example.org/" {
@@ -276,7 +315,7 @@ func TestParseFeedItemWithInvalidDate(t *testing.T) {
 
 	feed, err := Parse(bytes.NewBufferString(data))
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 
 	if len(feed.Entries) != 1 {
@@ -304,7 +343,7 @@ func TestParseFeedItemWithoutID(t *testing.T) {
 
 	feed, err := Parse(bytes.NewBufferString(data))
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 
 	if len(feed.Entries) != 1 {
@@ -331,7 +370,7 @@ func TestParseFeedItemWithoutTitle(t *testing.T) {
 
 	feed, err := Parse(bytes.NewBufferString(data))
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 
 	if len(feed.Entries) != 1 {
@@ -358,7 +397,7 @@ func TestParseTruncateItemTitle(t *testing.T) {
 
 	feed, err := Parse(bytes.NewBufferString(data))
 	if err != nil {
-		t.Error(err)
+		t.Fatal(err)
 	}
 
 	if len(feed.Entries) != 1 {

+ 36 - 0
reader/rss/parser_test.go

@@ -741,6 +741,42 @@ func TestParseEntryWithEnclosures(t *testing.T) {
 	}
 }
 
+func TestParseEntryWithEmptyEnclosureURL(t *testing.T) {
+	data := `<?xml version="1.0" encoding="utf-8"?>
+		<rss version="2.0">
+		<channel>
+		<title>My Podcast Feed</title>
+		<link>http://example.org</link>
+		<author>some.email@example.org</author>
+		<item>
+			<title>Podcasting with RSS</title>
+			<link>http://www.example.org/entries/1</link>
+			<description>An overview of RSS podcasting</description>
+			<pubDate>Fri, 15 Jul 2005 00:00:00 -0500</pubDate>
+			<guid isPermaLink="true">http://www.example.org/entries/1</guid>
+			<enclosure url="" length="0"/>
+		</item>
+		</channel>
+		</rss>`
+
+	feed, err := Parse(bytes.NewBufferString(data))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(feed.Entries) != 1 {
+		t.Errorf("Incorrect number of entries, got: %d", len(feed.Entries))
+	}
+
+	if feed.Entries[0].URL != "http://www.example.org/entries/1" {
+		t.Errorf("Incorrect entry URL, got: %s", feed.Entries[0].URL)
+	}
+
+	if len(feed.Entries[0].Enclosures) != 0 {
+		t.Errorf("Incorrect number of enclosures, got: %d", len(feed.Entries[0].Enclosures))
+	}
+}
+
 func TestParseEntryWithFeedBurnerEnclosures(t *testing.T) {
 	data := `<?xml version="1.0" encoding="utf-8"?>
 		<rss version="2.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

+ 4 - 0
reader/rss/rss.go

@@ -278,6 +278,10 @@ func (r *rssItem) entryEnclosures() model.EnclosureList {
 			}
 		}
 
+		if enclosureURL == "" {
+			continue
+		}
+
 		if _, found := duplicates[enclosureURL]; !found {
 			duplicates[enclosureURL] = true
 

+ 4 - 0
storage/enclosure.go

@@ -57,6 +57,10 @@ func (s *Storage) GetEnclosures(entryID int64) (model.EnclosureList, error) {
 
 // CreateEnclosure creates a new attachment.
 func (s *Storage) CreateEnclosure(enclosure *model.Enclosure) error {
+	if enclosure.URL == "" {
+		return nil
+	}
+
 	query := `
 		INSERT INTO enclosures
 			(url, size, mime_type, entry_id, user_id)

+ 2 - 0
template/html/entry.html

@@ -95,6 +95,7 @@
     <details class="entry-enclosures">
         <summary>{{ t "page.entry.attachments" }} ({{ len .entry.Enclosures }})</summary>
         {{ range .entry.Enclosures }}
+            {{ if ne .URL "" }}
             <div class="entry-enclosure">
                 {{ if hasPrefix .MimeType "audio/" }}
                     <div class="enclosure-audio">
@@ -119,6 +120,7 @@
                     <small>{{ if gt .Size 0 }} - <strong>{{ formatFileSize .Size }}</strong>{{ end }}</small>
                 </div>
             </div>
+            {{ end }}
         {{ end }}
         </details>
     {{ end }}

+ 3 - 1
template/views.go

@@ -645,6 +645,7 @@ var templateViewsMap = map[string]string{
     <details class="entry-enclosures">
         <summary>{{ t "page.entry.attachments" }} ({{ len .entry.Enclosures }})</summary>
         {{ range .entry.Enclosures }}
+            {{ if ne .URL "" }}
             <div class="entry-enclosure">
                 {{ if hasPrefix .MimeType "audio/" }}
                     <div class="enclosure-audio">
@@ -669,6 +670,7 @@ var templateViewsMap = map[string]string{
                     <small>{{ if gt .Size 0 }} - <strong>{{ formatFileSize .Size }}</strong>{{ end }}</small>
                 </div>
             </div>
+            {{ end }}
         {{ end }}
         </details>
     {{ end }}
@@ -1316,7 +1318,7 @@ var templateViewsMapChecksums = map[string]string{
 	"edit_category":       "b1c0b38f1b714c5d884edcd61e5b5295a5f1c8b71c469b35391e4dcc97cc6d36",
 	"edit_feed":           "cc0b5dbb73f81398410958b41771ed38246bc7ae4bd548228f0d48c49a598c2a",
 	"edit_user":           "c692db9de1a084c57b93e95a14b041d39bf489846cbb91fc982a62b72b77062a",
-	"entry":               "9aac76b1cfa80428f136edf292f8610b14289ca9595d725c1365bc0a2847a21d",
+	"entry":               "513183f0f0b11a199630562f5a85eb9a5646051aae278cbc682bac13d62e65cc",
 	"feed_entries":        "9c70b82f55e4b311eff20be1641733612e3c1b406ce8010861e4c417d97b6dcc",
 	"feeds":               "ec7d3fa96735bd8422ba69ef0927dcccddc1cc51327e0271f0312d3f881c64fd",
 	"history_entries":     "87e17d39de70eb3fdbc4000326283be610928758eae7924e4b08dcb446f3b6a9",