From 2aad93d24580e4562d53fbb804005c9880149a60 Mon Sep 17 00:00:00 2001 From: mushus Date: Thu, 7 Jun 2018 21:04:46 +0900 Subject: [PATCH] first commit! --- Gopkg.lock | 87 +++++++++++++++++++++++++++++++++++++++++ Gopkg.toml | 22 +++++++++++ main.go | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 222 insertions(+) create mode 100644 Gopkg.lock create mode 100644 Gopkg.toml create mode 100644 main.go diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..43b090f --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,87 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/PuerkitoBio/goquery" + packages = ["."] + revision = "a86ea073017a6beddef78c8659e7224e8ca634b0" + version = "v1.4.0" + +[[projects]] + name = "github.com/andybalholm/cascadia" + packages = ["."] + revision = "901648c87902174f774fac311d7f176f8647bdaa" + version = "v1.0.0" + +[[projects]] + name = "github.com/dgrijalva/jwt-go" + packages = ["."] + revision = "06ea1031745cb8b3dab3f6a236daf2b0aa468b7e" + version = "v3.2.0" + +[[projects]] + name = "github.com/gorilla/feeds" + packages = ["."] + revision = "6edcbcd2d57fd0bbd7f39947a593ed0c06648388" + version = "v1.1.0" + +[[projects]] + name = "github.com/labstack/echo" + packages = [".","middleware"] + revision = "6d227dfea4d2e52cb76856120b3c17f758139b4e" + version = "3.3.5" + +[[projects]] + name = "github.com/labstack/gommon" + packages = ["bytes","color","log","random"] + revision = "588f4e8bddc6cb45c27b448e925c7fd6a5545434" + version = "0.2.5" + +[[projects]] + name = "github.com/mattn/go-colorable" + packages = ["."] + revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072" + version = "v0.0.9" + +[[projects]] + name = "github.com/mattn/go-isatty" + packages = ["."] + revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" + version = "v0.0.3" + +[[projects]] + branch = "master" + name = "github.com/valyala/bytebufferpool" + packages = ["."] + revision = "e746df99fe4a3986f4d4f79e13c1e0117ce9c2f7" + +[[projects]] + branch = "master" + name = "github.com/valyala/fasttemplate" + packages = ["."] + revision = "dcecefd839c4193db0d35b88ec65b4c12d360ab0" + +[[projects]] + branch = "master" + name = "golang.org/x/crypto" + packages = ["acme","acme/autocert"] + revision = "b47b1587369238182299fe4dad77d05b8b461e06" + +[[projects]] + branch = "master" + name = "golang.org/x/net" + packages = ["html","html/atom"] + revision = "1e491301e022f8f977054da4c2d852decd59571f" + +[[projects]] + branch = "master" + name = "golang.org/x/sys" + packages = ["unix"] + revision = "9527bec2660bd847c050fda93a0f0c6dee0800bb" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "ae0e76b9424a4d9c99b1802e669483605ca5e67ca216a0563de479196362f9af" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..9425a54 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,22 @@ + +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" + diff --git a/main.go b/main.go new file mode 100644 index 0000000..66088a3 --- /dev/null +++ b/main.go @@ -0,0 +1,113 @@ +package main + +import ( + "encoding/json" + "flag" + "fmt" + "log" + "net/http" + "net/url" + "path" + "time" + + "github.com/PuerkitoBio/goquery" + "github.com/gorilla/feeds" + "github.com/labstack/echo" + "github.com/labstack/echo/middleware" +) + +// TrendData qiitaのトレンド +type TrendData struct { + Trend struct { + Edges []struct { + Node struct { + CreatedAt string `json:"createdAt"` + Title string `json:"title"` + UUID string `json:"uuid"` + Author struct { + ProfileImageURL string `json:"profileImageUrl"` + URLName string `json:"urlName"` + } `json:"author"` + } `json:"node"` + } `json:"edges"` + } `json:"trend"` +} + +const ( + trendURL = "https://qiita.com" + internalServerError = "internal server error" +) + +var port = flag.Int("port", 1234, "port mumber") + +func main() { + e := echo.New() + e.Use(middleware.Logger()) + e.Use(middleware.Recover()) + e.GET("/", handleFeed) + e.Logger.Fatal(e.Start(fmt.Sprintf(":%d", *port))) +} + +func handleFeed(c echo.Context) error { + res, err := http.Get(trendURL) + if err != nil { + log.Fatal(err) + } + + defer res.Body.Close() + if res.StatusCode != 200 { + log.Fatalf("status code error: %d %s", res.StatusCode, res.Status) + } + + doc, err := goquery.NewDocumentFromReader(res.Body) + if err != nil { + log.Fatal(err) + } + + feedItem := []*feeds.Item{} + + doc.Find("div[data-hyperapp-app=Trend]").Each(func(i int, s *goquery.Selection) { + text, exists := s.Attr("data-hyperapp-props") + if !exists { + return + } + + trends := &TrendData{} + err := json.Unmarshal([]byte(text), trends) + if err != nil { + return + } + + for _, item := range trends.Trend.Edges { + url := url.URL{ + Scheme: "https", + Host: "qiita.com", + Path: path.Join(item.Node.Author.URLName, "items", item.Node.UUID), + } + created, _ := time.Parse(time.RFC3339, item.Node.CreatedAt) + feedItem = append(feedItem, &feeds.Item{ + Title: item.Node.Title, + Link: &feeds.Link{Href: url.String()}, + Description: item.Node.Title, + Author: &feeds.Author{Name: item.Node.Author.URLName, Email: ""}, + Created: created, + }) + } + }) + + feed := &feeds.Feed{ + Title: "Qiita", + Link: &feeds.Link{Href: "https://qiita.com/trend"}, + Description: "Qiita trends", + Updated: time.Now(), + Items: feedItem, + } + text, err := feed.ToRss() + if err != nil { + c.Logger().Printf("%#v", err) + return c.String(http.StatusInternalServerError, internalServerError) + } + + c.Response().Header().Set("Content-Type", "text/xml; charset=utf-8") + return c.String(http.StatusOK, text) +}