推薦一個簡化搜尋的web小工具“鹹魚SOS”【附上伺服器端程式碼】

kaesalai發表於2017-12-06

##鹹魚 SOS 連結地址:http://xianyusos.fun

> 反正不要錢,不用白不用~ —— 周樹人

使用鹹魚 SOS可以簡化搜尋步驟,舉個例子,老師要小明同學在 github 中搜尋 “golang” 關鍵字,檢視 golang 的開源專案

  1. 普通小明會在瀏覽器的輸入框中輸入 “github.com”,等網頁顯示出來後再找到搜尋框搜尋;

  2. 2B 小明會先開啟百度,在百度中搜尋 “github”,再選中 github 官網,等網頁顯示出來後再找到搜尋框搜尋;

  3. 文藝小明會把鹹魚 SOS 設定為首頁或者加入書籤,只用選中左邊的 GitHub,就可以直接使用中央的搜尋框搜尋 github 裡的內容了。


服務端程式碼如下,請斧正: server.go

package main

import (
    "github.com/labstack/echo"
    "xianyusos/handlers"
    "io"
    "html/template"
    "time"
    "gopkg.in/redis.v5"
    "github.com/sirupsen/logrus"
    "os"
    "fmt"
)

const (
    PERIOD = 1*time.Hour
)

type Template struct {
    Templates *template.Template
}

func (t *Template) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
    return t.Templates.ExecuteTemplate(w, name, data)
}

func main() {
    if err := getEnvs(); err != nil {
        panic(err)
    }
    e := echo.New()
    defer e.Close()
    h, err := handlers.New()
    if err != nil {
        panic(err)
    }
    defer h.Client.Close()
    e.Renderer = &Template{
        Templates: template.Must(template.ParseGlob("views/*.html")),
    }
    logrus.SetOutput(os.Stdout)

    go func() {
        for {
            time.Sleep(PERIOD)
            if err := h.Client.Ping().Err(); err != nil {
                logrus.Errorf("Error in h.Client.Ping: [%s].", err.Error())
                h.Client = redis.NewClient(&redis.Options{
                    Addr: handlers.REDIS_ADDRESS,
                    Password: handlers.REDIS_PASSWORD,
                    MaxRetries: 5,
                })
                logrus.Infof("Reconnect redis[%s].", handlers.REDIS_ADDRESS)
            }
            for k, v := range h.VisitorsIp {
                if err := h.Client.HSet("visitors", k, v).Err(); err != nil {
                    logrus.Errorf("Error in h.Client.Set: [%s].", err.Error())
                    continue
                }
            }
            logrus.Info("Update the value of visitors success.")
        }
    }()

    e.GET("/", h.Home)
    e.GET("/:routerName", h.Search)
    e.Static("/static", "views")
    e.File("/favicon.ico", "views/katongxianyu.png")
    //h.RouterName["163music"] = true
    h.RouterName["github"] = true
    h.RouterName["baidu"] = true
    h.RouterName["bilibili"] = true
    h.RouterName["iqiyi"] = true
    h.RouterName["jd"] = true
    h.RouterName["mooc"] = true
    h.RouterName["qidian"] = true
    h.RouterName["runoob"] = true
    h.RouterName["segmentfault"] = true
    h.RouterName["stackoverflow"] = true
    h.RouterName["taobao"] = true
    h.RouterName["weibo"] = true
    h.RouterName["youku"] = true
    h.RouterName["zhihu"] = true
    e.Start(":8823")
}

func getEnvs() error {
    handlers.REDIS_ADDRESS = os.Getenv("REDIS_ADDRESS")
    if len(handlers.REDIS_ADDRESS) == 0 {
        return fmt.Errorf("Env [REDIS_ADDRESS] is nil.")
    }
    handlers.REDIS_PASSWORD = os.Getenv("REDIS_PASSWORD")
    if len(handlers.REDIS_PASSWORD) == 0 {
        return fmt.Errorf("Env [REDIS_PASSWORD] is nil.")
    }
    return nil
}

handler.go

package handlers

import (
    "github.com/labstack/echo"
    "net/http"
    "gopkg.in/redis.v5"
    "sync"
    "strings"
)

var (
    REDIS_ADDRESS = "na.huanyu0w0.cn:2333"
    REDIS_PASSWORD = "3.1415926"
)

type (
    handler struct {
        Client *redis.Client
        Mux sync.Mutex
        RouterName map[string]bool
        VisitorsIp map[string]string
    }
)

func New() (*handler, error) {
    h := new(handler)
    h.Client = redis.NewClient(&redis.Options{
        Addr: REDIS_ADDRESS,
        Password: REDIS_PASSWORD,
        MaxRetries: 5,
    })
    var err error
    h.VisitorsIp, err = h.Client.HGetAll("visitors").Result()
    if err != nil {
        return nil, err
    }
    h.Mux = sync.Mutex{}
    h.RouterName = make(map[string]bool)
    return h, nil
}

func (h *handler) Home(c echo.Context) error {
    routerName := ""
    for routerName = range h.RouterName {
        break
    }
    return c.Redirect(http.StatusFound, "/"+routerName)
}

func (h *handler) Search(c echo.Context) error {
    h.Mux.Lock()
    ip := strings.Split(c.Request().RemoteAddr, ":")[0]
    h.VisitorsIp[ip] = ip
    h.Mux.Unlock()
    routerName := c.Param("routerName")
    if len(routerName) == 0 {
        return echo.ErrNotFound
    }
    if b, ok := h.RouterName[routerName]; !ok && b == true {
        return echo.ErrNotFound
    }
    return c.Render(http.StatusOK, routerName, len(h.VisitorsIp))
}
更多原創文章乾貨分享,請關注公眾號
  • 推薦一個簡化搜尋的web小工具“鹹魚SOS”【附上伺服器端程式碼】
  • 加微信實戰群請加微信(註明:實戰群):gocnio

相關文章