PORTDIR = "/usr/portage/"
LOGFILE = "/var/log/emerge.log"
-
-
green_start = "\033[32m"
color_stop = "\033[m"
+packages = []
+class package:
+ def __init__(self, name, version=0):
+ self.name = name
+ self.version = version
+ self.versions = []
+ self.emerge_time = 12*3600
+ def add_version(self, version, emerge_time, emerge_date):
-def organize_times(time):
- """Takes the emerge time in seconds, organizes it into
- days, hours, minutes or seconds and finally prints that out."""
-
- days = time/(3600*24)
- hours = (days - int(days))*24
- minutes = (hours - int(hours))*60
- seconds = (minutes - int(minutes))*60
-
- days = int(days)
- hours = int(hours)
- minutes = int(minutes)
- seconds = int(round(seconds))
-
- if days > 0:
- print_days = (green_start + str(days) + color_stop + " day")
- if days != 1:
- print_days += "s"
- print print_days,
-
- if hours > 0:
- print_hours = (green_start + str(hours) + color_stop + " hour")
- if hours != 1:
- print_hours += "s"
- print print_hours,
+ self.versions.append((version, emerge_time, emerge_date))
- if minutes > 0:
- print_minutes = (green_start + str(minutes) + color_stop + " minute")
- if minutes != 1:
- print_minutes += "s"
- print print_minutes,
- printable_sec = (green_start + str(seconds) + color_stop + " second")
- if seconds != 1:
- printable_sec += "s"
- print printable_sec,
+ def average_time(self):
+ total_time = 0
+ for i in self.versions:
+ total_time += i[1]
+ average_time = total_time/len(self.versions)
+ return average_time
-def get_date(emerge_start):
- """Take the emerge startup time in seconds and turn it into a
- correct date."""
+ def total_time(self):
+ total_time = 0
+ for i in self.versions:
+ total_time += i[1]
- date = datetime.datetime.fromtimestamp(emerge_start)
+ return total_time
- weekday = date.weekday()
- if weekday == 0: weekday = 'Mon '
- if weekday == 1: weekday = 'Tue '
- if weekday == 2: weekday = 'Wed '
- if weekday == 3: weekday = 'Thu '
- if weekday == 4: weekday = 'Fri '
- if weekday == 5: weekday = 'Sat '
- if weekday == 6: weekday = 'Sun '
+ def max_time(self):
+ self.versions.sort()
+ return self.versions[len(self.versions)-1][1]
- # This is in the format 'Mon 23.05.2011 00:20:14'
- date = weekday + "{:%d.%m.%Y %H:%M:%S}".format(date)
+ def min_time(self):
+ self.versions.sort()
- return date
+ return self.versions[0][1]
+ def print_current_emerge(self):
+ print("\t" + green_start + self.name + '-' + self.version +
+ color_stop + "\n\t current time: " + self.time(self.emerge_time) +
+ "\n\t average time: "),
-def get_package(name):
- """Take the user-input package name and search for it
- in PORTDIR. """
-
- dirlist = os.listdir(PORTDIR)
- possible_package = []
-
-
- # If the given name is in the format xxx/zzz
- # assume that xxx is the package group
- if '/' in name:
- group = name.partition('/')[0]
- pkg = name.partition('/')[2]
- directory = PORTDIR + group
-
- if group in dirlist:
- dirs = os.listdir(directory)
- if pkg in dirs:
- possible_package.append(name)
-
-
- # Go through the directory listing searching for anything
- # that matches the given name
- for i in dirlist:
- directory = PORTDIR + i
- if os.path.isdir(directory):
- dirs = os.listdir(directory)
- if name in dirs:
- possible_package.append(i + '/' + name)
-
-
- if len(possible_package) > 1:
- print("Multiple packages found for '" + name + "'.")
- print("Possible packages: ")
- for value in possible_package:
- print("\t" + value)
-
-
- elif len(possible_package) == 1:
- package = possible_package[0]
- return package
+ if len(self.versions) > 1:
+ print(self.time(self.average_time())),
+ else:
+ print("unknown"),
+ print("\n\t " + '-'*45),
- else:
- print("No package '" + name + "' found")
+ finish_time = self.average_time() - self.emerge_time
+ print("\n\t time to finish: "),
- sys.exit(1)
+ if finish_time > 0:
+ print(self.time(finish_time))
+ else:
+ print("any time now")
+
+
+ def print_versions(self):
+ for p in self.versions:
+ print('-'*90 + "\n" +
+ green_start + self.name + p[0] + color_stop + " >>> " +
+ self.time(p[1]) + " >>> " +
+ self.date(p[2]))
+ print('-'*90 + "\n" + "Package " + green_start +
+ self.name + color_stop + " emerged " +
+ str(len(self.versions)) + " times.")
+ print
+ def print_pretended_times(self):
+ print("\t" + green_start + self.name + '-' + self.version + color_stop),
+ if len(self.versions) > 1:
+ print("\n\taverage time: " + self.time(self.average_time()))
+ else:
+ print("\n\t no previous emerges")
-def print_times(package, times, silent):
- """Print the maximum/minimum/average times of the given emerge package.
- If we're in the 'current emerge stage' (the 'silent' flag is True)
- print the appropriate comment for that package."""
+ def print_min_max_ave(self):
+ maxi = self.max_time()
+ mini = self.min_time()
+ average = self.average_time()
+ total = self.total_time()
- times.sort()
- times.reverse()
+ print("Max time: \t" + self.time(maxi) +
+ "\nMin time: \t" + self.time(mini) +
+ "\nAverage time: \t" + self.time(average) +
+ "\nIn total spent " + self.time(total) +
+ " emerging " + green_start + self.name + color_stop)
+ def time(self, time):
- # This should be True if we're in current emerge stage
- if silent == True:
- if len(times) == 0:
- print("\t no previous emerges found for this package"),
- return 0
+ days = time/(3600*24)
+ hours = (days - int(days))*24
+ minutes = (hours - int(hours))*60
+ seconds = (minutes - int(minutes))*60
- elif len(times) == 1:
- print("\t previous emerge time:\t"),
- organize_times(times[0][0])
- print("(" + green_start + "1" + color_stop + ")"),
- return times[0][0]
+ days = int(days)
+ hours = int(hours)
+ minutes = int(minutes)
+ seconds = int(round(seconds))
- else:
- print("\t average emerge time:\t"),
- all_times = 0
- for i in times:
- all_times += i[0]
+ pdays = str()
+ phours = str()
+ pminutes = str()
+ pseconds = str()
- organize_times(all_times/len(times))
- print("(" + green_start + str(len(times)) + color_stop + ")"),
- return all_times/len(times)
+ if days > 0:
+ pdays = (green_start + str(days) +
+ color_stop + " day ")
+ if days != 1:
+ pdays = (green_start + str(days) +
+ color_stop + " days ")
+ if hours > 0:
+ phours = (green_start + str(hours) +
+ color_stop + " hour ")
+ if hours != 1:
+ phours = (green_start + str(hours) +
+ color_stop + " hours ")
- if len(times) == 1:
- print(green_start + package + color_stop + " emerged once")
+ if minutes > 0:
+ pminutes = (green_start + str(minutes) +
+ color_stop + " minute ")
+ if minutes != 1:
+ pminutes = (green_start + str(minutes) +
+ color_stop + " minutes ")
- elif len(times) > 1:
- print(green_start + package + color_stop + " emerged " + green_start +
- str(len(times)) + color_stop + " times\n")
+ pseconds = (green_start + str(seconds) +
+ color_stop + " second ")
+ if seconds != 1:
+ pseconds = (green_start + str(seconds) +
+ color_stop + " seconds ")
- print "Max time:\t",
- organize_times(times[0][0])
- print "at", times[0][1]
+ return (pdays + phours + pminutes + pseconds)
- print "Min time:\t",
- organize_times(times[len(times)-1][0])
- print "at", times[len(times)-1][1]
- all_times = 0
- for i in times:
- all_times += i[0]
+ def date(self, emerge_date):
+ date = datetime.datetime.fromtimestamp(emerge_date)
- print "Average time\t",
- organize_times(all_times/len(times))
- print
+ date = "{:%d.%m.%Y %H:%M:%S}".format(date)
- print "In total spent\t",
- organize_times(all_times)
- print("emerging " + green_start +
- package + color_stop)
+ return date
except IOError as detail:
print detail
sys.exit(1)
-
- return f
+ finally:
+ return f
-def list_emerge_processes(f):
- """Look for the ebuild process with ps. If the process is found parse
- the command for the package. With this package search the LOGFILE for
- the emerge startup time."""
+def search_log_for_package(package_class):
- now = datetime.datetime.today()
- packages = []
+ log = open_log()
- for i in os.popen("ps ax"):
- if (("ebuild.sh" in i) and ("/bin/bash" not in i)):
- pack = i.partition('[')[2].partition(']')[0]
-
- version = pack.partition('/')[2].partition('-')[2]
-
- while not version[0].isdigit():
- version = version.partition('-')[2]
-
- package_name = pack[:-len(version)-1]
-
- packages.append([package_name, '-'+version, 12*3600])
-
-
- for line in f:
+ for line in log:
if ((">>>" in line) and ("emerge" in line)):
- for p in packages:
- if (p[0]+p[1] in line):
+ if package_class.name in line:
+ version = line.partition(package_class.name)[2].partition(' ')[0]
+ digit = version.strip('-')[0].isdigit()
- time = float(line.partition(' ')[0].strip(":"))
+ if digit:
+ time_string = line.partition(">>>")
+ start_time = float(time_string[0].strip().strip(':'))
- timestamp = datetime.datetime.fromtimestamp(time)
- difference = (now - timestamp).total_seconds()
+ elif ((":::" in line) and ("completed emerge" in line)):
+ if package_class.name in line:
+ if digit:
+ time_string = line.partition(":::")
+ stop_time = float(time_string[0].strip().strip(':'))
- if difference < p[2]:
- p[2] = difference
+ emerge_time = stop_time - start_time
+ package_class.add_version(version, emerge_time, start_time)
- if len(packages) == 0:
- print "No current emerge process found."
- return
- print_current_emerges(f, packages)
+def get_package(name):
+ """Take the user-input package name and search for it
+ in PORTDIR. """
+ dirlist = os.listdir(PORTDIR)
+ possible_package = []
+ # If the given name is in the format xxx/zzz
+ # assume that xxx is the package group
+ if '/' in name:
+ group = name.partition('/')[0]
+ pkg = name.partition('/')[2]
+ directory = PORTDIR + group
-def print_current_emerges(f, packages):
- """Print the current packages that are being merged with the
- current emerge time."""
+ if group in dirlist:
+ dirs = os.listdir(directory)
+ if pkg in dirs:
+ possible_package.append(name)
- print("Currently emerging: ")
+ # Go through the directory listing searching for anything
+ # that matches the given name
+ for i in dirlist:
+ directory = PORTDIR + i
+ if os.path.isdir(directory):
+ dirs = os.listdir(directory)
+ if name in dirs:
+ possible_package.append(i + '/' + name)
- for p in packages:
- print("\t" + green_start + p[0] + p[1] + color_stop),
- print("\n\t current emerge time:\t"),
- organize_times(p[2])
- print
+ if len(possible_package) > 1:
+ print("Multiple packages found for '" + name + "'.")
+ print("Possible packages: ")
+ for value in possible_package:
+ print("\t" + value)
- average_time = main_loop(f, p[0], True)
- if average_time != 0:
- print("\n\t " + '-'*45 + "\n\t time to finish: \t"),
+ elif len(possible_package) == 1:
+ package = possible_package[0]
+ return package
- if (average_time - p[2]) < 0:
- print(green_start + "Any time now" + color_stop),
- else:
- organize_times(average_time - p[2])
+ else:
+ print("No package '" + name + "' found")
- print "\n"
+ sys.exit(1)
-def list_pretended(f):
- """Print the average times of pretended packages"""
+def list_pretended():
+ log = open_log()
- packages = []
for line in sys.stdin:
if "[ebuild" in line:
- full_name = line.partition('] ')[2].partition(' ')[0]
+ full_name = line.partition("] ")[2].partition(' ')[0]
version = full_name.partition('/')[2].partition('-')[2]
while not version[0].isdigit():
version = version.partition('-')[2]
-
package_name = full_name[:-len(version)-1]
- packages.append((package_name, '-' + version))
-
-
- if len(packages) == 0:
- return
+ packages.append(package(package_name, version))
- print "This is how long these packages would take to emerge"
- all_time = 0
- for pack in packages:
+def list_emerge_processes():
+ """Look for the ebuild process with ps. If the process is found parse
+ the command for the package. With this package search the LOGFILE for
+ the emerge startup time."""
- print('\t' + green_start + pack[0] + pack[1] + color_stop)
+ f = open_log()
- all_time += main_loop(f, pack[0], True)
+ now = datetime.datetime.today()
- print "\n"
+ for i in os.popen("ps ax"):
+ if (("ebuild.sh" in i) and ("/bin/bash" not in i)):
+ pack = i.partition('[')[2].partition(']')[0]
+ version = pack.partition('/')[2].partition('-')[2]
- if len(packages) > 1:
- print("Total emerge time of " + green_start + str(len(packages)) +
- color_stop + " packages:"),
- organize_times(all_time)
+ while not version[0].isdigit():
+ version = version.partition('-')[2]
+ package_name = pack[:-len(version)-1]
+ packages.append(package(package_name, version))
-def main_loop(f, package, silent):
- """The main loop which parses the LOGFILE and if needed prints out emerge times."""
+ if len(packages) == 0:
+ print "No current emerge process found."
+ sys.exit(0)
- f.seek(0) # Seek to the beginning of the file
- times = []
- # MAIN LOOP
for line in f:
if ((">>>" in line) and ("emerge" in line)):
- if package in line:
- version = line.partition(package)[2].partition(' ')[0]
-
- if version.strip('-')[0].isdigit():
- full_package = package + version
-
- time_string = line.partition(">>>")
- start_time = float(time_string[0].strip().strip(':'))
-
-
- elif ((":::" in line) and ("completed emerge" in line)):
- if package in line:
- if version.strip('-')[0].isdigit():
-
- time_string = line.partition(":::")
- end_time = float(time_string[0].strip().strip(':'))
-
+ for p in packages:
+ if (p.name + '-' + p.version in line):
- emerge_time = end_time - start_time
+ time = float(line.partition(' ')[0].strip(":"))
- date = get_date(start_time)
+ timestamp = datetime.datetime.fromtimestamp(time)
+ difference = (now - timestamp).total_seconds()
+ if difference < p.emerge_time:
+ p.emerge_time = difference
- if silent == False:
- print(str(len(times)+1) + ". " +
- green_start + full_package + color_stop +
- " >>> " + date + " >>> "),
- organize_times(emerge_time)
- print("\n" + '-'*90)
- times.append((emerge_time, date))
+def main(status, user_package=None):
+ if status == "package":
+ user_package = get_package(user_package)
- average_time = print_times(package, times, silent)
- return average_time
+ pack = package(user_package)
+ search_log_for_package(pack)
+ pack.print_versions()
+ pack.print_min_max_ave()
-def main(status):
- """Change between current emerge stage and normal operating stage."""
+ elif status == "current":
+ list_emerge_processes()
- f = open_log()
+ print "Currently emerging:"
- if status == 'current':
- list_emerge_processes(f)
- return
- elif status == 'pretended':
- list_pretended(f)
- return
- else:
- pass
+ for p in packages:
+ search_log_for_package(p)
+ p.print_current_emerge()
- package = get_package(package_name)
- print('-'*90)
+ elif status == "pretended":
+ list_pretended()
- main_loop(f, package, False)
+ print "This is how long these packages would take to emerge"
- f.close()
+ for p in packages:
+ search_log_for_package(p)
+ p.print_pretended_times()
+ print
def usage():
\t--no-color \t Use colorless output"""
-
print usage
sys.exit(0)
if __name__ == "__main__":
mode = str()
+ input_package = None
for arg in sys.argv[1:]:
if arg == "-p" or arg == "--pretended":
mode = "pretended"
- if arg == "-h" or arg == "--help":
- usage()
-
if arg == "-c" or arg == "--current":
mode = "current"
- if arg == "--no-color":
- green_start = ''
- color_stop = ''
+ if arg == "-h" or arg == "--help":
+ usage()
if len(sys.argv) > 1:
- package_name = sys.argv[1]
+ mode = "package"
+ input_package = sys.argv[1]
else:
usage()
-
- main(mode)
- sys.exit(0)
-
-
+ main(mode, input_package)