package main import ( "encoding/base64" "flag" "fmt" "net/http" "strconv" "time" "github.com/gin-gonic/gin" "yumc.pw/cloud/clipboard-sync/lib/clipboard" ) func main() { t := flag.String("t", "c", "Type c(client) or s(server)") a := flag.String("a", "http://127.0.0.1:8080", "Server Address") b := flag.String("b", ":8080", "Server Listen Port") flag.Parse() if *t == "c" { if clipboard.Unsupported { panic("Unsupported On This Machine") } readClipboard(*a) } else { startServer(*b) } } const ( textHeader = "Go-Clipboard-Text" timeHeader = "Go-Clipboard-Time" ) func startServer(b string) { text := "" time := time.Now().Unix() g := gin.New() g.GET("/", func(c *gin.Context) { c.Header(textHeader, text) c.Header(timeHeader, strconv.FormatInt(time, 10)) }) g.POST("/", func(c *gin.Context) { text = c.Query("text") time, _ = strconv.ParseInt(c.Query("time"), 10, 64) }) g.Run(b) } func readClipboard(a string) { old, _ := clipboard.ReadAll() updateTime := time.Now().Unix() client := &http.Client{} address := a + "?text=%s&time=%s" for { time.Sleep(100 * time.Millisecond) text, _ := clipboard.ReadAll() if old != text { old = text updateTime = time.Now().Unix() request, _ := http.NewRequest("POST", fmt.Sprintf(address, encode(text), strconv.FormatInt(updateTime, 10)), nil) client.Do(request) } else { response, _ := http.Get(a) texts, ok := response.Header[textHeader] if ok { sText := decode(texts[0]) sTime, _ := strconv.ParseInt(response.Header[timeHeader][0], 10, 64) if sTime > updateTime && sText != old { old = sText updateTime = sTime clipboard.WriteAll(sText) } } } } } func encode(text string) string { return base64.URLEncoding.EncodeToString([]byte(text)) } func decode(text string) string { origin, _ := base64.URLEncoding.DecodeString(text) return string(origin) }