Skip to content

Instantly share code, notes, and snippets.

@SteveBate
Last active September 20, 2015 07:30
Show Gist options
  • Save SteveBate/e9f771861b647a746b2f to your computer and use it in GitHub Desktop.
Save SteveBate/e9f771861b647a746b2f to your computer and use it in GitHub Desktop.
Golang example showing how to use interfaces (Writer) to compose functionality, in this case, retrieve data from a url, encode response to a base64 string, compress it, and then save to a file. Also includes sample aspects for logging and timing
package main
import (
"bytes"
"compress/gzip"
"encoding/base64"
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
"github.com/SteveBate/gomailer"
)
// types
type WebFilter func(wd *WebData)
type WebData struct {
filename string
url string
raw []byte
}
// methods of WebData
func (wd *WebData) scrape() {
var err error
resp, err := http.Get(wd.url)
if err != nil {
log.Fatal(err)
}
wd.raw, err = ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
resp.Body.Close()
}
func (wd *WebData) encode() {
buf := bytes.Buffer{}
e := base64.NewEncoder(base64.URLEncoding, &buf)
e.Write(wd.raw)
e.Close()
wd.raw = buf.Bytes()
}
func (wd *WebData) compress() {
buf := bytes.Buffer{}
w := gzip.NewWriter(&buf)
w.Write(wd.raw)
w.Close()
wd.raw = buf.Bytes()
wd.filename += ".gz"
}
func (wd *WebData) save() {
fmt.Println("saving ", wd.filename)
ioutil.WriteFile(wd.filename, wd.raw, 0666)
}
func (wd *WebData) send() {
mail := gomailer.NewMail()
mail.Subject = "test email"
mail.Body = "Hello world"
mail.To = "" // an email address
mail.From = "" // a name
if err := mail.AttachBytes(wd.filename, wd.raw); err != nil {
fmt.Println(err)
}
client := gomailer.NewMailClient()
client.Username = "" // credentials
client.Password = ""
err := client.Send(mail)
if err != nil {
fmt.Println(err)
}
fmt.Println("mail sent")
}
// aspects
func Log(f WebFilter) WebFilter {
return func(wd *WebData) {
fmt.Println("fetching from ", wd.url)
f(wd)
fmt.Println("done fetching from ", wd.url)
}
}
func Time(f WebFilter) WebFilter {
return func(wd *WebData) {
start := time.Now()
f(wd)
end := time.Now().Sub(start)
fmt.Println("request completed in", end.String())
}
}
// program entry point
func main() {
wd1 := &WebData{filename: "bbc.txt", url: "http://www.bbc.co.uk"}
wd2 := &WebData{filename: "amazon.txt", url: "http://www.amazon.co.uk"}
wd3 := &WebData{filename: "google.txt", url: "http://www.google.co.uk"}
f1 := Log(Time(Execute))
f2 := Log(Time(Execute))
f3 := Log(Time(Execute))
go f1(wd1)
go f2(wd2)
go f3(wd3)
select {}
}
func Execute(wd *WebData) {
wd.scrape()
wd.encode()
wd.compress()
wd.save()
wd.send()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment