]> git.itanic.dy.fi Git - emerge-timer/blobdiff - emerge-timer.py
Fix correct newline behaviour in python3
[emerge-timer] / emerge-timer.py
index d26851c019f30fc10bcbd5c405d789bf044d3aa7..d782b34996fac6c9b6c791a58a069adace19de77 100755 (executable)
@@ -16,6 +16,11 @@ QUIET = False
 
 PACKAGES = []
 
+def GREEN(string):
+    return green_start + string + color_stop
+
+def RED(string):
+    return red_start + string + color_stop
 
 
 class package:
@@ -25,12 +30,27 @@ class package:
         self.versions = []
         self.emerge_time = "infinity"
 
+        self.plotData = []
+
 
     def add_version(self, version, emerge_time, emerge_date):
         """Add version to the class version list"""
         self.versions.append((version, emerge_time, emerge_date))
 
 
+    def seek_versions(self, whatToSeek, Input):
+
+        if whatToSeek == "date":
+            for i in self.versions:
+                if i[1] == Input:
+                    return i[2]
+
+        if whatToSeek == "version":
+            for i in self.versions:
+                if i[1] == Input:
+                    return i[0]
+
+
     def average_time(self):
         """Return average time from class version list"""
         total_time = 0
@@ -51,8 +71,8 @@ class package:
         return total_time
 
 
-    def max_time(self):
-        """Return maximum time from class version list"""
+    def min_max_time(self, setting):
+        """Return maximum or minimum time from class version list"""
 
         emerge_times = []
         for i in self.versions:
@@ -60,55 +80,47 @@ class package:
 
         emerge_times.sort()
 
-        return emerge_times[-1]
+        if setting == "max":
+            return emerge_times[-1]
+        elif setting == "min":
+            return emerge_times[0]
 
 
-    def min_time(self):
-        """Return minimum time from class version list"""
-
-        emerge_times = []
-        for i in self.versions:
-            emerge_times.append(i[1])
-
-        emerge_times.sort()
-
-        return emerge_times[0]
-
 
 
     def print_current_emerge(self):
         """Function used to print all the current emerge stuff"""
 
-        print("\t" + green_start + self.name + '-' + self.version +
-              color_stop + "\n\t current time: " + give_time(self.emerge_time))
+        print("\t" + GREEN(self.name + '-' + self.version) +
+              "\n\t current time: " + give_time(self.emerge_time))
 
 
         if len(self.versions) == 1:
             print("\t last time:   "),
-            print(give_time(self.average_time())),
+            print(give_time(self.average_time()), end='')
 
         elif len(self.versions) > 1:
-            print("\t average time:"),
-            print(give_time(self.average_time())),
+            print("\t average time: ", end='')
+            print(give_time(self.average_time()), end='')
 
         else:
-            print("\t average time: " + green_start + "unknown\n" + color_stop),
+            print("\t average time: " + GREEN("unknown\n")),
             return
 
-        print("\n\t " + '-'*45),
+        print("\n\t " + '-'*45, end='')
 
-        print("\n\t time to finish:"),
+        print("\n\t time to finish: ", end='')
 
         if type(self.emerge_time) != str:
 
             finish_time = self.average_time() - self.emerge_time
 
             if finish_time > 0:
-                print(give_time(finish_time))
+                print(give_time(finish_time), "\n")
             else:
-                print(green_start + "any time now" + color_stop)
+                print(GREEN("any time now"))
         else:
-            print(green_start + "unknown" + color_stop)
+            print(GREEN("unknown"))
         print
 
 
@@ -128,6 +140,9 @@ class package:
                 if len(give_time(p[1], True)) > time_length:
                     time_length = len(give_time(p[1], True))
 
+                # Create the data for plotting in the format (emerge time, emerge date)
+                self.plotData.append((p[1], p[2]))
+
             dots =  (version_length + time_length + len(self.name)
                      + len(give_date(self.versions[0][2])) + 14)
 
@@ -140,13 +155,15 @@ class package:
                 p_date = give_date(p[2])
 
                 print('-' * dots + "\n" +
-                      green_start + name + (p[0]).ljust(version_length) +
-                      color_stop + "  >>>  " + p_time + " "*pad +
-                      "  >>>  " + p_date)
+                      GREEN(name + (p[0]).ljust(version_length))
+                      + "  >>>  " + p_time + " "*pad + "  >>>  " + p_date)
 
-        print('-' * dots + "\n" + "Package " + green_start +
-              self.name + color_stop + " emerged " +
-              str(len(self.versions)) + " times.\n")
+        print("\n" + "Package " + GREEN(self.name) + " emerged"),
+
+        if len(self.versions) > 1:
+            print(str(len(self.versions)) + " times.\n")
+        elif len(self.versions) == 1:
+            print("once.\n")
 
 
 
@@ -154,7 +171,7 @@ class package:
         """This is used the print all the pretended times"""
 
         if QUIET == False:
-            print("\t" + green_start + self.name + '-' + self.version + color_stop),
+            print("\t" + GREEN(self.name + '-' + self.version)),
 
         if len(self.versions) > 1:
             aver_time = self.average_time()
@@ -172,16 +189,55 @@ class package:
 
 
     def print_min_max_ave(self):
-        maxi = self.max_time()
-        mini = self.min_time()
+
+        if len(self.versions) == 1:
+            return
+
+        maxi = self.min_max_time("max")
+        mini = self.min_max_time("min")
         average = self.average_time()
         total = self.total_time()
 
-        print("Max time:\t" + give_time(maxi) +
-              "\nMin time:\t" + give_time(mini) +
-              "\nAverage time:\t" + give_time(average) +
-              "\nIn total spent:\t" + give_time(total) +
-              "emerging " + green_start + self.name + color_stop)
+        print("-"*20 +
+              "\nMaximum emerge time:\n" +
+              give_time(maxi) + "for version " +
+              GREEN(self.seek_versions("version", maxi).lstrip("-"))
+              + " on " +
+              give_date(self.seek_versions("date", maxi)))
+
+        print("-"*20 +
+              "\nMinimum emerge time:\n" +
+              give_time(mini) + "for version " +
+              GREEN(self.seek_versions("version", mini).lstrip("-"))
+              + " on " +
+              give_date(self.seek_versions("date", mini)))
+
+        print("-"*20 +
+              "\nAverage emerge time:\n" +
+              give_time(average))
+
+        print("-"*20 +
+              "\nIn total spent:\n" +
+              give_time(total))
+
+
+    def plotToScreen(self):
+        dates = []
+        times = []
+
+        for i in self.plotData:
+            dates.append(datetime.date.fromtimestamp(i[1]))
+            times.append(i[0])
+
+        fig = plt.figure()
+
+        plt.plot_date(dates, times, xdate=True, ydate=False)
+
+        plt.ylabel("Emerge time [s]")
+        plt.suptitle(self.name)
+        plt.grid()
+        fig.autofmt_xdate()
+        plt.show()
 
 
 
@@ -197,7 +253,7 @@ def give_time(time, nocolor=False):
         color_stop = ""
 
     if type(time) == str:
-        return(green_start + "unknown" + color_stop)
+        return(GREEN("unknown"))
 
 
     days = time/(3600.0*24.0)
@@ -216,32 +272,24 @@ def give_time(time, nocolor=False):
     pseconds = str()
 
     if days > 0:
-        pdays = (green_start + str(days) +
-                 color_stop + " day ")
+        pdays = (GREEN(str(days)) + " day ")
         if days != 1:
-            pdays = (green_start + str(days) +
-                         color_stop + " days ")
+            pdays = (GREEN(str(days)) + " days ")
 
     if hours > 0:
-        phours = (green_start + str(hours) +
-                  color_stop + " hour ")
+        phours = (GREEN(str(hours)) + " hour ")
         if hours != 1:
-            phours = (green_start + str(hours) +
-                          color_stop + " hours ")
+            phours = (GREEN(str(hours)) + " hours ")
 
     if minutes > 0:
-        pminutes = (green_start + str(minutes) +
-                    color_stop + " minute ")
+        pminutes = (GREEN(str(minutes)) + " minute ")
         if minutes != 1:
-            pminutes = (green_start + str(minutes) +
-                        color_stop + " minutes ")
+            pminutes = (GREEN(str(minutes)) + " minutes ")
 
     if seconds > 0:
-        pseconds = (green_start + str(seconds) +
-                    color_stop + " second ")
+        pseconds = (GREEN(str(seconds)) + " second ")
         if seconds != 1:
-            pseconds = (green_start + str(seconds) +
-                        color_stop + " seconds ")
+            pseconds = (GREEN(str(seconds)) + " seconds ")
 
     if nocolor == True:
         green_start = "\033[32m"
@@ -267,7 +315,7 @@ def open_log():
     try:
         f = open(LOGFILE, 'r')
     except IOError as detail:
-        print detail
+        print(detail)
         sys.exit(1)
 
     return f
@@ -304,6 +352,37 @@ def search_log_for_package(package_class):
 
 
 
+def search_log_for_all_packages():
+    """Goes through the emerge.log and lists all packages in there"""
+
+    log = open_log()
+
+    all_packages = []
+
+    total_emerge_time = 0
+    emerge_number = 0
+
+    for line in log:
+        if ((">>>" in line) and ("emerge" in line)):
+            pack = line.partition(')')[2].strip().partition(' ')[0]
+            start_time = float(line.partition(':')[0])
+
+            all_packages.append((pack, start_time))
+
+        elif ((":::" in line) and ("completed emerge" in line)):
+            for p in all_packages:
+                if p[0] in line:
+                    print("\t" + give_date(p[1]) + " >>> " + GREEN(p[0]))
+
+                    emerge_number += 1
+
+                    all_packages.pop(all_packages.index(p))
+
+
+    print("\n" + GREEN(str(emerge_number)) + " emerges in total found.")
+
+
+
 def get_package(name):
     """Take the user-input package name and search for it
     in PORTDIR. """
@@ -399,7 +478,7 @@ def list_emerge_processes():
 
 
     if len(PACKAGES) == 0:
-        print "No current emerge process found."
+        print("No current emerge process found.")
 
         return 1
 
@@ -416,39 +495,79 @@ def list_emerge_processes():
                     timestamp = datetime.datetime.fromtimestamp(time)
                     difference = (now - timestamp).total_seconds()
 
-                    if ((difference < p.emerge_time) or
-                        (p.emerge_time == "infinity")):
+                    if ((p.emerge_time == "infinity") or
+                        (difference < p.emerge_time)):
 
                         p.emerge_time = difference
 
     return 0
 
 
+def search_syncs():
+    f = open_log()
+
+    print("These emerge syncs found")
+    print("\tDate                    Server")
+    print("\t------------------------------")
+
+    a = 0
+    for line in f:
+        if "=== Sync completed with" in line:
+            time = float(line.partition(' ')[0].strip(":"))
+            server = line.rpartition(' ')[2]
+
+            print("\t" + GREEN(give_date(time)) +
+                  " === " + server),
+            a += 1
+
+    print("\n" + GREEN(str(a)) + " emerge syncs found. ")
+
 
 def main(status, user_package=None):
-    """Main function. Hanlde all the different modes of operation."""
+    try:
+        _main(status, user_package)
+    except IOError:
+        sys.exit()
+
+
+def _main(status, user_package=None):
+    """Main function. Handle all the different modes of operation."""
 
     if status == "package":
-        user_package = get_package(user_package)
+        for p in user_package:
+            pack = get_package(p)
 
-        pack = package(user_package)
+            pack = package(pack)
 
-        search_log_for_package(pack)
+            search_log_for_package(pack)
 
-        if len(pack.versions) != 0:
-            pack.print_versions()
-            pack.print_min_max_ave()
+            if len(pack.versions) != 0:
+                pack.print_versions()
+                pack.print_min_max_ave()
 
-        else:
-            print("Package " + green_start + pack.name +
-                  color_stop + " has never been emerged.")
+                if matplotWorking:
+                    pack.plotToScreen()
+
+            else:
+                print("Package " + GREEN(pack.name)
+                      + " has never been emerged.")
+
+
+    elif status == "sync":
+        search_syncs()
+        return
+
+
+    elif status == "list":
+        search_log_for_all_packages()
+        return
 
 
     elif status == "current":
         if list_emerge_processes():
             return
 
-        print "Currently emerging:"
+        print("Currently emerging:")
 
         for p in PACKAGES:
             search_log_for_package(p)
@@ -458,7 +577,7 @@ def main(status, user_package=None):
     elif status == "pretended":
         list_pretended()
 
-        print "This is how long these packages would take to emerge"
+        print("This is how long these packages would take to emerge")
 
         total_pretended_time = 0
 
@@ -469,8 +588,8 @@ def main(status, user_package=None):
 
             print
 
-        print("Total emerge time of " + green_start + str(len(PACKAGES)) +
-              color_stop + " package(s): "+ give_time(total_pretended_time))
+        print("Total emerge time of " + GREEN(str(len(PACKAGES)))
+              + " package(s): "+ give_time(total_pretended_time))
 
 
 def usage():
@@ -481,12 +600,16 @@ Calculate emerge times from emerge log.
 Options:
 \t-c, --current \t Show time until currently compiling package finishes
 \t-p, --pretended  Calculate compile time from piped 'emerge -p' output
+\t-l, --list \t List all emerged packages
+\t-s, --sync \t Show emerge sync history
 \t-h, --help \t Show this helpscreen
 \t-q, --quiet \t Be less verbose
 \t--no-color \t Use colorless output
-\t--simulate \t Do a simulation run"""
+\t--plot \t\t Plot emerge times into a 2D scatter plot
+\t\t\t (needs matlibplot installed for this to work)"""
 
-    print usage
+
+    print(usage)
 
     sys.exit(0)
 
@@ -495,8 +618,9 @@ if __name__ == "__main__":
 
     # Set the default mode as "package"
     mode = "package"
-    input_package = None
+    input_packages = None
     simulation = False
+    matplotWorking = False
 
     for arg in sys.argv[1:]:
 
@@ -509,69 +633,41 @@ if __name__ == "__main__":
         if arg == "-h" or arg == "--help":
             usage()
 
+        if arg == "-l" or arg == "--list":
+            mode = "list"
+
+        if arg == "-s" or arg == "--sync":
+            mode = "sync"
+
         if arg == "-q" or arg == "--quiet":
             QUIET = True
 
+            sys.argv.pop(sys.argv.index(arg))
+
+        if arg == "--plot":
+            try:
+                import matplotlib.pyplot as plt
+                matplotWorking = True
+            except ImportError:
+                print(RED("Cannot initialize matplotlib!"))
+                print(RED("Check that you have properly installed matplotlib.\n"))
+                matplotWorking = False
+
+            sys.argv.pop(sys.argv.index(arg))
+
         if arg == "--no-color":
             green_start = ""
             color_stop = ""
 
+            sys.argv.pop(sys.argv.index(arg))
+
         if arg == "--simulate":
             simulation = True
 
 
     if len(sys.argv) > 1:
-        input_package = sys.argv[1]
+        input_packages = sys.argv[1:]
     else:
         usage()
 
-    if simulation == True:
-
-        print(red_start + "\n" + '*'*25 + "\n" + "THIS IS A SIMULATION RUN\n"
-              + '*'*25 + "\n")
-
-        print("Beginning 'package' mode check")
-
-        print("Checking for one emerge\n" + color_stop)
-
-        LOGFILE = "simulate/fake_emerge.log"
-        PORTDIR = "simulate/"
-
-        main("package", "first_fake_package")
-
-        print(red_start + "\nChecking for three emerges\n" + color_stop)
-
-        main("package", "second_fake_package")
-
-        print(red_start + "\n'package' mode check complete\n")
-
-        print(30*'*')
-
-        print("\nBeginning 'current' mode check")
-        print("Current emerge with no emerge process\n" + color_stop)
-
-        main("current", None)
-
-        print(red_start + "\nCurrent emerge with emerge processes\n" + color_stop)
-
-        PACKAGES.append(package("test-group/second_fake_package", "2.9-r2"))
-        PACKAGES[0].emerge_time = 60
-        PACKAGES.append(package("test-group/first_fake_package", "1.10.2-r1"))
-        PACKAGES[1].emerge_time = 120
-
-        main("current", None)
-
-        print(red_start + "\nCurrent emerge with incomplete emerge log" +
-              "(causes error in some cases)\n" + color_stop)
-
-        PACKAGES = []
-        PACKAGES.append(package("test-group/third_fake_package", "2.9-r2"))
-
-        main("current", None)
-
-        print(red_start + "\n" + '*'*20 + "\n" + "SIMULATION FINISHED\n" +
-              '*'*20 + color_stop)
-
-
-    else:
-        main(mode, input_package)
+    main(mode, input_packages)