Files
backtone/atom/atom.go
T

92 lines
2.5 KiB
Go

package atom
import (
"errors"
"regexp"
"strconv"
"strings"
"time"
"github.com/gorilla/feeds"
)
// Indices indicates which capture group in the
// regex-parsed HTML to reference for each Atom field.
// An empty slice will use a blank/default value.
// For the slices of strings, these will be appended between
// captured group text.
type IndicesT struct {
TitleC []string
TitleI []int8
LinkC []string
LinkI []int8
DescriptionC []string
DescriptionI []int8
AuthorNameC []string
AuthorNameI []int8
AuthorEmailC []string
AuthorEmailI []int8
}
func GetFromString(feed *feeds.Feed, input *string, regexString string, infoIndices IndicesT, maxFeedItems int) (*string, error) {
now := time.Now()
r := regexp.MustCompile(regexString)
newsItems := r.FindAllString(*input, maxFeedItems)
for i, item := range newsItems {
info := r.FindStringSubmatch(item)
link := stitchFields(info, infoIndices.LinkC, infoIndices.LinkI)
feedItem := &feeds.Item{
Title: stitchFields(info, infoIndices.TitleC, infoIndices.TitleI),
Link: &feeds.Link{Href: link},
Id: "urn:backtoneid:" + strconv.Itoa(i) + ":" + link,
Description: stitchFields(info, infoIndices.DescriptionC, infoIndices.DescriptionI),
Author: &feeds.Author{
Name: stitchFields(info, infoIndices.AuthorNameC, infoIndices.AuthorNameI),
Email: stitchFields(info, infoIndices.AuthorEmailC, infoIndices.AuthorEmailI),
},
Created: now,
}
feed.Items = append(feed.Items, feedItem)
}
atom, err := feed.ToAtom()
if err != nil {
return nil, errors.New("unable to create Atom RSS feed: " + err.Error())
}
return &atom, nil
}
func stitchFields(info []string, connectors []string, indices []int8) string {
var output strings.Builder
if len(connectors) > 0 {
for i := range connectors {
output.WriteString(connectors[i])
if len(indices) >= i+1 {
output.WriteString(info[indices[i]])
}
}
} else {
for i := range indices {
if i > 0 {
output.WriteString(" | ")
}
output.WriteString(info[indices[i]])
}
}
return interpretUnicode(output.String())
}
func interpretUnicode(s string) string {
// match \uXXXX patterns
r := regexp.MustCompile(`\\u([0-9a-fA-F]{4})`)
result := r.ReplaceAllStringFunc(s, func(match string) string {
// extract the hex value
hexStr := match[2:] // skip the \u part
code, err := strconv.ParseInt(hexStr, 16, 32)
if err != nil {
return match // if parsing fails, return original
}
return string(rune(code))
})
return result
}