Forum Archive

print: replace previous line

lukaskollmer

I'm writing a script to backup all files in the ~/Documents folder to S3.

Since the upload takes about 20 seconds, I'd like to display the current progress in the console.
Currently I print a new line every time the progress changes.
How can I replace the previous line when printing a new progress update?

I've seen some other scripts to this (eg: stash's wget), but for some reason I can't get it to work in my script.

Phuket2

@lukaskollmer , maybe not exactly what you are looking for. But have you looked at the ActivityIndicator

lukaskollmer

@Phuket2 Do you mean the ActivityIndicator in the ui module?
Yes I have, but I'd prefer this script not to have a GUI.

Phuket2

@lukaskollmer , ok. But you don't need a ui to call it. Maybe you mean Cross platform. But ActivityIndicator, works in the console

lukaskollmer

@Phuket2 Do you mean the activity indicator in the status bar? The problem with that one is that it can't show progress.

Phuket2

@lukaskollmer , sorry, I have mixed things up here in my mind. I feel sure there is a simple way to do it. I just did a few tests, I can't remember what I have done in the past.
I will still have a look. But someone with more experience will come along with the answer I am sure

dgelessus

In the Pythonista console this is basically impossible - the best you can do is clear the console every time before writing out the progress. In a normal terminal you would use \b or \r to go back one character or to the beginning of a line, but the Pythonista console doesn't understand that. stash uses a custom view to display text in and has more advanced terminal-like features, such as updating the current line. But before that was implemented scripts like wget would also write out a new line for each status update. Of course that takes up more space, but it didn't bother me much.

Phuket2

@lukaskollmer , sorry to screw you around. It's one of those normal days where I think I know everything and much to my suprise, I know nothing 😱

JonB

here is an approach that replaces the previously printed line, using objc.

https://github.com/jsbain/objc_hacks/blob/master/reprint_line.py

The text attributes get lost for some reason. it would be possible to get the previous attributes and apply after replacing the characters.... this works, but might be a tad ugly.

lukaskollmer

@JonB I'm trying right now, there is a - (NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range; method on NSTextStorage, but objc_util can't call it.

I don't know why, but the attributesAtIndex:effectiveRange: method seems to be unavailable on OMTextStorage

I'll see if I can get the attributes some other way (NSTextStorage inherits from NSAttributedString)

JonB

That method exists on the underlying text(). You may need to call use argtypes and restype kwargs, since one of the argument encodings is a pointer to an NSRange, and objc_utils does not always handle those nicely.

I don't know that much about attributedStrings,but it would seem like it should be able to insert characters into the middle of an attributedString without having to copy over the attributes...

khilnani

@lukaskollmer Slightly off topic, but did you finish your S3 Backup script? I needed one too and couldn't find one so wrote one - https://github.com/khilnani/s3sync.py

lukaskollmer

@khilnani yes. You can find it here. I commented out two lines that use the reprint line script from @JonB if you have it installed as well, just uncomment the import and the second print line in the upload progress function

khilnani

Thanks, will take a look!!