#!/usr/bin/python
-import sys, subprocess, datetime, os
+import sys, subprocess, datetime, os, re
PORTDIR = "/usr/portage/"
LOGFILE = "/var/log/emerge.log"
-
-emerge_number = 0
-times = []
-
-
green_start = "\033[32m"
color_stop = "\033[m"
+packages = []
-def write_times(emerge_times_list):
- """Writes the emerge times into a file called 'times'."""
-
- with open('times', 'w') as g:
-
- for i in emerge_times_list:
- line = str(i[0]) + " " + str(i[1]) + "\n"
- g.write(line)
-
- g.close()
-
-
-
-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,
-
- 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 get_date(emerge_start):
- """Take the emerge startup time in seconds and turn it into a
- correct date."""
-
- date = datetime.datetime.fromtimestamp(emerge_start)
-
- year = str(date.year)
- month = str(date.month)
- day = str(date.day)
- 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 '
-
- hour = str(date.hour)
- minute = str(date.minute)
- second = str(date.second)
-
- # This is in the format 'Mon 23.05.2011 00:20:14'
-
- date = weekday + "{:%d.%m.%Y %H:%M:%S}".format(date)
-
- return date
-
-
+class package:
+ def __init__(self, name):
+ self.name = name
-def list_all_packages():
- """Go through PORTDIR and create a list of all the packages in portage"""
+ self.versions = []
- root = os.listdir(PORTDIR)
- all_packages = []
+ def add_version(self, version, emerge_time, emerge_date):
- for package_group in root:
- group_dir = PORTDIR + package_group
- if (os.path.isdir(group_dir)
- and (package_group != "licenses")
- and (package_group != "metadata")):
+ self.versions.append((version, emerge_time, emerge_date))
- name_dir = os.listdir(group_dir)
- for package_name in name_dir:
- if ".xml" not in package_name:
+ def print_versions(self):
+ for p in self.versions:
+ print("\t" + self.name + p[0] + " >>> " +
+ self.time(p[1]) + " >>> " +
+ green_start + self.date(p[2]) + color_stop)
- all_packages.append((package_group +
- '/' + package_name))
- return all_packages
+ def time(self, time):
+ 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))
+ pdays = str()
+ phours = str()
+ pminutes = str()
+ pseconds = str()
-def get_package(name):
- """Take the user-input package name and search for it
- in PORTDIR. """
+ if days > 0:
+ pdays = (green_start + str(days) + color_stop + " day")
+ if days != 1:
+ pdays += "s"
- dirlist = os.listdir(PORTDIR)
- possible_package = []
+ if hours > 0:
+ phours = (green_start + str(hours) + color_stop + " hour")
+ if hours != 1:
+ phours += "s"
+ if minutes > 0:
+ pminutes = (green_start + str(minutes) + color_stop + " minute")
+ if minutes != 1:
+ pminutes += "s"
- # 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
+ pseconds = (green_start + str(seconds) + color_stop + " second")
+ if seconds != 1:
+ pseconds += "s"
- if group in dirlist:
- dirs = os.listdir(directory)
- if pkg in dirs:
- possible_package.append(name)
+ return (pdays + phours + pminutes + pdays)
- # 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)
+ def date(self, emerge_date):
+ date = datetime.datetime.fromtimestamp(emerge_date)
+ year = str(date.year)
+ month = str(date.month)
+ day = str(date.day)
+ hour = str(date.hour)
+ minute = str(date.minute)
+ second = str(date.second)
- if len(possible_package) > 1:
- print("Multiple packages found for '" + name + "'.")
- print("Possible packages: ")
- for value in possible_package:
- print("\t" + value)
+ date = "{:%d.%m.%Y %H:%M:%S}".format(date)
-
- elif len(possible_package) == 1:
- package = possible_package[0]
- return package
-
-
- else:
- print("No package '" + name + "' found")
-
-
- sys.exit(1)
-
-
-
-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."""
-
-
- times.sort()
- times.reverse()
-
-
- # This should be True if we're in current emerge stage
- if silent == True:
- if emerge_number == 0:
- print("\t no previous emerges found for this package"),
-
- elif emerge_number == 1:
- print("\t previous emerge time"),
- organize_times(times[0][0])
- print("(only one emerge previously)"),
-
- else:
- print("\t average emerge time: "),
- all_times = 0
- for i in times:
- all_times += i[0]
-
- organize_times(all_times/len(times))
-
- print('\n')
- return all_times/len(times)
-
-
- if emerge_number == 1:
- print(green_start + package + color_stop + " emerged once")
-
- else:
- print(green_start + package + color_stop + " emerged " + green_start +
- str(emerge_number) + color_stop + " times\n")
-
- print "Max time:\t",
- organize_times(times[0][0])
- print "at", times[0][1]
-
- 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]
-
- print "Average time\t",
- organize_times(all_times/len(times))
- print
-
- print "In total spent\t",
- organize_times(all_times)
- print("emerging " + green_start +
- package + color_stop)
+ return date
-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."""
-
- now = datetime.datetime.today()
- packages = []
-
- for i in os.popen("ps ax"):
- if (("ebuild" in i) and ("/bin/bash" not in i)):
- pack = i.partition('[')[2].partition(']')[0]
+def search_log_for_package(user_package):
- packages.append([pack, 12*3600])
+ log = open_log()
+ packages.insert(0, package(user_package))
- for line in f:
+ for line in log:
if ((">>>" in line) and ("emerge" in line)):
- for p in packages:
- if (p[0] in line):
+ if user_package in line:
+ version = line.partition(user_package)[2].partition(' ')[0]
- time = float(line.partition(' ')[0].strip(":"))
+ 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 user_package in line:
+ time_string = line.partition(":::")
+ stop_time = float(time_string[0].strip().strip(':'))
- if difference < p[1]:
- p[1] = difference
+ emerge_time = stop_time - start_time
+ packages[0].add_version(version, emerge_time, start_time)
- if len(packages) == 0:
- print "No current emerge process found."
- return
- print_current_emerges(f, packages)
-
-
-
-
-def print_current_emerges(f, packages):
- """Print the current packages that are being merged with the
- current emerge time."""
-
- all_packages = list_all_packages()
-
- print("Currently emerging: ")
+def print_stuff():
for p in packages:
- print("\t" + green_start + p[0] + color_stop),
- print('\n\t current emerge time: '),
-
- organize_times(p[1])
- print
-
-
- for i in all_packages:
- if i in p[0]:
- main_loop(f, i, True)
-
-
-
-
-def list_pretended(f):
- """Print the average times of pretended packages"""
-
- all_packages = list_all_packages()
-
- packages = []
- for line in sys.stdin:
- if "[ebuild" in line:
- full_name = line.partition('] ')[2].partition(' ')[0]
-
- for i in all_packages:
- if i in full_name:
- packages.append((i, full_name[len(i):]))
-
- if len(packages) == 0:
- return
-
- print "This is how long these packages would take to emerge"
-
- all_time = 0
- for pack in packages:
-
- print('\t' + green_start + pack[0] + pack[1] + color_stop)
-
- all_time += main_loop(f, pack[0], True)
-
-
- print("Total emerge time:"),
- organize_times(all_time)
-
-
-
+ p.print_versions()
-def main_loop(f, package, silent):
- """The main loop which parses the LOGFILE and if needed prints out emerge times."""
- global emerge_number
- emerge_number = 0
- f.seek(0) # Seek to the beginning of the file
+def main(status, user_package=None):
- # MAIN LOOP
- for line in f:
- if package in line:
- st = line.split(' ')
+ if status == "package":
+ search_log_for_package(user_package)
+ print_stuff()
- for string in st:
- if ((package in string) and (len(string) > len(package)+1)
- and (string[len(package)+1].isdigit())):
- full_package = st[st.index(string)]
-
- if ((">>>" in line) and ("emerge" in line)):
- time_string = line.partition(">>>")
- time = float(time_string[0].strip().strip(":"))
-
- try:
- if (":::" in line) and ("completed emerge" in line):
- emerge_number += 1
-
-
- time_string = line.partition(":::")
- time2 = float(time_string[0].strip().strip(":"))
-
-
- emerge_time = time2-time
-
- date = get_date(time)
-
-
- if silent == False:
- print(str(len(times)+1) + "."),
- print(green_start + full_package + color_stop + " >>> "
- + date + " >>> "),
-
- organize_times(emerge_time)
-
- print("\n" + '-'*90)
-
- times.append((emerge_time, date))
- except IndexError:
- pass
-
- average_time = print_times(package, times, silent)
- return average_time
-
-
-
-def main(status):
- """Change between current emerge stage and normal operating stage."""
-
- global emerge_number
-
- f = open_log()
-
- if status == 'current':
- list_emerge_processes(f)
- return
- elif status == 'pretended':
- list_pretended(f)
- return
- else:
+ elif status == "current":
pass
- package = get_package(package_name)
-
- print('-'*90)
-
- main_loop(f, package, False)
-
- if emerge_number == 0:
- print("Package '" + package + "' has never been emerged")
- sys.exit(1)
+ elif status == "pretended":
+ pass
- f.close()
if __name__ == "__main__":
if len(sys.argv) == 1:
- main('current')
+ main("current")
sys.exit(1)
elif sys.argv[1] == "-p":
- main('pretended')
+ main("pretended")
sys.exit(1)
+ elif len(sys.argv) > 1:
+ main("package", sys.argv[1])
- if len(sys.argv) > 1:
- package_name = sys.argv[1]
- main(0)
-
-
- write_times(times)