Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/sugar
diff options
context:
space:
mode:
authorBenjamin Berg <benjamin@sipsolutions.net>2008-08-24 12:33:58 (GMT)
committer Benjamin Berg <benjamin@sipsolutions.net>2008-08-24 12:33:58 (GMT)
commit927ae13aec406cd3d3f67d6e10a8ef1f253a0a80 (patch)
treec36d060a0656f161e9d30332c3088bc5c6bb35bb /src/sugar
parent3d3e453157ec8c1b107fac2bca5c46681c6cb0ad (diff)
parentc3873bfdcb78bf5e50568b591b3d9deec4d3d9db (diff)
Merge branch 'master' of git+ssh://benzea@dev.laptop.org/git/sugar-toolkit
Diffstat (limited to 'src/sugar')
-rw-r--r--src/sugar/activity/bundlebuilder.py76
-rw-r--r--src/sugar/bundle/activitybundle.py8
-rw-r--r--src/sugar/bundle/bundle.py37
-rw-r--r--src/sugar/bundle/contentbundle.py4
-rw-r--r--src/sugar/graphics/toolbutton.py6
-rw-r--r--src/sugar/util.py18
6 files changed, 101 insertions, 48 deletions
diff --git a/src/sugar/activity/bundlebuilder.py b/src/sugar/activity/bundlebuilder.py
index b8f87a7..75d6d89 100644
--- a/src/sugar/activity/bundlebuilder.py
+++ b/src/sugar/activity/bundlebuilder.py
@@ -51,7 +51,21 @@ def list_files(base_dir, ignore_dirs=None, ignore_files=None):
class Config(object):
def __init__(self, source_dir=None, dist_dir = None, dist_name = None):
self.source_dir = source_dir or os.getcwd()
-
+ self.dist_dir = dist_dir or os.path.join(self.source_dir, 'dist')
+ self.dist_name = dist_name
+ self.bundle = None
+ self.version = None
+ self.activity_name = None
+ self.bundle_id = None
+ self.bundle_name = None
+ self.bundle_root_dir = None
+ self.tar_root_dir = None
+ self.xo_name = None
+ self.tar_name = None
+
+ self.update()
+
+ def update(self):
self.bundle = bundle = ActivityBundle(self.source_dir)
self.version = bundle.get_activity_version()
self.activity_name = bundle.get_name()
@@ -59,14 +73,9 @@ class Config(object):
self.bundle_name = reduce(lambda x, y:x+y, self.activity_name.split())
self.bundle_root_dir = self.bundle_name + '.activity'
self.tar_root_dir = '%s-%d' % (self.bundle_name, self.version)
-
- if dist_dir:
- self.dist_dir = dist_dir
- else:
- self.dist_dir = os.path.join(self.source_dir, 'dist')
- if dist_name:
- self.xo_name = self.tar_name = dist_name
+ if self.dist_name:
+ self.xo_name = self.tar_name = self.dist_name
else:
self.xo_name = '%s-%d.xo' % (self.bundle_name, self.version)
self.tar_name = '%s-%d.tar.bz2' % (self.bundle_name, self.version)
@@ -118,6 +127,12 @@ class Packager(object):
if not os.path.exists(self.config.dist_dir):
os.mkdir(self.config.dist_dir)
+ def _list_files(self):
+ ignore_dirs = ['dist', '.git']
+ ignore_files = ['.gitignore', 'MANIFEST', '*.pyc', '*~', '*.bak']
+
+ return list_files(self.config.source_dir, ignore_dirs, ignore_files)
+
class BuildPackager(Packager):
def get_files(self):
files = self.config.bundle.get_files()
@@ -128,20 +143,22 @@ class BuildPackager(Packager):
files = self.config.bundle.get_files()
return files
-
- def _list_useful_files(self):
- ignore_dirs = ['dist', '.git']
- ignore_files = ['.gitignore', 'MANIFEST', '*.pyc', '*~', '*.bak']
-
- return list_files(self.config.source_dir, ignore_dirs, ignore_files)
+
+ def _check_manifest(self):
+ missing_files = []
+
+ allfiles = self._list_files()
+ for path in allfiles:
+ if path not in self.config.bundle.manifest:
+ missing_files.append(path)
+
+ return missing_files
def fix_manifest(self):
manifest = self.config.bundle.manifest
- allfiles = self._list_useful_files()
- for path in allfiles:
- if path not in manifest:
- manifest.append(path)
+ for path in self._check_manifest():
+ manifest.append(path)
f = open(os.path.join(self.config.source_dir, "MANIFEST"), "wb")
for line in manifest:
@@ -157,15 +174,22 @@ class XOPackager(BuildPackager):
bundle_zip = zipfile.ZipFile(self.package_path, 'w',
zipfile.ZIP_DEFLATED)
+ missing_files = self._check_manifest()
+ if missing_files:
+ logging.warn('These files are not included in the manifest ' \
+ 'and will not be present in the bundle:\n\n' +
+ '\n'.join(missing_files) +
+ '\n\nUse fix_manifest if you want to add them.')
+
for f in self.get_files():
bundle_zip.write(os.path.join(self.config.source_dir, f),
os.path.join(self.config.bundle_root_dir, f))
bundle_zip.close()
-class SourcePackager(BuildPackager):
+class SourcePackager(Packager):
def __init__(self, config):
- BuildPackager.__init__(self, config)
+ Packager.__init__(self, config)
self.package_path = os.path.join(self.config.dist_dir,
self.config.tar_name)
@@ -174,7 +198,7 @@ class SourcePackager(BuildPackager):
cwd=self.config.source_dir)
if git_ls.wait():
# Fall back to filtered list
- return self._list_useful_files()
+ return self._list_files()
return [path.strip() for path in git_ls.stdout.readlines()]
@@ -191,6 +215,7 @@ setup.py build - build generated files \n\
setup.py dev - setup for development \n\
setup.py dist_xo - create a xo bundle package \n\
setup.py dist_source - create a tar source package \n\
+setup.py fix_manifest - add missing files to the manifest \n\
setup.py install [dirname] - install the bundle \n\
setup.py uninstall [dirname] - uninstall the bundle \n\
setup.py genpot - generate the gettext pot file \n\
@@ -218,6 +243,13 @@ def cmd_dist_xo(config, options, args):
packager = XOPackager(config)
packager.package()
+def cmd_fix_manifest(config, options, args):
+ builder = Builder(config)
+ builder.build()
+
+ packager = XOPackager(config)
+ packager.fix_manifest()
+
def cmd_dist(config, options, args):
logging.warn("dist deprecated, use dist_xo.")
cmd_dist_xo(config, options, args)
@@ -309,6 +341,8 @@ def cmd_release(config, options, args):
f.write(info)
f.close()
+ config.update()
+
news_path = os.path.join(config.source_dir, 'NEWS')
if os.environ.has_key('SUGAR_NEWS'):
diff --git a/src/sugar/bundle/activitybundle.py b/src/sugar/bundle/activitybundle.py
index 5f29a69..be997cc 100644
--- a/src/sugar/bundle/activitybundle.py
+++ b/src/sugar/bundle/activitybundle.py
@@ -205,13 +205,13 @@ class ActivityBundle(Bundle):
def get_locale_path(self):
"""Get the locale path inside the (installed) activity bundle."""
- if not self._unpacked:
+ if self._zip_file is not None:
raise NotInstalledException
return os.path.join(self._path, 'locale')
def get_icons_path(self):
"""Get the icons path inside the (installed) activity bundle."""
- if not self._unpacked:
+ if self._zip_file is not None:
raise NotInstalledException
return os.path.join(self._path, 'icons')
@@ -237,7 +237,7 @@ class ActivityBundle(Bundle):
def get_icon(self):
"""Get the activity icon name"""
icon_path = os.path.join('activity', self._icon + '.svg')
- if self._unpacked:
+ if self._zip_file is None:
return os.path.join(self._path, icon_path)
else:
icon_data = self.get_file(icon_path).read()
@@ -365,7 +365,7 @@ class ActivityBundle(Bundle):
raise RegistrationException
def uninstall(self, force=False):
- if self._unpacked:
+ if self._zip_file is None:
install_path = self._path
else:
if not self.is_installed():
diff --git a/src/sugar/bundle/bundle.py b/src/sugar/bundle/bundle.py
index 3b12932..0319b9e 100644
--- a/src/sugar/bundle/bundle.py
+++ b/src/sugar/bundle/bundle.py
@@ -19,6 +19,7 @@
import os
import logging
+import shutil
import StringIO
import zipfile
@@ -59,9 +60,9 @@ class Bundle:
self._zip_root_dir = None
if os.path.isdir(self._path):
- self._unpacked = True
+ self._zip_file = None
else:
- self._unpacked = False
+ self._zip_file = zipfile.ZipFile(self._path)
self._check_zip_bundle()
# manifest = self._get_file(self._infodir + '/contents')
@@ -72,9 +73,12 @@ class Bundle:
# if signature is None:
# raise MalformedBundleException('No signature file')
+ def __del__(self):
+ if self._zip_file is not None:
+ self._zip_file.close()
+
def _check_zip_bundle(self):
- zip_file = zipfile.ZipFile(self._path)
- file_names = zip_file.namelist()
+ file_names = self._zip_file.namelist()
if len(file_names) == 0:
raise MalformedBundleException('Empty zip file')
@@ -99,48 +103,42 @@ class Bundle:
def get_file(self, filename):
f = None
- if self._unpacked:
+ if self._zip_file is None:
path = os.path.join(self._path, filename)
try:
f = open(path,"rb")
except IOError:
return None
else:
- zip_file = zipfile.ZipFile(self._path)
path = os.path.join(self._zip_root_dir, filename)
try:
- data = zip_file.read(path)
+ data = self._zip_file.read(path)
f = StringIO.StringIO(data)
except KeyError:
logging.debug('%s not found.' % filename)
- zip_file.close()
return f
def is_file(self, filename):
- if self._unpacked:
+ if self._zip_file is None:
path = os.path.join(self._path, filename)
return os.path.isfile(path)
else:
- zip_file = zipfile.ZipFile(self._path)
path = os.path.join(self._zip_root_dir, filename)
try:
- zip_file.getinfo(path)
+ self._zip_file.getinfo(path)
except KeyError:
return False
- finally:
- zip_file.close()
return True
def is_dir(self, filename):
- if self._unpacked:
+ if self._zip_file is None:
path = os.path.join(self._path, filename)
return os.path.isdir(path)
else:
- zip_file = zipfile.ZipFile(self._path)
path = os.path.join(self._zip_root_dir, filename, "")
- for f in zip_file.namelist():
+ for f in self._zip_file.namelist():
if f.startswith(path):
return True
return False
@@ -150,7 +148,7 @@ class Bundle:
return self._path
def _unzip(self, install_dir):
- if self._unpacked:
+ if self._zip_file is None:
raise AlreadyInstalledException
if not os.path.isdir(install_dir):
@@ -163,10 +161,13 @@ class Bundle:
# FIXME: use manifest
if os.spawnlp(os.P_WAIT, 'unzip', 'unzip', '-o', self._path,
'-x', 'mimetype', '-d', install_dir):
+ # clean up install dir after failure
+ shutil.rmtree(install_dir, ignore_errors=True)
+ # indicate failure.
raise ZipExtractException
def _zip(self, bundle_path):
- if not self._unpacked:
+ if self._zip_file is not None:
raise NotInstalledException
raise NotImplementedError
diff --git a/src/sugar/bundle/contentbundle.py b/src/sugar/bundle/contentbundle.py
index f99c13a..389fd70 100644
--- a/src/sugar/bundle/contentbundle.py
+++ b/src/sugar/bundle/contentbundle.py
@@ -195,7 +195,7 @@ class ContentBundle(Bundle):
return "file://" + urllib.pathname2url(self.get_start_path())
def is_installed(self):
- if self._unpacked:
+ if self._zip_file is None:
return True
elif os.path.isdir(self.get_root_dir()):
return True
@@ -207,7 +207,7 @@ class ContentBundle(Bundle):
self._run_indexer()
def uninstall(self):
- if self._unpacked:
+ if self._zip_file is None:
if not self.is_installed():
raise NotInstalledException
install_dir = self._path
diff --git a/src/sugar/graphics/toolbutton.py b/src/sugar/graphics/toolbutton.py
index bf392c8..715e7a9 100644
--- a/src/sugar/graphics/toolbutton.py
+++ b/src/sugar/graphics/toolbutton.py
@@ -65,6 +65,12 @@ class ToolButton(gtk.ToolButton):
self.set_icon(icon_name)
self.connect('clicked', self.__button_clicked_cb)
+ self.get_child().connect('can-activate-accel',
+ self.__button_can_activate_accel_cb)
+
+ def __button_can_activate_accel_cb(self, button, signal_id):
+ # Accept activation via accelerators regardless of this widget's state
+ return True
def set_tooltip(self, tooltip):
""" Set a simple palette with just a single label.
diff --git a/src/sugar/util.py b/src/sugar/util.py
index 955f4c8..c365dce 100644
--- a/src/sugar/util.py
+++ b/src/sugar/util.py
@@ -16,6 +16,7 @@
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
+import os
import time
import sha
import random
@@ -23,7 +24,6 @@ import binascii
import gettext
_ = lambda msg: gettext.dgettext('sugar-toolkit', msg)
-_ngettext = lambda m1, m2, n: gettext.dngettext('sugar-toolkit', m1, m2, n)
def printable_hash(in_hash):
"""Convert binary hash data into printable characters."""
@@ -217,6 +217,9 @@ del ngettext
# End of plurals hack
+# gettext perfs hack (#7959)
+_i18n_timestamps_cache = LRU(60)
+
def timestamp_to_elapsed_string(timestamp, max_levels=2):
levels = 0
time_period = ''
@@ -229,8 +232,17 @@ def timestamp_to_elapsed_string(timestamp, max_levels=2):
if levels > 0:
time_period += COMMA
- time_period += _ngettext(name_singular, name_plural,
- elapsed_units) % elapsed_units
+ key = ''.join((os.environ['LANG'], name_singular,
+ str(elapsed_units)))
+ if key in _i18n_timestamps_cache:
+ time_period += _i18n_timestamps_cache[key]
+ else:
+ translation = gettext.dngettext('sugar-toolkit',
+ name_singular,
+ name_plural,
+ elapsed_units) % elapsed_units
+ _i18n_timestamps_cache[key] = translation
+ time_period += translation
elapsed_seconds -= elapsed_units * factor