markdown support
for active, info, head, tail, stats
This commit is contained in:
parent
2fd5c8a1ce
commit
09cb682f86
@ -38,6 +38,14 @@ var (
|
||||
interval time.Duration = 2
|
||||
// duration controls how many intervals will happen
|
||||
duration = 10
|
||||
|
||||
// since telegram's markdown can't be escaped, we have to replace some chars
|
||||
// affects only markdown users: info, active, head, tail
|
||||
mdReplacer = strings.NewReplacer("*", "•",
|
||||
"[", "(",
|
||||
"]", ")",
|
||||
"_", "-",
|
||||
"`", "'")
|
||||
)
|
||||
|
||||
// init flags
|
||||
@ -225,7 +233,7 @@ func main() {
|
||||
|
||||
default:
|
||||
// no such command, try help
|
||||
go send("no such command, try /help", update.Message.Chat.ID)
|
||||
go send("no such command, try /help", update.Message.Chat.ID, false)
|
||||
|
||||
}
|
||||
}
|
||||
@ -235,7 +243,7 @@ func main() {
|
||||
func list(ud tgbotapi.Update, tokens []string) {
|
||||
torrents, err := Client.GetTorrents()
|
||||
if err != nil {
|
||||
send("list: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("list: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -245,7 +253,7 @@ func list(ud tgbotapi.Update, tokens []string) {
|
||||
// (?i) for case insensitivity
|
||||
regx, err := regexp.Compile("(?i)" + tokens[0])
|
||||
if err != nil {
|
||||
send("list: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("list: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -261,11 +269,11 @@ func list(ud tgbotapi.Update, tokens []string) {
|
||||
}
|
||||
|
||||
if buf.Len() == 0 {
|
||||
send("list: No torrents", ud.Message.Chat.ID)
|
||||
send("list: No torrents", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
send(buf.String(), ud.Message.Chat.ID)
|
||||
send(buf.String(), ud.Message.Chat.ID, false)
|
||||
}
|
||||
|
||||
// head will list the first 5 or n torrents
|
||||
@ -278,14 +286,14 @@ func head(ud tgbotapi.Update, tokens []string) {
|
||||
if len(tokens) > 0 {
|
||||
n, err = strconv.Atoi(tokens[0])
|
||||
if err != nil {
|
||||
send("head: argument must be a number", ud.Message.Chat.ID)
|
||||
send("head: argument must be a number", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
torrents, err := Client.GetTorrents()
|
||||
if err != nil {
|
||||
send("head: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("head: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -296,14 +304,18 @@ func head(ud tgbotapi.Update, tokens []string) {
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
for i := range torrents[:n] {
|
||||
buf.WriteString(fmt.Sprintf("<%d> %s\n", torrents[i].ID, torrents[i].Name))
|
||||
torrentName := mdReplacer.Replace(torrents[i].Name) // escape markdown
|
||||
buf.WriteString(fmt.Sprintf("<*%d*> *%s*\n%s `%s` of `%s` (`%.1f%%`) ↓ `%s` ↑ `%s` R: `%s`\n\n",
|
||||
torrents[i].ID, torrentName, torrents[i].TorrentStatus(), humanize.Bytes(torrents[i].Have()),
|
||||
humanize.Bytes(torrents[i].SizeWhenDone), torrents[i].PercentDone*100, humanize.Bytes(torrents[i].RateDownload),
|
||||
humanize.Bytes(torrents[i].RateUpload), torrents[i].Ratio()))
|
||||
}
|
||||
|
||||
if buf.Len() == 0 {
|
||||
send("head: No torrents", ud.Message.Chat.ID)
|
||||
send("head: No torrents", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send(buf.String(), ud.Message.Chat.ID)
|
||||
send(buf.String(), ud.Message.Chat.ID, true)
|
||||
|
||||
}
|
||||
|
||||
@ -317,14 +329,14 @@ func tail(ud tgbotapi.Update, tokens []string) {
|
||||
if len(tokens) > 0 {
|
||||
n, err = strconv.Atoi(tokens[0])
|
||||
if err != nil {
|
||||
send("tail: argument must be a number", ud.Message.Chat.ID)
|
||||
send("tail: argument must be a number", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
torrents, err := Client.GetTorrents()
|
||||
if err != nil {
|
||||
send("tail: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("tail: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -335,21 +347,25 @@ func tail(ud tgbotapi.Update, tokens []string) {
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
for _, torrent := range torrents[len(torrents)-n:] {
|
||||
buf.WriteString(fmt.Sprintf("<%d> %s\n", torrent.ID, torrent.Name))
|
||||
torrentName := mdReplacer.Replace(torrent.Name) // escape markdown
|
||||
buf.WriteString(fmt.Sprintf("<*%d*> *%s*\n%s `%s` of `%s` (`%.1f%%`) ↓ `%s` ↑ `%s` R: `%s`\n\n",
|
||||
torrent.ID, torrentName, torrent.TorrentStatus(), humanize.Bytes(torrent.Have()),
|
||||
humanize.Bytes(torrent.SizeWhenDone), torrent.PercentDone*100, humanize.Bytes(torrent.RateDownload),
|
||||
humanize.Bytes(torrent.RateUpload), torrent.Ratio()))
|
||||
}
|
||||
|
||||
if buf.Len() == 0 {
|
||||
send("tail: No torrents", ud.Message.Chat.ID)
|
||||
send("tail: No torrents", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send(buf.String(), ud.Message.Chat.ID)
|
||||
send(buf.String(), ud.Message.Chat.ID, true)
|
||||
}
|
||||
|
||||
// downs will send the names of torrents with status 'Downloading' or in queue to
|
||||
func downs(ud tgbotapi.Update) {
|
||||
torrents, err := Client.GetTorrents()
|
||||
if err != nil {
|
||||
send("downs: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("downs: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -363,17 +379,17 @@ func downs(ud tgbotapi.Update) {
|
||||
}
|
||||
|
||||
if buf.Len() == 0 {
|
||||
send("No downloads", ud.Message.Chat.ID)
|
||||
send("No downloads", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send(buf.String(), ud.Message.Chat.ID)
|
||||
send(buf.String(), ud.Message.Chat.ID, false)
|
||||
}
|
||||
|
||||
// seeding will send the names of the torrents with the status 'Seeding' or in the queue to
|
||||
func seeding(ud tgbotapi.Update) {
|
||||
torrents, err := Client.GetTorrents()
|
||||
if err != nil {
|
||||
send("seeding: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("seeding: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -386,11 +402,11 @@ func seeding(ud tgbotapi.Update) {
|
||||
}
|
||||
|
||||
if buf.Len() == 0 {
|
||||
send("No torrents seeding", ud.Message.Chat.ID)
|
||||
send("No torrents seeding", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
send(buf.String(), ud.Message.Chat.ID)
|
||||
send(buf.String(), ud.Message.Chat.ID, false)
|
||||
|
||||
}
|
||||
|
||||
@ -398,7 +414,7 @@ func seeding(ud tgbotapi.Update) {
|
||||
func paused(ud tgbotapi.Update) {
|
||||
torrents, err := Client.GetTorrents()
|
||||
if err != nil {
|
||||
send("paused: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("paused: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -413,18 +429,18 @@ func paused(ud tgbotapi.Update) {
|
||||
}
|
||||
|
||||
if buf.Len() == 0 {
|
||||
send("No paused torrents", ud.Message.Chat.ID)
|
||||
send("No paused torrents", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
send(buf.String(), ud.Message.Chat.ID)
|
||||
send(buf.String(), ud.Message.Chat.ID, false)
|
||||
}
|
||||
|
||||
// checking will send the names of torrents with the status 'verifying' or in the queue to
|
||||
func checking(ud tgbotapi.Update) {
|
||||
torrents, err := Client.GetTorrents()
|
||||
if err != nil {
|
||||
send("checking: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("checking: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -440,18 +456,18 @@ func checking(ud tgbotapi.Update) {
|
||||
}
|
||||
|
||||
if buf.Len() == 0 {
|
||||
send("No torrents verifying", ud.Message.Chat.ID)
|
||||
send("No torrents verifying", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
send(buf.String(), ud.Message.Chat.ID)
|
||||
send(buf.String(), ud.Message.Chat.ID, false)
|
||||
}
|
||||
|
||||
// active will send torrents that are actively downloading or uploading
|
||||
func active(ud tgbotapi.Update) {
|
||||
torrents, err := Client.GetTorrents()
|
||||
if err != nil {
|
||||
send("active: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("active: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -459,18 +475,20 @@ func active(ud tgbotapi.Update) {
|
||||
for i := range torrents {
|
||||
if torrents[i].RateDownload > 0 ||
|
||||
torrents[i].RateUpload > 0 {
|
||||
buf.WriteString(fmt.Sprintf("<%d> %s\n%s %s of %s (%.1f%%) ↓ %s ↑ %s, R: %s\n\n",
|
||||
torrents[i].ID, torrents[i].Name, torrents[i].TorrentStatus(), humanize.Bytes(torrents[i].Have()),
|
||||
// escape markdown
|
||||
torrentName := mdReplacer.Replace(torrents[i].Name)
|
||||
buf.WriteString(fmt.Sprintf("<*%d*> *%s*\n%s `%s` of `%s` (`%.1f%%`) ↓ `%s` ↑ `%s` R: `%s`\n\n",
|
||||
torrents[i].ID, torrentName, torrents[i].TorrentStatus(), humanize.Bytes(torrents[i].Have()),
|
||||
humanize.Bytes(torrents[i].SizeWhenDone), torrents[i].PercentDone*100, humanize.Bytes(torrents[i].RateDownload),
|
||||
humanize.Bytes(torrents[i].RateUpload), torrents[i].Ratio()))
|
||||
}
|
||||
}
|
||||
if buf.Len() == 0 {
|
||||
send("No active torrents", ud.Message.Chat.ID)
|
||||
send("No active torrents", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
msgID := send(buf.String(), ud.Message.Chat.ID)
|
||||
msgID := send(buf.String(), ud.Message.Chat.ID, true)
|
||||
|
||||
// keep the active list live for 'duration * interval'
|
||||
time.Sleep(time.Second * interval)
|
||||
@ -488,8 +506,10 @@ func active(ud tgbotapi.Update) {
|
||||
for i := range torrents {
|
||||
if torrents[i].RateDownload > 0 ||
|
||||
torrents[i].RateUpload > 0 {
|
||||
buf.WriteString(fmt.Sprintf("<%d> %s\n%s %s of %s (%.1f%%) ↓ %s ↑ %s, R: %s\n\n",
|
||||
torrents[i].ID, torrents[i].Name, torrents[i].TorrentStatus(), humanize.Bytes(torrents[i].Have()),
|
||||
// escape markdown
|
||||
torrentName := mdReplacer.Replace(torrents[i].Name)
|
||||
buf.WriteString(fmt.Sprintf("<*%d*> *%s*\n%s `%s` of `%s` (`%.1f%%`) ↓ `%s` ↑ `%s` R: `%s`\n\n",
|
||||
torrents[i].ID, torrentName, torrents[i].TorrentStatus(), humanize.Bytes(torrents[i].Have()),
|
||||
humanize.Bytes(torrents[i].SizeWhenDone), torrents[i].PercentDone*100, humanize.Bytes(torrents[i].RateDownload),
|
||||
humanize.Bytes(torrents[i].RateUpload), torrents[i].Ratio()))
|
||||
}
|
||||
@ -497,6 +517,7 @@ func active(ud tgbotapi.Update) {
|
||||
|
||||
// no need to check if it is empty, as if the buffer is empty telegram won't change the message
|
||||
editConf := tgbotapi.NewEditMessageText(ud.Message.Chat.ID, msgID, buf.String())
|
||||
editConf.ParseMode = tgbotapi.ModeMarkdown
|
||||
Bot.Send(editConf)
|
||||
time.Sleep(time.Second * interval)
|
||||
}
|
||||
@ -506,13 +527,16 @@ func active(ud tgbotapi.Update) {
|
||||
for i := range torrents {
|
||||
if torrents[i].RateDownload > 0 ||
|
||||
torrents[i].RateUpload > 0 {
|
||||
buf.WriteString(fmt.Sprintf("<%d> %s\n%s %s of %s (%.1f%%) ↓ - B ↑ - B, R: %s\n\n",
|
||||
torrents[i].ID, torrents[i].Name, torrents[i].TorrentStatus(), humanize.Bytes(torrents[i].Have()),
|
||||
// escape markdown
|
||||
torrentName := mdReplacer.Replace(torrents[i].Name)
|
||||
buf.WriteString(fmt.Sprintf("<*%d*> *%s*\n%s `%s` of `%s` (`%.1f%%`) ↓ `-` ↑ `-` R: `%s`\n\n",
|
||||
torrents[i].ID, torrentName, torrents[i].TorrentStatus(), humanize.Bytes(torrents[i].Have()),
|
||||
humanize.Bytes(torrents[i].SizeWhenDone), torrents[i].PercentDone*100, torrents[i].Ratio()))
|
||||
}
|
||||
}
|
||||
|
||||
editConf := tgbotapi.NewEditMessageText(ud.Message.Chat.ID, msgID, buf.String())
|
||||
editConf.ParseMode = tgbotapi.ModeMarkdown
|
||||
Bot.Send(editConf)
|
||||
|
||||
}
|
||||
@ -521,7 +545,7 @@ func active(ud tgbotapi.Update) {
|
||||
func errors(ud tgbotapi.Update) {
|
||||
torrents, err := Client.GetTorrents()
|
||||
if err != nil {
|
||||
send("errors: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("errors: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -533,18 +557,19 @@ func errors(ud tgbotapi.Update) {
|
||||
}
|
||||
}
|
||||
if buf.Len() == 0 {
|
||||
send("No errors", ud.Message.Chat.ID)
|
||||
send("No errors", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send(buf.String(), ud.Message.Chat.ID)
|
||||
send(buf.String(), ud.Message.Chat.ID, false)
|
||||
}
|
||||
|
||||
// sort changes torrents sorting
|
||||
func sort(ud tgbotapi.Update, tokens []string) {
|
||||
if len(tokens) == 0 {
|
||||
send(`sort takes one of (id, name, age, size, progress, downspeed, upspeed, download, upload, ratio)
|
||||
optionally start with (rev) for reversed order
|
||||
e.g. "sort rev size" to get biggest torrents first.`, ud.Message.Chat.ID)
|
||||
send(`sort takes one of:
|
||||
(*id, name, age, size, progress, downspeed, upspeed, download, upload, ratio*)
|
||||
optionally start with (*rev*) for reversed order
|
||||
e.g. "*sort rev size*" to get biggest torrents first.`, ud.Message.Chat.ID, true)
|
||||
return
|
||||
}
|
||||
|
||||
@ -616,15 +641,15 @@ func sort(ud tgbotapi.Update, tokens []string) {
|
||||
}
|
||||
Client.SetSort(transmission.SortRatio)
|
||||
default:
|
||||
send("unkown sorting method", ud.Message.Chat.ID)
|
||||
send("unkown sorting method", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
if reversed {
|
||||
send("sort: reversed "+tokens[0], ud.Message.Chat.ID)
|
||||
send("sort: reversed "+tokens[0], ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send("sort: "+tokens[0], ud.Message.Chat.ID)
|
||||
send("sort: "+tokens[0], ud.Message.Chat.ID, false)
|
||||
}
|
||||
|
||||
var trackerRegex = regexp.MustCompile(`[https?|udp]://([^:/]*)`)
|
||||
@ -633,7 +658,7 @@ var trackerRegex = regexp.MustCompile(`[https?|udp]://([^:/]*)`)
|
||||
func trackers(ud tgbotapi.Update) {
|
||||
torrents, err := Client.GetTorrents()
|
||||
if err != nil {
|
||||
send("trackers: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("trackers: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -660,16 +685,16 @@ func trackers(ud tgbotapi.Update) {
|
||||
}
|
||||
|
||||
if buf.Len() == 0 {
|
||||
send("No trackers!", ud.Message.Chat.ID)
|
||||
send("No trackers!", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send(buf.String(), ud.Message.Chat.ID)
|
||||
send(buf.String(), ud.Message.Chat.ID, false)
|
||||
}
|
||||
|
||||
// add takes an URL to a .torrent file to add it to transmission
|
||||
func add(ud tgbotapi.Update, tokens []string) {
|
||||
if len(tokens) == 0 {
|
||||
send("add: needs atleast one URL", ud.Message.Chat.ID)
|
||||
send("add: needs atleast one URL", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -679,16 +704,16 @@ func add(ud tgbotapi.Update, tokens []string) {
|
||||
|
||||
torrent, err := Client.ExecuteAddCommand(cmd)
|
||||
if err != nil {
|
||||
send("add: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("add: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
continue
|
||||
}
|
||||
|
||||
// check if torrent.Name is empty, then an error happened
|
||||
if torrent.Name == "" {
|
||||
send("add: error adding "+url, ud.Message.Chat.ID)
|
||||
send("add: error adding "+url, ud.Message.Chat.ID, false)
|
||||
continue
|
||||
}
|
||||
send(fmt.Sprintf("Added: <%d> %s", torrent.ID, torrent.Name), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("Added: <%d> %s", torrent.ID, torrent.Name), ud.Message.Chat.ID, false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -702,7 +727,7 @@ func receiveTorrent(ud tgbotapi.Update) {
|
||||
fconfig := tgbotapi.FileConfig{ud.Message.Document.FileID}
|
||||
file, err := Bot.GetFile(fconfig)
|
||||
if err != nil {
|
||||
send("receiver: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("receiver: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -714,7 +739,7 @@ func receiveTorrent(ud tgbotapi.Update) {
|
||||
func search(ud tgbotapi.Update, tokens []string) {
|
||||
// make sure that we got a query
|
||||
if len(tokens) == 0 {
|
||||
send("search: needs an argument", ud.Message.Chat.ID)
|
||||
send("search: needs an argument", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -722,13 +747,13 @@ func search(ud tgbotapi.Update, tokens []string) {
|
||||
// "(?i)" for case insensitivity
|
||||
regx, err := regexp.Compile("(?i)" + query)
|
||||
if err != nil {
|
||||
send("search: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("search: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
torrents, err := Client.GetTorrents()
|
||||
if err != nil {
|
||||
send("search: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("search: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -739,10 +764,10 @@ func search(ud tgbotapi.Update, tokens []string) {
|
||||
}
|
||||
}
|
||||
if buf.Len() == 0 {
|
||||
send("No matches!", ud.Message.Chat.ID)
|
||||
send("No matches!", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send(buf.String(), ud.Message.Chat.ID)
|
||||
send(buf.String(), ud.Message.Chat.ID, false)
|
||||
}
|
||||
|
||||
// latest takes n and returns the latest n torrents
|
||||
@ -755,14 +780,14 @@ func latest(ud tgbotapi.Update, tokens []string) {
|
||||
if len(tokens) > 0 {
|
||||
n, err = strconv.Atoi(tokens[0])
|
||||
if err != nil {
|
||||
send("latest: argument must be a number", ud.Message.Chat.ID)
|
||||
send("latest: argument must be a number", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
torrents, err := Client.GetTorrents()
|
||||
if err != nil {
|
||||
send("latest: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("latest: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -779,30 +804,30 @@ func latest(ud tgbotapi.Update, tokens []string) {
|
||||
buf.WriteString(fmt.Sprintf("<%d> %s\n", torrents[i].ID, torrents[i].Name))
|
||||
}
|
||||
if buf.Len() == 0 {
|
||||
send("latest: No torrents", ud.Message.Chat.ID)
|
||||
send("latest: No torrents", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send(buf.String(), ud.Message.Chat.ID)
|
||||
send(buf.String(), ud.Message.Chat.ID, false)
|
||||
}
|
||||
|
||||
// info takes an id of a torrent and returns some info about it
|
||||
func info(ud tgbotapi.Update, tokens []string) {
|
||||
if len(tokens) == 0 {
|
||||
send("info: needs a torrent ID number", ud.Message.Chat.ID)
|
||||
send("info: needs a torrent ID number", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
for _, id := range tokens {
|
||||
torrentID, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
send(fmt.Sprintf("info: %s is not a number", id), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("info: %s is not a number", id), ud.Message.Chat.ID, false)
|
||||
continue
|
||||
}
|
||||
|
||||
// get the torrent
|
||||
torrent, err := Client.GetTorrent(torrentID)
|
||||
if err != nil {
|
||||
send(fmt.Sprintf("info: Can't find a torrent with an ID of %d", torrentID), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("info: Can't find a torrent with an ID of %d", torrentID), ud.Message.Chat.ID, false)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -816,14 +841,15 @@ func info(ud tgbotapi.Update, tokens []string) {
|
||||
}
|
||||
|
||||
// format the info
|
||||
info := fmt.Sprintf("<%d> %s\n%s\t%s of %s (%.1f%%) ↓ %s ↑ %s, R: %s\nDL: %s, UP: %s\nAdded: %s, ETA: %s\nTrackers: %s",
|
||||
torrent.ID, torrent.Name, torrent.TorrentStatus(), humanize.Bytes(torrent.Have()), humanize.Bytes(torrent.SizeWhenDone),
|
||||
torrentName := mdReplacer.Replace(torrent.Name) // escape markdown
|
||||
info := fmt.Sprintf("<*%d*> *%s*\n%s `%s` of `%s` (`%.1f%%`) ↓ `%s` ↑ `%s` R: `%s`\nDL: `%s` UP: `%s`\nAdded: `%s`, ETA: `%s`\nTrackers: `%s`",
|
||||
torrent.ID, torrentName, torrent.TorrentStatus(), humanize.Bytes(torrent.Have()), humanize.Bytes(torrent.SizeWhenDone),
|
||||
torrent.PercentDone*100, humanize.Bytes(torrent.RateDownload), humanize.Bytes(torrent.RateUpload), torrent.Ratio(),
|
||||
humanize.Bytes(torrent.DownloadedEver), humanize.Bytes(torrent.UploadedEver), time.Unix(torrent.AddedDate, 0).Format(time.Stamp),
|
||||
torrent.ETA(), trackers)
|
||||
|
||||
// send it
|
||||
msgID := send(info, ud.Message.Chat.ID)
|
||||
msgID := send(info, ud.Message.Chat.ID, true)
|
||||
|
||||
// this go-routine will make the info live for 'duration * interval'
|
||||
// takes trackers so we don't have to regex them over and over.
|
||||
@ -834,26 +860,30 @@ func info(ud tgbotapi.Update, tokens []string) {
|
||||
continue // skip this iteration if there's an error retrieving the torrent's info
|
||||
}
|
||||
|
||||
info := fmt.Sprintf("<%d> %s\n%s\t%s of %s (%.1f%%) ↓ %s ↑ %s, R: %s\nDL: %s, UP: %s\nAdded: %s, ETA: %s\nTrackers: %s",
|
||||
torrent.ID, torrent.Name, torrent.TorrentStatus(), humanize.Bytes(torrent.Have()), humanize.Bytes(torrent.SizeWhenDone),
|
||||
torrentName := mdReplacer.Replace(torrent.Name)
|
||||
info := fmt.Sprintf("<*%d*> *%s*\n%s `%s` of `%s` (`%.1f%%`) ↓ `%s` ↑ `%s` R: `%s`\nDL: `%s` UP: `%s`\nAdded: `%s`, ETA: `%s`\nTrackers: `%s`",
|
||||
torrent.ID, torrentName, torrent.TorrentStatus(), humanize.Bytes(torrent.Have()), humanize.Bytes(torrent.SizeWhenDone),
|
||||
torrent.PercentDone*100, humanize.Bytes(torrent.RateDownload), humanize.Bytes(torrent.RateUpload), torrent.Ratio(),
|
||||
humanize.Bytes(torrent.DownloadedEver), humanize.Bytes(torrent.UploadedEver), time.Unix(torrent.AddedDate, 0).Format(time.Stamp),
|
||||
torrent.ETA(), trackers)
|
||||
|
||||
// update the message
|
||||
editConf := tgbotapi.NewEditMessageText(ud.Message.Chat.ID, msgID, info)
|
||||
editConf.ParseMode = tgbotapi.ModeMarkdown
|
||||
Bot.Send(editConf)
|
||||
time.Sleep(time.Second * interval)
|
||||
|
||||
}
|
||||
|
||||
// at the end write dashes to indicate that we are done being live.
|
||||
info := fmt.Sprintf("<%d> %s\n%s\t%s of %s (%.1f%%) ↓ - B ↑ - B, R: %s\nDL: %s, UP: %s\nAdded: %s, ETA: -\nTrackers: %s",
|
||||
torrent.ID, torrent.Name, torrent.TorrentStatus(), humanize.Bytes(torrent.Have()), humanize.Bytes(torrent.SizeWhenDone),
|
||||
torrentName := mdReplacer.Replace(torrent.Name)
|
||||
info := fmt.Sprintf("<*%d*> *%s*\n%s `%s` of `%s` (`%.1f%%`) ↓ `- B` ↑ `- B` R: `%s`\nDL: `%s` UP: `%s`\nAdded: `%s`, ETA: `-`\nTrackers: `%s`",
|
||||
torrent.ID, torrentName, torrent.TorrentStatus(), humanize.Bytes(torrent.Have()), humanize.Bytes(torrent.SizeWhenDone),
|
||||
torrent.PercentDone*100, torrent.Ratio(), humanize.Bytes(torrent.DownloadedEver), humanize.Bytes(torrent.UploadedEver),
|
||||
time.Unix(torrent.AddedDate, 0).Format(time.Stamp), trackers)
|
||||
|
||||
editConf := tgbotapi.NewEditMessageText(ud.Message.Chat.ID, msgID, info)
|
||||
editConf.ParseMode = tgbotapi.ModeMarkdown
|
||||
Bot.Send(editConf)
|
||||
}(trackers, torrentID, msgID)
|
||||
}
|
||||
@ -863,38 +893,38 @@ func info(ud tgbotapi.Update, tokens []string) {
|
||||
func stop(ud tgbotapi.Update, tokens []string) {
|
||||
// make sure that we got at least one argument
|
||||
if len(tokens) == 0 {
|
||||
send("stop: needs an argument", ud.Message.Chat.ID)
|
||||
send("stop: needs an argument", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
// if the first argument is 'all' then stop all torrents
|
||||
if tokens[0] == "all" {
|
||||
if err := Client.StopAll(); err != nil {
|
||||
send("stop: error occurred while stopping some torrents", ud.Message.Chat.ID)
|
||||
send("stop: error occurred while stopping some torrents", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send("stopped all torrents", ud.Message.Chat.ID)
|
||||
send("stopped all torrents", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
for _, id := range tokens {
|
||||
num, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
send(fmt.Sprintf("stop: %s is not a number", id), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("stop: %s is not a number", id), ud.Message.Chat.ID, false)
|
||||
continue
|
||||
}
|
||||
status, err := Client.StopTorrent(num)
|
||||
if err != nil {
|
||||
send("stop: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("stop: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
continue
|
||||
}
|
||||
|
||||
torrent, err := Client.GetTorrent(num)
|
||||
if err != nil {
|
||||
send(fmt.Sprintf("[fail] stop: No torrent with an ID of %d", num), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("[fail] stop: No torrent with an ID of %d", num), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send(fmt.Sprintf("[%s] stop: %s", status, torrent.Name), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("[%s] stop: %s", status, torrent.Name), ud.Message.Chat.ID, false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -902,17 +932,17 @@ func stop(ud tgbotapi.Update, tokens []string) {
|
||||
func start(ud tgbotapi.Update, tokens []string) {
|
||||
// make sure that we got at least one argument
|
||||
if len(tokens) == 0 {
|
||||
send("start: needs an argument", ud.Message.Chat.ID)
|
||||
send("start: needs an argument", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
// if the first argument is 'all' then start all torrents
|
||||
if tokens[0] == "all" {
|
||||
if err := Client.StartAll(); err != nil {
|
||||
send("start: error occurred while starting some torrents", ud.Message.Chat.ID)
|
||||
send("start: error occurred while starting some torrents", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send("started all torrents", ud.Message.Chat.ID)
|
||||
send("started all torrents", ud.Message.Chat.ID, false)
|
||||
return
|
||||
|
||||
}
|
||||
@ -920,21 +950,21 @@ func start(ud tgbotapi.Update, tokens []string) {
|
||||
for _, id := range tokens {
|
||||
num, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
send(fmt.Sprintf("start: %s is not a number", id), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("start: %s is not a number", id), ud.Message.Chat.ID, false)
|
||||
continue
|
||||
}
|
||||
status, err := Client.StartTorrent(num)
|
||||
if err != nil {
|
||||
send("stop: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("stop: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
continue
|
||||
}
|
||||
|
||||
torrent, err := Client.GetTorrent(num)
|
||||
if err != nil {
|
||||
send(fmt.Sprintf("[fail] start: No torrent with an ID of %d", num), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("[fail] start: No torrent with an ID of %d", num), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send(fmt.Sprintf("[%s] start: %s", status, torrent.Name), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("[%s] start: %s", status, torrent.Name), ud.Message.Chat.ID, false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -942,17 +972,17 @@ func start(ud tgbotapi.Update, tokens []string) {
|
||||
func check(ud tgbotapi.Update, tokens []string) {
|
||||
// make sure that we got at least one argument
|
||||
if len(tokens) == 0 {
|
||||
send("check: needs an argument", ud.Message.Chat.ID)
|
||||
send("check: needs an argument", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
// if the first argument is 'all' then start all torrents
|
||||
if tokens[0] == "all" {
|
||||
if err := Client.VerifyAll(); err != nil {
|
||||
send("check: error occurred while verifying some torrents", ud.Message.Chat.ID)
|
||||
send("check: error occurred while verifying some torrents", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send("verifying all torrents", ud.Message.Chat.ID)
|
||||
send("verifying all torrents", ud.Message.Chat.ID, false)
|
||||
return
|
||||
|
||||
}
|
||||
@ -960,21 +990,21 @@ func check(ud tgbotapi.Update, tokens []string) {
|
||||
for _, id := range tokens {
|
||||
num, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
send(fmt.Sprintf("check: %s is not a number", id), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("check: %s is not a number", id), ud.Message.Chat.ID, false)
|
||||
continue
|
||||
}
|
||||
status, err := Client.VerifyTorrent(num)
|
||||
if err != nil {
|
||||
send("stop: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("stop: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
continue
|
||||
}
|
||||
|
||||
torrent, err := Client.GetTorrent(num)
|
||||
if err != nil {
|
||||
send(fmt.Sprintf("[fail] check: No torrent with an ID of %d", num), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("[fail] check: No torrent with an ID of %d", num), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
send(fmt.Sprintf("[%s] check: %s", status, torrent.Name), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("[%s] check: %s", status, torrent.Name), ud.Message.Chat.ID, false)
|
||||
}
|
||||
|
||||
}
|
||||
@ -983,26 +1013,26 @@ func check(ud tgbotapi.Update, tokens []string) {
|
||||
func stats(ud tgbotapi.Update) {
|
||||
stats, err := Client.GetStats()
|
||||
if err != nil {
|
||||
send("stats: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("stats: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf(
|
||||
`
|
||||
Total torrents: %d
|
||||
Active: %d
|
||||
Paused: %d
|
||||
Total: *%d*
|
||||
Active: *%d*
|
||||
Paused: *%d*
|
||||
|
||||
- Current Stats -
|
||||
Downloaded: %s
|
||||
Uploaded: %s
|
||||
Running time: %d seconds
|
||||
_Current Stats_
|
||||
Downloaded: *%s*
|
||||
Uploaded: *%s*
|
||||
Running time: *%d seconds*
|
||||
|
||||
- Total Stats -
|
||||
Sessions: %d
|
||||
Downloaded: %s
|
||||
Uploaded: %s
|
||||
Total Running time: %d seconds
|
||||
_Accumulative Stats_
|
||||
Sessions: *%d*
|
||||
Downloaded: *%s*
|
||||
Uploaded: *%s*
|
||||
Total Running time: *%d seconds*
|
||||
`,
|
||||
|
||||
stats.TorrentCount,
|
||||
@ -1017,7 +1047,7 @@ func stats(ud tgbotapi.Update) {
|
||||
stats.CumulativeStats.SecondsActive,
|
||||
)
|
||||
|
||||
send(msg, ud.Message.Chat.ID)
|
||||
send(msg, ud.Message.Chat.ID, true)
|
||||
}
|
||||
|
||||
// speed will echo back the current download and upload speeds
|
||||
@ -1027,7 +1057,7 @@ func speed(ud tgbotapi.Update) {
|
||||
for i := 0; i < duration; i++ {
|
||||
stats, err := Client.GetStats()
|
||||
if err != nil {
|
||||
send("speed: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("speed: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -1035,7 +1065,7 @@ func speed(ud tgbotapi.Update) {
|
||||
|
||||
// if we haven't send a message, send it and save the message ID to edit it the next iteration
|
||||
if msgID == 0 {
|
||||
msgID = send(msg, ud.Message.Chat.ID)
|
||||
msgID = send(msg, ud.Message.Chat.ID, false)
|
||||
time.Sleep(time.Second * interval)
|
||||
continue
|
||||
}
|
||||
@ -1055,7 +1085,7 @@ func speed(ud tgbotapi.Update) {
|
||||
func count(ud tgbotapi.Update) {
|
||||
torrents, err := Client.GetTorrents()
|
||||
if err != nil {
|
||||
send("count: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("count: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -1083,7 +1113,7 @@ func count(ud tgbotapi.Update) {
|
||||
msg := fmt.Sprintf("Downloading: %d\nSeeding: %d\nPaused: %d\nVerifying: %d\n\n- Waiting to -\nDownload: %d\nSeed: %d\nVerify: %d\n\nTotal: %d",
|
||||
downloading, seeding, stopped, checking, downloadingQ, seedingQ, checkingQ, len(torrents))
|
||||
|
||||
send(msg, ud.Message.Chat.ID)
|
||||
send(msg, ud.Message.Chat.ID, false)
|
||||
|
||||
}
|
||||
|
||||
@ -1091,7 +1121,7 @@ func count(ud tgbotapi.Update) {
|
||||
func del(ud tgbotapi.Update, tokens []string) {
|
||||
// make sure that we got an argument
|
||||
if len(tokens) == 0 {
|
||||
send("del: needs an ID", ud.Message.Chat.ID)
|
||||
send("del: needs an ID", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
@ -1099,17 +1129,17 @@ func del(ud tgbotapi.Update, tokens []string) {
|
||||
for _, id := range tokens {
|
||||
num, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
send(fmt.Sprintf("del: %s is not an ID", id), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("del: %s is not an ID", id), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
name, err := Client.DeleteTorrent(num, false)
|
||||
if err != nil {
|
||||
send("del: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("del: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
send("Deleted: "+name, ud.Message.Chat.ID)
|
||||
send("Deleted: "+name, ud.Message.Chat.ID, false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1117,24 +1147,24 @@ func del(ud tgbotapi.Update, tokens []string) {
|
||||
func deldata(ud tgbotapi.Update, tokens []string) {
|
||||
// make sure that we got an argument
|
||||
if len(tokens) == 0 {
|
||||
send("deldata: needs an ID", ud.Message.Chat.ID)
|
||||
send("deldata: needs an ID", ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
// loop over tokens to read each potential id
|
||||
for _, id := range tokens {
|
||||
num, err := strconv.Atoi(id)
|
||||
if err != nil {
|
||||
send(fmt.Sprintf("deldata: %s is not an ID", id), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("deldata: %s is not an ID", id), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
name, err := Client.DeleteTorrent(num, true)
|
||||
if err != nil {
|
||||
send("deldata: "+err.Error(), ud.Message.Chat.ID)
|
||||
send("deldata: "+err.Error(), ud.Message.Chat.ID, false)
|
||||
return
|
||||
}
|
||||
|
||||
send("Deleted with data: "+name, ud.Message.Chat.ID)
|
||||
send("Deleted with data: "+name, ud.Message.Chat.ID, false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1142,11 +1172,11 @@ func deldata(ud tgbotapi.Update, tokens []string) {
|
||||
|
||||
// version sends transmission version + transmission-telegram version
|
||||
func version(ud tgbotapi.Update) {
|
||||
send(fmt.Sprintf("Transmission %s\nTransmission-telegram %s", Client.Version(), VERSION), ud.Message.Chat.ID)
|
||||
send(fmt.Sprintf("Transmission %s\nTransmission-telegram %s", Client.Version(), VERSION), ud.Message.Chat.ID, false)
|
||||
}
|
||||
|
||||
// send takes a chat id and a message to send, returns the message id of the send message
|
||||
func send(text string, chatID int64) int {
|
||||
func send(text string, chatID int64, markdown bool) int {
|
||||
// set typing action
|
||||
action := tgbotapi.NewChatAction(chatID, tgbotapi.ChatTyping)
|
||||
Bot.Send(action)
|
||||
@ -1158,6 +1188,9 @@ LenCheck:
|
||||
if msgRuneCount > 4096 {
|
||||
msg := tgbotapi.NewMessage(chatID, text[:4095])
|
||||
msg.DisableWebPagePreview = true
|
||||
if markdown {
|
||||
msg.ParseMode = tgbotapi.ModeMarkdown
|
||||
}
|
||||
|
||||
// send current chunk
|
||||
if _, err := Bot.Send(msg); err != nil {
|
||||
@ -1172,6 +1205,9 @@ LenCheck:
|
||||
// if msgRuneCount < 4096, send it normally
|
||||
msg := tgbotapi.NewMessage(chatID, text)
|
||||
msg.DisableWebPagePreview = true
|
||||
if markdown {
|
||||
msg.ParseMode = tgbotapi.ModeMarkdown
|
||||
}
|
||||
|
||||
resp, err := Bot.Send(msg)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user