summaryrefslogtreecommitdiff
path: root/bitbake/lib/bb/ui
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/ui')
-rw-r--r--bitbake/lib/bb/ui/__init__.py17
-rw-r--r--bitbake/lib/bb/ui/crumbs/__init__.py17
-rw-r--r--bitbake/lib/bb/ui/crumbs/buildmanager.py455
-rw-r--r--bitbake/lib/bb/ui/crumbs/progress.py17
-rw-r--r--bitbake/lib/bb/ui/crumbs/puccho.glade606
-rw-r--r--bitbake/lib/bb/ui/crumbs/runningbuild.py311
-rw-r--r--bitbake/lib/bb/ui/depexp.py307
-rw-r--r--bitbake/lib/bb/ui/goggle.py110
-rw-r--r--bitbake/lib/bb/ui/knotty.py248
-rw-r--r--bitbake/lib/bb/ui/ncurses.py352
-rw-r--r--bitbake/lib/bb/ui/puccho.py425
-rw-r--r--bitbake/lib/bb/ui/uievent.py127
-rw-r--r--bitbake/lib/bb/ui/uihelper.py42
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">&lt;b&gt;Build configuration&lt;/b&gt;</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">&lt;b&gt;Repository&lt;/b&gt;</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">&lt;b&gt;Repositories&lt;/b&gt;</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">&lt;b&gt;Additional packages&lt;/b&gt;</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)