#!/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 date_printer(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
-
-
-
-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
-
-
- else:
- print("No package '" + name + "' found")
+class package:
+ def __init__(self, name):
+ self.name = name
+ self.versions = []
- sys.exit(1)
+ def add_version(self, version, emerge_time, emerge_date):
+ self.versions.append((version, emerge_time, emerge_date))
-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_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)
- times.sort()
- times.reverse()
+ def time(self, time):
+ days = time/(3600*24)
+ hours = (days - int(days))*24
+ minutes = (hours - int(hours))*60
+ seconds = (minutes - int(minutes))*60
- # 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"),
+ days = int(days)
+ hours = int(hours)
+ minutes = int(minutes)
+ seconds = int(round(seconds))
- elif emerge_number == 1:
- print("\t previous emerge time"),
- organize_times(times[0][0])
- print("(only one emerge previously)"),
+ pdays = str()
+ phours = str()
+ pminutes = str()
+ pseconds = str()
- else:
- print("\t average emerge time: "),
- all_times = 0
- for i in times:
- all_times += i[0]
+ if days > 0:
+ pdays = (green_start + str(days) + color_stop + " day")
+ if days != 1:
+ pdays += "s"
- organize_times(all_times/len(times))
+ if hours > 0:
+ phours = (green_start + str(hours) + color_stop + " hour")
+ if hours != 1:
+ phours += "s"
- print('\n')
- return
+ if minutes > 0:
+ pminutes = (green_start + str(minutes) + color_stop + " minute")
+ if minutes != 1:
+ pminutes += "s"
+ pseconds = (green_start + str(seconds) + color_stop + " second")
+ if seconds != 1:
+ pseconds += "s"
- if emerge_number == 1:
- print(green_start + package + color_stop + " emerged once")
+ return (pdays + phours + pminutes + pdays)
- 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]
+ def date(self, emerge_date):
+ date = datetime.datetime.fromtimestamp(emerge_date)
- print "Min time:\t",
- organize_times(times[len(times)-1][0])
- print "at", times[len(times)-1][1]
+ year = str(date.year)
+ month = str(date.month)
+ day = str(date.day)
+ hour = str(date.hour)
+ minute = str(date.minute)
+ second = str(date.second)
- all_times = 0
- for i in times:
- all_times += i[0]
+ date = "{:%d.%m.%Y %H:%M:%S}".format(date)
- 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."""
-
-
- 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, 0])
+ 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):
-
- time = float(line.partition(' ')[0].strip(":"))
- if time > p[1]:
- p[1] = time
-
-
- if len(packages) == 0:
- print "No current emerge process found."
- return
-
-
- # Here we go through all the packages we have found and
- # printout the current emerge time
- a = 1
- for p in packages:
- now = datetime.datetime.today()
- timestamp = datetime.datetime.fromtimestamp(p[1])
-
- difference = now - timestamp
-
-
- if difference.total_seconds() < 12*60*60:
- if a:
- print("Currently emerging: ")
- a = 0
-
- print("\t" + green_start + p[0] + color_stop),
- print('\n\t current emerge time: '),
-
- organize_times(difference.total_seconds())
- print
-
-
- name = (p[0].partition('-')[0] + '-' +
- p[0].partition('-')[2].partition('-')[0])
- main_loop(f, name, True)
-
-
-
-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
+ if user_package in line:
+ version = line.partition(user_package)[2].partition(' ')[0]
+ digit = version.strip('-')[0].isdigit()
+ if digit:
+ time_string = line.partition(">>>")
+ start_time = float(time_string[0].strip().strip(':'))
- # MAIN LOOP
- for line in f:
- if package in line:
- st = line.split(' ')
+ elif ((":::" in line) and ("completed emerge" in line)):
+ if user_package in line:
+ if digit:
+ time_string = line.partition(":::")
+ stop_time = float(time_string[0].strip().strip(':'))
- 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)]
+ emerge_time = stop_time - start_time
+ packages[0].add_version(version, emerge_time, start_time)
- 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 = date_printer(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
-
- print_times(package, times, silent)
+def print_stuff():
+ for p in packages:
+ p.print_versions()
-def main(status):
- """Change between current emerge stage and normal operating stage."""
+def main(status, user_package=None):
- global emerge_number
+ if status == "package":
+ search_log_for_package(user_package)
+ print_stuff()
- f = open_log()
- if status == 'current':
- list_emerge_processes(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:
- package_name = sys.argv[1]
- main(0)
- else:
- main('current')
+ if len(sys.argv) == 1:
+ main("current")
+ sys.exit(1)
+
+ elif sys.argv[1] == "-p":
+ main("pretended")
sys.exit(1)
- write_times(times)
+ elif len(sys.argv) > 1:
+ main("package", sys.argv[1])
+