aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.go37
-rw-r--r--main_test.go67
-rw-r--r--testdata/TestServedFeed.golden92
3 files changed, 181 insertions, 15 deletions
diff --git a/main.go b/main.go
index 22846b0..f29fae3 100644
--- a/main.go
+++ b/main.go
@@ -52,6 +52,8 @@ var (
episodeUrlRe = regexp.MustCompile(`<a href="/brand/(.+?)?" class="title`)
outputPath, programNumber string
+
+ errBadEpisode = fmt.Errorf("bad episode")
)
func main() {
@@ -59,22 +61,27 @@ func main() {
flag.StringVar(&programNumber, "brand", "57083", "brand number (defaults to Aerostat)")
flag.Parse()
- programUrl := "http://www.radiorus.ru/brand/" + programNumber + "/episodes"
+ url := "http://www.radiorus.ru/brand/" + programNumber + "/episodes"
+
+ feed := processURL(url)
+
+ feed.Created = time.Now()
+ output := createFeed(feed)
+ outputFile := outputPath + "radiorus-" + programNumber + ".rss"
+
+ writeFile(output, outputFile)
+}
- feed := getFeed(programUrl)
+func processURL(url string) *feeds.Feed {
+ feed := getFeed(url)
var wg sync.WaitGroup
wg.Add(1)
go describeFeed(feed, &wg)
describeEpisodes(feed)
-
- feed.Created = time.Now()
wg.Wait()
- output := createFeed(feed)
-
- outputFile := outputPath + "radiorus-" + programNumber + ".rss"
- writeFile(output, outputFile)
+ return feed
}
func createFeed(feed *feeds.Feed) []byte {
@@ -98,9 +105,12 @@ func getFeed(url string) (feed *feeds.Feed) {
for {
page := getPage(url)
- if err := populateFeed(feed, page); err != nil {
+ if err := populateFeed(feed, page); err == errBadEpisode {
time.Sleep(15 * 60 * time.Second)
continue
+ } else if err != nil {
+ err = fmt.Errorf("could not process %v: %w", url, err)
+ log.Fatal(err)
}
break
}
@@ -109,7 +119,12 @@ func getFeed(url string) (feed *feeds.Feed) {
}
func populateFeed(feed *feeds.Feed, page []byte) (err error) {
- feed.Title = string(programNameRe.FindSubmatch(page)[1])
+ titleMatch := programNameRe.FindSubmatch(page)
+ if len(titleMatch) < 1 {
+ return fmt.Errorf("bad program page")
+ }
+
+ feed.Title = string(titleMatch[1])
programImage := programImageRe.FindSubmatch(page)
feed.Image = &feeds.Image{
Link: feed.Link.Href,
@@ -121,7 +136,7 @@ func populateFeed(feed *feeds.Feed, page []byte) (err error) {
for _, episode := range episodes {
if len(episodeUrlRe.FindAllSubmatch(episode, -1)) > 1 {
- return fmt.Errorf("bad episode")
+ return errBadEpisode
}
episodeUrl := "http://www.radiorus.ru/brand/" + string(episodeUrlRe.FindSubmatch(episode)[1])
episodeTitle := string(episodeTitleRe.FindSubmatch(episode)[1])
diff --git a/main_test.go b/main_test.go
index 4a5e53f..819f9d0 100644
--- a/main_test.go
+++ b/main_test.go
@@ -18,14 +18,24 @@ package main
import (
"bytes"
"flag"
+ "fmt"
"io/ioutil"
+ "net/http"
+ "net/http/httptest"
+ "os"
"path/filepath"
+ "sync"
"testing"
"github.com/gorilla/feeds"
)
-var update = flag.Bool("update", false, "update .golden files")
+var (
+ update = flag.Bool("update", false, "update .golden files")
+ fakeURL = `**localhost**`
+)
+
+const pth = "testdata/brand/57083"
func helperLoadBytes(t *testing.T, name string) []byte {
t.Helper()
@@ -56,9 +66,30 @@ func TestFeed(t *testing.T) {
actual := createFeed(feed)
golden := filepath.Join("testdata", t.Name()+".golden")
if *update {
- if err := ioutil.WriteFile(golden, actual, 0644); err != nil {
- t.Fatal(err)
- }
+ writeFile(actual, golden)
+ }
+ expected, _ := ioutil.ReadFile(golden)
+
+ if !bytes.Equal(actual, expected) {
+ t.Fail()
+ }
+}
+
+func TestServedFeed(t *testing.T) {
+ server := helperMockServer(t)
+ defer helperCleanupServer(t)
+
+ feed := getFeed(fmt.Sprintf("%s/brand/57083/episodes", server.URL))
+
+ var wg sync.WaitGroup
+ wg.Add(1)
+ describeFeed(feed, &wg)
+ wg.Wait()
+
+ actual := bytes.ReplaceAll(createFeed(feed), []byte(server.URL), []byte(fakeURL))
+ golden := filepath.Join("testdata", t.Name()+".golden")
+ if *update {
+ writeFile(actual, golden)
}
expected, _ := ioutil.ReadFile(golden)
@@ -66,3 +97,31 @@ func TestFeed(t *testing.T) {
t.Fail()
}
}
+
+func helperMockServer(t *testing.T) *httptest.Server {
+ t.Helper()
+
+ fileserver := http.FileServer(http.Dir("testdata"))
+ server := httptest.NewServer(fileserver)
+
+ episodes := helperLoadBytes(t, "episodes")
+ writeFile(episodes, filepath.Join(pth, "episodes"))
+
+ about := helperLoadBytes(t, "about")
+ writeFile(about, filepath.Join(pth, "about"))
+
+ return server
+}
+
+func helperCleanupServer(t *testing.T) {
+ t.Helper()
+ helperCleanupFile(t, "episodes")
+ helperCleanupFile(t, "about")
+}
+
+func helperCleanupFile(t *testing.T, name string) {
+ t.Helper()
+ if err := os.Remove(filepath.Join(pth, name)); err != nil {
+ t.Fatal(err)
+ }
+}
diff --git a/testdata/TestServedFeed.golden b/testdata/TestServedFeed.golden
new file mode 100644
index 0000000..a2301fa
--- /dev/null
+++ b/testdata/TestServedFeed.golden
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
+ <channel>
+ <title>&lt;a href=&#34;/brand/57083&#34;&gt;&#34;Аэростат&#34;&lt;/a&gt;</title>
+ <link>**localhost**/brand/57083/episodes</link>
+ <description>Вы не можете быть до конца уверены, что на этот раз вам откроет БГ – будь то взгляд на группу Doors или столь глобальные вопросы, как: что такое новое время, как делится история мира в соответствии с древней индийской космогонией, стоит ли ждать ветра перемен, ждет ли нас духовное возрождение, где граница между прошлым и будущим. А может и вовсе не стоит искать ответы на эти вопросы? Потому что это не те вопросы, а потому и ответы не приведут вас к истине...&#xD;&#xA;&#xD;&#xA;Прислушаемся к Борису Гребенщикову, который с улыбкой говорит всем нам &#34;Здравствуйте!&#34; и находит самые простые ответы...</description>
+ <image>
+ <url>https://cdn-st4.rtr-vesti.ru/vh/pictures/xw/124/617/1.jpg</url>
+ <title>&#34;Аэростат&#34;</title>
+ <link>**localhost**/brand/57083/episodes</link>
+ </image>
+ <item>
+ <title>Новые имена 27</title>
+ <link>http://www.radiorus.ru/brand/57083/episode/2237849</link>
+ <description></description>
+ <enclosure url="https://audio.vgtrk.com/download?id=2467579" length="1024" type="audio/mpeg"></enclosure>
+ <guid>http://www.radiorus.ru/brand/57083/episode/2237849</guid>
+ <pubDate>Sun, 26 Jan 2020 14:10:00 +0300</pubDate>
+ </item>
+ <item>
+ <title>The Cure</title>
+ <link>http://www.radiorus.ru/brand/57083/episode/2237781</link>
+ <description></description>
+ <enclosure url="https://audio.vgtrk.com/download?id=2466052" length="1024" type="audio/mpeg"></enclosure>
+ <guid>http://www.radiorus.ru/brand/57083/episode/2237781</guid>
+ <pubDate>Sun, 19 Jan 2020 14:10:00 +0300</pubDate>
+ </item>
+ <item>
+ <title>Новые песни января</title>
+ <link>http://www.radiorus.ru/brand/57083/episode/2236152</link>
+ <description></description>
+ <enclosure url="https://audio.vgtrk.com/download?id=2464622" length="1024" type="audio/mpeg"></enclosure>
+ <guid>http://www.radiorus.ru/brand/57083/episode/2236152</guid>
+ <pubDate>Sun, 12 Jan 2020 14:10:00 +0300</pubDate>
+ </item>
+ <item>
+ <title>Новогодние притчи</title>
+ <link>http://www.radiorus.ru/brand/57083/episode/2234173</link>
+ <description></description>
+ <enclosure url="https://audio.vgtrk.com/download?id=2463470" length="1024" type="audio/mpeg"></enclosure>
+ <guid>http://www.radiorus.ru/brand/57083/episode/2234173</guid>
+ <pubDate>Sun, 05 Jan 2020 14:10:00 +0300</pubDate>
+ </item>
+ <item>
+ <title>С наступающим!</title>
+ <link>http://www.radiorus.ru/brand/57083/episode/2233216</link>
+ <description></description>
+ <enclosure url="https://audio.vgtrk.com/download?id=2462338" length="1024" type="audio/mpeg"></enclosure>
+ <guid>http://www.radiorus.ru/brand/57083/episode/2233216</guid>
+ <pubDate>Sun, 29 Dec 2019 14:10:00 +0300</pubDate>
+ </item>
+ <item>
+ <title>Рождество</title>
+ <link>http://www.radiorus.ru/brand/57083/episode/2231513</link>
+ <description></description>
+ <enclosure url="https://audio.vgtrk.com/download?id=2460859" length="1024" type="audio/mpeg"></enclosure>
+ <guid>http://www.radiorus.ru/brand/57083/episode/2231513</guid>
+ <pubDate>Sun, 22 Dec 2019 14:10:00 +0300</pubDate>
+ </item>
+ <item>
+ <title>&#34;То да сё # 6&#34; (Сила музыки)</title>
+ <link>http://www.radiorus.ru/brand/57083/episode/2229234</link>
+ <description></description>
+ <enclosure url="https://audio.vgtrk.com/download?id=2459405" length="1024" type="audio/mpeg"></enclosure>
+ <guid>http://www.radiorus.ru/brand/57083/episode/2229234</guid>
+ <pubDate>Sun, 15 Dec 2019 14:10:00 +0300</pubDate>
+ </item>
+ <item>
+ <title>Новые песни декабря</title>
+ <link>http://www.radiorus.ru/brand/57083/episode/2226836</link>
+ <description></description>
+ <enclosure url="https://audio.vgtrk.com/download?id=2457932" length="1024" type="audio/mpeg"></enclosure>
+ <guid>http://www.radiorus.ru/brand/57083/episode/2226836</guid>
+ <pubDate>Sun, 08 Dec 2019 14:10:00 +0300</pubDate>
+ </item>
+ <item>
+ <title>То да сё № 5</title>
+ <link>http://www.radiorus.ru/brand/57083/episode/2223937</link>
+ <description></description>
+ <enclosure url="https://audio.vgtrk.com/download?id=2456411" length="1024" type="audio/mpeg"></enclosure>
+ <guid>http://www.radiorus.ru/brand/57083/episode/2223937</guid>
+ <pubDate>Sun, 01 Dec 2019 14:10:00 +0300</pubDate>
+ </item>
+ <item>
+ <title>ELO: &#34;Из ниоткуда&#34; 2019</title>
+ <link>http://www.radiorus.ru/brand/57083/episode/2222868</link>
+ <description></description>
+ <enclosure url="https://audio.vgtrk.com/download?id=2454907" length="1024" type="audio/mpeg"></enclosure>
+ <guid>http://www.radiorus.ru/brand/57083/episode/2222868</guid>
+ <pubDate>Sun, 24 Nov 2019 14:10:00 +0300</pubDate>
+ </item>
+ </channel>
+</rss> \ No newline at end of file