4 import sys, datetime, os
7 PORTDIR = "/usr/portage/"
8 LOGFILE = "/var/log/emerge.log"
10 green_start = "\033[32m"
17 def __init__(self, name, version=0):
19 self.version = version
21 self.emerge_time = 12*3600
23 def add_version(self, version, emerge_time, emerge_date):
25 self.versions.append((version, emerge_time, emerge_date))
28 def average_time(self):
30 for i in self.versions:
33 average_time = total_time/len(self.versions)
39 for i in self.versions:
48 return self.versions[len(self.versions)-1][1]
54 return self.versions[0][1]
57 def print_current_emerge(self):
59 print("\t" + green_start + self.name + '-' + self.version +
60 color_stop + "\n\t current time: " + self.time(self.emerge_time) +
61 "\n\t average time: "),
63 if len(self.versions) > 1:
64 print(self.time(self.average_time())),
68 print("\n\t " + '-'*45),
70 finish_time = self.average_time() - self.emerge_time
72 print("\n\t time to finish: "),
75 print(self.time(finish_time))
80 def print_versions(self):
81 for p in self.versions:
83 green_start + self.name + p[0] + color_stop + " >>> " +
84 self.time(p[1]) + " >>> " +
86 print('-'*90 + "\n" + "Package " + green_start +
87 self.name + color_stop + " emerged " +
88 str(len(self.versions)) + " times.")
91 def print_pretended_times(self):
92 print("\t" + green_start + self.name + '-' + self.version + color_stop),
94 if len(self.versions) > 1:
95 print("\n\taverage time: " + self.time(self.average_time()))
97 print("\n\t no previous emerges")
100 def print_min_max_ave(self):
101 maxi = self.max_time()
102 mini = self.min_time()
103 average = self.average_time()
104 total = self.total_time()
106 print("Max time: \t" + self.time(maxi) +
107 "\nMin time: \t" + self.time(mini) +
108 "\nAverage time: \t" + self.time(average) +
109 "\nIn total spent " + self.time(total) +
110 " emerging " + green_start + self.name + color_stop)
112 def time(self, time):
114 days = time/(3600*24)
115 hours = (days - int(days))*24
116 minutes = (hours - int(hours))*60
117 seconds = (minutes - int(minutes))*60
121 minutes = int(minutes)
122 seconds = int(round(seconds))
130 pdays = (green_start + str(days) +
131 color_stop + " day ")
133 pdays = (green_start + str(days) +
134 color_stop + " days ")
137 phours = (green_start + str(hours) +
138 color_stop + " hour ")
140 phours = (green_start + str(hours) +
141 color_stop + " hours ")
144 pminutes = (green_start + str(minutes) +
145 color_stop + " minute ")
147 pminutes = (green_start + str(minutes) +
148 color_stop + " minutes ")
150 pseconds = (green_start + str(seconds) +
151 color_stop + " second ")
153 pseconds = (green_start + str(seconds) +
154 color_stop + " seconds ")
156 return (pdays + phours + pminutes + pseconds)
159 def date(self, emerge_date):
160 date = datetime.datetime.fromtimestamp(emerge_date)
162 date = "{:%d.%m.%Y %H:%M:%S}".format(date)
169 """Attempt to open the LOGFILE."""
172 f = open(LOGFILE, 'r')
173 except IOError as detail:
181 def search_log_for_package(package_class):
186 if ((">>>" in line) and ("emerge" in line)):
187 if package_class.name in line:
188 version = line.partition(package_class.name)[2].partition(' ')[0]
189 digit = version.strip('-')[0].isdigit()
192 time_string = line.partition(">>>")
193 start_time = float(time_string[0].strip().strip(':'))
195 elif ((":::" in line) and ("completed emerge" in line)):
196 if package_class.name in line:
198 time_string = line.partition(":::")
199 stop_time = float(time_string[0].strip().strip(':'))
201 emerge_time = stop_time - start_time
203 package_class.add_version(version, emerge_time, start_time)
206 def get_package(name):
207 """Take the user-input package name and search for it
210 dirlist = os.listdir(PORTDIR)
211 possible_package = []
214 # If the given name is in the format xxx/zzz
215 # assume that xxx is the package group
217 group = name.partition('/')[0]
218 pkg = name.partition('/')[2]
219 directory = PORTDIR + group
222 dirs = os.listdir(directory)
224 possible_package.append(name)
227 # Go through the directory listing searching for anything
228 # that matches the given name
230 directory = PORTDIR + i
231 if os.path.isdir(directory):
232 dirs = os.listdir(directory)
234 possible_package.append(i + '/' + name)
237 if len(possible_package) > 1:
238 print("Multiple packages found for '" + name + "'.")
239 print("Possible packages: ")
240 for value in possible_package:
244 elif len(possible_package) == 1:
245 package = possible_package[0]
250 print("No package '" + name + "' found")
256 def list_pretended():
259 for line in sys.stdin:
260 if "[ebuild" in line:
261 full_name = line.partition("] ")[2].partition(' ')[0]
263 version = full_name.partition('/')[2].partition('-')[2]
264 while not version[0].isdigit():
265 version = version.partition('-')[2]
266 package_name = full_name[:-len(version)-1]
268 packages.append(package(package_name, version))
271 def list_emerge_processes():
272 """Look for the ebuild process with ps. If the process is found parse
273 the command for the package. With this package search the LOGFILE for
274 the emerge startup time."""
278 now = datetime.datetime.today()
280 for i in os.popen("ps ax"):
281 if (("ebuild.sh" in i) and ("/bin/bash" not in i)):
282 pack = i.partition('[')[2].partition(']')[0]
284 version = pack.partition('/')[2].partition('-')[2]
286 while not version[0].isdigit():
287 version = version.partition('-')[2]
289 package_name = pack[:-len(version)-1]
291 packages.append(package(package_name, version))
294 if len(packages) == 0:
295 print "No current emerge process found."
300 if ((">>>" in line) and ("emerge" in line)):
302 if (p.name + '-' + p.version in line):
304 time = float(line.partition(' ')[0].strip(":"))
306 timestamp = datetime.datetime.fromtimestamp(time)
307 difference = (now - timestamp).total_seconds()
309 if difference < p.emerge_time:
310 p.emerge_time = difference
316 def main(status, user_package=None):
318 if status == "package":
319 user_package = get_package(user_package)
321 pack = package(user_package)
323 search_log_for_package(pack)
324 pack.print_versions()
325 pack.print_min_max_ave()
328 elif status == "current":
329 list_emerge_processes()
331 print "Currently emerging:"
334 search_log_for_package(p)
335 p.print_current_emerge()
338 elif status == "pretended":
341 print "This is how long these packages would take to emerge"
344 search_log_for_package(p)
345 p.print_pretended_times()
350 usage = """Usage: emerge-timer.py [package] [options]
352 Calculate emerge times from emerge log.
355 \t-c, --current \t Show time until currently compiling package finishes
356 \t-p, --pretended Calculate compile time from piped 'emerge -p' output
357 \t-h, --help \t Show this helpscreen
359 \t--no-color \t Use colorless output"""
366 if __name__ == "__main__":
368 # Set the default mode as "package"
372 for arg in sys.argv[1:]:
374 if arg == "-p" or arg == "--pretended":
377 if arg == "-c" or arg == "--current":
380 if arg == "-h" or arg == "--help":
383 if arg == "--no-color":
388 if len(sys.argv) > 1:
389 input_package = sys.argv[1]
393 main(mode, input_package)