From 6f885ea19e9ab618eca1e1c868636e3045697cbb Mon Sep 17 00:00:00 2001 From: ville rantanen Date: Sat, 9 Nov 2013 12:01:22 +0200 Subject: [PATCH] Download speed estim. --- aerofs/aerofs-clean | 4 +- aerofs/aerofs-transfers | 95 +++++++++++++++++++++++++++++++---------- 2 files changed, 74 insertions(+), 25 deletions(-) diff --git a/aerofs/aerofs-clean b/aerofs/aerofs-clean index ee892f2..7f46356 100755 --- a/aerofs/aerofs-clean +++ b/aerofs/aerofs-clean @@ -10,7 +10,7 @@ function cacheusage { } if [ -z "$1" ] -then echo partial/revisions/conflicts: '(-f to delete all. -p/-r to delete +3 days)' +then echo partial/revisions/conflicts: '(-f to delete all. -p/-r to delete +1/+3 days)' cacheusage exit 0 fi @@ -25,7 +25,7 @@ do case ${OPTS} in find "$AEROAUX/r" -mindepth 1 -type f -mtime +3 -exec rm -Rf \{\} \; ;; p) - find "$AEROAUX/p" -mindepth 1 -type f -mtime +3 -exec rm -Rf \{\} \; + find "$AEROAUX/p" -mindepth 1 -type f -mtime +1 -exec rm -Rf \{\} \; ;; esac diff --git a/aerofs/aerofs-transfers b/aerofs/aerofs-transfers index 17aedeb..d5d7037 100755 --- a/aerofs/aerofs-transfers +++ b/aerofs/aerofs-transfers @@ -1,9 +1,9 @@ #!/usr/bin/env python -import sys,os +import sys,os,glob from datetime import datetime from datetime import timedelta - +import sqlite3 import re,signal import subprocess,threading @@ -51,18 +51,14 @@ You can tap in to an existing log with: return options def c(attribs): ''' ANSI colorizer ''' + if not options.colors: + return "" return '\033['+';'.join(attribs)+'m' def pos(y,x): ''' ANSI absolute position set ''' return "\033["+str(y)+";"+str(x)+"H" -color_match={#'line_ends':(re.compile('$'),c.END), - 'err':(re.compile('(Failed)'),c([R,S])+'\\1'+c([E])), - 'done':(re.compile('(Done)'),c([G,S])+'\\1'+c([E])), - 'percent':(re.compile('([0-9]+%)'),c([Y,S])+'\\1'+c([E])), -} - def colorize(string): ''' colorizes a string based on color_match ''' @@ -143,7 +139,9 @@ def print_stats(stats): e=5 else: e=0 - sys.stdout.write(pos(e+1,0)+"="*10+"AeroFS Transfers"+"="*10+" "+human_time()+CLRLN) + sys.stdout.write(pos(e+1,0)+c((S,C))+"=AeroFS Transfers"+"= "+c((E))+human_time()+ + " DL: "+c((S,Y))+human_size(stats['pspeed'],0)+"/s "+c((E))+ + "Cache: "+human_size(stats['psize'][4][0])+CLRLN) if (stats['running']): sys.stdout.write(pos(e+2,0)+"Last update: "+stats['running'][0][0]+CLRLN) else: @@ -179,10 +177,20 @@ def print_activities(activities): activities.join() return activities - def human_time(): - t=datetime.now().strftime("%I:%M:%S %p") - return t + return datetime.now().strftime("%I:%M:%S %p") + +def human_size(size,precision=1): + if size==None: + return 'nan' + suffixes=['B','KB','MB','GB','TB'] + suffixIndex = 0 + defPrecision=0 + while size > 1024: + suffixIndex += 1 + size = size/1024.0 + defPrecision=precision + return "%.*f%s"%(defPrecision,size,suffixes[suffixIndex]) def readinput(lf): try: @@ -196,6 +204,41 @@ def termsize(): rows, columns = os.popen('stty size', 'r').read().split() return (int(rows),int(columns)) +def get_partial_dir(): + sql_file=os.path.join(os.path.expanduser("~"), + ".aerofs", "conf") + conn=sqlite3.connect(sql_file) + db=conn.cursor() + conn.text_factory=str + db.execute("SELECT v FROM c WHERE k = 'root'") + for row in db: + continue + conn.close() + cache_dir=glob.glob(os.path.join(os.path.dirname(row[0]),'.aerofs.aux*')) + return os.path.join(cache_dir[0],'p') + +def get_partial_size(dir): + return sum([os.path.getsize(os.path.join(dir,f)) for f in os.listdir(dir) if os.path.isfile(os.path.join(dir,f))]) + +def partial_update(stats): + ''' Calculate average speed of transfer ''' + stats['psize'].pop(0) + stats['psize'].append( ( get_partial_size(stats['pdir']), datetime.now()) ) + speedlist=[] + for i in range(len(stats['psize'])-1): + sizediff=stats['psize'][i+1][0] - stats['psize'][i][0] + timediff=(stats['psize'][i+1][1] - stats['psize'][i][1]).total_seconds() + if timediff>0 and sizediff>0: + speedlist.append( sizediff / timediff ) + if len(speedlist)==0: + speed=0.0 + else: + speed=sum(speedlist)/len(speedlist) + + stats['pspeed']=speed + + return stats + class Threaded(threading.Thread): def __init__(self,command): self.stdout = None @@ -227,10 +270,20 @@ class Threaded(threading.Thread): options=setup_options() +color_match={#'line_ends':(re.compile('$'),c.END), + 'err':(re.compile('(Failed)'),c([R,S])+'\\1'+c([E])), + 'done':(re.compile('(Done)'),c([G,S])+'\\1'+c([E])), + 'percent':(re.compile('([0-9]+%)'),c([Y,S])+'\\1'+c([E])), +} + stats={'time':datetime.now()-timedelta(seconds=25), 'running':[], 'files':[], - 'size': termsize()} + 'size': termsize(), + 'pdir': get_partial_dir(), + 'psize': [( get_partial_size(get_partial_dir()), datetime.now())]*5, + 'pspeed': 0.0 + } sys.stdout.write(CLR+pos(0,0)+"Launching...") #proc = subprocess.Popen(['aerofs-sh','transfers'],stdout=subprocess.PIPE) @@ -239,31 +292,27 @@ transfers.start() for e in range(5): sys.stdout.write(pos(e+1,0)+CLRLN) -activities = print_activities(None) +activities = print_activities(None) + while 1: try: sys.stdout.flush() - # set a 3 second timeout for the line read. + # set a 5 second timeout for the line read. signal.signal(signal.SIGALRM, transfers.readline) - signal.alarm(3) + signal.alarm(5) line=transfers.readline() if not line: raise EndProgram if ( datetime.now() - stats['time'] > timedelta(seconds=30) ) and options.activities: activities=print_activities(activities) + stats=partial_update(stats) stats['time'] = datetime.now() stats=remove_running(stats) stats=count_running(line,stats) - # timeout returns a special string, in this case we re-read - if line=="CleanerTimeout": - print_stats(stats) - continue - # if line empty, read next - if line.strip()=="": - continue + print_stats(stats) except EndProgram,KeyboardInterrupt: