package tgbot
import (
"encoding/json"
"errors"
"github.com/dustin/go-humanize"
tele "gopkg.in/telebot.v4"
"gopkg.in/telebot.v4/middleware"
"net/http"
"os"
"path/filepath"
"server/log"
"server/settings"
"server/torr"
"server/web"
"strconv"
"strings"
"time"
)
type Config struct {
WhiteIds []int64
}
var cfg *Config
func init() {
cfg = &Config{}
fn := filepath.Join(settings.Path, "tg.cfg")
buf, err := os.ReadFile(fn)
if err != nil {
return
}
err = json.Unmarshal(buf, &cfg)
if err != nil {
log.TLogln("Error read tg config:", err)
}
}
func Start(token string) {
pref := tele.Settings{
Token: token,
Poller: &tele.LongPoller{Timeout: 5 * time.Minute},
ParseMode: tele.ModeHTML,
Client: &http.Client{Timeout: 5 * time.Minute},
}
log.TLogln("Starting Telegram Bot")
b, err := tele.NewBot(pref)
if err != nil {
log.TLogln("Error start tg bot:", err)
return
}
if len(cfg.WhiteIds) > 0 {
b.Use(middleware.Whitelist(cfg.WhiteIds...))
}
//Commands
b.Handle("help", help)
b.Handle("Help", help)
b.Handle("/help", help)
b.Handle("/Help", help)
b.Handle("/start", help)
b.Handle("/list", list)
//Text
b.Handle(tele.OnText, func(c tele.Context) error {
txt := c.Text()
if strings.HasPrefix(strings.ToLower(txt), "magnet:") || isHash(txt) {
return addTorrent(c, txt)
} else {
return c.Send("Вставьте магнет/хэш торрента чтоб добавить его на сервер")
}
})
b.Handle(tele.OnCallback, func(c tele.Context) error {
args := c.Args()
if len(args) > 0 {
if args[0] == "\ffiles" {
msg, err := c.Bot().Send(c.Sender(), "Подключение к торренту...")
t := torr.GetTorrent(args[1])
if t == nil {
c.Edit(msg, "Torrent not connected: "+args[1])
return nil
}
if err == nil {
go func() {
for !t.WaitInfo() {
time.Sleep(time.Second)
t = torr.GetTorrent(args[1])
}
c.Bot().Delete(msg)
host := settings.PubIPv4
if host == "" {
ips := web.GetLocalIps()
if len(ips) == 0 {
host = "127.0.0.1"
} else {
host = ips[0]
}
}
t = torr.GetTorrent(args[1])
st := t.Status()
txt := "Файлы:\n"
for _, file := range st.FileStats {
ff := "" + filepath.Base(file.Path) + " " + humanize.Bytes(uint64(file.Length)) + " " +
"Download\n\n"
if len(txt+ff) > 4096 {
c.Send(txt)
txt = ""
}
txt += ff
}
if len(txt) > 0 {
c.Send(txt)
}
}()
}
return err
}
if args[0] == "\fdelete" {
return nil
}
}
return errors.New("Ошибка кнопка не распознана")
})
go b.Start()
}
func help(c tele.Context) error {
return c.Send("Бот для управления TorrServer\n\n" +
"Список комманд:\n" +
" /help - эта справка\n" +
" /list - показать список торрентов на сервере")
}
func list(c tele.Context) error {
list := torr.ListTorrent()
for _, t := range list {
btnFiles := tele.InlineButton{Text: "Файлы", Unique: "files", Data: t.Hash().String()}
btnDelete := tele.InlineButton{Text: "Удалить", Unique: "delete", Data: t.Hash().String()}
torrKbd := &tele.ReplyMarkup{InlineKeyboard: [][]tele.InlineButton{{btnFiles, btnDelete}}}
c.Send(t.Title+" "+humanize.Bytes(uint64(t.Size)), torrKbd)
}
return nil
}
func isHash(txt string) bool {
if len(txt) == 40 {
for _, c := range strings.ToLower(txt) {
switch c {
case 'a', 'b', 'c', 'd', 'e', 'f', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
default:
return false
}
}
return true
}
return false
}