Closed GAS85 closed 1 month ago
Yes, you can't enter the with
context directly on the callback
, since that will create another alive-progress
bar each time a new update is received. And, unfortunately, it seems you do not have the total
beforehand. It would be much simpler to create the bar within the for message
, before calling client.download_media
...
In that case, you have to keep the alive-progress
context alive, which you can do with a generator. And, you also need a way to keep the bar
object, which you can do with a closure.
I think something like this could work:
def bar_gen(total):
with alive_bar(total) as bar:
yield bar
def callback_gen():
progress, bar = None, None
def callback(current, total):
nonlocal progress, bar
if bar is None:
progress = bar_gen(total)
bar = next(progress)
bar(current)
return callback
Then, in your code:
from alive_progress import alive_bar
from alive_progress import config_handler
config_handler.set_global(unit='B', scale='SI', precision=1, stats=False, elapsed=False)
client = TelegramClient('session_name', api_id, api_hash)
def downloader():
client.start()
for message in client.iter_messages(search_channel, search=search_line_update(search_hashtag, search_serie_number)):
print(message.id, message.text, '\n\n###\n')
callback = callback_gen()
client.download_media(message, file=download_location, progress_callback=callback)
That should work.
Cool, now it works, but running our of values :facepalm:. I do not know why it is taking total
as correct, but current progress is calculated in a wrong way...
I made some additional output to troubleshoot and seems it makes sum of previous current
and actual value, so it "explodes". It shown as "on" value.
def callback_gen():
progress, bar = None, None
def callback(current, total):
nonlocal progress, bar
if bar is None:
progress = bar_gen(total)
bar = next(progress)
bar(current)
print('Downloaded', current, 'out of', total,
'bytes: {:.2%}'.format(current / total), end='\r')
on 262144: Downloaded 262144 out of 474950838 bytes: 0.06%
on 786432: Downloaded 524288 out of 474950838 bytes: 0.11%
on 1572864: Downloaded 786432 out of 474950838 bytes: 0.17%
on 2621440: Downloaded 1048576 out of 474950838 bytes: 0.22%
on 3932160: Downloaded 1310720 out of 474950838 bytes: 0.28%
on 5505024: Downloaded 1572864 out of 474950838 bytes: 0.33%
on 7340032: Downloaded 1835008 out of 474950838 bytes: 0.39%
on 9437184: Downloaded 2097152 out of 474950838 bytes: 0.44%
on 11796480: Downloaded 2359296 out of 474950838 bytes: 0.50%
Ahh yes, my mistake. We should take the difference of the previous value. And, I now made the bar correctly shut down, stopping its internal thread. Here it is:
def callback_gen():
progress, bar = None, None
def callback(current, total):
nonlocal progress, bar
if bar is None:
progress = bar_gen(total)
bar = next(progress)
bar(current - bar.current)
if current == total:
del progress
return callback
Wow, this works perfect, thanks! I'm only since Monday in python and it seems a lot of fun here :smile:
Hey, I was thinking how to implement this bar inside of callbacks within Telethon and didn't find a good way. The issue: There is a Method download_media with
progress_callback
exist that is designed to callback function accepting two parameters: (received bytes, total). So I can implement progress like this:it will looks like this in one line only:
But how to do it with alive_bar? I tried:
But this sill spam my console:
and I need to disable
stats
andelapsed
as those values will show some false data. Any idea how to proceed with this callback?