]> git.itanic.dy.fi Git - emerge-timer/blob - emerge-timer.py
Remove unused module imports
[emerge-timer] / emerge-timer.py
1 #!/usr/bin/python
2
3
4 import sys, datetime, os
5
6
7 PORTDIR = "/usr/portage/"
8 LOGFILE = "/var/log/emerge.log"
9
10 green_start = "\033[32m"
11 color_stop = "\033[m"
12
13 packages = []
14
15
16 class package:
17     def __init__(self, name, version=0):
18         self.name = name
19         self.version = version
20         self.versions = []
21         self.emerge_time = 12*3600
22
23     def add_version(self, version, emerge_time, emerge_date):
24
25         self.versions.append((version, emerge_time, emerge_date))
26
27
28     def average_time(self):
29         total_time = 0
30         for i in self.versions:
31             total_time += i[1]
32
33         average_time = total_time/len(self.versions)
34
35         return average_time
36
37     def total_time(self):
38         total_time = 0
39         for i in self.versions:
40             total_time += i[1]
41
42         return total_time
43
44
45     def max_time(self):
46         self.versions.sort()
47
48         return self.versions[len(self.versions)-1][1]
49
50
51     def min_time(self):
52         self.versions.sort()
53
54         return self.versions[0][1]
55
56
57     def print_current_emerge(self):
58
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: "),
62
63         if len(self.versions) > 1:
64             print(self.time(self.average_time())),
65         else:
66             print("unknown"),
67
68         print("\n\t " + '-'*45),
69
70         finish_time = self.average_time() - self.emerge_time
71
72         print("\n\t time to finish: "),
73
74         if finish_time > 0:
75             print(self.time(finish_time))
76         else:
77             print("any time now")
78
79
80     def print_versions(self):
81         for p in self.versions:
82             print('-'*90 + "\n" +
83                   green_start + self.name + p[0] + color_stop + "  >>>  " +
84                   self.time(p[1]) + "  >>>  " +
85                   self.date(p[2]))
86         print('-'*90 + "\n" + "Package " + green_start +
87               self.name + color_stop + " emerged " +
88               str(len(self.versions)) + " times.")
89         print
90
91     def print_pretended_times(self):
92         print("\t" + green_start + self.name + '-' + self.version + color_stop),
93
94         if len(self.versions) > 1:
95             print("\n\taverage time: " + self.time(self.average_time()))
96         else:
97             print("\n\t no previous emerges")
98
99
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()
105
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)
111
112     def time(self, time):
113
114         days = time/(3600*24)
115         hours = (days - int(days))*24
116         minutes = (hours - int(hours))*60
117         seconds = (minutes - int(minutes))*60
118
119         days = int(days)
120         hours = int(hours)
121         minutes = int(minutes)
122         seconds = int(round(seconds))
123
124         pdays = str()
125         phours = str()
126         pminutes = str()
127         pseconds = str()
128
129         if days > 0:
130             pdays = (green_start + str(days) +
131                      color_stop + " day ")
132             if days != 1:
133                 pdays = (green_start + str(days) +
134                          color_stop + " days ")
135
136         if hours > 0:
137             phours = (green_start + str(hours) +
138                       color_stop + " hour ")
139             if hours != 1:
140                 phours = (green_start + str(hours) +
141                           color_stop + " hours ")
142
143         if minutes > 0:
144             pminutes = (green_start + str(minutes) +
145                         color_stop + " minute ")
146             if minutes != 1:
147                 pminutes = (green_start + str(minutes) +
148                             color_stop + " minutes ")
149
150         pseconds = (green_start + str(seconds) +
151                     color_stop + " second ")
152         if seconds != 1:
153             pseconds = (green_start + str(seconds) +
154                         color_stop + " seconds ")
155
156         return (pdays + phours + pminutes + pseconds)
157
158
159     def date(self, emerge_date):
160         date = datetime.datetime.fromtimestamp(emerge_date)
161
162         year = str(date.year)
163         month = str(date.month)
164         day = str(date.day)
165         hour = str(date.hour)
166         minute = str(date.minute)
167         second = str(date.second)
168
169         date = "{:%d.%m.%Y %H:%M:%S}".format(date)
170
171         return date
172
173
174
175 def open_log():
176     """Attempt to open the LOGFILE."""
177
178     try:
179         f = open(LOGFILE, 'r')
180     except IOError as detail:
181         print detail
182         sys.exit(1)
183     finally:
184         return f
185
186
187
188 def search_log_for_package(package_class):
189
190     log = open_log()
191
192     for line in log:
193         if ((">>>" in line) and ("emerge" in line)):
194             if package_class.name in line:
195                 version = line.partition(package_class.name)[2].partition(' ')[0]
196                 digit = version.strip('-')[0].isdigit()
197
198                 if digit:
199                     time_string = line.partition(">>>")
200                     start_time = float(time_string[0].strip().strip(':'))
201
202         elif ((":::" in line) and ("completed emerge" in line)):
203             if package_class.name in line:
204                 if digit:
205                     time_string = line.partition(":::")
206                     stop_time = float(time_string[0].strip().strip(':'))
207
208                     emerge_time = stop_time - start_time
209
210                     package_class.add_version(version, emerge_time, start_time)
211
212
213 def get_package(name):
214     """Take the user-input package name and search for it
215     in PORTDIR. """
216
217     dirlist = os.listdir(PORTDIR)
218     possible_package = []
219
220
221     # If the given name is in the format xxx/zzz
222     # assume that xxx is the package group
223     if '/' in name:
224         group = name.partition('/')[0]
225         pkg = name.partition('/')[2]
226         directory = PORTDIR + group
227
228         if group in dirlist:
229             dirs = os.listdir(directory)
230             if pkg in dirs:
231                 possible_package.append(name)
232
233
234     # Go through the directory listing searching for anything
235     # that matches the given name
236     for i in dirlist:
237         directory = PORTDIR + i
238         if os.path.isdir(directory):
239             dirs = os.listdir(directory)
240             if name in dirs:
241                 possible_package.append(i + '/' + name)
242
243
244     if len(possible_package) > 1:
245         print("Multiple packages found for '" + name + "'.")
246         print("Possible packages: ")
247         for value in possible_package:
248             print("\t" + value)
249
250
251     elif len(possible_package) == 1:
252         package = possible_package[0]
253         return package
254
255
256     else:
257         print("No package '" + name + "' found")
258
259
260     sys.exit(1)
261
262
263 def list_pretended():
264     log = open_log()
265
266     for line in sys.stdin:
267         if "[ebuild" in line:
268             full_name = line.partition("] ")[2].partition(' ')[0]
269
270             version = full_name.partition('/')[2].partition('-')[2]
271             while not version[0].isdigit():
272                 version = version.partition('-')[2]
273             package_name = full_name[:-len(version)-1]
274
275             packages.append(package(package_name, version))
276
277
278 def list_emerge_processes():
279     """Look for the ebuild process with ps. If the process is found parse
280     the command for the package. With this package search the LOGFILE for
281     the emerge startup time."""
282
283     f = open_log()
284
285     now = datetime.datetime.today()
286
287     for i in os.popen("ps ax"):
288         if (("ebuild.sh" in i) and ("/bin/bash" not in i)):
289             pack = i.partition('[')[2].partition(']')[0]
290
291             version = pack.partition('/')[2].partition('-')[2]
292
293             while not version[0].isdigit():
294                 version = version.partition('-')[2]
295
296             package_name = pack[:-len(version)-1]
297
298             packages.append(package(package_name, version))
299
300
301     if len(packages) == 0:
302         print "No current emerge process found."
303         sys.exit(0)
304
305
306     for line in f:
307         if ((">>>" in line) and ("emerge" in line)):
308             for p in packages:
309                 if (p.name + '-' + p.version in line):
310
311                     time = float(line.partition(' ')[0].strip(":"))
312
313                     timestamp = datetime.datetime.fromtimestamp(time)
314                     difference = (now - timestamp).total_seconds()
315
316                     if difference < p.emerge_time:
317                         p.emerge_time = difference
318
319
320
321
322
323 def main(status, user_package=None):
324
325     if status == "package":
326         user_package = get_package(user_package)
327
328         pack = package(user_package)
329
330         search_log_for_package(pack)
331         pack.print_versions()
332         pack.print_min_max_ave()
333
334
335     elif status == "current":
336         list_emerge_processes()
337
338         print "Currently emerging:"
339
340         for p in packages:
341             search_log_for_package(p)
342             p.print_current_emerge()
343
344
345     elif status == "pretended":
346         list_pretended()
347
348         print "This is how long these packages would take to emerge"
349
350         for p in packages:
351             search_log_for_package(p)
352             p.print_pretended_times()
353             print
354
355
356 if __name__ == "__main__":
357
358     if len(sys.argv) == 1:
359         main("current")
360         sys.exit(1)
361
362     elif sys.argv[1] == "-p":
363         main("pretended")
364         sys.exit(1)
365
366     elif len(sys.argv) > 1:
367         main("package", sys.argv[1])
368