aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go188
1 files changed, 188 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..945b30b
--- /dev/null
+++ b/main.go
@@ -0,0 +1,188 @@
+package main
+
+import (
+ "context"
+ "errors"
+ "flag"
+ "fmt"
+ "io"
+ "net/http"
+ "regexp"
+ "strings"
+
+ "github.com/beevik/etree"
+)
+
+type ErrorRequestHandler func(w http.ResponseWriter, r *http.Request) error
+
+var RegexCollection = map[string]string{
+ "nerdcast": "NerdCast [0-9]+[a-c]* -",
+ "empreendedor": "Empreendedor [0-9]+ -",
+ "mamicas": "Caneca de Mamicas [0-9]+ -",
+ "english": "Speak English [0-9]+ -",
+ "nerdcash": "NerdCash [0-9]+ -",
+ "bunker": "Lá do Bunker [0-9]+ -",
+ "tech": "NerdTech [0-9]+ -",
+ "genera": "Generacast [0-9]+ -",
+}
+
+const (
+ FeedUrl = "https://api.jovemnerd.com.br/feed-nerdcast/"
+)
+
+func getSeries(r *http.Request) []string {
+ query := r.URL.Query().Get("q")
+
+ var series []string
+
+ for _, q := range strings.Split(query, ",") {
+ if _, ok := RegexCollection[q]; ok {
+ series = append(series, q)
+ }
+ }
+
+ if len(series) > 0 {
+ return series
+ }
+
+ return []string{"nerdcast"}
+}
+
+func match(title string, series []string) bool {
+ for _, s := range series {
+ if ok, err := regexp.MatchString(RegexCollection[s], title); err == nil && ok {
+ return true
+ }
+ }
+
+ return false
+}
+
+func fetchXML(_ context.Context) ([]byte, error) {
+ res, err := http.Get(FeedUrl)
+ if err != nil {
+ return nil, err
+ }
+ defer res.Body.Close()
+
+ if res.StatusCode == http.StatusOK {
+ return io.ReadAll(res.Body)
+ }
+
+ return nil, errors.New("Invalid http code")
+}
+
+func appendTag(tag *etree.Element, ap string) {
+ text := tag.Text()
+ tag.SetText(text + ap)
+}
+
+func filterBySeries(series []string, xml []byte, temper bool) ([]byte, error) {
+ doc := etree.NewDocument()
+ err := doc.ReadFromBytes(xml)
+ if err != nil {
+ return nil, err
+ }
+
+ channel := doc.FindElement("//channel")
+
+ if temper {
+ tmp := strings.ToUpper(strings.Join(series, ","))
+ tmp = fmt.Sprintf(" [%s]", tmp)
+ appendTag(channel.FindElement("title"), tmp)
+ appendTag(channel.FindElement("description"), tmp)
+ appendTag(channel.FindElement("link"), "?"+tmp)
+ appendTag(channel.FindElement("author[namespace-prefix()='itunes']"), tmp)
+ appendTag(channel.FindElement("subtitle[namespace-prefix()='itunes']"), tmp)
+ appendTag(channel.FindElement("summary[namespace-prefix()='itunes']"), tmp)
+ appendTag(channel.FindElement("author[namespace-prefix()='googleplay']"), tmp)
+
+ }
+
+ for _, tag := range channel.FindElements("item") {
+ title := tag.FindElement("title").Text()
+ if !match(title, series) {
+ channel.RemoveChild(tag)
+ }
+ }
+
+ return doc.WriteToBytes()
+}
+
+func wrap(next ErrorRequestHandler) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ if err := next(w, r); err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ }
+ }
+}
+
+func titles(w http.ResponseWriter, r *http.Request) error {
+ xml, err := fetchXML(r.Context())
+ if err != nil {
+ return err
+ }
+
+ doc := etree.NewDocument()
+ err = doc.ReadFromBytes(xml)
+ if err != nil {
+ return err
+ }
+
+ series := getSeries(r)
+
+ els := doc.FindElements("//channel/item")
+ for _, e := range els {
+ txt := e.FindElement("title").Text() + "\n"
+ if match(txt, series) {
+ _, err = w.Write([]byte(txt))
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
+func podcast(w http.ResponseWriter, r *http.Request) error {
+ xml, err := fetchXML(r.Context())
+ if err != nil {
+ return err
+ }
+
+ series := getSeries(r)
+ filterdXML, err := filterBySeries(series, xml, true)
+ if err != nil {
+ return err
+ }
+
+ _, err = w.Write(filterdXML)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func main() {
+ var (
+ addr = flag.String("addr", ":8080", "Server address")
+ )
+
+ flag.Parse()
+
+ mux := http.NewServeMux()
+ mux.HandleFunc("/titles", wrap(titles))
+ mux.HandleFunc("/", wrap(podcast))
+
+ server := http.Server{
+ Handler: mux,
+ Addr: *addr,
+ }
+
+ err := server.ListenAndServe()
+ if err != nil {
+ fmt.Printf("Server error: %s", err.Error())
+ }
+}