I am currently generating a python-script with the fabric framwork that is supposed to collect a backup from a remote server and store it locally on the client running fabric.
Now, since the backup file is >400MB, it takes quite some time to transfer it. And here is where my question bumps in:
Is there any kind of progressbars for the fabric get()-function? Or rather, is it possible to add a progressbar somehow?
Here's a piece of my code:
def collect_backup():
env.warn_only=True
run('uptime')
print "Copying scrips to be run..."
filename, remotepath = _getlatest()
print "Copy complete."
print "Collecting backup..."
localpath = _collect(filename, remotepath)
def _collect(filename, remotepath):
a=remotepath + filename
localpath="/home/bcns/backups/"
####Here's the get() I was talking about
get(a, localpath)
return(localpath)
The "filename" and "remotepath" variables are set in another function.
There is a lot of great info at the following site:
http://thelivingpearl.com/2012/12/31/creating-progress-bars-with-python/
Here is their solution for a console prog bar with threading:
import sys
import time
import threading
class progress_bar_loading(threading.Thread):
def run(self):
global stop
global kill
print 'Loading.... ',
sys.stdout.flush()
i = 0
while stop != True:
if (i%4) == 0:
sys.stdout.write('\b/')
elif (i%4) == 1:
sys.stdout.write('\b-')
elif (i%4) == 2:
sys.stdout.write('\b\\')
elif (i%4) == 3:
sys.stdout.write('\b|')
sys.stdout.flush()
time.sleep(0.2)
i+=1
if kill == True:
print '\b\b\b\b ABORT!',
else:
print '\b\b done!',
kill = False
stop = False
p = progress_bar_loading()
p.start()
try:
#anything you want to run.
time.sleep(1)
stop = True
except KeyboardInterrupt or EOFError:
kill = True
stop = True
Hope that helps or at least gets you started.
Related
I have a program which has to run a 'watcher' function in the background, which checks if the time specified on an 'alarm' object equals to the current time, and if so, it triggers the alarm. This is the function:
def watcher(this):
while this.run:
this.lock.acquire(True)
for i , a in enumerate(this.alarms):
if a.activate:
if a.repeat:
if a.dateTime.minute + (a.dateTime.hour*60) == datetime.datetime.now().minute + (datetime.datetime.now().hour*60):
this.trigger(i)
while True:
if keyboard.is_pressed('a'):
this.stop()
break
elif a.dateTime.date() == datetime.datetime.now().date() and a.dateTime.minute + a.dateTime.hour*60 == datetime.datetime.now().minute + datetime.datetime.now().hour*60:
this.trigger(i)
while True:
if keyboard.is_pressed('a'):
this.stop()
break
this.lock.release()
The lock object is created previously inside the class this function is in.
It works when i run it on a program where i set the alarms beforehand, but when i have to run another program alongside it that manipules the alarms, the other program hangs and only this one runs.
Here part of the main program:
import alarms
import datetime
import manager
import threading
import keyboard
lock = threading.Lock()
mngr = manager.manager()
print("Program Test")
tr = threading.Thread(target = mngr.watcher)
tr.start()
while True:
command = input()
if len(command) == 0:
print('')
elif command.split()[0] == "rem":
lock.acquire(True)
try:
mngr.remove_alarm(int(command.split()[1]) - 1)
except IndexError as excp:
print('Invalid alarm number. Use the command "list" to get alarms')
except Exception as excp:
print('Wrong usage of command: use like this: rem {alarmNumber}')
print('DEBUG: ' + str(excp))
finally:
lock.release()
Am i doing the synchronization wrong? Upon even instancing the Thread on the main program it halts execution.
I'm trying to design a control interface for my system which sends and receives some data through serial link. My searches related to GUI design took me to understand the "multi-threading" issue and code below shows the latest position I arrived.
This indicates similar parts (e.g try, run) with the ones I've seen on example GUIs. I planned to convert this to a GUI, once I understand how it exactly works.
So the problem is after I start, stop the code below I can't restart it again. Because, as I understand, multi-threading features only one cycle: start, stop and quit. I mean it doesn't accept start command after stop.
My question is how I can make this code to accept start after stopping?
Best wishes
import threading, random, time
class process(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
self.leave = 0
print("\n it's running ...\n\n")
while self.leave != 1:
print "Done!"
time.sleep(1)
operate = process()
while True:
inputt = input(" START : 1 \n STOP\t : 0 \n QUIT\t : 2 \n")
try:
if int(inputt) == 1:
operate.start()
elif int(inputt) == 0:
operate.leave = 1
elif int(inputt) == 2:
break
except:
print(" Wrong input, try egain...\n")
Create process inside while True loop
if int(inputt) == 1:
operate = process()
operate.start()
It should work.
... but your code may need other changes to make it safer - you will have to check if process exists before you try to stop it. You could use operate = None to control it.
import threading
import random
import time
class Process(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
self.leave = False
print("\n it's running ...\n\n")
while self.leave == False:
print("Done!")
time.sleep(1)
operate = None
while True:
inputt = input(" START : 1 \n STOP\t : 0 \n QUIT\t : 2 \n")
try:
if int(inputt) == 1:
if operate is None:
operate = Process()
operate.start()
elif int(inputt) == 0:
if operate is not None:
operate.leave = True
operate.join() # wait on process end
operate = None
elif int(inputt) == 2:
if operate is not None:
operate.leave = True
operate.join() # wait on process end
break
except:
print(" Wrong input, try egain...\n")
Other method is not to leave run() when you set leave = True but keep running thead. You would need two loops.
def run(self):
self.leave = False
self.stoped = False
print("\n it's running ...\n\n")
while self.leave == False:
while self.stoped == False:
print("Done!")
time.sleep(1)
I try to make a simple game, give a sum random number and input to answer it, I try to limit the time for input, but I can stop the input processing when timeout.
score=0
from threading import Timer
while score<=3:
import random
a=random.randint(0,100)
b=random.randint(0,100)
sum=a+b
d=str(sum)
while True:
print(a,"+",b,"=")
timeout = 3
t = Timer(timeout, print, ['Sorry, times up'])
t.start()
prompt = "you have %d s to input your answer\n" % timeout
c = input(prompt)
t.cancel()
#i want to stop input c and make other code like 'do you want to play again'
if c.isdigit():
break
else:
print('invalid input')
continue
result=c
if result==d:
score=score+1
print('your score',score)
else:
score=score-1
print('your score',score)
else:
print('you win')
Similar question has been answered before here.
I have tested it before and the following codes work in my Ubuntu. I'm not sure if this works in Windows too.
import sys
from select import select
timeout = 5
print "What is your name?"
# Assignment to three different variables based on select() paramenters
# rlist: wait until ready for reading
# wlist: wait until ready for writing
# xlist: wait for an "exceptional condition"
rlist, _, _ = select([sys.stdin], [], [], timeout)
if rlist:
s = sys.stdin.readline()
print "Your name is: %s" %(s)
else:
print "Timeout!! Try again."
Hope this helps.
This works also for me (Debian)
import sys, termios, signal
from _thread import interrupt_main
while True:
timeout = 3
signal.signal(signal.SIGALRM, lambda x,y: interrupt_main())
signal.alarm(3)
try:
c = input("Number? ")
except:
termios.tcflush(sys.stdin, termios.TCIOFLUSH)
answer = input('\nContinue? ')
if (len(answer) == 0) or (answer.lower()[0] != 'y'):
break
signal.alarm(0)
If you are using Windows you could try using interrupt_main as handler for Timer
t = Timer(timeout, interrupt_main)
This approach does not fully work for me. In my linux box the signal handler is able to interrupt the input() call but the timer handler, however, not. Only if you press Enter, the program flow follows to the "Continue" question
How can I run a timer while asking for user input from the console? I was reading about multiprocessing, and I tried to use this answer: Python: Executing multiple functions simultaneously. When I tried to get it going, it gave me a bunch of framework errors.
Right now it runs start_timer(), but then stops it when it runs cut_wire().
Here's my start_timer function:
def start_timer():
global timer
timer = 10
while timer > 0:
time.sleep(1)
timer -= 1
sys.stdout.write ("There's only %i seconds left. Good luck. \r" % (timer))
sys.stdout.flush()
cut_wire()
if timer == 0:
print("Boom!")
sys.exit()
and this is the cut_wire function:
def cut_wire():
wire_choice = raw_input("\n> ")
if wire_choice == "cut wire" or wire_choice == "Cut Wire":
stop_timer()
else:
print("Boom!")
sys.exit()
Of course it stops running when it plays the cut_wire function because "raw_input" command reads the text and wait for the user to put the text and press enter.
My suggestion is to check for they key press "Enter" and when then key was press, read the line. If the key wasn't press, just continue with your timer.
Regards.
Instead of using raw_input() use this function taken from here.
def readInput( caption, timeout = 1):
start_time = time.time()
sys.stdout.write('\n%s:'%(caption));
input = ''
while True:
if msvcrt.kbhit():
chr = msvcrt.getche()
if ord(chr) == 13: # enter_key
break
elif ord(chr) >= 32: #space_char
input += chr
if len(input) == 0 and (time.time() - start_time) > timeout:
break
print '' # needed to move to next line
if len(input) > 0:
return input
else:
return ""
Thearding option
To make sure that both functions run completely simultaneously you can use this example of threading event:
import threading
event = threading.Event()
th = theading.Thread(target=start_timer, args=(event, ))
th1 = theading.Thread(target=cut_wire, args=(event, ))
th.start()
th1.start()
th.join()
th1.join()
In your function you can set an event using event.set(), check it using event.is_set() and clear it using event.clear().
Only addressing your concerns, here is a quick fix using threading :
import time
import sys
import os
def start_timer():
global timer
timer = 10
while timer > 0:
time.sleep(1)
timer -= 1
sys.stdout.write ("There's only %i seconds left. Good luck. \r" % (timer))
sys.stdout.flush()
#cut_wire() ==> separate call is easier to handle
if timer == 0:
print("Boom!")
os._exit(0) #sys.exit() only exits thread
def cut_wire():
wire_choice = raw_input("\n> ")
if wire_choice == "cut wire" or wire_choice == "Cut Wire":
stop_timer()
else:
print("Boom!")
os._exit(0) #same reason
if __name__ == '__main__':
import threading
looper = threading.Thread(target=start_timer)
looper.start()
cut_wire()
I'm creating part of a program right now for a personal project and I need some help on one aspect of it.
Here is how the program works:
User enters the amount of time to run
User enters the text - Files are modified
Timer is started
optional User can enter "password" to interrupt the timer
Actions are reversed
I have all of the steps coded except the Timer because I'm trying to figure out the best way to do this. Ideally, I'd like the timer to be displaying a countdown, and if the user enters a certain "password" the timer is interrupted and it skips to step number 5.
Would the best way to do this be with a thread? I haven't worked much with threads in the past. I just need someway for the timer to be displayed while also giving control back to the user in case they want to enter that password.
Thanks for any help you provide.
Here's the code:
import time
import urllib
import sys
def restore():
backup = open(r'...backupfile.txt','r')
text = open(r'...file.txt', 'w+')
text.seek(0)
for line in backup:
text.write(line)
backup.close()
text.close()
text = open(r'...file.txt', 'a+')
backup = open(r'...backupfile.txt','w+')
text.seek(0)
for line in text:
backup.write(line)
backup.close()
while True:
url = raw_input('Please enter a URL: ')
try:
if url[:7] != 'http://':
urllib.urlopen('http://' + url)
else:
urllib.urlopen(url)
except IOError:
print "Not a real URL"
continue
text.write(url)
while True:
choice = raw_input('Would you like to enter another url? (y/n): ')
try:
if choice == 'y' or choice == 'n':
break
except:
continue
if choice == 'y':
text.seek(2)
continue
elif choice == 'n':
while True:
choice = raw_input('Would you to restore your file to the original backup (y/n): ')
try:
if choice == 'y' or choice == 'n':
break
except:
continue
if choice == 'y':
text.close()
restore()
sys.exit('Your file has been restored')
else:
text.close()
sys.exit('Your file has been modified')
As you can see, I haven't added the timing part yet. It's pretty straight forward, just adding urls to a text file and then closing them. If the user wants the original file, reverse() is called.
Under Windows you can use msvcrt to ask for a key. Asking for a password is actually more complex, because you have to track several keys. This program stops with F1.
import time
import msvcrt
from threading import Thread
import threading
class worker(Thread):
def __init__(self,maxsec):
self._maxsec = maxsec
Thread.__init__(self)
self._stop = threading.Event()
def run(self):
i = 1
start = time.time()
while not self.stopped():
t = time.time()
dif = t-start
time.sleep(1) # you want to take this out later (implement progressbar)
# print something once in a while
if i%2==0: print '.',
#check key pressed
if msvcrt.kbhit():
if ord(msvcrt.getch()) == 59:
self.stop()
#do stuff
# timeout
if dif > self._maxsec:
break
i+=1
def stop(self):
print 'thread stopped'
self._stop.set()
def stopped(self):
return self._stop.isSet()
print 'number of seconds to run '
timeToRun = raw_input()
#input files
#not implemented
#run
w = worker(timeToRun)
w.run()
#reverse actions