Reading RSS feeds in Go

in #programming6 years ago

I needed a simple program to get RSS feeds and do something on few information; I wanted to use it on several GNU/Linux boxes (CPU: Intel x86), without having to install something more than what was already installed, i.e. with no dependencies, if possible.

I suppose Perl and Python, and likely also Ruby, could have been a choice because they are almost always already installed. But I tried Go instead, mainly because I've read it can give a stand-alone executable, statically linked, so that the dynamic dependencies are nothing but the bare minimum . Which is what I wanted.



So I've studied a little bit how it can be done and in a matter of at most one hour, likely less (but I did know a little bit of Go before), I came up with this:

package main

import (
    "fmt"
    "encoding/xml"
    "os"
    "io/ioutil"
    "net/http"
    "strings"
)

type Item struct {
    Title string `xml:"title"`
    Link string `xml:"link"`
    Description string `xml:"description"`  
}

type Feed struct {
    Title string `xml:"channel>title"`
    Link string `xml:"channel>link"`
    Description string `xml:"channel>description"`
    Items []Item `xml:"channel>item"`
}


func main() {
    var str []byte
    var err error

    if len(os.Args) < 2 {
        fmt.Println("missing arg")
        return
    }
    obj := os.Args[1]

    if strings.HasPrefix(obj, "http://") ||
        strings.HasPrefix(obj, "https://") {
        var resp *http.Response
        resp, err = http.Get(obj)
        if err == nil {
            defer resp.Body.Close()
            str, err = ioutil.ReadAll(resp.Body)
        }
    } else {
        str, err = ioutil.ReadFile(os.Args[1])
    }
    if err != nil {
        fmt.Println(err)
        return
    }
    rss := Feed{}
    err = xml.Unmarshal([]byte(str), &rss)
    fmt.Println("title ", rss.Title)
    for a := range rss.Items {
        fmt.Println("title ", rss.Items[a].Title)
        fmt.Println("link ", rss.Items[a].Link)
    }
}

You can pass a file name as first argument — I did it for testing purposes.

This is easy, clean, and once you do go build, you obtain an executable with no dependiencies on libraries which must be installed on the target machine:

$ ldd rsstest
    linux-gate.so.1
    libpthread.so.0 => /lib/i386-linux-gnu/i686/cmov/libpthread.so.0
    libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6
    /lib/ld-linux.so.2

Nothing more!

The next step for me will be to turn it into a server accepting requests and spitting HTML. That, I bet, will be easy too! I think Go is a good language, with great libraries and solid practical concepts — though programming language theorists scorn it, but usually they are the guys who don't need to do things. All the others know that there's always room for powerful tools like Go (in fact programming languages are tools).

Purists and experts of Go are welcome to fix my code style, maybe it's not very idiomatic — I am still a Go learner. Well, indeed I am studying Ada now, as you can tell from the lessons I will continue soon, but guess what? You can't do this in Ada so easily and quickly!

Sort:  

Congratulations @xinta! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Do not miss the last post from @steemitboard:

Are you a DrugWars early adopter? Benvenuto in famiglia!
Vote for @Steemitboard as a witness to get one more award and increased upvotes!

Coin Marketplace

STEEM 0.30
TRX 0.12
JST 0.034
BTC 64038.60
ETH 3148.89
USDT 1.00
SBD 3.97