Browse Source

historyMaxJobs, RUNS IN ORDER!!, list works way better

Drn 2 years ago
parent
commit
a3df40f70d
6 changed files with 185 additions and 59 deletions
  1. 68 26
      commands.go
  2. 2 0
      config.go
  3. 36 0
      discord.go
  4. 23 19
      history.go
  5. 53 14
      main.go
  6. 3 0
      vars.go

+ 68 - 26
commands.go

@@ -23,6 +23,20 @@ const (
 	cmderrSendFailure          = "Failed to send command message (requested by %s)...\t%s"
 )
 
+func safeReply(ctx *exrouter.Context, content string) bool {
+	if hasPerms(ctx.Msg.ChannelID, discordgo.PermissionSendMessages) {
+		if _, err := ctx.Reply(content); err != nil {
+			log.Println(lg("Command", "", color.HiRedString, cmderrSendFailure, getUserIdentifier(*ctx.Msg.Author), err))
+			return false
+		} else {
+			return true
+		}
+	} else {
+		log.Println(lg("Command", "", color.HiRedString, fmtBotSendPerm, ctx.Msg.ChannelID))
+		return false
+	}
+}
+
 // TODO: function for handling perm error messages, etc etc to reduce clutter
 func handleCommands() *exrouter.Route {
 	router := exrouter.New()
@@ -209,21 +223,21 @@ func handleCommands() *exrouter.Route {
 				if argKey == 0 { // skip head
 					continue
 				}
+				//SUBCOMMAND: cancel
 				if strings.Contains(strings.ToLower(argValue), "cancel") ||
 					strings.Contains(strings.ToLower(argValue), "stop") {
 					shouldAbort = true
 				} else if strings.Contains(strings.ToLower(argValue), "dbwipe") ||
-					strings.Contains(strings.ToLower(argValue), "wipedb") {
+					strings.Contains(strings.ToLower(argValue), "wipedb") { //SUBCOMMAND: dbwipe
 					shouldProcess = false
 					shouldWipeDB = true
 				} else if strings.Contains(strings.ToLower(argValue), "cachewipe") ||
-					strings.Contains(strings.ToLower(argValue), "wipecache") {
+					strings.Contains(strings.ToLower(argValue), "wipecache") { //SUBCOMMAND: cachewipe
 					shouldProcess = false
 					shouldWipeCache = true
 				} else if strings.Contains(strings.ToLower(argValue), "help") ||
-					strings.Contains(strings.ToLower(argValue), "info") {
+					strings.Contains(strings.ToLower(argValue), "info") { //SUBCOMMAND: help
 					shouldProcess = false
-
 					if hasPerms(ctx.Msg.ChannelID, discordgo.PermissionSendMessages) {
 						//content := fmt.Sprintf("")
 						_, err := replyEmbed(ctx.Msg, "Command — History Help", "TODO: this")
@@ -237,35 +251,63 @@ func handleCommands() *exrouter.Route {
 					log.Println(lg("Command", "History", color.CyanString, "%s requested history help.", getUserIdentifier(*ctx.Msg.Author)))
 				} else if strings.Contains(strings.ToLower(argValue), "list") ||
 					strings.Contains(strings.ToLower(argValue), "status") ||
-					strings.Contains(strings.ToLower(argValue), "output") {
+					strings.Contains(strings.ToLower(argValue), "output") { //SUBCOMMAND: list
 					shouldProcess = false
-
-					output := "Running history jobs...\n"
 					//MARKER: history jobs list
 
+					// 1st
+					output := fmt.Sprintf("**CURRENT HISTORY JOBS** ~ `%d total, %d running",
+						historyJobCnt, historyJobCntRunning)
+					outputC := fmt.Sprintf("CURRENT HISTORY JOBS ~ %d total, %d running",
+						historyJobCnt, historyJobCntRunning)
+					if historyJobCntCompleted > 0 {
+						t := fmt.Sprintf(", %d completed", historyJobCntCompleted)
+						output += t
+						outputC += t
+					}
+					if historyJobCntAborted > 0 {
+						t := fmt.Sprintf(", %d cancelled", historyJobCntAborted)
+						output += t
+						outputC += t
+					}
+					if historyJobCntErrored > 0 {
+						t := fmt.Sprintf(", %d failed", historyJobCntErrored)
+						output += t
+						outputC += t
+					}
+					safeReply(ctx, output+"`")
+					log.Println(lg("Command", "History", color.HiCyanString, outputC))
+
+					// Following
+					output = ""
 					for pair := historyJobs.Oldest(); pair != nil; pair = pair.Next() {
 						channelID := pair.Key
 						job := pair.Value
-						channelLabel := channelID
-						channelInfo, err := bot.State.Channel(channelID)
-						if err == nil {
-							channelLabel = "#" + channelInfo.Name
+						jobSourceName, jobChannelName := channelDisplay(channelID)
+
+						newline := fmt.Sprintf("• _%s_ (%s) `%s - %s`, `updated %s ago, added %s ago`\n",
+							historyStatusLabel(job.Status), job.OriginUser, jobSourceName, jobChannelName,
+							shortenTime(durafmt.ParseShort(time.Since(job.Updated)).String()),
+							shortenTime(durafmt.ParseShort(time.Since(job.Added)).String()))
+					redothismath: // bad way but dont care right now
+						if len(output)+len(newline) > limitMsg {
+							// send batch
+							safeReply(ctx, output)
+							output = ""
+							goto redothismath
 						}
-						output += fmt.Sprintf("• _%s_ - (%s)`%s`, `updated %s ago, added %s ago`\n",
-							historyStatusLabel(job.Status), job.OriginUser, channelLabel,
-							shortenTime(durafmt.ParseShort(time.Since(job.Updated)).String()), shortenTime(durafmt.ParseShort(time.Since(job.Added)).String()))
-						log.Println(lg("Command", "History", color.HiCyanString, "History Job: %s - (%s)%s, updated %s ago, added %s ago",
-							historyStatusLabel(job.Status), job.OriginUser, channelLabel,
-							shortenTime(durafmt.ParseShort(time.Since(job.Updated)).String()), shortenTime(durafmt.ParseShort(time.Since(job.Added)).String())))
+						output += newline
+						log.Println(lg("Command", "History", color.HiCyanString,
+							fmt.Sprintf("%s (%s) %s - %s, updated %s ago, added %s ago",
+								historyStatusLabel(job.Status), job.OriginUser, jobSourceName, jobChannelName,
+								shortenTime(durafmt.ParseShort(time.Since(job.Updated)).String()),
+								shortenTime(durafmt.ParseShort(time.Since(job.Added)).String())))) // no batching
 					}
-					if hasPerms(ctx.Msg.ChannelID, discordgo.PermissionSendMessages) {
-						_, err := ctx.Reply(output)
-						if err != nil {
-							log.Println(lg("Command", "History", color.HiRedString, cmderrSendFailure, getUserIdentifier(*ctx.Msg.Author), err))
-						}
-					} else {
-						log.Println(lg("Command", "History", color.HiRedString, fmtBotSendPerm, ctx.Msg.ChannelID))
+					// finish off
+					if output != "" {
+						safeReply(ctx, output)
 					}
+					// done
 					log.Println(lg("Command", "History", color.HiRedString, "%s requested statuses of history jobs.",
 						getUserIdentifier(*ctx.Msg.Author)))
 				} else if strings.Contains(strings.ToLower(argValue), "--before=") { // before key
@@ -367,7 +409,7 @@ func handleCommands() *exrouter.Route {
 					if shouldProcess { // PROCESS TREE; MARKER: history queue via cmd
 						if shouldAbort { // ABORT
 							if job, exists := historyJobs.Get(channel); exists &&
-								(job.Status == historyStatusDownloading || job.Status == historyStatusWaiting) {
+								(job.Status == historyStatusRunning || job.Status == historyStatusWaiting) {
 								// DOWNLOADING, ABORTING
 								job.Status = historyStatusAbortRequested
 								if job.Status == historyStatusWaiting {
@@ -384,7 +426,7 @@ func handleCommands() *exrouter.Route {
 							}
 						} else { // RUN
 							if job, exists := historyJobs.Get(channel); !exists ||
-								(job.Status != historyStatusDownloading && job.Status != historyStatusAbortRequested) {
+								(job.Status != historyStatusRunning && job.Status != historyStatusAbortRequested) {
 								job.Status = historyStatusWaiting
 								job.OriginChannel = ctx.Msg.ChannelID
 								job.OriginUser = getUserIdentifier(*ctx.Msg.Author)

+ 2 - 0
config.go

@@ -120,6 +120,7 @@ func defaultConfiguration() configuration {
 		HistoryTyping:              true,
 
 		// History
+		HistoryMaxJobs:        3,
 		AutoHistory:           false,
 		AutoHistoryBefore:     "",
 		AutoHistorySince:      "",
@@ -221,6 +222,7 @@ type configuration struct {
 	EmbedColor                 *string            `json:"embedColor,omitempty"`                 // optional, defaults to role if undefined, then defaults random if no role color
 
 	// History
+	HistoryMaxJobs        int    `json:"historyMaxJobs"`                  // optional, defaults
 	AutoHistory           bool   `json:"autoHistory,omitempty"`           // optional, defaults
 	AutoHistoryBefore     string `json:"autoHistoryBefore,omitempty"`     // optional
 	AutoHistorySince      string `json:"autoHistorySince,omitempty"`      // optional

+ 36 - 0
discord.go

@@ -172,6 +172,42 @@ func fixMessage(m *discordgo.Message) *discordgo.Message {
 
 //#endregion
 
+func channelDisplay(channelID string) (string, string) {
+	sourceChannelName := channelID
+	sourceName := "UNKNOWN"
+	sourceChannel, _ := bot.State.Channel(channelID)
+	if sourceChannel != nil {
+		// Channel Naming
+		if sourceChannel.Name != "" {
+			sourceChannelName = "#" + sourceChannel.Name
+		}
+		switch sourceChannel.Type {
+		case discordgo.ChannelTypeGuildText:
+			// Server Naming
+			if sourceChannel.GuildID != "" {
+				sourceGuild, _ := bot.State.Guild(sourceChannel.GuildID)
+				if sourceGuild != nil && sourceGuild.Name != "" {
+					sourceName = sourceGuild.Name
+				}
+			}
+			// Category Naming
+			if sourceChannel.ParentID != "" {
+				sourceParent, _ := bot.State.Channel(sourceChannel.ParentID)
+				if sourceParent != nil {
+					if sourceParent.Name != "" {
+						sourceChannelName = sourceParent.Name + " / " + sourceChannelName
+					}
+				}
+			}
+		case discordgo.ChannelTypeDM:
+			sourceName = "Direct Messages"
+		case discordgo.ChannelTypeGroupDM:
+			sourceName = "Group Messages"
+		}
+	}
+	return sourceName, sourceChannelName
+}
+
 //#region Presence
 
 func dataKeyReplacement(input string) string {

+ 23 - 19
history.go

@@ -18,7 +18,7 @@ type historyStatus int
 
 const (
 	historyStatusWaiting historyStatus = iota
-	historyStatusDownloading
+	historyStatusRunning
 	historyStatusAbortRequested
 	historyStatusAbortCompleted
 	historyStatusErrorReadMessageHistoryPerms
@@ -32,7 +32,7 @@ func historyStatusLabel(status historyStatus) string {
 	switch status {
 	case historyStatusWaiting:
 		return "Waiting..."
-	case historyStatusDownloading:
+	case historyStatusRunning:
 		return "Currently Downloading..."
 	case historyStatusAbortRequested:
 		return "Abort Requested..."
@@ -68,20 +68,32 @@ type historyJob struct {
 }
 
 var (
-	historyJobs       *orderedmap.OrderedMap[string, historyJob]
-	historyProcessing bool
+	historyJobs            *orderedmap.OrderedMap[string, historyJob]
+	historyJobCnt          int
+	historyJobCntWaiting   int
+	historyJobCntRunning   int
+	historyJobCntAborted   int
+	historyJobCntErrored   int
+	historyJobCntCompleted int
 )
 
 func handleHistory(commandingMessage *discordgo.Message, subjectChannelID string, before string, since string) int {
-	historyProcessing = true
-	defer func() { historyProcessing = false }()
+	var err error
+
+	var commander string = "AUTORUN"
+	var autorun bool = true
+	if commandingMessage != nil { // Only time commandingMessage is nil is Autorun
+		commander = getUserIdentifier(*commandingMessage.Author)
+		autorun = false
+	}
+	logPrefix := fmt.Sprintf("%s/%s: ", subjectChannelID, commander)
+
+	// skip?
 	if job, exists := historyJobs.Get(subjectChannelID); exists && job.Status != historyStatusWaiting {
-		log.Println(lg("History", "", color.RedString, "History job skipped, Status: %s", historyStatusLabel(job.Status)))
+		log.Println(lg("History", "", color.RedString, logPrefix+"History job skipped, Status: %s", historyStatusLabel(job.Status)))
 		return -1
 	}
 
-	var err error
-
 	var totalMessages int64 = 0
 	var totalDownloads int64 = 0
 	var totalFilesize int64 = 0
@@ -92,14 +104,6 @@ func handleHistory(commandingMessage *discordgo.Message, subjectChannelID string
 	responseMsg.ChannelID = subjectChannelID
 	responseMsg.GuildID = ""
 
-	var commander string = "AUTORUN"
-	var autorun bool = true
-	if commandingMessage != nil { // Only time commandingMessage is nil is Autorun
-		commander = getUserIdentifier(*commandingMessage.Author)
-		autorun = false
-	}
-	logPrefix := fmt.Sprintf("%s/%s: ", subjectChannelID, commander)
-
 	// Send Status?
 	var sendStatus bool = true
 	if (autorun && !config.SendAutoHistoryStatus) || (!autorun && !config.SendHistoryStatus) {
@@ -114,7 +118,7 @@ func handleHistory(commandingMessage *discordgo.Message, subjectChannelID string
 	// Check Read History perms
 	if !channelinfo.IsThread() && !hasPerms(subjectChannelID, discordgo.PermissionReadMessageHistory) {
 		if job, exists := historyJobs.Get(subjectChannelID); exists {
-			job.Status = historyStatusDownloading
+			job.Status = historyStatusRunning
 			job.Updated = time.Now()
 			historyJobs.Set(subjectChannelID, job)
 		}
@@ -128,7 +132,7 @@ func handleHistory(commandingMessage *discordgo.Message, subjectChannelID string
 
 	// Update Job Status to Downloading
 	if job, exists := historyJobs.Get(subjectChannelID); exists {
-		job.Status = historyStatusDownloading
+		job.Status = historyStatusRunning
 		job.Updated = time.Now()
 		historyJobs.Set(subjectChannelID, job)
 	}

+ 53 - 14
main.go

@@ -270,7 +270,7 @@ func main() {
 	for _, ah := range autoHistoryChannels {
 		//MARKER: history jobs queued from auto
 		if job, exists := historyJobs.Get(ah.channel); !exists ||
-			(job.Status != historyStatusDownloading && job.Status != historyStatusAbortRequested) {
+			(job.Status != historyStatusRunning && job.Status != historyStatusAbortRequested) {
 			job.Status = historyStatusWaiting
 			job.OriginChannel = "AUTORUN"
 			job.OriginUser = "AUTORUN"
@@ -296,30 +296,69 @@ func main() {
 	//#region BG Tasks - History Job Processing
 	go func() {
 		for {
+			// Empty Local Cache
+			nhistoryJobCnt,
+				nhistoryJobCntWaiting,
+				nhistoryJobCntRunning,
+				nhistoryJobCntAborted,
+				nhistoryJobCntErrored,
+				nhistoryJobCntCompleted := historyJobs.Len(), 0, 0, 0, 0, 0
+
 			//MARKER: history jobs launch
-			if !historyProcessing && historyJobs.Len() > 0 {
-				anyRunning := false
+			// do we even bother?
+			if nhistoryJobCnt > 0 {
+				// New Cache
 				for pair := historyJobs.Oldest(); pair != nil; pair = pair.Next() {
-					if pair.Value.Status == historyStatusDownloading {
-						anyRunning = true
-						break
+					job := pair.Value
+					if job.Status == historyStatusWaiting {
+						nhistoryJobCntWaiting++
+					} else if job.Status == historyStatusRunning {
+						nhistoryJobCntRunning++
+					} else if job.Status == historyStatusAbortRequested || job.Status == historyStatusAbortCompleted {
+						nhistoryJobCntAborted++
+					} else if job.Status == historyStatusErrorReadMessageHistoryPerms || job.Status == historyStatusErrorRequesting {
+						nhistoryJobCntErrored++
+					} else if job.Status >= historyStatusCompletedNoMoreMessages {
+						nhistoryJobCntCompleted++
 					}
 				}
-				if !anyRunning {
-					var job historyJob
+
+				// Should Start New Job(s)?
+				if nhistoryJobCntRunning < config.HistoryMaxJobs {
+					openSlots := config.HistoryMaxJobs - nhistoryJobCntRunning
+					newJobs := make([]historyJob, openSlots)
+					filledSlots := 0
+					// Find Jobs
 					for pair := historyJobs.Oldest(); pair != nil; pair = pair.Next() {
-						if pair.Value.Status == historyStatusWaiting {
-							job = pair.Value
+						if filledSlots == openSlots {
 							break
 						}
+						if pair.Value.Status == historyStatusWaiting {
+							newJobs = append(newJobs, pair.Value)
+							filledSlots++
+						}
 					}
-					if job != (historyJob{}) {
-						// because of modifying the job while iterating historyJobs above
-						go handleHistory(job.TargetCommandingMessage, job.TargetChannelID, job.TargetBefore, job.TargetSince)
+					// Start Jobs
+					if len(newJobs) > 0 {
+						for _, job := range newJobs {
+							if job != (historyJob{}) {
+								go handleHistory(job.TargetCommandingMessage, job.TargetChannelID, job.TargetBefore, job.TargetSince)
+							}
+						}
 					}
 				}
 			}
-			time.Sleep(8 * time.Second)
+
+			// Update Cache
+			historyJobCnt = nhistoryJobCnt
+			historyJobCntWaiting = nhistoryJobCntWaiting
+			historyJobCntRunning = nhistoryJobCntRunning
+			historyJobCntAborted = nhistoryJobCntAborted
+			historyJobCntErrored = nhistoryJobCntErrored
+			historyJobCntCompleted = nhistoryJobCntCompleted
+
+			//~ optional setting?
+			time.Sleep(5 * time.Second)
 		}
 	}()
 	//#endregion

+ 3 - 0
vars.go

@@ -23,6 +23,9 @@ const (
 	constantsPath      = cachePath + string(os.PathSeparator) + "constants.json"
 
 	defaultReact = "✅"
+
+	limitMsg       = 2000
+	limitEmbedDesc = 4096
 )
 
 var (