Skip to content

Instantly share code, notes, and snippets.

@saml
Created August 4, 2015 21:50
Show Gist options
  • Select an option

  • Save saml/cdbdd4636bc2c76be4f0 to your computer and use it in GitHub Desktop.

Select an option

Save saml/cdbdd4636bc2c76be4f0 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"strings"
)
func safeFirst(m map[string][]string, key string, defaultValue string) string {
l := m[key]
if len(l) > 0 {
return l[0]
}
return defaultValue
}
type Component interface {
html() string
}
type unknownComponent struct {
key string
value map[string]interface{}
}
type Article struct {
url string
title string
body string
}
type textComponent struct {
value string
}
func (c *textComponent) html() string {
return c.value
}
func asString(x interface{}) string {
if x, ok := x.(string); ok {
return x
}
return ""
}
func parseTextComponent(c *unknownComponent) *textComponent {
if strings.HasPrefix(c.key, "entry") {
html := asString(c.value["entrytext"])
if html == "" {
html = asString(c.value["entryText"])
}
return &textComponent{value: html}
}
return nil
}
func parseComponent(doc map[string]interface{}) Component {
unknown := asUnknownComponent(doc)
c := parseTextComponent(unknown)
if c != nil {
return c
}
return nil
}
func asUnknownComponent(doc map[string]interface{}) *unknownComponent {
for k, v := range doc {
return &unknownComponent{key: k, value: v.(map[string]interface{})}
}
return nil
}
func parseArticle(doc map[string]interface{}) *Article {
article := &Article{}
article.url = doc["canonicalUrl"].(string)
article.title = doc["entryTitle"].(string)
body := doc["body"]
if body != nil {
components := body.([]interface{})
for _, d := range components {
component := parseComponent(d.(map[string]interface{}))
if component != nil {
log.Printf("%v", component.html())
}
}
}
return article
}
func handleArticle(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
articleUrl := safeFirst(query, "url", "")
if len(articleUrl) > 0 {
url := conf.urlArticle(articleUrl)
log.Printf("GET %s", url)
resp, err := http.Get(url)
if err != nil {
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
}
var doc map[string]interface{}
err = json.Unmarshal(body, &doc)
if err != nil {
}
article := parseArticle(doc)
log.Printf("%v", article)
w.Write(body)
}
}
type config struct {
port int
apiUrl string
}
var conf *config = &config{}
func (c *config) addr() string {
return fmt.Sprintf(":%d", c.port)
}
func (c *config) urlArticle(url string) string {
return c.apiUrl + "/v1/content/articles/" + url
}
func main() {
flag.IntVar(&conf.port, "port", 8080, "port to listen to")
flag.StringVar(&conf.apiUrl, "api", "http://localhost:3000", "base url to api")
flag.Parse()
log.Printf("%v", conf)
addr := conf.addr()
mux := http.NewServeMux()
mux.HandleFunc("/", handleArticle)
log.Printf("Listening http://localhost%s\n", addr)
http.ListenAndServe(addr, mux)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment