Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move item-related functions from proc to feed module #44

Merged
merged 1 commit into from
Jul 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions app/feed/item.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package feed

import (
"html/template"
"io"
"net/http"
"path"
"time"
)

// Item for rss
type Item struct {
// Required
Title string `xml:"title"`
Link string `xml:"link"`
Description template.HTML `xml:"description"`
// Optional
Content template.HTML `xml:"encoded"`
PubDate string `xml:"pubDate"`
Comments string `xml:"comments"`
Enclosure Enclosure `xml:"enclosure"`
GUID string `xml:"guid"`

// Internal
DT time.Time `xml:"-"`
Junk bool `xml:"-"`
}

// DownloadAudio return httpBody for Item's Enclosure.URL
func (item Item) DownloadAudio(timeout time.Duration) (io.ReadCloser, error) {
clientHTTP := &http.Client{Timeout: timeout}

resp, err := clientHTTP.Get(item.Enclosure.URL)
if err != nil {
return nil, err
}

return resp.Body, nil
}

// GetFilename returns the filename for Item's Enclosure.URL
func (item Item) GetFilename() string {
_, filename := path.Split(item.Enclosure.URL)
return filename
}
64 changes: 64 additions & 0 deletions app/feed/item_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package feed

import (
"fmt"
"net/http"
"net/http/httptest"
"strconv"
"testing"
"time"

"github.com/stretchr/testify/assert"
)

func TestGetFilename(t *testing.T) {
tbl := []struct {
url, expected string
}{
{"https://example.com/100500/song.mp3", "song.mp3"},
{"https://example.com//song.mp3", "song.mp3"},
{"https://example.com/song.mp3", "song.mp3"},
{"https://example.com/song.mp3/", ""},
{"https://example.com/", ""},
}

for i, tt := range tbl {
i := i
tt := tt
t.Run(strconv.Itoa(i), func(t *testing.T) {
item := Item{Enclosure: Enclosure{URL: tt.url}}
fname := item.GetFilename()
assert.Equal(t, tt.expected, fname)
})
}
}

func TestDownloadAudioIfRequestError(t *testing.T) {
var ts *httptest.Server
ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ts.CloseClientConnections()
}))

defer ts.Close()

item := Item{Enclosure: Enclosure{URL: ts.URL}}
got, err := item.DownloadAudio(time.Minute)

assert.Nil(t, got)
assert.EqualError(t, err, fmt.Sprintf("Get %q: EOF", ts.URL))
}

func TestDownloadAudio(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Length", "4")
fmt.Fprint(w, "abcd")
}))
defer ts.Close()

item := Item{Enclosure: Enclosure{URL: ts.URL}}
got, err := item.DownloadAudio(time.Minute)

assert.NotNil(t, got)
assert.Nil(t, err)
}
18 changes: 0 additions & 18 deletions app/feed/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,6 @@ type Rss2 struct {
ItemList []Item `xml:"channel>item"`
}

// Item for rss
type Item struct {
// Required
Title string `xml:"title"`
Link string `xml:"link"`
Description template.HTML `xml:"description"`
// Optional
Content template.HTML `xml:"encoded"`
PubDate string `xml:"pubDate"`
Comments string `xml:"comments"`
Enclosure Enclosure `xml:"enclosure"`
GUID string `xml:"guid"`

// Internal
DT time.Time `xml:"-"`
Junk bool `xml:"-"`
}

// Enclosure element from item
type Enclosure struct {
URL string `xml:"url,attr"`
Expand Down
25 changes: 3 additions & 22 deletions app/proc/telegram.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ package proc
import (
"bytes"
"fmt"
"github.com/tcolgate/mp3"
"io"
"net/http"
"path"
"strings"
"time"

log "github.com/go-pkgz/lgr"
"github.com/microcosm-cc/bluemonday"
"github.com/pkg/errors"
"github.com/tcolgate/mp3"
"golang.org/x/net/html"
tb "gopkg.in/tucnak/telebot.v2"

Expand Down Expand Up @@ -85,7 +84,7 @@ func (client TelegramClient) sendText(channelID string, item feed.Item) (*tb.Mes
}

func (client TelegramClient) sendAudio(channelID string, item feed.Item) (*tb.Message, error) {
httpBody, err := client.downloadAudio(item.Enclosure.URL)
httpBody, err := item.DownloadAudio(client.Timeout)
if err != nil {
return nil, err
}
Expand All @@ -96,7 +95,7 @@ func (client TelegramClient) sendAudio(channelID string, item feed.Item) (*tb.Me

audio := tb.Audio{
File: tb.FromReader(&httpBodyCopy),
FileName: client.getFilenameByURL(item.Enclosure.URL),
FileName: item.GetFilename(),
MIME: "audio/mpeg",
Caption: client.getMessageHTML(item, false),
Title: item.Title,
Expand All @@ -114,19 +113,6 @@ func (client TelegramClient) sendAudio(channelID string, item feed.Item) (*tb.Me
return message, err
}

func (client TelegramClient) downloadAudio(url string) (io.ReadCloser, error) {
clientHTTP := &http.Client{Timeout: client.Timeout * time.Second}

resp, err := clientHTTP.Get(url)
if err != nil {
return nil, err
}

log.Printf("[DEBUG] start download audio: %s", url)

return resp.Body, err
}

// https://core.telegram.org/bots/api#html-style
func (client TelegramClient) tagLinkOnlySupport(htmlText string) string {
p := bluemonday.NewPolicy()
Expand Down Expand Up @@ -164,11 +150,6 @@ func (client TelegramClient) getMessageHTML(item feed.Item, withMp3Link bool) st
return messageHTML
}

func (client TelegramClient) getFilenameByURL(url string) string {
_, filename := path.Split(url)
return filename
}

// duration scans MP3 file from provided io.Reader and returns it's duration in seconds, ignoring possible errors
func (client TelegramClient) duration(r io.Reader) int {
d := mp3.NewDecoder(r)
Expand Down
55 changes: 0 additions & 55 deletions app/proc/telegram_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ package proc

import (
"bytes"
"fmt"
"net/http"
"net/http/httptest"
"strconv"
"testing"
"testing/iotest"
Expand Down Expand Up @@ -164,58 +161,6 @@ func TestRecipientChannelIDNotStartWithAt(t *testing.T) {
}
}

func TestGetFilenameByURL(t *testing.T) {
tbl := []struct {
url, expected string
}{
{"https://example.com/100500/song.mp3", "song.mp3"},
{"https://example.com//song.mp3", "song.mp3"},
{"https://example.com/song.mp3", "song.mp3"},
{"https://example.com/song.mp3/", ""},
{"https://example.com/", ""},
}

for i, tt := range tbl {
i := i
tt := tt
t.Run(strconv.Itoa(i), func(t *testing.T) {
client := TelegramClient{}
fname := client.getFilenameByURL(tt.url)
assert.Equal(t, tt.expected, fname)
})
}
}

func TestDownloadAudioIfRequestError(t *testing.T) {
var ts *httptest.Server
ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ts.CloseClientConnections()
}))

defer ts.Close()

client := TelegramClient{}
got, err := client.downloadAudio(ts.URL)

assert.Nil(t, got)
assert.EqualError(t, err, fmt.Sprintf("Get %q: EOF", ts.URL))
}

func TestDownloadAudio(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Length", "4")
fmt.Fprint(w, "abcd")
}))
defer ts.Close()

client := TelegramClient{}
got, err := client.downloadAudio(ts.URL)

assert.NotNil(t, got)
assert.NoError(t, err)
}

func TestDurationBadReader(t *testing.T) {
r := iotest.ErrReader(bytes.ErrTooLarge)
client := TelegramClient{}
Expand Down