123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 |
- package main
- import (
- "encoding/json"
- "fmt"
- "log"
- "net/http"
- "os"
- "path"
- "regexp"
- "strconv"
- "strings"
- "time"
- "github.com/bwmarrin/discordgo"
- "github.com/fatih/color"
- "github.com/hako/durafmt"
- "github.com/hashicorp/go-version"
- )
- //#region Instance
- func uptime() time.Duration {
- return time.Since(startTime) //.Truncate(time.Second)
- }
- func properExit() {
- // Not formatting string because I only want the exit message to be red.
- log.Println(lg("Main", "", color.HiRedString, "[EXIT IN 15 SECONDS] Uptime was %s...", durafmt.Parse(time.Since(startTime)).String()))
- log.Println(color.HiCyanString("--------------------------------------------------------------------------------"))
- time.Sleep(15 * time.Second)
- os.Exit(1)
- }
- //#endregion
- //#region Files
- var (
- pathBlacklist = []string{"/", "\\", "<", ">", ":", "\"", "|", "?", "*"}
- )
- func clearPath(p string) string {
- r := p
- for _, key := range pathBlacklist {
- r = strings.ReplaceAll(r, key, "")
- }
- return r
- }
- func filenameFromURL(inputURL string) string {
- base := path.Base(inputURL)
- parts := strings.Split(base, "?")
- return path.Clean(parts[0])
- }
- func filepathExtension(filepath string) string {
- if strings.Contains(filepath, "?") {
- filepath = strings.Split(filepath, "?")[0]
- }
- filepath = path.Ext(filepath)
- return filepath
- }
- //#endregion
- //#region Text Formatting & Querying
- func stringInSlice(a string, list []string) bool {
- for _, b := range list {
- if strings.EqualFold(a, b) {
- return true
- }
- }
- return false
- }
- func formatNumber(n int64) string {
- var numberSeparator byte = ','
- if config.EuropeanNumbers {
- numberSeparator = '.'
- }
- in := strconv.FormatInt(n, 10)
- out := make([]byte, len(in)+(len(in)-2+int(in[0]/'0'))/3)
- if in[0] == '-' {
- in, out[0] = in[1:], '-'
- }
- for i, j, k := len(in)-1, len(out)-1, 0; ; i, j = i-1, j-1 {
- out[j] = in[i]
- if i == 0 {
- return string(out)
- }
- if k++; k == 3 {
- j, k = j-1, 0
- out[j] = numberSeparator
- }
- }
- }
- func formatNumberShort(x int64) string {
- var numberSeparator string = ","
- if config.EuropeanNumbers {
- numberSeparator = "."
- }
- var decimalSeparator string = "."
- if config.EuropeanNumbers {
- decimalSeparator = ","
- }
- if x > 1000 {
- formattedNumber := formatNumber(x)
- splitSlice := strings.Split(formattedNumber, numberSeparator)
- suffixes := [4]string{"k", "m", "b", "t"}
- partCount := len(splitSlice) - 1
- var output string
- if splitSlice[1][:1] != "0" {
- output = fmt.Sprintf("%s%s%s%s", splitSlice[0], decimalSeparator, splitSlice[1][:1], suffixes[partCount-1])
- } else {
- output = fmt.Sprintf("%s%s", splitSlice[0], suffixes[partCount-1])
- }
- return output
- }
- return fmt.Sprint(x)
- }
- func pluralS(num int) string {
- if num == 1 {
- return ""
- }
- return "s"
- }
- func wrapHyphens(i string, l int) string {
- n := i
- if len(n) < l {
- n = "- " + n + " -"
- for len(n) < l {
- n = "-" + n + "-"
- }
- }
- return n
- }
- func wrapHyphensW(i string) string {
- return wrapHyphens(i, 80)
- }
- func stripSymbols(i string) string {
- re, err := regexp.Compile(`[^\w]`)
- if err != nil {
- log.Fatal(err)
- }
- return re.ReplaceAllString(i, " ")
- }
- func isNumeric(s string) bool {
- _, err := strconv.ParseFloat(s, 64)
- return err == nil
- }
- func isDate(s string) bool {
- _, err := time.Parse("2006-01-02", s)
- return err == nil
- }
- func shortenTime(input string) string {
- input = strings.ReplaceAll(input, " nanoseconds", "ns")
- input = strings.ReplaceAll(input, " nanosecond", "ns")
- input = strings.ReplaceAll(input, " microseconds", "μs")
- input = strings.ReplaceAll(input, " microsecond", "μs")
- input = strings.ReplaceAll(input, " milliseconds", "ms")
- input = strings.ReplaceAll(input, " millisecond", "ms")
- input = strings.ReplaceAll(input, " seconds", "s")
- input = strings.ReplaceAll(input, " second", "s")
- input = strings.ReplaceAll(input, " minutes", "m")
- input = strings.ReplaceAll(input, " minute", "m")
- input = strings.ReplaceAll(input, " hours", "h")
- input = strings.ReplaceAll(input, " hour", "h")
- input = strings.ReplaceAll(input, " days", "d")
- input = strings.ReplaceAll(input, " day", "d")
- input = strings.ReplaceAll(input, " weeks", "w")
- input = strings.ReplaceAll(input, " week", "w")
- input = strings.ReplaceAll(input, " months", "mo")
- input = strings.ReplaceAll(input, " month", "mo")
- return input
- }
- /*func condenseString(input string, length int) string {
- filler := "....."
- ret := input
- if len(input) > length+len(filler) {
- half := int((length / 2) - len(filler))
- ret = input[0:half] + filler + input[len(input)-half:]
- }
- return ret
- }*/
- //#endregion
- //#region Github Release Checking
- type githubReleaseApiObject struct {
- TagName string `json:"tag_name"`
- }
- var latestGithubRelease string
- func getLatestGithubRelease() string {
- githubReleaseApiObject := new(githubReleaseApiObject)
- err := getJSON("https://api.github.com/repos/"+projectRepoBase+"/releases/latest", githubReleaseApiObject)
- if err != nil {
- log.Println(lg("API", "Github", color.RedString, "Error fetching current Release JSON: %s", err))
- return ""
- }
- return githubReleaseApiObject.TagName
- }
- func isLatestGithubRelease() bool {
- latestGithubRelease = getLatestGithubRelease()
- if latestGithubRelease == "" {
- return true
- }
- thisVersion, err := version.NewVersion(projectVersion)
- if err != nil {
- log.Println(lg("API", "Github", color.RedString, "Error parsing current version: %s", err))
- return true
- }
- latestVersion, err := version.NewVersion(latestGithubRelease)
- if err != nil {
- log.Println(lg("API", "Github", color.RedString, "Error parsing latest version: %s", err))
- return true
- }
- if latestVersion.GreaterThan(thisVersion) {
- return false
- }
- return true
- }
- //#endregion
- //#region Requests
- func getJSON(url string, target interface{}) error {
- r, err := http.Get(url)
- if err != nil {
- return err
- }
- defer r.Body.Close()
- return json.NewDecoder(r.Body).Decode(target)
- }
- func getJSONwithHeaders(url string, target interface{}, headers map[string]string) error {
- client := &http.Client{}
- req, _ := http.NewRequest("GET", url, nil)
- for k, v := range headers {
- req.Header.Set(k, v)
- }
- r, err := client.Do(req)
- if err != nil {
- return err
- }
- defer r.Body.Close()
- return json.NewDecoder(r.Body).Decode(target)
- }
- //#endregion
- //#region Log
- /*const (
- logLevelOff = -1
- logLevelEssential = iota
- logLevelFatal
- logLevelError
- logLevelWarning
- logLevelInfo
- logLevelDebug
- logLevelVerbose
- logLevelAll
- )*/
- func lg(group string, subgroup string, colorFunc func(string, ...interface{}) string, line string, p ...interface{}) string {
- colorPrefix := group
- switch strings.ToLower(group) {
- case "main":
- if subgroup == "" {
- colorPrefix = ""
- } else {
- colorPrefix = ""
- }
- case "debug":
- if subgroup == "" {
- colorPrefix = color.HiYellowString("[DEBUG]")
- } else {
- colorPrefix = color.HiYellowString("[DEBUG | %s]", subgroup)
- }
- case "test":
- if subgroup == "" {
- colorPrefix = color.HiYellowString("[TEST]")
- } else {
- colorPrefix = color.HiYellowString("[TEST | %s]", subgroup)
- }
- case "info":
- if subgroup == "" {
- colorPrefix = color.CyanString("[Info]")
- } else {
- colorPrefix = color.CyanString("[Info | %s]", subgroup)
- }
- case "version":
- colorPrefix = color.HiMagentaString("[Version]")
- case "settings":
- colorPrefix = color.GreenString("[Settings]")
- case "database":
- colorPrefix = color.HiYellowString("[Database]")
- case "setup":
- colorPrefix = color.HiGreenString("[Setup]")
- case "checkup":
- colorPrefix = color.HiGreenString("[Checkup]")
- case "discord":
- if subgroup == "" {
- colorPrefix = color.HiBlueString("[Discord]")
- } else {
- colorPrefix = color.HiBlueString("[Discord | %s]", subgroup)
- }
- case "history":
- if subgroup == "" {
- colorPrefix = color.HiCyanString("[History]")
- } else {
- colorPrefix = color.HiCyanString("[History | %s]", subgroup)
- }
- case "command":
- if subgroup == "" {
- colorPrefix = color.HiGreenString("[Commands]")
- } else {
- colorPrefix = color.HiGreenString("[Command : %s]", subgroup)
- }
- case "download":
- if subgroup == "" {
- colorPrefix = color.GreenString("[Downloads]")
- } else {
- colorPrefix = color.GreenString("[Downloads | %s]", subgroup)
- }
- case "message":
- if subgroup == "" {
- colorPrefix = color.CyanString("[Messages]")
- } else {
- colorPrefix = color.CyanString("[Messages | %s]", subgroup)
- }
- case "regex":
- if subgroup == "" {
- colorPrefix = color.YellowString("[Regex]")
- } else {
- colorPrefix = color.YellowString("[Regex | %s]", subgroup)
- }
- case "api":
- if subgroup == "" {
- colorPrefix = color.HiMagentaString("[APIs]")
- } else {
- colorPrefix = color.HiMagentaString("[API | %s]", subgroup)
- }
- }
- if bot != nil && botReady {
- simplePrefix := group
- if subgroup != "" {
- simplePrefix += ":" + subgroup
- }
- for _, adminChannel := range config.AdminChannels {
- if *adminChannel.LogProgram {
- outputToChannel := func(channel string) {
- if channel != "" {
- if hasPerms(channel, discordgo.PermissionSendMessages) {
- if _, err := bot.ChannelMessageSend(channel,
- fmt.Sprintf("```%s | [%s] %s```",
- time.Now().Format(time.RFC3339), simplePrefix, fmt.Sprintf(line, p...)),
- ); err != nil {
- log.Println(color.HiRedString("Failed to send message...\t%s", err))
- }
- }
- }
- }
- outputToChannel(adminChannel.ChannelID)
- if adminChannel.ChannelIDs != nil {
- for _, ch := range *adminChannel.ChannelIDs {
- outputToChannel(ch)
- }
- }
- }
- }
- }
- pp := "> " // prefix prefix :)
- if strings.ToLower(group) == "debug" || strings.ToLower(subgroup) == "debug" {
- pp = color.YellowString("? ")
- }
- if colorPrefix != "" {
- colorPrefix += " "
- }
- return "\t" + pp + colorPrefix + colorFunc(line, p...)
- }
- //#endregion
|