Mohammad Shahid commited on
Commit
5f51c88
·
1 Parent(s): 8773b00

added file que system

Browse files
cmd/fsb/run.go CHANGED
@@ -1,19 +1,25 @@
 
 
1
  package main
2
 
3
  import (
4
  "EverythingSuckz/fsb/config"
5
  "EverythingSuckz/fsb/internal/bot"
6
  "EverythingSuckz/fsb/internal/cache"
 
7
  "EverythingSuckz/fsb/internal/routes"
8
  "EverythingSuckz/fsb/internal/types"
9
  "EverythingSuckz/fsb/internal/utils"
10
  "fmt"
11
  "net/http"
 
12
  "time"
13
 
14
- "github.com/spf13/cobra"
15
-
16
  "github.com/gin-gonic/gin"
 
 
 
17
  "go.uber.org/zap"
18
  )
19
 
@@ -31,13 +37,25 @@ func runApp(cmd *cobra.Command, args []string) {
31
  log := utils.Logger
32
  mainLogger := log.Named("Main")
33
  mainLogger.Info("Starting server")
 
 
 
34
  config.Load(log, cmd)
35
  router := getRouter(log)
36
 
 
37
  mainBot, err := bot.StartClient(log)
38
  if err != nil {
39
  log.Panic("Failed to start main bot", zap.Error(err))
40
  }
 
 
 
 
 
 
 
 
41
  cache.InitCache(log)
42
  workers, err := bot.StartWorkers(log)
43
  if err != nil {
@@ -55,6 +73,66 @@ func runApp(cmd *cobra.Command, args []string) {
55
  }
56
  }
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  func getRouter(log *zap.Logger) *gin.Engine {
59
  if config.ValueOf.Dev {
60
  gin.SetMode(gin.DebugMode)
@@ -71,10 +149,9 @@ func getRouter(log *zap.Logger) *gin.Engine {
71
  Version: versionString,
72
  })
73
  })
74
-
75
  router.HEAD("/", func(ctx *gin.Context) {
76
- ctx.Status(http.StatusOK)
77
- })
78
  routes.Load(log, router)
79
  return router
80
- }
 
1
+ // In file: cmd/fsb/run.go
2
+
3
  package main
4
 
5
  import (
6
  "EverythingSuckz/fsb/config"
7
  "EverythingSuckz/fsb/internal/bot"
8
  "EverythingSuckz/fsb/internal/cache"
9
+ "EverythingSuckz/fsb/internal/commands"
10
  "EverythingSuckz/fsb/internal/routes"
11
  "EverythingSuckz/fsb/internal/types"
12
  "EverythingSuckz/fsb/internal/utils"
13
  "fmt"
14
  "net/http"
15
+ "strings"
16
  "time"
17
 
18
+ "github.com/celestix/gotgproto/ext"
 
19
  "github.com/gin-gonic/gin"
20
+ "github.com/gotd/td/telegram/message/styling"
21
+ "github.com/gotd/td/tg"
22
+ "github.com/spf13/cobra"
23
  "go.uber.org/zap"
24
  )
25
 
 
37
  log := utils.Logger
38
  mainLogger := log.Named("Main")
39
  mainLogger.Info("Starting server")
40
+
41
+ bot.MessageQueue = make(chan bot.QueueItem, 200)
42
+
43
  config.Load(log, cmd)
44
  router := getRouter(log)
45
 
46
+ // Start the client FIRST.
47
  mainBot, err := bot.StartClient(log)
48
  if err != nil {
49
  log.Panic("Failed to start main bot", zap.Error(err))
50
  }
51
+
52
+ // **** THIS IS THE FIX ****
53
+ // Now that the client and its dispatcher exist, load the commands into it.
54
+ commands.Load(log, mainBot.Dispatcher)
55
+ // **************************
56
+
57
+ go processMessageQueue(log)
58
+
59
  cache.InitCache(log)
60
  workers, err := bot.StartWorkers(log)
61
  if err != nil {
 
73
  }
74
  }
75
 
76
+ // This is the "methodical worker". It runs in the background.
77
+ func processMessageQueue(log *zap.Logger) {
78
+ log = log.Named("QueueWorker")
79
+ log.Info("Message processing worker started.")
80
+
81
+ // This loop will run forever, waiting for items to appear in the queue.
82
+ for item := range bot.MessageQueue {
83
+ ctx := item.Ctx
84
+ u := item.Update
85
+ log.Info("Processing message from queue", zap.Int("MessageID", u.EffectiveMessage.ID))
86
+
87
+ // --- ALL THE HEAVY LIFTING IS DONE HERE, SLOWLY ---
88
+ chatId := u.EffectiveChat().GetID()
89
+ update, err := utils.ForwardMessages(ctx, chatId, config.ValueOf.LogChannelID, u.EffectiveMessage.ID)
90
+ if err != nil {
91
+ log.Error("Failed to forward message", zap.Error(err))
92
+ ctx.Reply(u, fmt.Sprintf("Error forwarding message: %s", err.Error()), nil)
93
+ continue // Skip to the next item in the queue
94
+ }
95
+
96
+ messageID := update.Updates[0].(*tg.UpdateMessageID).ID
97
+ doc := update.Updates[1].(*tg.UpdateNewChannelMessage).Message.(*tg.Message).Media
98
+ file, err := utils.FileFromMedia(doc)
99
+ if err != nil {
100
+ log.Error("Failed to get file from media", zap.Error(err))
101
+ ctx.Reply(u, fmt.Sprintf("Error getting file data: %s", err.Error()), nil)
102
+ continue
103
+ }
104
+
105
+ fullHash := utils.PackFile(file.FileName, file.FileSize, file.MimeType, file.ID)
106
+ hash := utils.GetShortHash(fullHash)
107
+ link := fmt.Sprintf("%s/stream/%d?hash=%s", config.ValueOf.Host, messageID, hash)
108
+ text := []styling.StyledTextOption{styling.Code(link)}
109
+ row := tg.KeyboardButtonRow{
110
+ Buttons: []tg.KeyboardButtonClass{
111
+ &tg.KeyboardButtonURL{Text: "Download", URL: link + "&d=true"},
112
+ },
113
+ }
114
+
115
+ // *** FIXING YOUR TYPO: Mime_Type -> MimeType ***
116
+ if strings.Contains(file.MimeType, "video") || strings.Contains(file.MimeType, "audio") || strings.Contains(file.MimeType, "pdf") {
117
+ row.Buttons = append(row.Buttons, &tg.KeyboardButtonURL{Text: "Stream", URL: link})
118
+ }
119
+
120
+ markup := &tg.ReplyInlineMarkup{Rows: []tg.KeyboardButtonRow{row}}
121
+ replyOpts := &ext.ReplyOpts{Markup: markup, NoWebpage: false, ReplyToMessageId: u.EffectiveMessage.ID}
122
+ if strings.Contains(link, "http://localhost") {
123
+ replyOpts.Markup = nil // Don't send buttons for localhost links
124
+ }
125
+
126
+ if _, err = ctx.Reply(u, text, replyOpts); err != nil {
127
+ log.Error("Failed to send final link reply", zap.Error(err))
128
+ }
129
+ // --- END OF HEAVY LIFTING ---
130
+
131
+ // PAUSE between each message to avoid flood limits.
132
+ time.Sleep(500 * time.Millisecond)
133
+ }
134
+ }
135
+
136
  func getRouter(log *zap.Logger) *gin.Engine {
137
  if config.ValueOf.Dev {
138
  gin.SetMode(gin.DebugMode)
 
149
  Version: versionString,
150
  })
151
  })
 
152
  router.HEAD("/", func(ctx *gin.Context) {
153
+ ctx.Status(http.StatusOK)
154
+ })
155
  routes.Load(log, router)
156
  return router
157
+ }
internal/bot/client.go CHANGED
@@ -2,7 +2,6 @@ package bot
2
 
3
  import (
4
  "EverythingSuckz/fsb/config"
5
- "EverythingSuckz/fsb/internal/commands"
6
  "context"
7
  "time"
8
 
@@ -47,9 +46,8 @@ func StartClient(log *zap.Logger) (*gotgproto.Client, error) {
47
  if result.err != nil {
48
  return nil, result.err
49
  }
50
- commands.Load(log, result.client.Dispatcher)
51
  log.Info("Client started", zap.String("username", result.client.Self.Username))
52
  Bot = result.client
53
  return result.client, nil
54
  }
55
- }
 
2
 
3
  import (
4
  "EverythingSuckz/fsb/config"
 
5
  "context"
6
  "time"
7
 
 
46
  if result.err != nil {
47
  return nil, result.err
48
  }
 
49
  log.Info("Client started", zap.String("username", result.client.Self.Username))
50
  Bot = result.client
51
  return result.client, nil
52
  }
53
+ }
internal/bot/queue.go ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // In file: internal/bot/queue.go
2
+
3
+ package bot
4
+
5
+ import "github.com/celestix/gotgproto/ext"
6
+
7
+ // QueueItem holds the necessary context and update for a message to be processed.
8
+ // It is EXPORTED (starts with a capital letter) so other packages can use it.
9
+ type QueueItem struct {
10
+ Ctx *ext.Context
11
+ Update *ext.Update
12
+ }
13
+
14
+ // MessageQueue is the channel that will act as our queue.
15
+ // It is also EXPORTED so it can be accessed from other packages.
16
+ var MessageQueue chan QueueItem
internal/commands/stream.go CHANGED
@@ -1,10 +1,10 @@
 
 
1
  package commands
2
 
3
  import (
4
- "fmt"
5
- "strings"
6
-
7
  "EverythingSuckz/fsb/config"
 
8
  "EverythingSuckz/fsb/internal/utils"
9
 
10
  "github.com/celestix/gotgproto/dispatcher"
@@ -12,8 +12,8 @@ import (
12
  "github.com/celestix/gotgproto/ext"
13
  "github.com/celestix/gotgproto/storage"
14
  "github.com/celestix/gotgproto/types"
15
- "github.com/gotd/td/telegram/message/styling"
16
  "github.com/gotd/td/tg"
 
17
  )
18
 
19
  func (m *command) LoadStream(dispatcher dispatcher.Dispatcher) {
@@ -33,13 +33,12 @@ func supportedMediaFilter(m *types.Message) (bool, error) {
33
  return true, nil
34
  case *tg.MessageMediaPhoto:
35
  return true, nil
36
- case tg.MessageMediaClass:
37
- return false, dispatcher.EndGroups
38
  default:
39
- return false, nil
40
  }
41
  }
42
 
 
43
  func sendLink(ctx *ext.Context, u *ext.Update) error {
44
  chatId := u.EffectiveChat().GetID()
45
  peerChatId := ctx.PeerStorage.GetPeerById(chatId)
@@ -51,67 +50,16 @@ func sendLink(ctx *ext.Context, u *ext.Update) error {
51
  return dispatcher.EndGroups
52
  }
53
  supported, err := supportedMediaFilter(u.EffectiveMessage)
54
- if err != nil {
55
- return err
56
- }
57
- if !supported {
58
  ctx.Reply(u, "Sorry, this message type is unsupported.", nil)
59
  return dispatcher.EndGroups
60
  }
61
- update, err := utils.ForwardMessages(ctx, chatId, config.ValueOf.LogChannelID, u.EffectiveMessage.ID)
62
- if err != nil {
63
- utils.Logger.Sugar().Error(err)
64
- ctx.Reply(u, fmt.Sprintf("Error - %s", err.Error()), nil)
65
- return dispatcher.EndGroups
66
- }
67
- messageID := update.Updates[0].(*tg.UpdateMessageID).ID
68
- doc := update.Updates[1].(*tg.UpdateNewChannelMessage).Message.(*tg.Message).Media
69
- file, err := utils.FileFromMedia(doc)
70
- if err != nil {
71
- ctx.Reply(u, fmt.Sprintf("Error - %s", err.Error()), nil)
72
- return dispatcher.EndGroups
73
- }
74
- fullHash := utils.PackFile(
75
- file.FileName,
76
- file.FileSize,
77
- file.MimeType,
78
- file.ID,
79
- )
80
- hash := utils.GetShortHash(fullHash)
81
- link := fmt.Sprintf("%s/stream/%d?hash=%s", config.ValueOf.Host, messageID, hash)
82
- text := []styling.StyledTextOption{styling.Code(link)}
83
- row := tg.KeyboardButtonRow{
84
- Buttons: []tg.KeyboardButtonClass{
85
- &tg.KeyboardButtonURL{
86
- Text: "Download",
87
- URL: link + "&d=true",
88
- },
89
- },
90
- }
91
- if strings.Contains(file.MimeType, "video") || strings.Contains(file.MimeType, "audio") || strings.Contains(file.MimeType, "pdf") {
92
- row.Buttons = append(row.Buttons, &tg.KeyboardButtonURL{
93
- Text: "Stream",
94
- URL: link,
95
- })
96
- }
97
- markup := &tg.ReplyInlineMarkup{
98
- Rows: []tg.KeyboardButtonRow{row},
99
- }
100
- if strings.Contains(link, "http://localhost") {
101
- _, err = ctx.Reply(u, text, &ext.ReplyOpts{
102
- NoWebpage: false,
103
- ReplyToMessageId: u.EffectiveMessage.ID,
104
- })
105
- } else {
106
- _, err = ctx.Reply(u, text, &ext.ReplyOpts{
107
- Markup: markup,
108
- NoWebpage: false,
109
- ReplyToMessageId: u.EffectiveMessage.ID,
110
- })
111
- }
112
- if err != nil {
113
- utils.Logger.Sugar().Error(err)
114
- ctx.Reply(u, fmt.Sprintf("Error - %s", err.Error()), nil)
115
- }
116
  return dispatcher.EndGroups
117
- }
 
1
+ // In file: internal/commands/stream.go
2
+
3
  package commands
4
 
5
  import (
 
 
 
6
  "EverythingSuckz/fsb/config"
7
+ "EverythingSuckz/fsb/internal/bot" // <--- Import the bot package
8
  "EverythingSuckz/fsb/internal/utils"
9
 
10
  "github.com/celestix/gotgproto/dispatcher"
 
12
  "github.com/celestix/gotgproto/ext"
13
  "github.com/celestix/gotgproto/storage"
14
  "github.com/celestix/gotgproto/types"
 
15
  "github.com/gotd/td/tg"
16
+ "go.uber.org/zap"
17
  )
18
 
19
  func (m *command) LoadStream(dispatcher dispatcher.Dispatcher) {
 
33
  return true, nil
34
  case *tg.MessageMediaPhoto:
35
  return true, nil
 
 
36
  default:
37
+ return false, dispatcher.EndGroups
38
  }
39
  }
40
 
41
+ // This function is now the "fast receptionist". It does minimal work.
42
  func sendLink(ctx *ext.Context, u *ext.Update) error {
43
  chatId := u.EffectiveChat().GetID()
44
  peerChatId := ctx.PeerStorage.GetPeerById(chatId)
 
50
  return dispatcher.EndGroups
51
  }
52
  supported, err := supportedMediaFilter(u.EffectiveMessage)
53
+ if err != nil || !supported {
 
 
 
54
  ctx.Reply(u, "Sorry, this message type is unsupported.", nil)
55
  return dispatcher.EndGroups
56
  }
57
+
58
+ // Create an item with our data and send it to the queue.
59
+ // This is very fast and will not cause a flood error.
60
+ item := bot.QueueItem{Ctx: ctx, Update: u}
61
+ bot.MessageQueue <- item
62
+ utils.Logger.Info("Added message to processing queue", zap.Int("MessageID", u.EffectiveMessage.ID))
63
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  return dispatcher.EndGroups
65
+ }