diff options
Diffstat (limited to 'bitbake/lib/bb/ui')
| -rw-r--r-- | bitbake/lib/bb/ui/__init__.py | 17 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/crumbs/__init__.py | 17 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/crumbs/buildmanager.py | 455 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/crumbs/progress.py | 17 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/crumbs/puccho.glade | 606 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/crumbs/runningbuild.py | 311 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/depexp.py | 307 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/goggle.py | 110 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/knotty.py | 248 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/ncurses.py | 352 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/puccho.py | 425 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/uievent.py | 127 | ||||
| -rw-r--r-- | bitbake/lib/bb/ui/uihelper.py | 42 | 
13 files changed, 0 insertions, 3034 deletions
| diff --git a/bitbake/lib/bb/ui/__init__.py b/bitbake/lib/bb/ui/__init__.py deleted file mode 100644 index a4805ed02..000000000 --- a/bitbake/lib/bb/ui/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# -# BitBake UI Implementation -# -# Copyright (C) 2006-2007 Richard Purdie -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. diff --git a/bitbake/lib/bb/ui/crumbs/__init__.py b/bitbake/lib/bb/ui/crumbs/__init__.py deleted file mode 100644 index a4805ed02..000000000 --- a/bitbake/lib/bb/ui/crumbs/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -# -# BitBake UI Implementation -# -# Copyright (C) 2006-2007 Richard Purdie -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. diff --git a/bitbake/lib/bb/ui/crumbs/buildmanager.py b/bitbake/lib/bb/ui/crumbs/buildmanager.py deleted file mode 100644 index e858d75e4..000000000 --- a/bitbake/lib/bb/ui/crumbs/buildmanager.py +++ /dev/null @@ -1,455 +0,0 @@ -# -# BitBake Graphical GTK User Interface -# -# Copyright (C) 2008        Intel Corporation -# -# Authored by Rob Bradford <rob@linux.intel.com> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -import gtk -import gobject -import threading -import os -import datetime -import time - -class BuildConfiguration: -    """ Represents a potential *or* historic *or* concrete build. It -    encompasses all the things that we need to tell bitbake to do to make it -    build what we want it to build. - -    It also stored the metadata URL and the set of possible machines (and the -    distros / images / uris for these. Apart from the metdata URL these are -    not serialised to file (since they may be transient). In some ways this -    functionality might be shifted to the loader class.""" - -    def __init__ (self): -        self.metadata_url = None - -        # Tuple of (distros, image, urls) -        self.machine_options = {} - -        self.machine = None -        self.distro = None -        self.image = None -        self.urls = [] -        self.extra_urls = [] -        self.extra_pkgs = [] - -    def get_machines_model (self): -        model = gtk.ListStore (gobject.TYPE_STRING) -        for machine in self.machine_options.keys(): -            model.append ([machine]) - -        return model - -    def get_distro_and_images_models (self, machine): -        distro_model = gtk.ListStore (gobject.TYPE_STRING) - -        for distro in self.machine_options[machine][0]: -            distro_model.append ([distro]) - -        image_model = gtk.ListStore (gobject.TYPE_STRING) - -        for image in self.machine_options[machine][1]: -            image_model.append ([image]) - -        return (distro_model, image_model) - -    def get_repos (self): -        self.urls = self.machine_options[self.machine][2] -        return self.urls - -    # It might be a lot lot better if we stored these in like, bitbake conf -    # file format. -    @staticmethod -    def load_from_file (filename): - -        conf = BuildConfiguration() -        with open(filename, "r") as f: -            for line in f: -                data = line.split (";")[1] -                if (line.startswith ("metadata-url;")): -                    conf.metadata_url = data.strip() -                    continue -                if (line.startswith ("url;")): -                    conf.urls += [data.strip()] -                    continue -                if (line.startswith ("extra-url;")): -                    conf.extra_urls += [data.strip()] -                    continue -                if (line.startswith ("machine;")): -                    conf.machine = data.strip() -                    continue -                if (line.startswith ("distribution;")): -                    conf.distro = data.strip() -                    continue -                if (line.startswith ("image;")): -                    conf.image = data.strip() -                    continue - -        return conf - -    # Serialise to a file. This is part of the build process and we use this -    # to be able to repeat a given build (using the same set of parameters) -    # but also so that we can include the details of the image / machine / -    # distro in the build manager tree view. -    def write_to_file (self, filename): -        f = open (filename, "w") - -        lines = [] - -        if (self.metadata_url): -            lines += ["metadata-url;%s\n" % (self.metadata_url)] - -        for url in self.urls: -            lines += ["url;%s\n" % (url)] - -        for url in self.extra_urls: -            lines += ["extra-url;%s\n" % (url)] - -        if (self.machine): -            lines += ["machine;%s\n" % (self.machine)] - -        if (self.distro): -            lines += ["distribution;%s\n" % (self.distro)] - -        if (self.image): -            lines += ["image;%s\n" % (self.image)] - -        f.writelines (lines) -        f.close () - -class BuildResult(gobject.GObject): -    """ Represents an historic build. Perhaps not successful. But it includes -    things such as the files that are in the directory (the output from the -    build) as well as a deserialised BuildConfiguration file that is stored in -    ".conf" in the directory for the build. - -    This is GObject so that it can be included in the TreeStore.""" - -    (STATE_COMPLETE, STATE_FAILED, STATE_ONGOING) = \ -        (0, 1, 2) - -    def __init__ (self, parent, identifier): -        gobject.GObject.__init__ (self) -        self.date = None - -        self.files = [] -        self.status = None -        self.identifier = identifier -        self.path = os.path.join (parent, identifier) - -        # Extract the date, since the directory name is of the -        # format build-<year><month><day>-<ordinal> we can easily -        # pull it out. -        # TODO: Better to stat a file? -        (_, date, revision) = identifier.split ("-") -        print(date) - -        year = int (date[0:4]) -        month = int (date[4:6]) -        day = int (date[6:8]) - -        self.date = datetime.date (year, month, day) - -        self.conf = None - -        # By default builds are STATE_FAILED unless we find a "complete" file -        # in which case they are STATE_COMPLETE -        self.state = BuildResult.STATE_FAILED -        for file in os.listdir (self.path): -            if (file.startswith (".conf")): -                conffile = os.path.join (self.path, file) -                self.conf = BuildConfiguration.load_from_file (conffile) -            elif (file.startswith ("complete")): -                self.state = BuildResult.STATE_COMPLETE -            else: -                self.add_file (file) - -    def add_file (self, file): -        # Just add the file for now. Don't care about the type. -        self.files += [(file, None)] - -class BuildManagerModel (gtk.TreeStore): -    """ Model for the BuildManagerTreeView. This derives from gtk.TreeStore -    but it abstracts nicely what the columns mean and the setup of the columns -    in the model. """ - -    (COL_IDENT, COL_DESC, COL_MACHINE, COL_DISTRO, COL_BUILD_RESULT, COL_DATE, COL_STATE) = \ -        (0, 1, 2, 3, 4, 5, 6) - -    def __init__ (self): -        gtk.TreeStore.__init__ (self, -            gobject.TYPE_STRING, -            gobject.TYPE_STRING, -            gobject.TYPE_STRING, -            gobject.TYPE_STRING, -            gobject.TYPE_OBJECT, -            gobject.TYPE_INT64, -            gobject.TYPE_INT) - -class BuildManager (gobject.GObject): -    """ This class manages the historic builds that have been found in the -    "results" directory but is also used for starting a new build.""" - -    __gsignals__ = { -        'population-finished' : (gobject.SIGNAL_RUN_LAST, -                                 gobject.TYPE_NONE, -                                 ()), -        'populate-error' : (gobject.SIGNAL_RUN_LAST, -                            gobject.TYPE_NONE, -                            ()) -    } - -    def update_build_result (self, result, iter): -        # Convert the date into something we can sort by. -        date = long (time.mktime (result.date.timetuple())) - -        # Add a top level entry for the build - -        self.model.set (iter, -            BuildManagerModel.COL_IDENT, result.identifier, -            BuildManagerModel.COL_DESC, result.conf.image, -            BuildManagerModel.COL_MACHINE, result.conf.machine, -            BuildManagerModel.COL_DISTRO, result.conf.distro, -            BuildManagerModel.COL_BUILD_RESULT, result, -            BuildManagerModel.COL_DATE, date, -            BuildManagerModel.COL_STATE, result.state) - -        # And then we use the files in the directory as the children for the -        # top level iter. -        for file in result.files: -            self.model.append (iter, (None, file[0], None, None, None, date, -1)) - -    # This function is called as an idle by the BuildManagerPopulaterThread -    def add_build_result (self, result): -        gtk.gdk.threads_enter() -        self.known_builds += [result] - -        self.update_build_result (result, self.model.append (None)) - -        gtk.gdk.threads_leave() - -    def notify_build_finished (self): -        # This is a bit of a hack. If we have a running build running then we -        # will have a row in the model in STATE_ONGOING. Find it and make it -        # as if it was a proper historic build (well, it is completed now....) - -        # We need to use the iters here rather than the Python iterator -        # interface to the model since we need to pass it into -        # update_build_result - -        iter = self.model.get_iter_first() - -        while (iter): -            (ident, state) = self.model.get(iter, -                BuildManagerModel.COL_IDENT, -                BuildManagerModel.COL_STATE) - -            if state == BuildResult.STATE_ONGOING: -                result = BuildResult (self.results_directory, ident) -                self.update_build_result (result, iter) -            iter = self.model.iter_next(iter) - -    def notify_build_succeeded (self): -        # Write the "complete" file so that when we create the BuildResult -        # object we put into the model - -        complete_file_path = os.path.join (self.cur_build_directory, "complete") -        f = file (complete_file_path, "w") -        f.close() -        self.notify_build_finished() - -    def notify_build_failed (self): -        # Without a "complete" file then this will mark the build as failed: -        self.notify_build_finished() - -    # This function is called as an idle -    def emit_population_finished_signal (self): -        gtk.gdk.threads_enter() -        self.emit ("population-finished") -        gtk.gdk.threads_leave() - -    class BuildManagerPopulaterThread (threading.Thread): -        def __init__ (self, manager, directory): -            threading.Thread.__init__ (self) -            self.manager = manager -            self.directory = directory - -        def run (self): -            # For each of the "build-<...>" directories .. - -            if os.path.exists (self.directory): -                for directory in os.listdir (self.directory): - -                    if not directory.startswith ("build-"): -                        continue - -                    build_result = BuildResult (self.directory, directory) -                    self.manager.add_build_result (build_result) - -            gobject.idle_add (BuildManager.emit_population_finished_signal, -                self.manager) - -    def __init__ (self, server, results_directory): -        gobject.GObject.__init__ (self) - -        # The builds that we've found from walking the result directory -        self.known_builds = [] - -        # Save out the bitbake server, we need this for issuing commands to -        # the cooker: -        self.server = server - -        # The TreeStore that we use -        self.model = BuildManagerModel () - -        # The results directory is where we create (and look for) the -        # build-<xyz>-<n> directories. We need to populate ourselves from -        # directory -        self.results_directory = results_directory -        self.populate_from_directory (self.results_directory) - -    def populate_from_directory (self, directory): -        thread = BuildManager.BuildManagerPopulaterThread (self, directory) -        thread.start() - -    # Come up with the name for the next build ident by combining "build-" -    # with the date formatted as yyyymmdd and then an ordinal. We do this by -    # an optimistic algorithm incrementing the ordinal if we find that it -    # already exists. -    def get_next_build_ident (self): -        today = datetime.date.today () -        datestr = str (today.year) + str (today.month) + str (today.day) - -        revision = 0 -        test_name = "build-%s-%d" % (datestr, revision) -        test_path = os.path.join (self.results_directory, test_name) - -        while (os.path.exists (test_path)): -            revision += 1 -            test_name = "build-%s-%d" % (datestr, revision) -            test_path = os.path.join (self.results_directory, test_name) - -        return test_name - -    # Take a BuildConfiguration and then try and build it based on the -    # parameters of that configuration. S -    def do_build (self, conf): -        server = self.server - -        # Work out the build directory. Note we actually create the -        # directories here since we need to write the ".conf" file. Otherwise -        # we could have relied on bitbake's builder thread to actually make -        # the directories as it proceeds with the build. -        ident = self.get_next_build_ident () -        build_directory = os.path.join (self.results_directory, -            ident) -        self.cur_build_directory = build_directory -        os.makedirs (build_directory) - -        conffile = os.path.join (build_directory, ".conf") -        conf.write_to_file (conffile) - -        # Add a row to the model representing this ongoing build. It's kinda a -        # fake entry. If this build completes or fails then this gets updated -        # with the real stuff like the historic builds -        date = long (time.time()) -        self.model.append (None, (ident, conf.image, conf.machine, conf.distro, -            None, date, BuildResult.STATE_ONGOING)) -        try: -            server.runCommand(["setVariable", "BUILD_IMAGES_FROM_FEEDS", 1]) -            server.runCommand(["setVariable", "MACHINE", conf.machine]) -            server.runCommand(["setVariable", "DISTRO", conf.distro]) -            server.runCommand(["setVariable", "PACKAGE_CLASSES", "package_ipk"]) -            server.runCommand(["setVariable", "BBFILES", \ -              """${OEROOT}/meta/packages/*/*.bb ${OEROOT}/meta-moblin/packages/*/*.bb"""]) -            server.runCommand(["setVariable", "TMPDIR", "${OEROOT}/build/tmp"]) -            server.runCommand(["setVariable", "IPK_FEED_URIS", \ -                " ".join(conf.get_repos())]) -            server.runCommand(["setVariable", "DEPLOY_DIR_IMAGE", -                build_directory]) -            server.runCommand(["buildTargets", [conf.image], "rootfs"]) - -        except Exception as e: -            print(e) - -class BuildManagerTreeView (gtk.TreeView): -    """ The tree view for the build manager. This shows the historic builds -    and so forth. """ - -    # We use this function to control what goes in the cell since we store -    # the date in the model as seconds since the epoch (for sorting) and so we -    # need to make it human readable. -    def date_format_custom_cell_data_func (self, col, cell, model, iter): -        date = model.get (iter, BuildManagerModel.COL_DATE)[0] -        datestr = time.strftime("%A %d %B %Y", time.localtime(date)) -        cell.set_property ("text", datestr) - -    # This format function controls what goes in the cell. We use this to map -    # the integer state to a string and also to colourise the text -    def state_format_custom_cell_data_fun (self, col, cell, model, iter): -        state = model.get (iter, BuildManagerModel.COL_STATE)[0] - -        if (state == BuildResult.STATE_ONGOING): -            cell.set_property ("text", "Active") -            cell.set_property ("foreground", "#000000") -        elif (state == BuildResult.STATE_FAILED): -            cell.set_property ("text", "Failed") -            cell.set_property ("foreground", "#ff0000") -        elif (state == BuildResult.STATE_COMPLETE): -            cell.set_property ("text", "Complete") -            cell.set_property ("foreground", "#00ff00") -        else: -            cell.set_property ("text", "") - -    def __init__ (self): -        gtk.TreeView.__init__(self) - -        # Misc descriptiony thing -        renderer = gtk.CellRendererText () -        col = gtk.TreeViewColumn (None, renderer, -            text=BuildManagerModel.COL_DESC) -        self.append_column (col) - -        # Machine -        renderer = gtk.CellRendererText () -        col = gtk.TreeViewColumn ("Machine", renderer, -            text=BuildManagerModel.COL_MACHINE) -        self.append_column (col) - -        # distro -        renderer = gtk.CellRendererText () -        col = gtk.TreeViewColumn ("Distribution", renderer, -            text=BuildManagerModel.COL_DISTRO) -        self.append_column (col) - -        # date (using a custom function for formatting the cell contents it -        # takes epoch -> human readable string) -        renderer = gtk.CellRendererText () -        col = gtk.TreeViewColumn ("Date", renderer, -            text=BuildManagerModel.COL_DATE) -        self.append_column (col) -        col.set_cell_data_func (renderer, -            self.date_format_custom_cell_data_func) - -        # For status. -        renderer = gtk.CellRendererText () -        col = gtk.TreeViewColumn ("Status", renderer, -            text = BuildManagerModel.COL_STATE) -        self.append_column (col) -        col.set_cell_data_func (renderer, -            self.state_format_custom_cell_data_fun) diff --git a/bitbake/lib/bb/ui/crumbs/progress.py b/bitbake/lib/bb/ui/crumbs/progress.py deleted file mode 100644 index 36eca3829..000000000 --- a/bitbake/lib/bb/ui/crumbs/progress.py +++ /dev/null @@ -1,17 +0,0 @@ -import gtk - -class ProgressBar(gtk.Dialog): -    def __init__(self, parent): - -        gtk.Dialog.__init__(self) -        self.set_title("Parsing metadata, please wait...") -        self.set_default_size(500, 0) -        self.set_transient_for(parent) -        self.set_destroy_with_parent(True) -        self.progress = gtk.ProgressBar() -        self.vbox.pack_start(self.progress) -        self.show_all() - -    def update(self, x, y): -        self.progress.set_fraction(float(x)/float(y)) -        self.progress.set_text("%2d %%" % (x*100/y)) diff --git a/bitbake/lib/bb/ui/crumbs/puccho.glade b/bitbake/lib/bb/ui/crumbs/puccho.glade deleted file mode 100644 index d7553a6e1..000000000 --- a/bitbake/lib/bb/ui/crumbs/puccho.glade +++ /dev/null @@ -1,606 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--Generated with glade3 3.4.5 on Mon Nov 10 12:24:12 2008 --> -<glade-interface> -  <widget class="GtkDialog" id="build_dialog"> -    <property name="title" translatable="yes">Start a build</property> -    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> -    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> -    <property name="has_separator">False</property> -    <child internal-child="vbox"> -      <widget class="GtkVBox" id="dialog-vbox1"> -        <property name="visible">True</property> -        <property name="spacing">2</property> -        <child> -          <widget class="GtkTable" id="build_table"> -            <property name="visible">True</property> -            <property name="border_width">6</property> -            <property name="n_rows">7</property> -            <property name="n_columns">3</property> -            <property name="column_spacing">5</property> -            <property name="row_spacing">6</property> -            <child> -              <widget class="GtkAlignment" id="status_alignment"> -                <property name="visible">True</property> -                <property name="left_padding">12</property> -                <child> -                  <widget class="GtkHBox" id="status_hbox"> -                    <property name="spacing">6</property> -                    <child> -                      <widget class="GtkImage" id="status_image"> -                        <property name="visible">True</property> -                        <property name="no_show_all">True</property> -                        <property name="xalign">0</property> -                        <property name="stock">gtk-dialog-error</property> -                      </widget> -                      <packing> -                        <property name="expand">False</property> -                        <property name="fill">False</property> -                      </packing> -                    </child> -                    <child> -                      <widget class="GtkLabel" id="status_label"> -                        <property name="visible">True</property> -                        <property name="xalign">0</property> -                        <property name="label" translatable="yes">If you see this text something is wrong...</property> -                        <property name="use_markup">True</property> -                        <property name="use_underline">True</property> -                      </widget> -                      <packing> -                        <property name="position">1</property> -                      </packing> -                    </child> -                  </widget> -                </child> -              </widget> -              <packing> -                <property name="right_attach">3</property> -                <property name="top_attach">2</property> -                <property name="bottom_attach">3</property> -              </packing> -            </child> -            <child> -              <widget class="GtkLabel" id="label2"> -                <property name="visible">True</property> -                <property name="xalign">0</property> -                <property name="label" translatable="yes"><b>Build configuration</b></property> -                <property name="use_markup">True</property> -              </widget> -              <packing> -                <property name="right_attach">3</property> -                <property name="top_attach">3</property> -                <property name="bottom_attach">4</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkComboBox" id="image_combo"> -                <property name="visible">True</property> -                <property name="sensitive">False</property> -              </widget> -              <packing> -                <property name="left_attach">1</property> -                <property name="right_attach">2</property> -                <property name="top_attach">6</property> -                <property name="bottom_attach">7</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkLabel" id="image_label"> -                <property name="visible">True</property> -                <property name="sensitive">False</property> -                <property name="xalign">0</property> -                <property name="xpad">12</property> -                <property name="label" translatable="yes">Image:</property> -              </widget> -              <packing> -                <property name="top_attach">6</property> -                <property name="bottom_attach">7</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkComboBox" id="distribution_combo"> -                <property name="visible">True</property> -                <property name="sensitive">False</property> -              </widget> -              <packing> -                <property name="left_attach">1</property> -                <property name="right_attach">2</property> -                <property name="top_attach">5</property> -                <property name="bottom_attach">6</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkLabel" id="distribution_label"> -                <property name="visible">True</property> -                <property name="sensitive">False</property> -                <property name="xalign">0</property> -                <property name="xpad">12</property> -                <property name="label" translatable="yes">Distribution:</property> -              </widget> -              <packing> -                <property name="top_attach">5</property> -                <property name="bottom_attach">6</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkComboBox" id="machine_combo"> -                <property name="visible">True</property> -                <property name="sensitive">False</property> -              </widget> -              <packing> -                <property name="left_attach">1</property> -                <property name="right_attach">2</property> -                <property name="top_attach">4</property> -                <property name="bottom_attach">5</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkLabel" id="machine_label"> -                <property name="visible">True</property> -                <property name="sensitive">False</property> -                <property name="xalign">0</property> -                <property name="xpad">12</property> -                <property name="label" translatable="yes">Machine:</property> -              </widget> -              <packing> -                <property name="top_attach">4</property> -                <property name="bottom_attach">5</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkButton" id="refresh_button"> -                <property name="visible">True</property> -                <property name="sensitive">False</property> -                <property name="can_focus">True</property> -                <property name="receives_default">True</property> -                <property name="label" translatable="yes">gtk-refresh</property> -                <property name="use_stock">True</property> -                <property name="response_id">0</property> -              </widget> -              <packing> -                <property name="left_attach">2</property> -                <property name="right_attach">3</property> -                <property name="top_attach">1</property> -                <property name="bottom_attach">2</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkEntry" id="location_entry"> -                <property name="visible">True</property> -                <property name="can_focus">True</property> -                <property name="width_chars">32</property> -              </widget> -              <packing> -                <property name="left_attach">1</property> -                <property name="right_attach">2</property> -                <property name="top_attach">1</property> -                <property name="bottom_attach">2</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkLabel" id="label3"> -                <property name="visible">True</property> -                <property name="xalign">0</property> -                <property name="xpad">12</property> -                <property name="label" translatable="yes">Location:</property> -              </widget> -              <packing> -                <property name="top_attach">1</property> -                <property name="bottom_attach">2</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkLabel" id="label1"> -                <property name="visible">True</property> -                <property name="xalign">0</property> -                <property name="label" translatable="yes"><b>Repository</b></property> -                <property name="use_markup">True</property> -              </widget> -              <packing> -                <property name="right_attach">3</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkAlignment" id="alignment1"> -                <property name="visible">True</property> -                <child> -                  <placeholder/> -                </child> -              </widget> -              <packing> -                <property name="left_attach">2</property> -                <property name="right_attach">3</property> -                <property name="top_attach">4</property> -                <property name="bottom_attach">5</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkAlignment" id="alignment2"> -                <property name="visible">True</property> -                <child> -                  <placeholder/> -                </child> -              </widget> -              <packing> -                <property name="left_attach">2</property> -                <property name="right_attach">3</property> -                <property name="top_attach">5</property> -                <property name="bottom_attach">6</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkAlignment" id="alignment3"> -                <property name="visible">True</property> -                <child> -                  <placeholder/> -                </child> -              </widget> -              <packing> -                <property name="left_attach">2</property> -                <property name="right_attach">3</property> -                <property name="top_attach">6</property> -                <property name="bottom_attach">7</property> -                <property name="y_options"></property> -              </packing> -            </child> -          </widget> -          <packing> -            <property name="position">1</property> -          </packing> -        </child> -        <child internal-child="action_area"> -          <widget class="GtkHButtonBox" id="dialog-action_area1"> -            <property name="visible">True</property> -            <property name="layout_style">GTK_BUTTONBOX_END</property> -            <child> -              <placeholder/> -            </child> -            <child> -              <placeholder/> -            </child> -            <child> -              <placeholder/> -            </child> -          </widget> -          <packing> -            <property name="expand">False</property> -            <property name="pack_type">GTK_PACK_END</property> -          </packing> -        </child> -      </widget> -    </child> -  </widget> -  <widget class="GtkDialog" id="dialog2"> -    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property> -    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property> -    <property name="has_separator">False</property> -    <child internal-child="vbox"> -      <widget class="GtkVBox" id="dialog-vbox2"> -        <property name="visible">True</property> -        <property name="spacing">2</property> -        <child> -          <widget class="GtkTable" id="table2"> -            <property name="visible">True</property> -            <property name="border_width">6</property> -            <property name="n_rows">7</property> -            <property name="n_columns">3</property> -            <property name="column_spacing">6</property> -            <property name="row_spacing">6</property> -            <child> -              <widget class="GtkLabel" id="label7"> -                <property name="visible">True</property> -                <property name="xalign">0</property> -                <property name="label" translatable="yes"><b>Repositories</b></property> -                <property name="use_markup">True</property> -              </widget> -              <packing> -                <property name="right_attach">3</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkAlignment" id="alignment4"> -                <property name="visible">True</property> -                <property name="xalign">0</property> -                <property name="left_padding">12</property> -                <child> -                  <widget class="GtkScrolledWindow" id="scrolledwindow1"> -                    <property name="visible">True</property> -                    <property name="can_focus">True</property> -                    <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> -                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> -                    <child> -                      <widget class="GtkTreeView" id="treeview1"> -                        <property name="visible">True</property> -                        <property name="can_focus">True</property> -                        <property name="headers_clickable">True</property> -                      </widget> -                    </child> -                  </widget> -                </child> -              </widget> -              <packing> -                <property name="right_attach">3</property> -                <property name="top_attach">2</property> -                <property name="bottom_attach">3</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkEntry" id="entry1"> -                <property name="visible">True</property> -                <property name="can_focus">True</property> -              </widget> -              <packing> -                <property name="left_attach">1</property> -                <property name="right_attach">3</property> -                <property name="top_attach">1</property> -                <property name="bottom_attach">2</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkLabel" id="label9"> -                <property name="visible">True</property> -                <property name="xalign">0</property> -                <property name="label" translatable="yes"><b>Additional packages</b></property> -                <property name="use_markup">True</property> -              </widget> -              <packing> -                <property name="right_attach">3</property> -                <property name="top_attach">4</property> -                <property name="bottom_attach">5</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkAlignment" id="alignment6"> -                <property name="visible">True</property> -                <property name="xalign">0</property> -                <property name="xscale">0</property> -                <child> -                  <widget class="GtkLabel" id="label8"> -                    <property name="visible">True</property> -                    <property name="xalign">0</property> -                    <property name="yalign">0</property> -                    <property name="xpad">12</property> -                    <property name="label" translatable="yes">Location: </property> -                  </widget> -                </child> -              </widget> -              <packing> -                <property name="top_attach">1</property> -                <property name="bottom_attach">2</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkAlignment" id="alignment7"> -                <property name="visible">True</property> -                <property name="xalign">1</property> -                <property name="xscale">0</property> -                <child> -                  <widget class="GtkHButtonBox" id="hbuttonbox1"> -                    <property name="visible">True</property> -                    <property name="spacing">5</property> -                    <child> -                      <widget class="GtkButton" id="button7"> -                        <property name="visible">True</property> -                        <property name="can_focus">True</property> -                        <property name="receives_default">True</property> -                        <property name="label" translatable="yes">gtk-remove</property> -                        <property name="use_stock">True</property> -                        <property name="response_id">0</property> -                      </widget> -                    </child> -                    <child> -                      <widget class="GtkButton" id="button6"> -                        <property name="visible">True</property> -                        <property name="can_focus">True</property> -                        <property name="receives_default">True</property> -                        <property name="label" translatable="yes">gtk-edit</property> -                        <property name="use_stock">True</property> -                        <property name="response_id">0</property> -                      </widget> -                      <packing> -                        <property name="position">1</property> -                      </packing> -                    </child> -                    <child> -                      <widget class="GtkButton" id="button5"> -                        <property name="visible">True</property> -                        <property name="can_focus">True</property> -                        <property name="receives_default">True</property> -                        <property name="label" translatable="yes">gtk-add</property> -                        <property name="use_stock">True</property> -                        <property name="response_id">0</property> -                      </widget> -                      <packing> -                        <property name="position">2</property> -                      </packing> -                    </child> -                  </widget> -                </child> -              </widget> -              <packing> -                <property name="left_attach">1</property> -                <property name="right_attach">3</property> -                <property name="top_attach">3</property> -                <property name="bottom_attach">4</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkAlignment" id="alignment5"> -                <property name="visible">True</property> -                <child> -                  <placeholder/> -                </child> -              </widget> -              <packing> -                <property name="top_attach">3</property> -                <property name="bottom_attach">4</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkLabel" id="label10"> -                <property name="visible">True</property> -                <property name="xalign">0</property> -                <property name="yalign">0</property> -                <property name="xpad">12</property> -                <property name="label" translatable="yes">Search:</property> -              </widget> -              <packing> -                <property name="top_attach">5</property> -                <property name="bottom_attach">6</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkEntry" id="entry2"> -                <property name="visible">True</property> -                <property name="can_focus">True</property> -              </widget> -              <packing> -                <property name="left_attach">1</property> -                <property name="right_attach">3</property> -                <property name="top_attach">5</property> -                <property name="bottom_attach">6</property> -                <property name="y_options"></property> -              </packing> -            </child> -            <child> -              <widget class="GtkAlignment" id="alignment8"> -                <property name="visible">True</property> -                <property name="xalign">0</property> -                <property name="left_padding">12</property> -                <child> -                  <widget class="GtkScrolledWindow" id="scrolledwindow2"> -                    <property name="visible">True</property> -                    <property name="can_focus">True</property> -                    <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> -                    <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> -                    <child> -                      <widget class="GtkTreeView" id="treeview2"> -                        <property name="visible">True</property> -                        <property name="can_focus">True</property> -                        <property name="headers_clickable">True</property> -                      </widget> -                    </child> -                  </widget> -                </child> -              </widget> -              <packing> -                <property name="right_attach">3</property> -                <property name="top_attach">6</property> -                <property name="bottom_attach">7</property> -                <property name="y_options"></property> -              </packing> -            </child> -          </widget> -          <packing> -            <property name="position">1</property> -          </packing> -        </child> -        <child internal-child="action_area"> -          <widget class="GtkHButtonBox" id="dialog-action_area2"> -            <property name="visible">True</property> -            <property name="layout_style">GTK_BUTTONBOX_END</property> -            <child> -              <widget class="GtkButton" id="button4"> -                <property name="visible">True</property> -                <property name="can_focus">True</property> -                <property name="receives_default">True</property> -                <property name="label" translatable="yes">gtk-close</property> -                <property name="use_stock">True</property> -                <property name="response_id">0</property> -              </widget> -            </child> -          </widget> -          <packing> -            <property name="expand">False</property> -            <property name="pack_type">GTK_PACK_END</property> -          </packing> -        </child> -      </widget> -    </child> -  </widget> -  <widget class="GtkWindow" id="main_window"> -    <child> -      <widget class="GtkVBox" id="main_window_vbox"> -        <property name="visible">True</property> -        <child> -          <widget class="GtkToolbar" id="main_toolbar"> -            <property name="visible">True</property> -            <child> -              <widget class="GtkToolButton" id="main_toolbutton_build"> -                <property name="visible">True</property> -                <property name="label" translatable="yes">Build</property> -                <property name="stock_id">gtk-execute</property> -              </widget> -              <packing> -                <property name="expand">False</property> -              </packing> -            </child> -          </widget> -          <packing> -            <property name="expand">False</property> -          </packing> -        </child> -        <child> -          <widget class="GtkVPaned" id="vpaned1"> -            <property name="visible">True</property> -            <property name="can_focus">True</property> -            <child> -              <widget class="GtkScrolledWindow" id="results_scrolledwindow"> -                <property name="visible">True</property> -                <property name="can_focus">True</property> -                <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> -                <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> -                <child> -                  <placeholder/> -                </child> -              </widget> -              <packing> -                <property name="resize">False</property> -                <property name="shrink">True</property> -              </packing> -            </child> -            <child> -              <widget class="GtkScrolledWindow" id="progress_scrolledwindow"> -                <property name="visible">True</property> -                <property name="can_focus">True</property> -                <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> -                <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> -                <child> -                  <placeholder/> -                </child> -              </widget> -              <packing> -                <property name="resize">True</property> -                <property name="shrink">True</property> -              </packing> -            </child> -          </widget> -          <packing> -            <property name="position">1</property> -          </packing> -        </child> -      </widget> -    </child> -  </widget> -</glade-interface> diff --git a/bitbake/lib/bb/ui/crumbs/runningbuild.py b/bitbake/lib/bb/ui/crumbs/runningbuild.py deleted file mode 100644 index 4703e6d84..000000000 --- a/bitbake/lib/bb/ui/crumbs/runningbuild.py +++ /dev/null @@ -1,311 +0,0 @@ - -# -# BitBake Graphical GTK User Interface -# -# Copyright (C) 2008        Intel Corporation -# -# Authored by Rob Bradford <rob@linux.intel.com> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -import gtk -import gobject -import logging -import time -import urllib -import urllib2 - -class Colors(object): -    OK = "#ffffff" -    RUNNING = "#aaffaa" -    WARNING ="#f88017" -    ERROR = "#ffaaaa" - -class RunningBuildModel (gtk.TreeStore): -    (COL_LOG, COL_PACKAGE, COL_TASK, COL_MESSAGE, COL_ICON, COL_COLOR, COL_NUM_ACTIVE) = range(7) - -    def __init__ (self): -        gtk.TreeStore.__init__ (self, -                                gobject.TYPE_STRING, -                                gobject.TYPE_STRING, -                                gobject.TYPE_STRING, -                                gobject.TYPE_STRING, -                                gobject.TYPE_STRING, -                                gobject.TYPE_STRING, -                                gobject.TYPE_INT) - -class RunningBuild (gobject.GObject): -    __gsignals__ = { -          'build-succeeded' : (gobject.SIGNAL_RUN_LAST, -                               gobject.TYPE_NONE, -                               ()), -          'build-failed' : (gobject.SIGNAL_RUN_LAST, -                            gobject.TYPE_NONE, -                            ()) -          } -    pids_to_task = {} -    tasks_to_iter = {} - -    def __init__ (self): -        gobject.GObject.__init__ (self) -        self.model = RunningBuildModel() - -    def handle_event (self, event, pbar=None): -        # Handle an event from the event queue, this may result in updating -        # the model and thus the UI. Or it may be to tell us that the build -        # has finished successfully (or not, as the case may be.) - -        parent = None -        pid = 0 -        package = None -        task = None - -        # If we have a pid attached to this message/event try and get the -        # (package, task) pair for it. If we get that then get the parent iter -        # for the message. -        if hasattr(event, 'pid'): -            pid = event.pid -        if hasattr(event, 'process'): -            pid = event.process - -        if pid and pid in self.pids_to_task: -            (package, task) = self.pids_to_task[pid] -            parent = self.tasks_to_iter[(package, task)] - -        if(isinstance(event, logging.LogRecord)): -            if (event.msg.startswith ("Running task")): -                return # don't add these to the list - -            if event.levelno >= logging.ERROR: -                icon = "dialog-error" -                color = Colors.ERROR -            elif event.levelno >= logging.WARNING: -                icon = "dialog-warning" -                color = Colors.WARNING -            else: -                icon = None -                color = Colors.OK - -            # if we know which package we belong to, we'll append onto its list. -            # otherwise, we'll jump to the top of the master list -            if parent: -                tree_add = self.model.append -            else: -                tree_add = self.model.prepend -            tree_add(parent, -                              (None, -                               package, -                               task, -                               event.getMessage(), -                               icon, -                               color, -                               0)) - -        elif isinstance(event, bb.build.TaskStarted): -            (package, task) = (event._package, event._task) - -            # Save out this PID. -            self.pids_to_task[pid] = (package, task) - -            # Check if we already have this package in our model. If so then -            # that can be the parent for the task. Otherwise we create a new -            # top level for the package. -            if ((package, None) in self.tasks_to_iter): -                parent = self.tasks_to_iter[(package, None)] -            else: -                parent = self.model.prepend(None, (None, -                                                   package, -                                                   None, -                                                   "Package: %s" % (package), -                                                   None, -                                                   Colors.OK, -                                                   0)) -                self.tasks_to_iter[(package, None)] = parent - -            # Because this parent package now has an active child mark it as -            # such. -            # @todo if parent is already in error, don't mark it green -            self.model.set(parent, self.model.COL_ICON, "gtk-execute", -                           self.model.COL_COLOR, Colors.RUNNING) - -            # Add an entry in the model for this task -            i = self.model.append (parent, (None, -                                            package, -                                            task, -                                            "Task: %s" % (task), -                                            "gtk-execute", -                                            Colors.RUNNING, -                                            0)) - -            # update the parent's active task count -            num_active = self.model.get(parent, self.model.COL_NUM_ACTIVE)[0] + 1 -            self.model.set(parent, self.model.COL_NUM_ACTIVE, num_active) - -            # Save out the iter so that we can find it when we have a message -            # that we need to attach to a task. -            self.tasks_to_iter[(package, task)] = i - -        elif isinstance(event, bb.build.TaskBase): -            current = self.tasks_to_iter[(package, task)] -            parent = self.tasks_to_iter[(package, None)] - -            # remove this task from the parent's active count -            num_active = self.model.get(parent, self.model.COL_NUM_ACTIVE)[0] - 1 -            self.model.set(parent, self.model.COL_NUM_ACTIVE, num_active) - -            if isinstance(event, bb.build.TaskFailed): -                # Mark the task and parent as failed -                icon = "dialog-error" -                color = Colors.ERROR - -                logfile = event.logfile -                if logfile and os.path.exists(logfile): -                    with open(logfile) as f: -                        logdata = f.read() -                        self.model.append(current, ('pastebin', None, None, logdata, 'gtk-error', Colors.OK, 0)) - -                for i in (current, parent): -                    self.model.set(i, self.model.COL_ICON, icon, -                                   self.model.COL_COLOR, color) -            else: -                icon = None -                color = Colors.OK - -                # Mark the task as inactive -                self.model.set(current, self.model.COL_ICON, icon, -                               self.model.COL_COLOR, color) - -                # Mark the parent package as inactive, but make sure to -                # preserve error and active states -                i = self.tasks_to_iter[(package, None)] -                if self.model.get(parent, self.model.COL_ICON) != 'dialog-error': -                    self.model.set(parent, self.model.COL_ICON, icon) -                    if num_active == 0: -                        self.model.set(parent, self.model.COL_COLOR, Colors.OK) - -            # Clear the iters and the pids since when the task goes away the -            # pid will no longer be used for messages -            del self.tasks_to_iter[(package, task)] -            del self.pids_to_task[pid] - -        elif isinstance(event, bb.event.BuildStarted): - -            self.model.prepend(None, (None, -                                      None, -                                      None, -                                      "Build Started (%s)" % time.strftime('%m/%d/%Y %H:%M:%S'), -                                      None, -                                      Colors.OK, -                                      0)) -        elif isinstance(event, bb.event.BuildCompleted): -            failures = int (event._failures) -            self.model.prepend(None, (None, -                                      None, -                                      None, -                                      "Build Completed (%s)" % time.strftime('%m/%d/%Y %H:%M:%S'), -                                      None, -                                      Colors.OK, -                                      0)) - -            # Emit the appropriate signal depending on the number of failures -            if (failures >= 1): -                self.emit ("build-failed") -            else: -                self.emit ("build-succeeded") - -        elif isinstance(event, bb.event.CacheLoadStarted) and pbar: -            pbar.set_title("Loading cache") -            self.progress_total = event.total -            pbar.update(0, self.progress_total) -        elif isinstance(event, bb.event.CacheLoadProgress) and pbar: -            pbar.update(event.current, self.progress_total) -        elif isinstance(event, bb.event.CacheLoadCompleted) and pbar: -            pbar.update(self.progress_total, self.progress_total) - -        elif isinstance(event, bb.event.ParseStarted) and pbar: -            pbar.set_title("Processing recipes") -            self.progress_total = event.total -            pbar.update(0, self.progress_total) -        elif isinstance(event, bb.event.ParseProgress) and pbar: -            pbar.update(event.current, self.progress_total) -        elif isinstance(event, bb.event.ParseCompleted) and pbar: -            pbar.hide() - -        return - - -def do_pastebin(text): -    url = 'http://pastebin.com/api_public.php' -    params = {'paste_code': text, 'paste_format': 'text'} - -    req = urllib2.Request(url, urllib.urlencode(params)) -    response = urllib2.urlopen(req) -    paste_url = response.read() - -    return paste_url - - -class RunningBuildTreeView (gtk.TreeView): -    __gsignals__ = { -        "button_press_event" : "override" -        } -    def __init__ (self): -        gtk.TreeView.__init__ (self) - -        # The icon that indicates whether we're building or failed. -        renderer = gtk.CellRendererPixbuf () -        col = gtk.TreeViewColumn ("Status", renderer) -        col.add_attribute (renderer, "icon-name", 4) -        self.append_column (col) - -        # The message of the build. -        self.message_renderer = gtk.CellRendererText () -        self.message_column = gtk.TreeViewColumn ("Message", self.message_renderer, text=3) -        self.message_column.add_attribute(self.message_renderer, 'background', 5) -        self.message_renderer.set_property('editable', 5) -        self.append_column (self.message_column) - -    def do_button_press_event(self, event): -        gtk.TreeView.do_button_press_event(self, event) - -        if event.button == 3: -            selection = super(RunningBuildTreeView, self).get_selection() -            (model, iter) = selection.get_selected() -            if iter is not None: -                can_paste = model.get(iter, model.COL_LOG)[0] -                if can_paste == 'pastebin': -                    # build a simple menu with a pastebin option -                    menu = gtk.Menu() -                    menuitem = gtk.MenuItem("Send log to pastebin") -                    menu.append(menuitem) -                    menuitem.connect("activate", self.pastebin_handler, (model, iter)) -                    menuitem.show() -                    menu.show() -                    menu.popup(None, None, None, event.button, event.time) - -    def pastebin_handler(self, widget, data): -        """ -        Send the log data to pastebin, then add the new paste url to the -        clipboard. -        """ -        (model, iter) = data -        paste_url = do_pastebin(model.get(iter, model.COL_MESSAGE)[0]) - -        # @todo Provide visual feedback to the user that it is done and that -        # it worked. -        print paste_url - -        clipboard = gtk.clipboard_get() -        clipboard.set_text(paste_url) -        clipboard.store()
\ No newline at end of file diff --git a/bitbake/lib/bb/ui/depexp.py b/bitbake/lib/bb/ui/depexp.py deleted file mode 100644 index 3dbd5e0ec..000000000 --- a/bitbake/lib/bb/ui/depexp.py +++ /dev/null @@ -1,307 +0,0 @@ -# -# BitBake Graphical GTK based Dependency Explorer -# -# Copyright (C) 2007        Ross Burton -# Copyright (C) 2007 - 2008 Richard Purdie -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -import gobject -import gtk -import Queue -import threading -import xmlrpclib -import bb -import bb.event -from bb.ui.crumbs.progress import ProgressBar - -# Package Model -(COL_PKG_NAME) = (0) - -# Dependency Model -(TYPE_DEP, TYPE_RDEP) = (0, 1) -(COL_DEP_TYPE, COL_DEP_PARENT, COL_DEP_PACKAGE) = (0, 1, 2) - - -class PackageDepView(gtk.TreeView): -    def __init__(self, model, dep_type, label): -        gtk.TreeView.__init__(self) -        self.current = None -        self.dep_type = dep_type -        self.filter_model = model.filter_new() -        self.filter_model.set_visible_func(self._filter) -        self.set_model(self.filter_model) -        #self.connect("row-activated", self.on_package_activated, COL_DEP_PACKAGE) -        self.append_column(gtk.TreeViewColumn(label, gtk.CellRendererText(), text=COL_DEP_PACKAGE)) - -    def _filter(self, model, iter): -        (this_type, package) = model.get(iter, COL_DEP_TYPE, COL_DEP_PARENT) -        if this_type != self.dep_type: return False -        return package == self.current - -    def set_current_package(self, package): -        self.current = package -        self.filter_model.refilter() - - -class PackageReverseDepView(gtk.TreeView): -    def __init__(self, model, label): -        gtk.TreeView.__init__(self) -        self.current = None -        self.filter_model = model.filter_new() -        self.filter_model.set_visible_func(self._filter) -        self.set_model(self.filter_model) -        self.append_column(gtk.TreeViewColumn(label, gtk.CellRendererText(), text=COL_DEP_PARENT)) - -    def _filter(self, model, iter): -        package = model.get_value(iter, COL_DEP_PACKAGE) -        return package == self.current - -    def set_current_package(self, package): -        self.current = package -        self.filter_model.refilter() - - -class DepExplorer(gtk.Window): -    def __init__(self): -        gtk.Window.__init__(self) -        self.set_title("Dependency Explorer") -        self.set_default_size(500, 500) -        self.connect("delete-event", gtk.main_quit) - -        # Create the data models -        self.pkg_model = gtk.ListStore(gobject.TYPE_STRING) -        self.pkg_model.set_sort_column_id(COL_PKG_NAME, gtk.SORT_ASCENDING) -        self.depends_model = gtk.ListStore(gobject.TYPE_INT, gobject.TYPE_STRING, gobject.TYPE_STRING) -        self.depends_model.set_sort_column_id(COL_DEP_PACKAGE, gtk.SORT_ASCENDING) - -        pane = gtk.HPaned() -        pane.set_position(250) -        self.add(pane) - -        # The master list of packages -        scrolled = gtk.ScrolledWindow() -        scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) -        scrolled.set_shadow_type(gtk.SHADOW_IN) - -        self.pkg_treeview = gtk.TreeView(self.pkg_model) -        self.pkg_treeview.get_selection().connect("changed", self.on_cursor_changed) -        column = gtk.TreeViewColumn("Package", gtk.CellRendererText(), text=COL_PKG_NAME) -        self.pkg_treeview.append_column(column) -        pane.add1(scrolled) -        scrolled.add(self.pkg_treeview) - -        box = gtk.VBox(homogeneous=True, spacing=4) - -        # Runtime Depends -        scrolled = gtk.ScrolledWindow() -        scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) -        scrolled.set_shadow_type(gtk.SHADOW_IN) -        self.rdep_treeview = PackageDepView(self.depends_model, TYPE_RDEP, "Runtime Depends") -        self.rdep_treeview.connect("row-activated", self.on_package_activated, COL_DEP_PACKAGE) -        scrolled.add(self.rdep_treeview) -        box.add(scrolled) - -        # Build Depends -        scrolled = gtk.ScrolledWindow() -        scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) -        scrolled.set_shadow_type(gtk.SHADOW_IN) -        self.dep_treeview = PackageDepView(self.depends_model, TYPE_DEP, "Build Depends") -        self.dep_treeview.connect("row-activated", self.on_package_activated, COL_DEP_PACKAGE) -        scrolled.add(self.dep_treeview) -        box.add(scrolled) -        pane.add2(box) - -        # Reverse Depends -        scrolled = gtk.ScrolledWindow() -        scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) -        scrolled.set_shadow_type(gtk.SHADOW_IN) -        self.revdep_treeview = PackageReverseDepView(self.depends_model, "Reverse Depends") -        self.revdep_treeview.connect("row-activated", self.on_package_activated, COL_DEP_PARENT) -        scrolled.add(self.revdep_treeview) -        box.add(scrolled) -        pane.add2(box) - -        self.show_all() - -    def on_package_activated(self, treeview, path, column, data_col): -        model = treeview.get_model() -        package = model.get_value(model.get_iter(path), data_col) - -        pkg_path = [] -        def finder(model, path, iter, needle): -            package = model.get_value(iter, COL_PKG_NAME) -            if package == needle: -                pkg_path.append(path) -                return True -            else: -                return False -        self.pkg_model.foreach(finder, package) -        if pkg_path: -            self.pkg_treeview.get_selection().select_path(pkg_path[0]) -            self.pkg_treeview.scroll_to_cell(pkg_path[0]) - -    def on_cursor_changed(self, selection): -        (model, it) = selection.get_selected() -        if iter is None: -            current_package = None -        else: -            current_package = model.get_value(it, COL_PKG_NAME) -        self.rdep_treeview.set_current_package(current_package) -        self.dep_treeview.set_current_package(current_package) -        self.revdep_treeview.set_current_package(current_package) - - -def parse(depgraph, pkg_model, depends_model): -    for package in depgraph["pn"]: -        pkg_model.set(pkg_model.append(), COL_PKG_NAME, package) - -    for package in depgraph["depends"]: -        for depend in depgraph["depends"][package]: -            depends_model.set (depends_model.append(), -                              COL_DEP_TYPE, TYPE_DEP, -                              COL_DEP_PARENT, package, -                              COL_DEP_PACKAGE, depend) - -    for package in depgraph["rdepends-pn"]: -        for rdepend in depgraph["rdepends-pn"][package]: -            depends_model.set (depends_model.append(), -                              COL_DEP_TYPE, TYPE_RDEP, -                              COL_DEP_PARENT, package, -                              COL_DEP_PACKAGE, rdepend) - - -class gtkthread(threading.Thread): -    quit = threading.Event() -    def __init__(self, shutdown): -        threading.Thread.__init__(self) -        self.setDaemon(True) -        self.shutdown = shutdown - -    def run(self): -        gobject.threads_init() -        gtk.gdk.threads_init() -        gtk.main() -        gtkthread.quit.set() - - -def main(server, eventHandler): -    try: -        cmdline = server.runCommand(["getCmdLineAction"]) -        if not cmdline or cmdline[0] != "generateDotGraph": -            print("This UI is only compatible with the -g option") -            return -        ret = server.runCommand(["generateDepTreeEvent", cmdline[1], cmdline[2]]) -        if ret != True: -            print("Couldn't run command! %s" % ret) -            return -    except xmlrpclib.Fault as x: -        print("XMLRPC Fault getting commandline:\n %s" % x) -        return - -    shutdown = 0 - -    gtkgui = gtkthread(shutdown) -    gtkgui.start() - -    gtk.gdk.threads_enter() -    dep = DepExplorer() -    pbar = ProgressBar(dep) -    pbar.connect("delete-event", gtk.main_quit) -    gtk.gdk.threads_leave() - -    progress_total = 0 -    while True: -        try: -            event = eventHandler.waitEvent(0.25) -            if gtkthread.quit.isSet(): -                server.runCommand(["stateStop"]) -                break - -            if event is None: -                continue - -            if isinstance(event, bb.event.CacheLoadStarted): -                progress_total = event.total -                gtk.gdk.threads_enter() -                pbar.set_title("Loading Cache") -                pbar.update(0, progress_total) -                gtk.gdk.threads_leave() - -            if isinstance(event, bb.event.CacheLoadProgress): -                x = event.current -                gtk.gdk.threads_enter() -                pbar.update(x, progress_total) -                gtk.gdk.threads_leave() -                continue - -            if isinstance(event, bb.event.CacheLoadCompleted): -                gtk.gdk.threads_enter() -                pbar.update(progress_total, progress_total) -                gtk.gdk.threads_leave() -                continue - -            if isinstance(event, bb.event.ParseStarted): -                progress_total = event.total -                gtk.gdk.threads_enter() -                pbar.set_title("Processing recipes") -                pbar.update(0, progress_total) -                gtk.gdk.threads_leave() - -            if isinstance(event, bb.event.ParseProgress): -                x = event.current -                gtk.gdk.threads_enter() -                pbar.update(x, progress_total) -                gtk.gdk.threads_leave() -                continue - -            if isinstance(event, bb.event.ParseCompleted): -                pbar.hide() -                continue - -            if isinstance(event, bb.event.DepTreeGenerated): -                gtk.gdk.threads_enter() -                parse(event._depgraph, dep.pkg_model, dep.depends_model) -                gtk.gdk.threads_leave() - -            if isinstance(event, bb.command.CommandCompleted): -                continue - -            if isinstance(event, bb.command.CommandFailed): -                print("Command execution failed: %s" % event.error) -                return event.exitcode - -            if isinstance(event, bb.command.CommandExit): -                return event.exitcode - -            if isinstance(event, bb.cooker.CookerExit): -                break - -            continue -        except EnvironmentError as ioerror: -            # ignore interrupted io -            if ioerror.args[0] == 4: -                pass -        except KeyboardInterrupt: -            if shutdown == 2: -                print("\nThird Keyboard Interrupt, exit.\n") -                break -            if shutdown == 1: -                print("\nSecond Keyboard Interrupt, stopping...\n") -                server.runCommand(["stateStop"]) -            if shutdown == 0: -                print("\nKeyboard Interrupt, closing down...\n") -                server.runCommand(["stateShutdown"]) -            shutdown = shutdown + 1 -            pass diff --git a/bitbake/lib/bb/ui/goggle.py b/bitbake/lib/bb/ui/goggle.py deleted file mode 100644 index ec5a38dd4..000000000 --- a/bitbake/lib/bb/ui/goggle.py +++ /dev/null @@ -1,110 +0,0 @@ -# -# BitBake Graphical GTK User Interface -# -# Copyright (C) 2008        Intel Corporation -# -# Authored by Rob Bradford <rob@linux.intel.com> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -import gobject -import gtk -import xmlrpclib -from bb.ui.crumbs.runningbuild import RunningBuildTreeView, RunningBuild -from bb.ui.crumbs.progress import ProgressBar - -import Queue - - -def event_handle_idle_func (eventHandler, build, pbar): - -    # Consume as many messages as we can in the time available to us -    event = eventHandler.getEvent() -    while event: -        build.handle_event (event, pbar) -        event = eventHandler.getEvent() - -    return True - -def scroll_tv_cb (model, path, iter, view): -    view.scroll_to_cell (path) - - -# @todo hook these into the GUI so the user has feedback... -def running_build_failed_cb (running_build): -    pass - - -def running_build_succeeded_cb (running_build): -    pass - - -class MainWindow (gtk.Window): -    def __init__ (self): -        gtk.Window.__init__ (self, gtk.WINDOW_TOPLEVEL) - -        # Setup tree view and the scrolled window -        scrolled_window = gtk.ScrolledWindow () -        self.add (scrolled_window) -        self.cur_build_tv = RunningBuildTreeView() -        self.connect("delete-event", gtk.main_quit) -        self.set_default_size(640, 480) -        scrolled_window.add (self.cur_build_tv) - - -def main (server, eventHandler): -    gobject.threads_init() -    gtk.gdk.threads_init() - -    window = MainWindow () -    window.show_all () -    pbar = ProgressBar(window) -    pbar.connect("delete-event", gtk.main_quit) - -    # Create the object for the current build -    running_build = RunningBuild () -    window.cur_build_tv.set_model (running_build.model) -    running_build.model.connect("row-inserted", scroll_tv_cb, window.cur_build_tv) -    running_build.connect ("build-succeeded", running_build_succeeded_cb) -    running_build.connect ("build-failed", running_build_failed_cb) - -    try: -        cmdline = server.runCommand(["getCmdLineAction"]) -        if not cmdline: -            return 1 -        ret = server.runCommand(cmdline) -        if ret != True: -            print("Couldn't get default commandline! %s" % ret) -            return 1 -    except xmlrpclib.Fault as x: -        print("XMLRPC Fault getting commandline:\n %s" % x) -        return 1 - -    # Use a timeout function for probing the event queue to find out if we -    # have a message waiting for us. -    gobject.timeout_add (100, -                         event_handle_idle_func, -                         eventHandler, -                         running_build, -                         pbar) - -    try: -        gtk.main() -    except EnvironmentError as ioerror: -        # ignore interrupted io -        if ioerror.args[0] == 4: -            pass -    finally: -        server.runCommand(["stateStop"]) - diff --git a/bitbake/lib/bb/ui/knotty.py b/bitbake/lib/bb/ui/knotty.py deleted file mode 100644 index 042dbe902..000000000 --- a/bitbake/lib/bb/ui/knotty.py +++ /dev/null @@ -1,248 +0,0 @@ -# -# BitBake (No)TTY UI Implementation -# -# Handling output to TTYs or files (no TTY) -# -# Copyright (C) 2006-2007 Richard Purdie -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -from __future__ import division - -import os -import sys -import xmlrpclib -import logging -import progressbar -import bb.msg -from bb.ui import uihelper - -logger = logging.getLogger("BitBake") -interactive = sys.stdout.isatty() - -class BBProgress(progressbar.ProgressBar): -    def __init__(self, msg, maxval): -        self.msg = msg -        widgets = [progressbar.Percentage(), ' ', progressbar.Bar(), ' ', -           progressbar.ETA()] - -        progressbar.ProgressBar.__init__(self, maxval, [self.msg + ": "] + widgets) - -class NonInteractiveProgress(object): -    fobj = sys.stdout - -    def __init__(self, msg, maxval): -        self.msg = msg -        self.maxval = maxval - -    def start(self): -        self.fobj.write("%s..." % self.msg) -        self.fobj.flush() -        return self - -    def update(self, value): -        pass - -    def finish(self): -        self.fobj.write("done.\n") -        self.fobj.flush() - -def new_progress(msg, maxval): -    if interactive: -        return BBProgress(msg, maxval) -    else: -        return NonInteractiveProgress(msg, maxval) - -def main(server, eventHandler): - -    # Get values of variables which control our output -    includelogs = server.runCommand(["getVariable", "BBINCLUDELOGS"]) -    loglines = server.runCommand(["getVariable", "BBINCLUDELOGS_LINES"]) - -    helper = uihelper.BBUIHelper() - -    console = logging.StreamHandler(sys.stdout) -    format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") -    console.setFormatter(format) -    logger.addHandler(console) - -    try: -        cmdline = server.runCommand(["getCmdLineAction"]) -        if not cmdline: -            return 1 -        ret = server.runCommand(cmdline) -        if ret != True: -            print("Couldn't get default commandline! %s" % ret) -            return 1 -    except xmlrpclib.Fault as x: -        print("XMLRPC Fault getting commandline:\n %s" % x) -        return 1 - - -    parseprogress = None -    cacheprogress = None -    shutdown = 0 -    return_value = 0 -    while True: -        try: -            event = eventHandler.waitEvent(0.25) -            if event is None: -                continue -            helper.eventHandler(event) -            if isinstance(event, bb.runqueue.runQueueExitWait): -                if not shutdown: -                    shutdown = 1 -            if shutdown and helper.needUpdate: -                activetasks, failedtasks = helper.getTasks() -                if activetasks: -                    print("Waiting for %s active tasks to finish:" % len(activetasks)) -                    for tasknum, task in enumerate(activetasks): -                        print("%s: %s (pid %s)" % (tasknum, activetasks[task]["title"], task)) - -            if isinstance(event, logging.LogRecord): -                if event.levelno >= format.ERROR: -                    return_value = 1 -                # For "normal" logging conditions, don't show note logs from tasks -                # but do show them if the user has changed the default log level to  -                # include verbose/debug messages -                if logger.getEffectiveLevel() > format.VERBOSE: -                    if event.taskpid != 0 and event.levelno <= format.NOTE: -                        continue -                logger.handle(event) -                continue - -            if isinstance(event, bb.build.TaskFailed): -                return_value = 1 -                logfile = event.logfile -                if logfile and os.path.exists(logfile): -                    print("ERROR: Logfile of failure stored in: %s" % logfile) -                    if 1 or includelogs: -                        print("Log data follows:") -                        f = open(logfile, "r") -                        lines = [] -                        while True: -                            l = f.readline() -                            if l == '': -                                break -                            l = l.rstrip() -                            if loglines: -                                lines.append(' | %s' % l) -                                if len(lines) > int(loglines): -                                    lines.pop(0) -                            else: -                                print('| %s' % l) -                        f.close() -                        if lines: -                            for line in lines: -                                print(line) -            if isinstance(event, bb.build.TaskBase): -                logger.info(event._message) -                continue -            if isinstance(event, bb.event.ParseStarted): -                parseprogress = new_progress("Parsing recipes", event.total).start() -                continue -            if isinstance(event, bb.event.ParseProgress): -                parseprogress.update(event.current) -                continue -            if isinstance(event, bb.event.ParseCompleted): -                parseprogress.finish() -                print(("Parsing of %d .bb files complete (%d cached, %d parsed). %d targets, %d skipped, %d masked, %d errors." -                    % ( event.total, event.cached, event.parsed, event.virtuals, event.skipped, event.masked, event.errors))) -                continue - -            if isinstance(event, bb.event.CacheLoadStarted): -                cacheprogress = new_progress("Loading cache", event.total).start() -                continue -            if isinstance(event, bb.event.CacheLoadProgress): -                cacheprogress.update(event.current) -                continue -            if isinstance(event, bb.event.CacheLoadCompleted): -                cacheprogress.finish() -                print("Loaded %d entries from dependency cache." % event.num_entries) -                continue - -            if isinstance(event, bb.command.CommandCompleted): -                break -            if isinstance(event, bb.command.CommandFailed): -                return_value = event.exitcode -                logger.error("Command execution failed: %s", event.error) -                break -            if isinstance(event, bb.command.CommandExit): -                return_value = event.exitcode -                continue -            if isinstance(event, bb.cooker.CookerExit): -                break -            if isinstance(event, bb.event.MultipleProviders): -                logger.info("multiple providers are available for %s%s (%s)", event._is_runtime and "runtime " or "", -                            event._item, -                            ", ".join(event._candidates)) -                logger.info("consider defining a PREFERRED_PROVIDER entry to match %s", event._item) -                continue -            if isinstance(event, bb.event.NoProvider): -                if event._runtime: -                    r = "R" -                else: -                    r = "" - -                if event._dependees: -                    logger.error("Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)", r, event._item, ", ".join(event._dependees), r) -                else: -                    logger.error("Nothing %sPROVIDES '%s'", r, event._item) -                continue - -            if isinstance(event, bb.runqueue.runQueueTaskStarted): -                if event.noexec: -                    tasktype = 'noexec task' -                else: -                    tasktype = 'task' -                logger.info("Running %s %s of %s (ID: %s, %s)", -                            tasktype, -                            event.stats.completed + event.stats.active + -                                event.stats.failed + 1, -                            event.stats.total, event.taskid, event.taskstring) -                continue - -            if isinstance(event, bb.runqueue.runQueueTaskFailed): -                logger.error("Task %s (%s) failed with exit code '%s'", -                             event.taskid, event.taskstring, event.exitcode) -                continue - -            # ignore -            if isinstance(event, (bb.event.BuildBase, -                                  bb.event.StampUpdate, -                                  bb.event.ConfigParsed, -                                  bb.event.RecipeParsed, -                                  bb.runqueue.runQueueEvent, -                                  bb.runqueue.runQueueExitWait)): -                continue - -            logger.error("Unknown event: %s", event) - -        except EnvironmentError as ioerror: -            # ignore interrupted io -            if ioerror.args[0] == 4: -                pass -        except KeyboardInterrupt: -            if shutdown == 2: -                print("\nThird Keyboard Interrupt, exit.\n") -                break -            if shutdown == 1: -                print("\nSecond Keyboard Interrupt, stopping...\n") -                server.runCommand(["stateStop"]) -            if shutdown == 0: -                print("\nKeyboard Interrupt, closing down...\n") -                server.runCommand(["stateShutdown"]) -            shutdown = shutdown + 1 -            pass -    return return_value diff --git a/bitbake/lib/bb/ui/ncurses.py b/bitbake/lib/bb/ui/ncurses.py deleted file mode 100644 index 469f1b730..000000000 --- a/bitbake/lib/bb/ui/ncurses.py +++ /dev/null @@ -1,352 +0,0 @@ -# -# BitBake Curses UI Implementation -# -# Implements an ncurses frontend for the BitBake utility. -# -# Copyright (C) 2006 Michael 'Mickey' Lauer -# Copyright (C) 2006-2007 Richard Purdie -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -""" -    We have the following windows: - -        1.) Main Window: Shows what we are ultimately building and how far we are. Includes status bar -        2.) Thread Activity Window: Shows one status line for every concurrent bitbake thread. -        3.) Command Line Window: Contains an interactive command line where you can interact w/ Bitbake. - -    Basic window layout is like that: - -        |---------------------------------------------------------| -        | <Main Window>               | <Thread Activity Window>  | -        |                             | 0: foo do_compile complete| -        | Building Gtk+-2.6.10        | 1: bar do_patch complete  | -        | Status: 60%                 | ...                       | -        |                             | ...                       | -        |                             | ...                       | -        |---------------------------------------------------------| -        |<Command Line Window>                                    | -        |>>> which virtual/kernel                                 | -        |openzaurus-kernel                                        | -        |>>> _                                                    | -        |---------------------------------------------------------| - -""" - - -from __future__ import division -import logging -import os, sys, curses, itertools, time -import bb -import xmlrpclib -from bb import ui -from bb.ui import uihelper - -parsespin = itertools.cycle( r'|/-\\' ) - -X = 0 -Y = 1 -WIDTH = 2 -HEIGHT = 3 - -MAXSTATUSLENGTH = 32 - -class NCursesUI: -    """ -    NCurses UI Class -    """ -    class Window: -        """Base Window Class""" -        def __init__( self, x, y, width, height, fg=curses.COLOR_BLACK, bg=curses.COLOR_WHITE ): -            self.win = curses.newwin( height, width, y, x ) -            self.dimensions = ( x, y, width, height ) -            """ -            if curses.has_colors(): -                color = 1 -                curses.init_pair( color, fg, bg ) -                self.win.bkgdset( ord(' '), curses.color_pair(color) ) -            else: -                self.win.bkgdset( ord(' '), curses.A_BOLD ) -            """ -            self.erase() -            self.setScrolling() -            self.win.noutrefresh() - -        def erase( self ): -            self.win.erase() - -        def setScrolling( self, b = True ): -            self.win.scrollok( b ) -            self.win.idlok( b ) - -        def setBoxed( self ): -            self.boxed = True -            self.win.box() -            self.win.noutrefresh() - -        def setText( self, x, y, text, *args ): -            self.win.addstr( y, x, text, *args ) -            self.win.noutrefresh() - -        def appendText( self, text, *args ): -            self.win.addstr( text, *args ) -            self.win.noutrefresh() - -        def drawHline( self, y ): -            self.win.hline( y, 0, curses.ACS_HLINE, self.dimensions[WIDTH] ) -            self.win.noutrefresh() - -    class DecoratedWindow( Window ): -        """Base class for windows with a box and a title bar""" -        def __init__( self, title, x, y, width, height, fg=curses.COLOR_BLACK, bg=curses.COLOR_WHITE ): -            NCursesUI.Window.__init__( self, x+1, y+3, width-2, height-4, fg, bg ) -            self.decoration = NCursesUI.Window( x, y, width, height, fg, bg ) -            self.decoration.setBoxed() -            self.decoration.win.hline( 2, 1, curses.ACS_HLINE, width-2 ) -            self.setTitle( title ) - -        def setTitle( self, title ): -            self.decoration.setText( 1, 1, title.center( self.dimensions[WIDTH]-2 ), curses.A_BOLD ) - -    #-------------------------------------------------------------------------# -#    class TitleWindow( Window ): -    #-------------------------------------------------------------------------# -#        """Title Window""" -#        def __init__( self, x, y, width, height ): -#            NCursesUI.Window.__init__( self, x, y, width, height ) -#            version = bb.__version__ -#            title = "BitBake %s" % version -#            credit = "(C) 2003-2007 Team BitBake" -#            #self.win.hline( 2, 1, curses.ACS_HLINE, width-2 ) -#            self.win.border() -#            self.setText( 1, 1, title.center( self.dimensions[WIDTH]-2 ), curses.A_BOLD ) -#            self.setText( 1, 2, credit.center( self.dimensions[WIDTH]-2 ), curses.A_BOLD ) - -    #-------------------------------------------------------------------------# -    class ThreadActivityWindow( DecoratedWindow ): -    #-------------------------------------------------------------------------# -        """Thread Activity Window""" -        def __init__( self, x, y, width, height ): -            NCursesUI.DecoratedWindow.__init__( self, "Thread Activity", x, y, width, height ) - -        def setStatus( self, thread, text ): -            line = "%02d: %s" % ( thread, text ) -            width = self.dimensions[WIDTH] -            if ( len(line) > width ): -                line = line[:width-3] + "..." -            else: -                line = line.ljust( width ) -            self.setText( 0, thread, line ) - -    #-------------------------------------------------------------------------# -    class MainWindow( DecoratedWindow ): -    #-------------------------------------------------------------------------# -        """Main Window""" -        def __init__( self, x, y, width, height ): -            self.StatusPosition = width - MAXSTATUSLENGTH -            NCursesUI.DecoratedWindow.__init__( self, None, x, y, width, height ) -            curses.nl() - -        def setTitle( self, title ): -            title = "BitBake %s" % bb.__version__ -            self.decoration.setText( 2, 1, title, curses.A_BOLD ) -            self.decoration.setText( self.StatusPosition - 8, 1, "Status:", curses.A_BOLD ) - -        def setStatus(self, status): -            while len(status) < MAXSTATUSLENGTH: -                status = status + " " -            self.decoration.setText( self.StatusPosition, 1, status, curses.A_BOLD ) - - -    #-------------------------------------------------------------------------# -    class ShellOutputWindow( DecoratedWindow ): -    #-------------------------------------------------------------------------# -        """Interactive Command Line Output""" -        def __init__( self, x, y, width, height ): -            NCursesUI.DecoratedWindow.__init__( self, "Command Line Window", x, y, width, height ) - -    #-------------------------------------------------------------------------# -    class ShellInputWindow( Window ): -    #-------------------------------------------------------------------------# -        """Interactive Command Line Input""" -        def __init__( self, x, y, width, height ): -            NCursesUI.Window.__init__( self, x, y, width, height ) - -# put that to the top again from curses.textpad import Textbox -#            self.textbox = Textbox( self.win ) -#            t = threading.Thread() -#            t.run = self.textbox.edit -#            t.start() - -    #-------------------------------------------------------------------------# -    def main(self, stdscr, server, eventHandler): -    #-------------------------------------------------------------------------# -        height, width = stdscr.getmaxyx() - -        # for now split it like that: -        # MAIN_y + THREAD_y = 2/3 screen at the top -        # MAIN_x = 2/3 left, THREAD_y = 1/3 right -        # CLI_y = 1/3 of screen at the bottom -        # CLI_x = full - -        main_left = 0 -        main_top = 0 -        main_height = ( height // 3 * 2 ) -        main_width = ( width // 3 ) * 2 -        clo_left = main_left -        clo_top = main_top + main_height -        clo_height = height - main_height - main_top - 1 -        clo_width = width -        cli_left = main_left -        cli_top = clo_top + clo_height -        cli_height = 1 -        cli_width = width -        thread_left = main_left + main_width -        thread_top = main_top -        thread_height = main_height -        thread_width = width - main_width - -        #tw = self.TitleWindow( 0, 0, width, main_top ) -        mw = self.MainWindow( main_left, main_top, main_width, main_height ) -        taw = self.ThreadActivityWindow( thread_left, thread_top, thread_width, thread_height ) -        clo = self.ShellOutputWindow( clo_left, clo_top, clo_width, clo_height ) -        cli = self.ShellInputWindow( cli_left, cli_top, cli_width, cli_height ) -        cli.setText( 0, 0, "BB>" ) - -        mw.setStatus("Idle") - -        helper = uihelper.BBUIHelper() -        shutdown = 0 - -        try: -            cmdline = server.runCommand(["getCmdLineAction"]) -            if not cmdline: -                return -            ret = server.runCommand(cmdline) -            if ret != True: -                print("Couldn't get default commandlind! %s" % ret) -                return -        except xmlrpclib.Fault as x: -            print("XMLRPC Fault getting commandline:\n %s" % x) -            return - -        exitflag = False -        while not exitflag: -            try: -                event = eventHandler.waitEvent(0.25) -                if not event: -                    continue - -                helper.eventHandler(event) -                if isinstance(event, bb.build.TaskBase): -                    mw.appendText("NOTE: %s\n" % event._message) -                if isinstance(event, logging.LogRecord): -                    mw.appendText(logging.getLevelName(event.levelno) + ': ' + event.getMessage() + '\n') - -                if isinstance(event, bb.event.CacheLoadStarted): -                    self.parse_total = event.total -                if isinstance(event, bb.event.CacheLoadProgress): -                    x = event.current -                    y = self.parse_total -                    mw.setStatus("Loading Cache:   %s [%2d %%]" % ( next(parsespin), x*100/y ) ) -                if isinstance(event, bb.event.CacheLoadCompleted): -                    mw.setStatus("Idle") -                    mw.appendText("Loaded %d entries from dependency cache.\n" -                                % ( event.num_entries)) - -                if isinstance(event, bb.event.ParseStarted): -                    self.parse_total = event.total -                if isinstance(event, bb.event.ParseProgress): -                    x = event.current -                    y = self.parse_total -                    mw.setStatus("Parsing Recipes: %s [%2d %%]" % ( next(parsespin), x*100/y ) ) -                if isinstance(event, bb.event.ParseCompleted): -                    mw.setStatus("Idle") -                    mw.appendText("Parsing finished. %d cached, %d parsed, %d skipped, %d masked.\n" -                                % ( event.cached, event.parsed, event.skipped, event.masked )) - -#                if isinstance(event, bb.build.TaskFailed): -#                    if event.logfile: -#                        if data.getVar("BBINCLUDELOGS", d): -#                            bb.msg.error(bb.msg.domain.Build, "log data follows (%s)" % logfile) -#                            number_of_lines = data.getVar("BBINCLUDELOGS_LINES", d) -#                            if number_of_lines: -#                                os.system('tail -n%s %s' % (number_of_lines, logfile)) -#                            else: -#                                f = open(logfile, "r") -#                                while True: -#                                    l = f.readline() -#                                    if l == '': -#                                        break -#                                    l = l.rstrip() -#                                    print '| %s' % l -#                                f.close() -#                        else: -#                            bb.msg.error(bb.msg.domain.Build, "see log in %s" % logfile) - -                if isinstance(event, bb.command.CommandCompleted): -                    # stop so the user can see the result of the build, but -                    # also allow them to now exit with a single ^C -                    shutdown = 2 -                if isinstance(event, bb.command.CommandFailed): -                    mw.appendText("Command execution failed: %s" % event.error) -                    time.sleep(2) -                    exitflag = True -                if isinstance(event, bb.command.CommandExit): -                    exitflag = True -                if isinstance(event, bb.cooker.CookerExit): -                    exitflag = True - -                if helper.needUpdate: -                    activetasks, failedtasks = helper.getTasks() -                    taw.erase() -                    taw.setText(0, 0, "") -                    if activetasks: -                        taw.appendText("Active Tasks:\n") -                        for task in activetasks.itervalues(): -                            taw.appendText(task["title"] + '\n') -                    if failedtasks: -                        taw.appendText("Failed Tasks:\n") -                        for task in failedtasks: -                            taw.appendText(task["title"] + '\n') - -                curses.doupdate() -            except EnvironmentError as ioerror: -                # ignore interrupted io -                if ioerror.args[0] == 4: -                    pass - -            except KeyboardInterrupt: -                if shutdown == 2: -                    mw.appendText("Third Keyboard Interrupt, exit.\n") -                    exitflag = True -                if shutdown == 1: -                    mw.appendText("Second Keyboard Interrupt, stopping...\n") -                    server.runCommand(["stateStop"]) -                if shutdown == 0: -                    mw.appendText("Keyboard Interrupt, closing down...\n") -                    server.runCommand(["stateShutdown"]) -                shutdown = shutdown + 1 -                pass - -def main(server, eventHandler): -    if not os.isatty(sys.stdout.fileno()): -        print("FATAL: Unable to run 'ncurses' UI without a TTY.") -        return -    ui = NCursesUI() -    try: -        curses.wrapper(ui.main, server, eventHandler) -    except: -        import traceback -        traceback.print_exc() diff --git a/bitbake/lib/bb/ui/puccho.py b/bitbake/lib/bb/ui/puccho.py deleted file mode 100644 index 3ce4590c1..000000000 --- a/bitbake/lib/bb/ui/puccho.py +++ /dev/null @@ -1,425 +0,0 @@ -# -# BitBake Graphical GTK User Interface -# -# Copyright (C) 2008        Intel Corporation -# -# Authored by Rob Bradford <rob@linux.intel.com> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -import gtk -import gobject -import gtk.glade -import threading -import urllib2 -import os -import contextlib - -from bb.ui.crumbs.buildmanager import BuildManager, BuildConfiguration -from bb.ui.crumbs.buildmanager import BuildManagerTreeView - -from bb.ui.crumbs.runningbuild import RunningBuild, RunningBuildTreeView - -# The metadata loader is used by the BuildSetupDialog to download the -# available options to populate the dialog -class MetaDataLoader(gobject.GObject): -    """ This class provides the mechanism for loading the metadata (the -    fetching and parsing) from a given URL. The metadata encompasses details -    on what machines are available. The distribution and images available for -    the machine and the the uris to use for building the given machine.""" -    __gsignals__ = { -        'success' : (gobject.SIGNAL_RUN_LAST, -                     gobject.TYPE_NONE, -                     ()), -        'error' : (gobject.SIGNAL_RUN_LAST, -                   gobject.TYPE_NONE, -                   (gobject.TYPE_STRING,)) -        } - -    # We use these little helper functions to ensure that we take the gdk lock -    # when emitting the signal. These functions are called as idles (so that -    # they happen in the gtk / main thread's main loop. -    def emit_error_signal (self, remark): -        gtk.gdk.threads_enter() -        self.emit ("error", remark) -        gtk.gdk.threads_leave() - -    def emit_success_signal (self): -        gtk.gdk.threads_enter() -        self.emit ("success") -        gtk.gdk.threads_leave() - -    def __init__ (self): -        gobject.GObject.__init__ (self) - -    class LoaderThread(threading.Thread): -        """ This class provides an asynchronous loader for the metadata (by -        using threads and signals). This is useful since the metadata may be -        at a remote URL.""" -        class LoaderImportException (Exception): -            pass - -        def __init__(self, loader, url): -            threading.Thread.__init__ (self) -            self.url = url -            self.loader = loader - -        def run (self): -            result = {} -            try: -                with contextlib.closing (urllib2.urlopen (self.url)) as f: -                    # Parse the metadata format. The format is.... -                    # <machine>;<default distro>|<distro>...;<default image>|<image>...;<type##url>|... -                    for line in f: -                        components = line.split(";") -                        if (len (components) < 4): -                            raise MetaDataLoader.LoaderThread.LoaderImportException -                        machine = components[0] -                        distros = components[1].split("|") -                        images = components[2].split("|") -                        urls = components[3].split("|") - -                        result[machine] = (distros, images, urls) - -                # Create an object representing this *potential* -                # configuration. It can become concrete if the machine, distro -                # and image are all chosen in the UI -                configuration = BuildConfiguration() -                configuration.metadata_url = self.url -                configuration.machine_options = result -                self.loader.configuration = configuration - -                # Emit that we've actually got a configuration -                gobject.idle_add (MetaDataLoader.emit_success_signal, -                    self.loader) - -            except MetaDataLoader.LoaderThread.LoaderImportException as e: -                gobject.idle_add (MetaDataLoader.emit_error_signal, self.loader, -                    "Repository metadata corrupt") -            except Exception as e: -                gobject.idle_add (MetaDataLoader.emit_error_signal, self.loader, -                    "Unable to download repository metadata") -                print(e) - -    def try_fetch_from_url (self, url): -        # Try and download the metadata. Firing a signal if successful -        thread = MetaDataLoader.LoaderThread(self, url) -        thread.start() - -class BuildSetupDialog (gtk.Dialog): -    RESPONSE_BUILD = 1 - -    # A little helper method that just sets the states on the widgets based on -    # whether we've got good metadata or not. -    def set_configurable (self, configurable): -        if (self.configurable == configurable): -            return - -        self.configurable = configurable -        for widget in self.conf_widgets: -            widget.set_sensitive (configurable) - -        if not configurable: -            self.machine_combo.set_active (-1) -            self.distribution_combo.set_active (-1) -            self.image_combo.set_active (-1) - -    # GTK widget callbacks -    def refresh_button_clicked (self, button): -        # Refresh button clicked. - -        url = self.location_entry.get_chars (0, -1) -        self.loader.try_fetch_from_url(url) - -    def repository_entry_editable_changed (self, entry): -        if (len (entry.get_chars (0, -1)) > 0): -            self.refresh_button.set_sensitive (True) -        else: -            self.refresh_button.set_sensitive (False) -            self.clear_status_message() - -        # If we were previously configurable we are no longer since the -        # location entry has been changed -        self.set_configurable (False) - -    def machine_combo_changed (self, combobox): -        active_iter = combobox.get_active_iter() - -        if not active_iter: -            return - -        model = combobox.get_model() - -        if model: -            chosen_machine = model.get (active_iter, 0)[0] - -        (distros_model, images_model) = \ -            self.loader.configuration.get_distro_and_images_models (chosen_machine) - -        self.distribution_combo.set_model (distros_model) -        self.image_combo.set_model (images_model) - -    # Callbacks from the loader -    def loader_success_cb (self, loader): -        self.status_image.set_from_icon_name ("info", -            gtk.ICON_SIZE_BUTTON) -        self.status_image.show() -        self.status_label.set_label ("Repository metadata successfully downloaded") - -        # Set the models on the combo boxes based on the models generated from -        # the configuration that the loader has created - -        # We just need to set the machine here, that then determines the -        # distro and image options. Cunning huh? :-) - -        self.configuration = self.loader.configuration -        model = self.configuration.get_machines_model () -        self.machine_combo.set_model (model) - -        self.set_configurable (True) - -    def loader_error_cb (self, loader, message): -        self.status_image.set_from_icon_name ("error", -            gtk.ICON_SIZE_BUTTON) -        self.status_image.show() -        self.status_label.set_text ("Error downloading repository metadata") -        for widget in self.conf_widgets: -            widget.set_sensitive (False) - -    def clear_status_message (self): -        self.status_image.hide() -        self.status_label.set_label ( -            """<i>Enter the repository location and press _Refresh</i>""") - -    def __init__ (self): -        gtk.Dialog.__init__ (self) - -        # Cancel -        self.add_button (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL) - -        # Build -        button = gtk.Button ("_Build", None, True) -        image = gtk.Image () -        image.set_from_stock (gtk.STOCK_EXECUTE, gtk.ICON_SIZE_BUTTON) -        button.set_image (image) -        self.add_action_widget (button, BuildSetupDialog.RESPONSE_BUILD) -        button.show_all () - -        # Pull in *just* the table from the Glade XML data. -        gxml = gtk.glade.XML (os.path.dirname(__file__) + "/crumbs/puccho.glade", -            root = "build_table") -        table = gxml.get_widget ("build_table") -        self.vbox.pack_start (table, True, False, 0) - -        # Grab all the widgets that we need to turn on/off when we refresh... -        self.conf_widgets = [] -        self.conf_widgets += [gxml.get_widget ("machine_label")] -        self.conf_widgets += [gxml.get_widget ("distribution_label")] -        self.conf_widgets += [gxml.get_widget ("image_label")] -        self.conf_widgets += [gxml.get_widget ("machine_combo")] -        self.conf_widgets += [gxml.get_widget ("distribution_combo")] -        self.conf_widgets += [gxml.get_widget ("image_combo")] - -        # Grab the status widgets -        self.status_image = gxml.get_widget ("status_image") -        self.status_label = gxml.get_widget ("status_label") - -        # Grab the refresh button and connect to the clicked signal -        self.refresh_button = gxml.get_widget ("refresh_button") -        self.refresh_button.connect ("clicked", self.refresh_button_clicked) - -        # Grab the location entry and connect to editable::changed -        self.location_entry = gxml.get_widget ("location_entry") -        self.location_entry.connect ("changed", -            self.repository_entry_editable_changed) - -        # Grab the machine combo and hook onto the changed signal. This then -        # allows us to populate the distro and image combos -        self.machine_combo = gxml.get_widget ("machine_combo") -        self.machine_combo.connect ("changed", self.machine_combo_changed) - -        # Setup the combo -        cell = gtk.CellRendererText() -        self.machine_combo.pack_start(cell, True) -        self.machine_combo.add_attribute(cell, 'text', 0) - -        # Grab the distro and image combos. We need these to populate with -        # models once the machine is chosen -        self.distribution_combo = gxml.get_widget ("distribution_combo") -        cell = gtk.CellRendererText() -        self.distribution_combo.pack_start(cell, True) -        self.distribution_combo.add_attribute(cell, 'text', 0) - -        self.image_combo = gxml.get_widget ("image_combo") -        cell = gtk.CellRendererText() -        self.image_combo.pack_start(cell, True) -        self.image_combo.add_attribute(cell, 'text', 0) - -        # Put the default descriptive text in the status box -        self.clear_status_message() - -        # Mark as non-configurable, this is just greys out the widgets the -        # user can't yet use -        self.configurable = False -        self.set_configurable(False) - -        # Show the table -        table.show_all () - -        # The loader and some signals connected to it to update the status -        # area -        self.loader = MetaDataLoader() -        self.loader.connect ("success", self.loader_success_cb) -        self.loader.connect ("error", self.loader_error_cb) - -    def update_configuration (self): -        """ A poorly named function but it updates the internal configuration -        from the widgets. This can make that configuration concrete and can -        thus be used for building """ -        # Extract the chosen machine from the combo -        model = self.machine_combo.get_model() -        active_iter = self.machine_combo.get_active_iter() -        if (active_iter): -            self.configuration.machine = model.get(active_iter, 0)[0] - -        # Extract the chosen distro from the combo -        model = self.distribution_combo.get_model() -        active_iter = self.distribution_combo.get_active_iter() -        if (active_iter): -            self.configuration.distro = model.get(active_iter, 0)[0] - -        # Extract the chosen image from the combo -        model = self.image_combo.get_model() -        active_iter = self.image_combo.get_active_iter() -        if (active_iter): -            self.configuration.image = model.get(active_iter, 0)[0] - -# This function operates to pull events out from the event queue and then push -# them into the RunningBuild (which then drives the RunningBuild which then -# pushes through and updates the progress tree view.) -# -# TODO: Should be a method on the RunningBuild class -def event_handle_timeout (eventHandler, build): -    # Consume as many messages as we can ... -    event = eventHandler.getEvent() -    while event: -        build.handle_event (event) -        event = eventHandler.getEvent() -    return True - -class MainWindow (gtk.Window): - -    # Callback that gets fired when the user hits a button in the -    # BuildSetupDialog. -    def build_dialog_box_response_cb (self, dialog, response_id): -        conf = None -        if (response_id == BuildSetupDialog.RESPONSE_BUILD): -            dialog.update_configuration() -            print(dialog.configuration.machine, dialog.configuration.distro, \ -                dialog.configuration.image) -            conf = dialog.configuration - -        dialog.destroy() - -        if conf: -            self.manager.do_build (conf) - -    def build_button_clicked_cb (self, button): -        dialog = BuildSetupDialog () - -        # For some unknown reason Dialog.run causes nice little deadlocks ... :-( -        dialog.connect ("response", self.build_dialog_box_response_cb) -        dialog.show() - -    def __init__ (self): -        gtk.Window.__init__ (self) - -        # Pull in *just* the main vbox from the Glade XML data and then pack -        # that inside the window -        gxml = gtk.glade.XML (os.path.dirname(__file__) + "/crumbs/puccho.glade", -            root = "main_window_vbox") -        vbox = gxml.get_widget ("main_window_vbox") -        self.add (vbox) - -        # Create the tree views for the build manager view and the progress view -        self.build_manager_view = BuildManagerTreeView() -        self.running_build_view = RunningBuildTreeView() - -        # Grab the scrolled windows that we put the tree views into -        self.results_scrolledwindow = gxml.get_widget ("results_scrolledwindow") -        self.progress_scrolledwindow = gxml.get_widget ("progress_scrolledwindow") - -        # Put the tree views inside ... -        self.results_scrolledwindow.add (self.build_manager_view) -        self.progress_scrolledwindow.add (self.running_build_view) - -        # Hook up the build button... -        self.build_button = gxml.get_widget ("main_toolbutton_build") -        self.build_button.connect ("clicked", self.build_button_clicked_cb) - -# I'm not very happy about the current ownership of the RunningBuild. I have -# my suspicions that this object should be held by the BuildManager since we -# care about the signals in the manager - -def running_build_succeeded_cb (running_build, manager): -    # Notify the manager that a build has succeeded. This is necessary as part -    # of the 'hack' that we use for making the row in the model / view -    # representing the ongoing build change into a row representing the -    # completed build. Since we know only one build can be running a time then -    # we can handle this. - -    # FIXME: Refactor all this so that the RunningBuild is owned by the -    # BuildManager. It can then hook onto the signals directly and drive -    # interesting things it cares about. -    manager.notify_build_succeeded () -    print("build succeeded") - -def running_build_failed_cb (running_build, manager): -    # As above -    print("build failed") -    manager.notify_build_failed () - -def main (server, eventHandler): -    # Initialise threading... -    gobject.threads_init() -    gtk.gdk.threads_init() - -    main_window = MainWindow () -    main_window.show_all () - -    # Set up the build manager stuff in general -    builds_dir = os.path.join (os.getcwd(),  "results") -    manager = BuildManager (server, builds_dir) -    main_window.build_manager_view.set_model (manager.model) - -    # Do the running build setup -    running_build = RunningBuild () -    main_window.running_build_view.set_model (running_build.model) -    running_build.connect ("build-succeeded", running_build_succeeded_cb, -        manager) -    running_build.connect ("build-failed", running_build_failed_cb, manager) - -    # We need to save the manager into the MainWindow so that the toolbar -    # button can use it. -    # FIXME: Refactor ? -    main_window.manager = manager - -    # Use a timeout function for probing the event queue to find out if we -    # have a message waiting for us. -    gobject.timeout_add (200, -                         event_handle_timeout, -                         eventHandler, -                         running_build) - -    gtk.main() diff --git a/bitbake/lib/bb/ui/uievent.py b/bitbake/lib/bb/ui/uievent.py deleted file mode 100644 index 2fef4e465..000000000 --- a/bitbake/lib/bb/ui/uievent.py +++ /dev/null @@ -1,127 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (C) 2006 - 2007  Michael 'Mickey' Lauer -# Copyright (C) 2006 - 2007  Richard Purdie -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - - -""" -Use this class to fork off a thread to recieve event callbacks from the bitbake -server and queue them for the UI to process. This process must be used to avoid -client/server deadlocks. -""" - -import socket, threading, pickle -from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler - -class BBUIEventQueue: -    def __init__(self, BBServer): - -        self.eventQueue = [] -        self.eventQueueLock = threading.Lock() -        self.eventQueueNotify = threading.Event() - -        self.BBServer = BBServer - -        self.t = threading.Thread() -        self.t.setDaemon(True) -        self.t.run = self.startCallbackHandler -        self.t.start() - -    def getEvent(self): - -        self.eventQueueLock.acquire() - -        if len(self.eventQueue) == 0: -            self.eventQueueLock.release() -            return None - -        item = self.eventQueue.pop(0) - -        if len(self.eventQueue) == 0: -            self.eventQueueNotify.clear() - -        self.eventQueueLock.release() -        return item - -    def waitEvent(self, delay): -        self.eventQueueNotify.wait(delay) -        return self.getEvent() - -    def queue_event(self, event): -        self.eventQueueLock.acquire() -        self.eventQueue.append(event) -        self.eventQueueNotify.set() -        self.eventQueueLock.release() - -    def send_event(self, event): -        self.queue_event(pickle.loads(event)) - -    def startCallbackHandler(self): - -        server = UIXMLRPCServer() -        self.host, self.port = server.socket.getsockname() - -        server.register_function( self.system_quit, "event.quit" ) -        server.register_function( self.send_event, "event.send" ) -        server.socket.settimeout(1) - -        self.EventHandle = self.BBServer.registerEventHandler(self.host, self.port) - -        self.server = server -        while not server.quit: -            server.handle_request() -        server.server_close() - -    def system_quit( self ): -        """ -        Shut down the callback thread -        """ -        try: -            self.BBServer.unregisterEventHandler(self.EventHandle) -        except: -            pass -        self.server.quit = True - -class UIXMLRPCServer (SimpleXMLRPCServer): - -    def __init__( self, interface = ("localhost", 0) ): -        self.quit = False -        SimpleXMLRPCServer.__init__( self, -                                    interface, -                                    requestHandler=SimpleXMLRPCRequestHandler, -                                    logRequests=False, allow_none=True) - -    def get_request(self): -        while not self.quit: -            try: -                sock, addr = self.socket.accept() -                sock.settimeout(1) -                return (sock, addr) -            except socket.timeout: -                pass -        return (None, None) - -    def close_request(self, request): -        if request is None: -            return -        SimpleXMLRPCServer.close_request(self, request) - -    def process_request(self, request, client_address): -        if request is None: -            return -        SimpleXMLRPCServer.process_request(self, request, client_address) - diff --git a/bitbake/lib/bb/ui/uihelper.py b/bitbake/lib/bb/ui/uihelper.py deleted file mode 100644 index 617d60db8..000000000 --- a/bitbake/lib/bb/ui/uihelper.py +++ /dev/null @@ -1,42 +0,0 @@ -# ex:ts=4:sw=4:sts=4:et -# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- -# -# Copyright (C) 2006 - 2007  Michael 'Mickey' Lauer -# Copyright (C) 2006 - 2007  Richard Purdie -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -import bb.build - -class BBUIHelper: -    def __init__(self): -        self.needUpdate = False -        self.running_tasks = {} -        self.failed_tasks = [] - -    def eventHandler(self, event): -        if isinstance(event, bb.build.TaskStarted): -            self.running_tasks[event.pid] = { 'title' : "%s %s" % (event._package, event._task) } -            self.needUpdate = True -        if isinstance(event, bb.build.TaskSucceeded): -            del self.running_tasks[event.pid] -            self.needUpdate = True -        if isinstance(event, bb.build.TaskFailed): -            del self.running_tasks[event.pid] -            self.failed_tasks.append( { 'title' : "%s %s" % (event._package, event._task)}) -            self.needUpdate = True - -    def getTasks(self): -        self.needUpdate = False -        return (self.running_tasks, self.failed_tasks) | 
