Created
January 26, 2017 01:00
-
-
Save jonas747/0538fcdd5449f2b86b7ed07752458e1c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"errors" | |
"flag" | |
"fmt" | |
"github.com/PuerkitoBio/goquery" | |
"github.com/jonas747/discordgo" | |
"io" | |
"io/ioutil" | |
"log" | |
"net/http" | |
"os/exec" | |
"strconv" | |
"strings" | |
"time" | |
"unicode" | |
) | |
const ( | |
ScriptStartsWith = "webpackJsonp(" | |
) | |
var ( | |
DToken string | |
DCHannel string | |
DMention string | |
DG *discordgo.Session | |
) | |
func init() { | |
flag.StringVar(&DToken, "t", "", "Discord token for notifications") | |
flag.StringVar(&DCHannel, "c", "", "Discord channel for notifications") | |
flag.StringVar(&DMention, "m", "", "Mention") | |
flag.Parse() | |
} | |
func main() { | |
if DToken == "" || DCHannel == "" { | |
log.Println("No discord token or channel specified, no notifications will be provided") | |
} else { | |
d, err := discordgo.New(DToken) | |
if err != nil { | |
log.Fatal("Failed initializing discordgo session: ", err) | |
} | |
DG = d | |
log.Println("Discord notifications enabled") | |
} | |
runLoop() | |
} | |
func runLoop() { | |
for { | |
source, err := grabScript() | |
if err != nil { | |
log.Println("GRAB Error: ", err) | |
time.Sleep(time.Minute) | |
continue | |
} | |
// ioutil.WriteFile("source.js", []byte(source), 0755) | |
newVersion, err := findVersion(source) | |
if err != nil { | |
log.Println("Couldnt find version: ", err) | |
time.Sleep(time.Minute) | |
continue | |
} | |
currentVersion := getCurrentVersion() | |
if newVersion <= currentVersion { | |
log.Println("No new version") | |
time.Sleep(time.Minute) | |
continue | |
} | |
log.Printf("New version! %d -> %d", currentVersion, newVersion) | |
git, err := updateVersion(source, newVersion) | |
if err != nil { | |
log.Fatal("Failed updating: ", err) | |
} else { | |
notify(currentVersion, newVersion, git) | |
} | |
log.Println("Update finished") | |
time.Sleep(time.Minute) | |
} | |
} | |
func getCurrentVersion() int { | |
content, err := ioutil.ReadFile("current_appversion") | |
if err != nil { | |
log.Println("Failed reading current version file: ", err) | |
return 0 | |
} | |
v, err := strconv.ParseInt(strings.TrimSpace(string(content)), 10, 32) | |
if err != nil { | |
log.Println("Failed reading current version: ", err) | |
} | |
return int(v) | |
} | |
func saveVersion(version int) error { | |
return ioutil.WriteFile("current_appversion", []byte(fmt.Sprint(version)), 0755) | |
} | |
func grabScript() (string, error) { | |
doc, err := goquery.NewDocument("https://canary.discordapp.com/login") | |
if err != nil { | |
return "", err | |
} | |
result := "" | |
doc.Find("script").Each(func(i int, s *goquery.Selection) { | |
src, found := s.Attr("src") | |
if !found { | |
return | |
} | |
resp, err := http.Get("https://canary.discordapp.com" + src) | |
if err != nil { | |
return | |
} | |
defer resp.Body.Close() | |
buf := make([]byte, len(ScriptStartsWith)) | |
_, err = resp.Body.Read(buf) | |
if err != nil { | |
return | |
} | |
if string(buf) != ScriptStartsWith { | |
//log.Println(string(buf), "does not match", ScriptStartsWith) | |
return | |
} | |
if result != "" { | |
panic("Multiple matched scripts") | |
} | |
last, err := ioutil.ReadAll(resp.Body) | |
if err != nil { | |
log.Println("Failed reading body") | |
return | |
} | |
result = string(buf) + string(last) | |
}) | |
if result == "" { | |
return "", errors.New("Couldn't find script") | |
} | |
return result, nil | |
} | |
const ( | |
VersionMatch = ".appVersion=" | |
) | |
func findVersion(source string) (int, error) { | |
index := strings.Index(source, VersionMatch) | |
if index == -1 { | |
return 0, errors.New("Couldn't find version in source") | |
} | |
offset := index + len(VersionMatch) | |
view := source[offset+1 : offset+50] | |
buf := "" | |
for _, r := range view { | |
if !unicode.IsNumber(r) { | |
break | |
} | |
buf += string(r) | |
} | |
ver, err := strconv.ParseInt(buf, 10, 32) | |
if err != nil { | |
return 0, errors.New("Failed parsing version number " + buf) | |
} | |
return int(ver), nil | |
} | |
// Returns the git summary and an error | |
func updateVersion(source string, version int) (string, error) { | |
log.Println("Updating") | |
err := writeSource(source) | |
if err != nil { | |
return "", err | |
} | |
err = saveVersion(version) | |
if err != nil { | |
return "", err | |
} | |
output, err := commitVersion(version) | |
log.Println("Git: " + output) | |
if err != nil { | |
return "", err | |
} | |
return output, nil | |
} | |
func writeSource(source string) error { | |
cmd := exec.Command("js-beautify", "-i", "-o", "discord.js") | |
inPipe, err := cmd.StdinPipe() | |
if err != nil { | |
return err | |
} | |
err = cmd.Start() | |
if err != nil { | |
return err | |
} | |
io.WriteString(inPipe, source) | |
inPipe.Close() | |
out, err := cmd.Output() | |
if len(out) > 1 { | |
log.Println("JSB: ", string(out)) | |
} | |
return cmd.Wait() | |
} | |
func commitVersion(version int) (string, error) { | |
cmd := exec.Command("git", "commit", "-m", fmt.Sprintf("auto v%d", version), "discord.js", "current_appversion") | |
out, err := cmd.Output() | |
if err != nil { | |
return "", err | |
} | |
return string(out), nil | |
} | |
func notify(old, newV int, git string) { | |
msg := fmt.Sprintf("New discord version pulled (%d -> %d) %s\n```\n%s\n```", old, newV, DMention, git) | |
_, err := DG.ChannelMessageSend(DCHannel, msg) | |
if err != nil { | |
log.Println("Failed sending notification in discord: ", err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment