mirror of
https://github.com/NohamR/TransmissionBot.git
synced 2025-05-24 14:22:00 +00:00
new feature and performance improvoments
Added `t/compact` command to toggle between mobile or desktop command output that applies to `t/summary`, `t/list`, `t/modify` User can click a reaction of `t/summary` or `t/modify` while reactions are still being printed.
This commit is contained in:
parent
f664459431
commit
ba2c55f3ca
215
bot.py
215
bot.py
@ -48,6 +48,7 @@ logging.basicConfig(format='%(asctime)s %(message)s',filename=join(expanduser("~
|
|||||||
|
|
||||||
# END USER CONFIGURATION
|
# END USER CONFIGURATION
|
||||||
|
|
||||||
|
COMPACT_OUTPUT = False
|
||||||
REPEAT_COMMAND = False
|
REPEAT_COMMAND = False
|
||||||
REPEAT_MSG_LIST = []
|
REPEAT_MSG_LIST = []
|
||||||
REPEAT_START_TIME = 0
|
REPEAT_START_TIME = 0
|
||||||
@ -435,24 +436,36 @@ async def on_ready():
|
|||||||
print("Running on:", platform.system(), platform.release(), "(" + os.name + ")")
|
print("Running on:", platform.system(), platform.release(), "(" + os.name + ")")
|
||||||
print('-------------------')
|
print('-------------------')
|
||||||
|
|
||||||
def humanbytes(B):
|
def humanbytes(B,d = 2):
|
||||||
'Return the given bytes as a human friendly KB, MB, GB, or TB string'
|
'Return the given bytes as a human friendly KB, MB, GB, or TB string'
|
||||||
B = float(B)
|
B = float(B)
|
||||||
KB = float(1024)
|
KB = float(1024)
|
||||||
MB = float(KB ** 2) # 1,048,576
|
MB = float(KB ** 2) # 1,048,576
|
||||||
GB = float(KB ** 3) # 1,073,741,824
|
GB = float(KB ** 3) # 1,073,741,824
|
||||||
TB = float(KB ** 4) # 1,099,511,627,776
|
TB = float(KB ** 4) # 1,099,511,627,776
|
||||||
|
|
||||||
if B < KB:
|
if d <= 0:
|
||||||
return '{0} {1}'.format(B,'B')
|
if B < KB:
|
||||||
elif KB <= B < MB:
|
return '{0}B'.format(int(B))
|
||||||
return '{0:.2f} kB'.format(B/KB)
|
elif KB <= B < MB:
|
||||||
elif MB <= B < GB:
|
return '{0:d}kB'.format(int(B/KB))
|
||||||
return '{0:.2f} MB'.format(B/MB)
|
elif MB <= B < GB:
|
||||||
elif GB <= B < TB:
|
return '{0:d}MB'.format(int(B/MB))
|
||||||
return '{0:.2f} GB'.format(B/GB)
|
elif GB <= B < TB:
|
||||||
elif TB <= B:
|
return '{0:d}GB'.format(int(B/GB))
|
||||||
return '{0:.2f} TB'.format(B/TB)
|
elif TB <= B:
|
||||||
|
return '{0:d}TB'.format(int(B/TB))
|
||||||
|
else:
|
||||||
|
if B < KB:
|
||||||
|
return '{0} B'.format(B)
|
||||||
|
elif KB <= B < MB:
|
||||||
|
return '{0:.{nd}f} kB'.format(B/KB, nd = d)
|
||||||
|
elif MB <= B < GB:
|
||||||
|
return '{0:.{nd}f} MB'.format(B/MB, nd = d)
|
||||||
|
elif GB <= B < TB:
|
||||||
|
return '{0:.{nd}f} GB'.format(B/GB, nd = d)
|
||||||
|
elif TB <= B:
|
||||||
|
return '{0:.{nd}f} TB'.format(B/TB, nd = d)
|
||||||
|
|
||||||
def tobytes(B):
|
def tobytes(B):
|
||||||
'Return the number of bytes given by a string (a float followed by a space and the unit of prefix-bytes eg. "21.34 GB")'
|
'Return the number of bytes given by a string (a float followed by a space and the unit of prefix-bytes eg. "21.34 GB")'
|
||||||
@ -522,7 +535,7 @@ torStates = ('downloading', 'seeding', 'stopped', 'verifying', 'queued', 'finish
|
|||||||
)
|
)
|
||||||
torStateEmoji = ('🔻','🌱','⏸','🩺','🚧','🏁',
|
torStateEmoji = ('🔻','🌱','⏸','🩺','🚧','🏁',
|
||||||
'🐢','🐇','🚀',
|
'🐢','🐇','🚀',
|
||||||
'🔒','🔓',
|
'🔐','🔓',
|
||||||
'‼️','✅','⚠️','🌐','🖥'
|
'‼️','✅','⚠️','🌐','🖥'
|
||||||
)
|
)
|
||||||
torStateFilters = {i:"--filter {}".format(j) for i,j in zip(torStateEmoji,torStates)}
|
torStateFilters = {i:"--filter {}".format(j) for i,j in zip(torStateEmoji,torStates)}
|
||||||
@ -592,10 +605,13 @@ def torSummary(torrents, repeat=False):
|
|||||||
embed.add_field(name="⬇️ {}/s".format(totDownRate), value="⬆️ {}/s".format(totUpRate), inline=False)
|
embed.add_field(name="⬇️ {}/s".format(totDownRate), value="⬆️ {}/s".format(totUpRate), inline=False)
|
||||||
embed.add_field(name="⏬ {} of {}".format(totDown,totSize), value="⏫ {} ⚖️ {}".format(totUp,totRatio), inline=False)
|
embed.add_field(name="⏬ {} of {}".format(totDown,totSize), value="⏫ {} ⚖️ {}".format(totUp,totRatio), inline=False)
|
||||||
embed.add_field(name="↕️ {} transfer{}".format(numTot, 's' if numTot != 1 else ''), value=' '.join(['{} {}'.format(i,j) for i,j in zip(torStateEmoji[:6], numInState[:6])]), inline=False)
|
embed.add_field(name="↕️ {} transfer{}".format(numTot, 's' if numTot != 1 else ''), value=' '.join(['{} {}'.format(i,j) for i,j in zip(torStateEmoji[:6], numInState[:6])]), inline=False)
|
||||||
embed.add_field(name="{} Error{}".format(numInState[11], 's' if numInState[9] != 1 else ''), value='\n'.join(['{} {}'.format(i,"**{}**".format(j) if i != '✅' and j > 0 else j) for i,j in zip(torStateEmoji[12:], numInState[12:])]), inline=True)
|
if COMPACT_OUTPUT:
|
||||||
embed.add_field(name="Activity", value='\n'.join(['{} {}'.format(i,j) for i,j in zip(torStateEmoji[6:9], numInState[6:9])]), inline=True)
|
embed.add_field(name=' '.join(['{} {}'.format(i,j) for i,j in zip(torStateEmoji[11:], numInState[11:])]), value=' '.join(['{} {}'.format(i,j) for i,j in zip(torStateEmoji[6:9], numInState[6:9])]) + "—" + ' '.join(['{} {}'.format(i,j) for i,j in zip(torStateEmoji[9:11], numInState[9:11])]), inline=False)
|
||||||
embed.add_field(name="Tracker", value='\n'.join(['{} {}'.format(i,j) for i,j in zip(torStateEmoji[9:11], numInState[9:11])]), inline=True)
|
else:
|
||||||
|
embed.add_field(name="{} Error{}".format(numInState[11], 's' if numInState[9] != 1 else ''), value='\n'.join(['{} {}'.format(i,"**{}**".format(j) if i != '✅' and j > 0 else j) for i,j in zip(torStateEmoji[12:], numInState[12:])]), inline=not COMPACT_OUTPUT)
|
||||||
|
embed.add_field(name="Activity", value='\n'.join(['{} {}'.format(i,j) for i,j in zip(torStateEmoji[6:9], numInState[6:9])]), inline=not COMPACT_OUTPUT)
|
||||||
|
embed.add_field(name="Tracker", value='\n'.join(['{} {}'.format(i,j) for i,j in zip(torStateEmoji[9:11], numInState[9:11])]), inline=not COMPACT_OUTPUT)
|
||||||
|
|
||||||
embed.set_footer(text=topRatios+"\n📜 Symbol legend{}".format('\nUpdating every {} second{}—❎ to stop'.format(REPEAT_FREQ,'s' if REPEAT_FREQ != 1 else '') if repeat else ', 🔄 to auto-update'))
|
embed.set_footer(text=topRatios+"\n📜 Symbol legend{}".format('\nUpdating every {} second{}—❎ to stop'.format(REPEAT_FREQ,'s' if REPEAT_FREQ != 1 else '') if repeat else ', 🔄 to auto-update'))
|
||||||
# await context.message.channel.send(embed=embed)
|
# await context.message.channel.send(embed=embed)
|
||||||
return embed,numInState
|
return embed,numInState
|
||||||
@ -629,7 +645,7 @@ async def summary(context, *, content="", repeat=False):
|
|||||||
cache_msg = await context.message.channel.fetch_message(msg.id)
|
cache_msg = await context.message.channel.fetch_message(msg.id)
|
||||||
msgRxns = [str(r.emoji) for r in cache_msg.reactions]
|
msgRxns = [str(r.emoji) for r in cache_msg.reactions]
|
||||||
|
|
||||||
for i in stateEmoji[:2]:
|
for i in stateEmoji[:3]:
|
||||||
if i not in msgRxns:
|
if i not in msgRxns:
|
||||||
await msg.add_reaction(i)
|
await msg.add_reaction(i)
|
||||||
for i in range(len(summaryData[1])):
|
for i in range(len(summaryData[1])):
|
||||||
@ -637,6 +653,58 @@ async def summary(context, *, content="", repeat=False):
|
|||||||
await msg.add_reaction(stateEmoji[i+3])
|
await msg.add_reaction(stateEmoji[i+3])
|
||||||
elif summaryData[1][i] == 0 and stateEmoji[i+3] in msgRxns:
|
elif summaryData[1][i] == 0 and stateEmoji[i+3] in msgRxns:
|
||||||
await msg.clear_reaction(stateEmoji[i+3])
|
await msg.clear_reaction(stateEmoji[i+3])
|
||||||
|
cache_msg = await context.message.channel.fetch_message(msg.id)
|
||||||
|
for r in cache_msg.reactions:
|
||||||
|
if r.count > 1:
|
||||||
|
async for user in r.users():
|
||||||
|
if user.id == context.message.author.id:
|
||||||
|
if str(r.emoji) == stateEmoji[0]:
|
||||||
|
await legend(context)
|
||||||
|
return
|
||||||
|
elif str(r.emoji) == stateEmoji[1]:
|
||||||
|
if repeat:
|
||||||
|
REPEAT_COMMAND = False
|
||||||
|
REPEAT_MSG_LIST = []
|
||||||
|
await context.message.channel.send("❎ Auto-update cancelled...")
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
await msg.clear_reaction('🔄')
|
||||||
|
await repeat_command(summary, context=context, content=content, msg_list=[msg])
|
||||||
|
return
|
||||||
|
elif str(r.emoji) in stateEmoji[2:]:
|
||||||
|
if repeat:
|
||||||
|
REPEAT_COMMAND = False
|
||||||
|
REPEAT_MSG_LIST = []
|
||||||
|
await context.message.channel.send("❎ Auto-update cancelled...")
|
||||||
|
await list_transfers(context, content=torStateFilters[str(r.emoji)])
|
||||||
|
return
|
||||||
|
|
||||||
|
# first check to see if a user clicked a reaction before they finished printing
|
||||||
|
# cache_msg = await context.message.channel.fetch_message(msg.id)
|
||||||
|
# for r in cache_msg.reactions:
|
||||||
|
# if r.count > 1:
|
||||||
|
# async for user in r.users():
|
||||||
|
# if user.id == context.message.author.id:
|
||||||
|
# if str(r.emoji) == stateEmoji[0]:
|
||||||
|
# await legend(context)
|
||||||
|
# return
|
||||||
|
# elif str(r.emoji) == stateEmoji[1]:
|
||||||
|
# if repeat:
|
||||||
|
# REPEAT_COMMAND = False
|
||||||
|
# REPEAT_MSG_LIST = []
|
||||||
|
# await context.message.channel.send("❎ Auto-update cancelled...")
|
||||||
|
# return
|
||||||
|
# else:
|
||||||
|
# await msg.clear_reaction('🔄')
|
||||||
|
# await repeat_command(summary, context=context, content=content, msg_list=[msg])
|
||||||
|
# return
|
||||||
|
# elif str(r.emoji) in stateEmoji[2:]:
|
||||||
|
# if repeat:
|
||||||
|
# REPEAT_COMMAND = False
|
||||||
|
# REPEAT_MSG_LIST = []
|
||||||
|
# await context.message.channel.send("❎ Auto-update cancelled...")
|
||||||
|
# await list_transfers(context, content=torStateFilters[str(r.emoji)])
|
||||||
|
# return
|
||||||
|
|
||||||
def check(reaction, user):
|
def check(reaction, user):
|
||||||
return user == context.message.author and reaction.message.id == msg.id and str(reaction.emoji) in stateEmoji
|
return user == context.message.author and reaction.message.id == msg.id and str(reaction.emoji) in stateEmoji
|
||||||
@ -708,23 +776,37 @@ def torList(torrents, author_name="Torrent Transfers",title=None,description=Non
|
|||||||
errorStrs = ['✅','⚠️','🌐','🖥']
|
errorStrs = ['✅','⚠️','🌐','🖥']
|
||||||
|
|
||||||
def torListLine(t):
|
def torListLine(t):
|
||||||
down = humanbytes(t.progress * 0.01 * t.totalSize)
|
if COMPACT_OUTPUT:
|
||||||
out = "{} {} {} {} ".format(stateEmoji[t.status],errorStrs[t.error],'🚀' if t.rateDownload + t.rateUpload > 0 else '🐢' if t.isStalled else '🐇', '🔒' if t.isPrivate else '🔓')
|
down = humanbytes(t.progress * 0.01 * t.totalSize, d=0)
|
||||||
if t.status == 'downloading':
|
out = "{}{} ".format(stateEmoji[t.status],errorStrs[t.error])
|
||||||
out += "{}/{} ⬇️ {}/s ⬆️ {}/s ⚖️ {:.2f}".format(down,humanbytes(t.totalSize),humanbytes(t.rateDownload),humanbytes(t.rateUpload),t.uploadRatio)
|
if t.status == 'downloading':
|
||||||
elif t.status == 'seeding':
|
out += "{}%{} {}/s:*{}/s*:{:.1f}".format(int(t.progress), down, humanbytes(t.rateDownload, d=0), humanbytes(t.rateUpload, d=0), t.uploadRatio)
|
||||||
out += "{} ⬆️ {}/s ⚖️ {:.2f}".format(humanbytes(t.totalSize),humanbytes(t.rateUpload),t.uploadRatio)
|
elif t.status == 'seeding':
|
||||||
elif t.status == 'stopped':
|
out += "{} *{}/s*:{:.1f}".format(down, humanbytes(t.rateUpload, d=0), t.uploadRatio)
|
||||||
out += "{}/{} ⚖️ {:.2f}".format(down,humanbytes(t.totalSize),t.uploadRatio)
|
elif t.status == 'stopped':
|
||||||
elif t.status == 'finished':
|
out += "{}%{} {:.1f}".format(int(t.progress), down, t.uploadRatio)
|
||||||
out += "{} ⚖️ {:.2f}".format(humanbytes(t.totalSize),t.uploadRatio)
|
elif t.status == 'finished':
|
||||||
|
out += "{} {:.1f}".format(down, t.uploadRatio)
|
||||||
if t.error != 0:
|
else:
|
||||||
out += "\n**Error:** *{}*".format(t.errorString)
|
down = humanbytes(t.progress * 0.01 * t.totalSize)
|
||||||
|
out = "{} {} {} {} ".format(stateEmoji[t.status],errorStrs[t.error],'🚀' if t.rateDownload + t.rateUpload > 0 else '🐢' if t.isStalled else '🐇', '🔐' if t.isPrivate else '🔓')
|
||||||
|
if t.status == 'downloading':
|
||||||
|
out += "⏬ {}/{} ({:.1f}%) ⬇️ {}/s ⬆️ *{}/s* ⚖️ *{:.2f}*".format(down,humanbytes(t.totalSize),t.progress, humanbytes(t.rateDownload),humanbytes(t.rateUpload),t.uploadRatio)
|
||||||
|
elif t.status == 'seeding':
|
||||||
|
out += "⏬ {} ⬆️ *{}/s* ⚖️ *{:.2f}*".format(humanbytes(t.totalSize),humanbytes(t.rateUpload),t.uploadRatio)
|
||||||
|
elif t.status == 'stopped':
|
||||||
|
out += "⏬ {}/{} ({:.1f}%) ⚖️ *{:.2f}*".format(down,humanbytes(t.totalSize),t.progress,t.uploadRatio)
|
||||||
|
elif t.status == 'finished':
|
||||||
|
out += "⏬ {} ⚖️ {:.2f}".format(humanbytes(t.totalSize),t.uploadRatio)
|
||||||
|
|
||||||
|
if t.error != 0:
|
||||||
|
out += "***Error:*** *{}*".format(t.errorString)
|
||||||
return out
|
return out
|
||||||
|
|
||||||
nameList = ["{}) {:.245}{}".format(t.id,t.name,"..." if len(t.name) > 245 else "") for t in torrents]
|
if COMPACT_OUTPUT:
|
||||||
|
nameList = ["{}){:.26}{}".format(t.id,t.name,"..." if len(t.name) > 26 else "") for t in torrents]
|
||||||
|
else:
|
||||||
|
nameList = ["{}) {:.245}{}".format(t.id,t.name,"..." if len(t.name) > 245 else "") for t in torrents]
|
||||||
valList = [torListLine(t) for t in torrents]
|
valList = [torListLine(t) for t in torrents]
|
||||||
|
|
||||||
n = 0
|
n = 0
|
||||||
@ -887,6 +969,7 @@ async def list_transfers(context, *, content="", repeat=False):
|
|||||||
REPEAT_COMMAND = False
|
REPEAT_COMMAND = False
|
||||||
REPEAT_MSG_LIST = []
|
REPEAT_MSG_LIST = []
|
||||||
await context.message.channel.send("❎ Auto-update cancelled...")
|
await context.message.channel.send("❎ Auto-update cancelled...")
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
await msg.clear_reaction('🔄')
|
await msg.clear_reaction('🔄')
|
||||||
await repeat_command(list_transfers, context=context, content=content, msg_list=msgs)
|
await repeat_command(list_transfers, context=context, content=content, msg_list=msgs)
|
||||||
@ -920,7 +1003,7 @@ async def modify(context, *, content=""):
|
|||||||
if sort_by == -1:
|
if sort_by == -1:
|
||||||
await context.message.channel.send("Invalid sort specified. Choose one of {}".format(str(sort_names)))
|
await context.message.channel.send("Invalid sort specified. Choose one of {}".format(str(sort_names)))
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
await context.message.delete()
|
await context.message.delete()
|
||||||
except:
|
except:
|
||||||
@ -958,8 +1041,61 @@ async def modify(context, *, content=""):
|
|||||||
|
|
||||||
opEmoji.append('📜')
|
opEmoji.append('📜')
|
||||||
|
|
||||||
|
msg = msgs[-1]
|
||||||
|
|
||||||
for i in opEmoji:
|
for i in opEmoji:
|
||||||
await msgs[-1].add_reaction(i)
|
await msgs[-1].add_reaction(i)
|
||||||
|
cache_msg = await context.message.channel.fetch_message(msg.id)
|
||||||
|
for reaction in cache_msg.reactions:
|
||||||
|
if reaction.count > 1:
|
||||||
|
async for user in reaction.users():
|
||||||
|
if user.id == context.message.author.id:
|
||||||
|
if str(reaction.emoji) == opEmoji[-1]:
|
||||||
|
await legend(context)
|
||||||
|
elif str(reaction.emoji) in opEmoji[:-1]:
|
||||||
|
cmds = {i:j for i,j in zip(opEmoji,ops)}
|
||||||
|
cmdNames = {i:j for i,j in zip(opEmoji,opNames)}
|
||||||
|
cmd = cmds[str(reaction.emoji)]
|
||||||
|
cmdName = cmdNames[str(reaction.emoji)]
|
||||||
|
|
||||||
|
doContinue = True
|
||||||
|
if "remove" in cmds[str(reaction.emoji)]:
|
||||||
|
embed=discord.Embed(title="Are you sure you wish to remove{} {} transfer{}?".format(' and DELETE' if 'delete' in cmds[str(reaction.emoji)] else '', len(torrents), '' if len(torrents)==1 else 's'),description="**This action is irreversible!**",color=0xb51a00)
|
||||||
|
embed.set_footer(text="react ✅ to continue or ❌ to cancel")
|
||||||
|
msg = await context.message.channel.send(embed=embed)
|
||||||
|
|
||||||
|
for i in ['✅','❌']:
|
||||||
|
await msg.add_reaction(i)
|
||||||
|
|
||||||
|
def check1(reaction, user):
|
||||||
|
return user == context.message.author and str(reaction.emoji) in ['✅','❌']
|
||||||
|
try:
|
||||||
|
reaction, user = await client.wait_for('reaction_add', timeout=60.0, check=check1)
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
doContinue = False
|
||||||
|
else:
|
||||||
|
doContinue = str(reaction.emoji) == '✅'
|
||||||
|
if doContinue:
|
||||||
|
await context.message.channel.send("{} Trying to {} transfer{}, please wait...".format(str(reaction.emoji), cmdName, 's' if allOnly or len(torrents) > 1 else ''))
|
||||||
|
if "pause" in cmd:
|
||||||
|
stop_torrents(torrents)
|
||||||
|
elif "resume" in cmd:
|
||||||
|
resume_torrents(torrents)
|
||||||
|
elif "verify" in cmd:
|
||||||
|
verify_torrents(torrents)
|
||||||
|
else:
|
||||||
|
remove_torrents(torrents,delete_files="delete" in cmd)
|
||||||
|
|
||||||
|
ops = ["pause","resume","remove","removedelete","pauseall","resumeall","verify"]
|
||||||
|
opNames = ["paused","resumed","removed","removed and deleted","paused","resumed","queued for verification"]
|
||||||
|
opEmoji = ["⏸","▶️","❌","🗑","⏸","▶️","🩺"]
|
||||||
|
ops = {i:j for i,j in zip(ops,opNames)}
|
||||||
|
opEmoji = {i:j for i,j in zip(ops,opEmoji)}
|
||||||
|
await context.message.channel.send("{} Transfer{} {}".format(str(reaction.emoji),'s' if allOnly or len(torrents) > 1 else '', ops[cmd]))
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
await context.message.channel.send("❌ Cancelled!")
|
||||||
|
return
|
||||||
|
|
||||||
def check(reaction, user):
|
def check(reaction, user):
|
||||||
return user == context.message.author and str(reaction.emoji) in opEmoji
|
return user == context.message.author and str(reaction.emoji) in opEmoji
|
||||||
@ -1015,7 +1151,15 @@ async def modify(context, *, content=""):
|
|||||||
else:
|
else:
|
||||||
await context.message.channel.send("❌ Cancelled!")
|
await context.message.channel.send("❌ Cancelled!")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@client.command(name='compact', aliases=['c'], pass_context=True)
|
||||||
|
async def toggle_compact_out(context):
|
||||||
|
global COMPACT_OUTPUT
|
||||||
|
COMPACT_OUTPUT = not COMPACT_OUTPUT
|
||||||
|
outStr = ''
|
||||||
|
await context.message.channel.send('📱 Switched to mobile output' if COMPACT_OUTPUT else '🖥 Switched to desktop output')
|
||||||
|
return
|
||||||
|
|
||||||
@client.command(name='legend', pass_context=True)
|
@client.command(name='legend', pass_context=True)
|
||||||
async def legend(context):
|
async def legend(context):
|
||||||
embed = discord.Embed(title='Symbol legend', color=0xb51a00)
|
embed = discord.Embed(title='Symbol legend', color=0xb51a00)
|
||||||
@ -1023,7 +1167,7 @@ async def legend(context):
|
|||||||
embed.add_field(name="Error", value="✅—none\n⚠️—tracker warning\n🌐—tracker error\n🖥—local error", inline=True)
|
embed.add_field(name="Error", value="✅—none\n⚠️—tracker warning\n🌐—tracker error\n🖥—local error", inline=True)
|
||||||
embed.add_field(name="Metrics", value="⬇️—download rate\n⬆️—upload rate\n⏬—total downloaded\n⏫—total uploaded\n⚖️—seed ratio", inline=True)
|
embed.add_field(name="Metrics", value="⬇️—download rate\n⬆️—upload rate\n⏬—total downloaded\n⏫—total uploaded\n⚖️—seed ratio", inline=True)
|
||||||
embed.add_field(name="Activity", value="🐢—stalled\n🐇—active\n🚀—running (rate>0)", inline=True)
|
embed.add_field(name="Activity", value="🐢—stalled\n🐇—active\n🚀—running (rate>0)", inline=True)
|
||||||
embed.add_field(name="Tracker", value="🔒—private\n🔓—public", inline=True)
|
embed.add_field(name="Tracker", value="🔐—private\n🔓—public", inline=True)
|
||||||
embed.add_field(name="Modifications", value="⏸—pause\n▶️—resume\n❌—remove\n🗑—remove and delete\n🩺—verify", inline=True)
|
embed.add_field(name="Modifications", value="⏸—pause\n▶️—resume\n❌—remove\n🗑—remove and delete\n🩺—verify", inline=True)
|
||||||
await context.message.channel.send(embed=embed)
|
await context.message.channel.send(embed=embed)
|
||||||
if REPEAT_COMMAND:
|
if REPEAT_COMMAND:
|
||||||
@ -1067,6 +1211,7 @@ async def help(context, *, content=""):
|
|||||||
embed.add_field(name="List torrent transfers", value="*list current transfers with sorting, filtering, and search options*\n*ex.* `{0}list [OPTIONS]` or `{0}l [OPTIONS]`".format(BOT_PREFIX), inline=False)
|
embed.add_field(name="List torrent transfers", value="*list current transfers with sorting, filtering, and search options*\n*ex.* `{0}list [OPTIONS]` or `{0}l [OPTIONS]`".format(BOT_PREFIX), inline=False)
|
||||||
embed.add_field(name="Add new torrent transfers", value="*add one or more specified torrents by magnet link or url to torrent file*\n*ex.* `{0}add TORRENT ...` or `{0}a TORRENT ...`".format(BOT_PREFIX), inline=False)
|
embed.add_field(name="Add new torrent transfers", value="*add one or more specified torrents by magnet link or url to torrent file*\n*ex.* `{0}add TORRENT ...` or `{0}a TORRENT ...`".format(BOT_PREFIX), inline=False)
|
||||||
embed.add_field(name="Modify existing transfers", value="*pause, resume, remove, or remove and delete specified transfers*\n*ex.* `{0}modify [TORRENT]` or `{0}m [TORRENT]`".format(BOT_PREFIX), inline=False)
|
embed.add_field(name="Modify existing transfers", value="*pause, resume, remove, or remove and delete specified transfers*\n*ex.* `{0}modify [TORRENT]` or `{0}m [TORRENT]`".format(BOT_PREFIX), inline=False)
|
||||||
|
embed.add_field(name='Toggle output style', value='*toggle between desktop (default) and mobile (narrow) output style*\n*ex.* `{0}compact` or {0}c'.format(BOT_PREFIX), inline=False)
|
||||||
embed.add_field(name='Show legend', value='*prints legend showing the meaning of symbols used in the output of other commands*\n*ex.* `{0}legend`'.format(BOT_PREFIX), inline=False)
|
embed.add_field(name='Show legend', value='*prints legend showing the meaning of symbols used in the output of other commands*\n*ex.* `{0}legend`'.format(BOT_PREFIX), inline=False)
|
||||||
embed.add_field(name='Help - Gives this menu', value='*with optional details of specified command*\n*ex.* `{0}help` or `{0}help COMMAND`'.format(BOT_PREFIX), inline=False)
|
embed.add_field(name='Help - Gives this menu', value='*with optional details of specified command*\n*ex.* `{0}help` or `{0}help COMMAND`'.format(BOT_PREFIX), inline=False)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user