4 import sys, subprocess, datetime, os
7 PORTDIR = "/usr/portage/"
8 LOGFILE = "/var/log/emerge.log"
15 green_start = "\033[32m"
20 def write_times(emerge_times_list):
21 """Writes the emerge times into a file called 'times'."""
23 with open('times', 'w') as g:
25 for i in emerge_times_list:
26 line = str(i[0]) + " " + str(i[1]) + "\n"
33 def organize_times(time):
34 """Takes the emerge time in seconds, organizes it into
35 days, hours, minutes or seconds and finally prints that out."""
38 hours = (days - int(days))*24
39 minutes = (hours - int(hours))*60
40 seconds = (minutes - int(minutes))*60
44 minutes = int(minutes)
45 seconds = int(round(seconds))
48 print_days = (green_start + str(days) + color_stop + " day")
54 print_hours = (green_start + str(hours) + color_stop + " hour")
60 print_minutes = (green_start + str(minutes) + color_stop + " minute")
65 printable_sec = (green_start + str(seconds) + color_stop + " second")
72 def get_date(emerge_start):
73 """Take the emerge startup time in seconds and turn it into a
76 date = datetime.datetime.fromtimestamp(emerge_start)
79 month = str(date.month)
81 weekday = date.weekday()
83 if weekday == 0: weekday = 'Mon '
84 if weekday == 1: weekday = 'Tue '
85 if weekday == 2: weekday = 'Wed '
86 if weekday == 3: weekday = 'Thu '
87 if weekday == 4: weekday = 'Fri '
88 if weekday == 5: weekday = 'Sat '
89 if weekday == 6: weekday = 'Sun '
92 minute = str(date.minute)
93 second = str(date.second)
95 # This is in the format 'Mon 23.05.2011 00:20:14'
97 date = weekday + "{:%d.%m.%Y %H:%M:%S}".format(date)
103 def list_all_packages():
104 """Go through PORTDIR and create a list of all the packages in portage"""
106 root = os.listdir(PORTDIR)
109 for package_group in root:
110 group_dir = PORTDIR + package_group
111 if (os.path.isdir(group_dir)
112 and (package_group != "licenses")
113 and (package_group != "metadata")):
115 name_dir = os.listdir(group_dir)
117 for package_name in name_dir:
118 if ".xml" not in package_name:
120 all_packages.append((package_group +
128 def get_package(name):
129 """Take the user-input package name and search for it
132 dirlist = os.listdir(PORTDIR)
133 possible_package = []
136 # If the given name is in the format xxx/zzz
137 # assume that xxx is the package group
139 group = name.partition('/')[0]
140 pkg = name.partition('/')[2]
141 directory = PORTDIR + group
144 dirs = os.listdir(directory)
146 possible_package.append(name)
149 # Go through the directory listing searching for anything
150 # that matches the given name
152 directory = PORTDIR + i
153 if os.path.isdir(directory):
154 dirs = os.listdir(directory)
156 possible_package.append(i + '/' + name)
159 if len(possible_package) > 1:
160 print("Multiple packages found for '" + name + "'.")
161 print("Possible packages: ")
162 for value in possible_package:
166 elif len(possible_package) == 1:
167 package = possible_package[0]
172 print("No package '" + name + "' found")
179 def print_times(package, times, silent):
180 """Print the maximum/minimum/average times of the given emerge package.
181 If we're in the 'current emerge stage' (the 'silent' flag is True)
182 print the appropriate comment for that package."""
189 # This should be True if we're in current emerge stage
191 if emerge_number == 0:
192 print("\t no previous emerges found for this package"),
194 elif emerge_number == 1:
195 print("\t previous emerge time"),
196 organize_times(times[0][0])
197 print("(only one emerge previously)"),
200 print("\t average emerge time: "),
205 organize_times(all_times/len(times))
211 if emerge_number == 1:
212 print(green_start + package + color_stop + " emerged once")
215 print(green_start + package + color_stop + " emerged " + green_start +
216 str(emerge_number) + color_stop + " times\n")
219 organize_times(times[0][0])
220 print "at", times[0][1]
223 organize_times(times[len(times)-1][0])
224 print "at", times[len(times)-1][1]
230 print "Average time\t",
231 organize_times(all_times/len(times))
234 print "In total spent\t",
235 organize_times(all_times)
236 print("emerging " + green_start +
237 package + color_stop)
242 """Attempt to open the LOGFILE."""
245 f = open(LOGFILE, 'r')
246 except IOError as detail:
254 def list_emerge_processes(f):
255 """Look for the ebuild process with ps. If the process is found parse
256 the command for the package. With this package search the LOGFILE for
257 the emerge startup time."""
259 now = datetime.datetime.today()
262 for i in os.popen("ps ax"):
263 if (("ebuild" in i) and ("/bin/bash" not in i)):
264 pack = i.partition('[')[2].partition(']')[0]
266 packages.append([pack, 12*3600])
270 if ((">>>" in line) and ("emerge" in line)):
274 time = float(line.partition(' ')[0].strip(":"))
276 timestamp = datetime.datetime.fromtimestamp(time)
277 difference = (now - timestamp).total_seconds()
279 if difference < p[1]:
283 if len(packages) == 0:
284 print "No current emerge process found."
287 print_current_emerges(f, packages)
292 def print_current_emerges(f, packages):
293 """Print the current packages that are being merged with the
294 current emerge time."""
296 all_packages = list_all_packages()
298 print("Currently emerging: ")
301 print("\t" + green_start + p[0] + color_stop),
302 print('\n\t current emerge time: '),
308 for i in all_packages:
310 main_loop(f, i, True)
315 def list_pretended(f):
316 """Print the average times of pretended packages"""
318 all_packages = list_all_packages()
321 for line in sys.stdin:
322 if "[ebuild" in line:
323 full_name = line.partition('] ')[2].partition(' ')[0]
325 for i in all_packages:
327 packages.append((i, full_name[len(i):]))
330 print "This is how long these packages would take to emerge"
332 for pack in packages:
333 print('\t' + green_start + pack[0] + pack[1] + color_stop)
334 main_loop(f, pack[0], True)
339 def main_loop(f, package, silent):
340 """The main loop which parses the LOGFILE and if needed prints out emerge times."""
344 f.seek(0) # Seek to the beginning of the file
353 if ((package in string) and (len(string) > len(package)+1)
354 and (string[len(package)+1].isdigit())):
355 full_package = st[st.index(string)]
358 if ((">>>" in line) and ("emerge" in line)):
359 time_string = line.partition(">>>")
360 time = float(time_string[0].strip().strip(":"))
363 if (":::" in line) and ("completed emerge" in line):
367 time_string = line.partition(":::")
368 time2 = float(time_string[0].strip().strip(":"))
371 emerge_time = time2-time
373 date = get_date(time)
377 print(str(len(times)+1) + "."),
378 print(green_start + full_package + color_stop + " >>> "
381 organize_times(emerge_time)
385 times.append((emerge_time, date))
389 print_times(package, times, silent)
394 """Change between current emerge stage and normal operating stage."""
400 if status == 'current':
401 list_emerge_processes(f)
403 elif status == 'pretended':
409 package = get_package(package_name)
413 main_loop(f, package, False)
415 if emerge_number == 0:
416 print("Package '" + package + "' has never been emerged")
423 if __name__ == "__main__":
425 if len(sys.argv) == 1:
429 elif sys.argv[1] == "-p":
434 if len(sys.argv) > 1:
435 package_name = sys.argv[1]