diff --git a/TODO b/TODO index 0dcb62fb..3124f101 100644 --- a/TODO +++ b/TODO @@ -78,7 +78,7 @@ Legend: - configure-pending (eray) / i18n support - summary,description için doğru dili kullanmak - - pisi mesajlarının çevrilebilir hale getirilmesi (build.py yi örnek alın) + / pisi mesajlarının çevrilebilir hale getirilmesi (build.py yi örnek alın) - build sistemine .pot oluşturma vs desteği (pygettext) - mesajların çevirisinin yapılması (pisi tr.po) / query @@ -119,6 +119,7 @@ Legend: - removable media: media:// - partial caching and automatic resume for file download (meren) - use a separate "partial/" subdir like urpmi + - a helper script for finding dependencies * low priority diff --git a/pisi/api.py b/pisi/api.py index d3044d59..e0c44d73 100644 --- a/pisi/api.py +++ b/pisi/api.py @@ -17,6 +17,7 @@ import sys ver = sys.version_info if ver[0] <= 2 and ver[1] < 4: from sets import Set as set + import gettext __trans = gettext.translation('pisi', fallback=True) _ = __trans.ugettext @@ -53,7 +54,7 @@ def init(database = True, options = None, ui = None, comar = True): ctx.comard = comar.Link() except ImportError: raise Error(_("COMAR: comard not fully installed")) - print "skipping COMAR connection for now..." + print _("skipping COMAR connection for now...") except comar.Error: raise Error(_("COMAR: comard not running or defunct")) @@ -109,10 +110,10 @@ def install_pkg_files(package_URIs): for x in package_URIs: if not x.endswith(ctx.const.package_prefix): - ctx.ui.error('Mixing file names and package names not supported YET.\n') + ctx.ui.error(_('Mixing file names and package names not supported YET.')) return False - if ctx.config.get_option('ignore_dependency'): + if ctx.config.get_option(_('ignore_dependency')): # simple code path then for x in package_URIs: operations.install_single_file(x) @@ -164,7 +165,7 @@ def install_pkg_files(package_URIs): A = d_t.keys() if len(A)==0: - ctx.ui.info('No packages to install.') + ctx.ui.info(_('No packages to install.')) return True # try to construct a pisi graph of packages to @@ -199,7 +200,7 @@ def install_pkg_files(package_URIs): for x in order: operations.install_single_file(dfn[x]) else: - raise Error('External dependencies not satisfied') + raise Error(_('External dependencies not satisfied')) return True # everything went OK. @@ -211,7 +212,7 @@ def install_pkg_names(A): ctx.ui.debug('A = %s' % str(A)) if len(A)==0: - ctx.ui.info('No packages to install.') + ctx.ui.info(_('No packages to install.')) return True # try to construct a pisi graph of packages to @@ -232,7 +233,7 @@ def install_pkg_names(A): pkg = packagedb.get_package(x) print pkg for dep in pkg.runtimeDeps: - print 'checking ', dep + ctx.ui.debug('checking %s' % str(dep)) # we don't deal with already *satisfied* dependencies if not dependency.installed_satisfies_dep(dep): if not dep.package in G_f.vertices(): @@ -285,7 +286,6 @@ def package_graph(A, ignore_installed = False): def upgrade(A): upgrade_pkg_names(A) - def upgrade_pkg_names(A): """Re-installs packages from the repository, trying to perform a maximum number of upgrades.""" @@ -296,9 +296,9 @@ def upgrade_pkg_names(A): Ap = [] for x in A: if x.endswith('.pisi'): - ctx.ui.debug("Warning: package *name* ends with '.pisi'") + ctx.ui.debug(_("Warning: package *name* ends with '.pisi'")) if not ctx.installdb.is_installed(x): - ctx.ui.info('Package %s is not installed.' % x) + ctx.ui.info(_('Package %s is not installed.') % x) continue (version, release, build) = ctx.installdb.get_version(x) pkg = packagedb.get_package(x) @@ -316,13 +316,13 @@ def upgrade_pkg_names(A): Ap.append(x) else: #ctx.ui.info('Package %s cannot be upgraded. ' % x) - ctx.ui.info('Package %s is already at its latest version %s,\ - release %s, build %s.' + ctx.ui.info(_('Package %s is already at its latest version %s,\ + release %s, build %s.') % (x, pkg.version, pkg.release, pkg.build)) A = Ap if len(A)==0: - ctx.ui.info('No packages to upgrade.') + ctx.ui.info(_('No packages to upgrade.')) return True ctx.ui.debug('A = %s' % str(A)) @@ -344,7 +344,7 @@ def upgrade_pkg_names(A): pkg = packagedb.get_package(x) print pkg for dep in pkg.runtimeDeps: - print 'checking ', dep + #print 'checking ', dep # add packages that can be upgraded if dependency.repo_satisfies_dep(dep): if ctx.installdb.is_installed(dep.package): @@ -401,11 +401,11 @@ def remove(A): if ctx.installdb.is_installed(x): Ap.append(x) else: - ctx.ui.info('Package %s does not exist. Cannot remove.' % x) + ctx.ui.info(_('Package %s does not exist. Cannot remove.') % x) A = Ap if len(A)==0: - ctx.ui.info('No packages to remove.') + ctx.ui.info(_('No packages to remove.')) return True # try to construct a pisi graph of packages to @@ -424,32 +424,53 @@ def remove(A): Bp = set() for x in B: pkg = packagedb.get_package(x) - print 'processing', pkg.name + #print 'processing', pkg.name rev_deps = packagedb.get_rev_deps(x) for (rev_dep, depinfo) in rev_deps: - print 'checking ', rev_dep + #print 'checking ', rev_dep # we don't deal with unsatisfied dependencies if dependency.installed_satisfies_dep(depinfo): if not rev_dep in G_f.vertices(): Bp.add(rev_dep) G_f.add_plain_dep(rev_dep, x) B = Bp - G_f.write_graphviz(sys.stdout) + #G_f.write_graphviz(sys.stdout) order = G_f.topological_sort() - print order + #FIXME: do something more informative here + #print order for x in order: if ctx.installdb.is_installed(x): operations.remove_single(x) else: - ctx.ui.info('Package %s is not installed. Cannot remove.' % x) + ctx.ui.info(_('Package %s is not installed. Cannot remove.') % x) return True # everything went OK :) def configure_pending(): - # TODO: not coded yet # start with pending packages - # configure them in reverse topological order of configuration dependency - pass + # configure them in reverse topological order of dependency + A = ctx.installdb.list_pending() + print A + G_f = pgraph.PGraph(packagedb) # construct G_f + for x in A: + G_f.add_package(x) + B = A + #state = {} + while len(B) > 0: + Bp = set() + for x in B: + pkg = packagedb.get_package(x) + print pkg + for dep in pkg.runtimeDeps: + if dep.package in G_f.vertices(): + G_f.add_dep(x, dep) + B = Bp + G_f.write_graphviz(sys.stdout) + order = G_f.topological_sort() + order.reverse() + print order + #for x in order: + def info(package): if package.endswith(ctx.const.package_prefix): @@ -457,13 +478,13 @@ def info(package): else: return info_name(package) -def info_file(package): +def info_file(package_fn): from package import Package - if not os.path.exists(package): - raise Error ('File %s not found' % package) + if not os.path.exists(package_fn): + raise Error (_('File %s not found') % package_fn) - package = Package(package) + package = Package(package_fn) package.read() return package.metadata, package.files @@ -483,15 +504,15 @@ def info_name(package_name): files = None return metadata, files else: - raise Error('Package %s not found' % package_name) + raise Error(_('Package %s not found') % package_name) def index(repo_dir = '.'): - ctx.ui.info('* Building index of PISI files under %s' % repo_dir) + ctx.ui.info(_('* Building index of PISI files under %s') % repo_dir) index = Index() index.index(repo_dir) index.write(ctx.const.pisi_index) - ctx.ui.info('* Index file written') + ctx.ui.info(_('* Index file written')) def add_repo(name, indexuri): @@ -502,16 +523,16 @@ def remove_repo(name): if ctx.repodb.has_repo(name): ctx.repodb.remove_repo(name) else: - ctx.ui.error('* Repository %s does not exist. Cannot remove.' + ctx.ui.error(_('* Repository %s does not exist. Cannot remove.') % name) def update_repo(repo): - ctx.ui.info('* Updating repository: %s' % repo) + ctx.ui.info(_('* Updating repository: %s') % repo) index = Index() index.read(ctx.repodb.get_repo(repo).indexuri.get_uri(), repo) index.update_db(repo) - ctx.ui.info('* Package database updated.') + ctx.ui.info(_('* Package database updated.')) # build functions... @@ -538,13 +559,14 @@ def prepare_for_build(pspecfile, authInfo=None): # FIXME: take care of the required buildDeps... # For now just report an error! if dep_unsatis: - ctx.ui.error("Unsatisfied Build Dependencies:") + ctx.ui.error(_("Unsatisfied Build Dependencies:")) for dep in dep_unsatis: - ctx.ui.error(dep.package) -# FIXME: Don't exit for now! It's annoying to test on a system that -# doesn't has all packages made with pisi. -# Will be enabled on the full-pisi system. -# sys.exit(1) + ctx.ui.warning(dep.package) + + # FIXME: Don't exit for now! It's annoying to test on a system that + # doesn't has all packages made with pisi. + # Will be enabled on the full-pisi system. + # sys.exit(1) return pb diff --git a/pisi/archive.py b/pisi/archive.py index 950536f4..710784ab 100644 --- a/pisi/archive.py +++ b/pisi/archive.py @@ -17,6 +17,10 @@ import os import tarfile import zipfile +import gettext +__trans = gettext.translation('pisi', fallback=True) +_ = __trans.ugettext + # PiSi modules import pisi import pisi.util as util @@ -61,7 +65,7 @@ class ArchiveTar(ArchiveBase): elif self.type == 'tarbz2': rmode = 'r:bz2' else: - raise ArchiveError("Archive type not recognized") + raise ArchiveError(_("Archive type not recognized")) tar = tarfile.open(self.file_path, rmode) oldwd = os.getcwd() diff --git a/pisi/config.py b/pisi/config.py index 6939fd16..a358a175 100644 --- a/pisi/config.py +++ b/pisi/config.py @@ -16,6 +16,10 @@ # Authors: Baris Metin +import gettext +__trans = gettext.translation('pisi', fallback=True) +_ = __trans.ugettext + import pisi import pisi.context as ctx from pisi.configfile import ConfigurationFile diff --git a/pisi/configfile.py b/pisi/configfile.py index 787d75d6..92911f1a 100644 --- a/pisi/configfile.py +++ b/pisi/configfile.py @@ -38,6 +38,9 @@ import os from ConfigParser import ConfigParser, NoSectionError +import gettext +__trans = gettext.translation('pisi', fallback=True) +_ = __trans.ugettext class ConfigException(Exception): pass @@ -79,7 +82,7 @@ class ConfigurationSection(object): elif section == "directories": self.defaults = DirsDefaults else: - e = "No section by name '%s'" % section + e = _("No section by name '%s'") % section raise ConfigException, e self.section = section diff --git a/pisi/constants.py b/pisi/constants.py index fb9409d4..4db541a4 100644 --- a/pisi/constants.py +++ b/pisi/constants.py @@ -16,6 +16,10 @@ # Author: Baris Metin +import gettext +__trans = gettext.translation('pisi', fallback=True) +_ = __trans.ugettext + #import pisi.db as db import pisi.context as ctx import pisi.packagedb as packagedb @@ -47,7 +51,7 @@ class DepInfo: def has_errors(self): if not self.package: - return [ "Dependency should have a package string" ] + return [ _("Dependency should have a package string") ] return None def satisfies(self, pkg_name, version, release): @@ -111,7 +115,7 @@ dependency spec""" def satisfies_dependencies(pkg, deps, sat = installed_satisfies_dep): for dep in deps: if not sat(dep): - ctx.ui.error('Package %s does not satisfy dependency %s' % + ctx.ui.error(_('Package %s does not satisfy dependency %s') % (pkg,dep)) return False return True @@ -124,7 +128,7 @@ def installable(pkg): """calculate if pkg is installable currently which means it has to satisfy both install and runtime dependencies""" if not packagedb.has_package(pkg): - ctx.ui.info("Package " + pkg + " is not present in the package database"); + ctx.ui.info(_("Package %s is not present in the package database") % pkg); return False elif satisfies_runtime_deps(pkg): return True diff --git a/pisi/fetcher.py b/pisi/fetcher.py index 6519238a..a321d742 100644 --- a/pisi/fetcher.py +++ b/pisi/fetcher.py @@ -20,6 +20,10 @@ import urllib2 import os from base64 import encodestring +import gettext +__trans = gettext.translation('pisi', fallback=True) +_ = __trans.ugettext + # pisi modules import pisi import pisi.util as util @@ -59,10 +63,10 @@ class Fetcher: """Return value: Fetched file's full path..""" if not self.url.filename(): - self.err("filename error") + self.err(_("Filename error")) if not os.access(self.filedest, os.W_OK): - self.err("no perm to write to dest dir") + self.err(_("Access denied to write to dest dir")) if self.url.is_local_file(): self.fetchLocalFile() @@ -110,7 +114,7 @@ class Fetcher: url = self.url if not os.access(url.path(), os.F_OK): - self.err("no such file or no perm to read") + self.err(_("No such file or no permission to read")) dest = open(os.path.join(self.filedest, url.filename()) , "w") totalsize = os.path.getsize(url.path()) diff --git a/pisi/index.py b/pisi/index.py index e20e36d7..df548382 100644 --- a/pisi/index.py +++ b/pisi/index.py @@ -16,6 +16,10 @@ import os +import gettext +__trans = gettext.translation('pisi', fallback=True) +_ = __trans.ugettext + import pisi.context as ctx import pisi.metadata as metadata import pisi.packagedb as packagedb @@ -67,7 +71,7 @@ class Index(XmlFile): for root, dirs, files in os.walk(repo_uri): for fn in files: if fn.endswith(ctx.const.package_prefix): - ctx.ui.info('Adding ' + fn + ' to package index') + ctx.ui.info(_('Adding %s to package index') %s) self.add_package(os.path.join(root, fn), repo_uri) def update_db(self, repo): @@ -93,6 +97,6 @@ class Index(XmlFile): md.package.packageURI = util.removepathprefix(repo_uri, path) # check package semantics if md.has_errors(): - ctx.ui.error('Package ' + md.package.name + ': metadata corrupt') + ctx.ui.error(_('Package %s: metadata corrupt') % md.package.name) else: self.packages.append(md.package) diff --git a/pisi/install.py b/pisi/install.py index e24a0e87..4738a5f5 100644 --- a/pisi/install.py +++ b/pisi/install.py @@ -16,6 +16,10 @@ import os +import gettext +__trans = gettext.translation('pisi', fallback=True) +_ = __trans.ugettext + import pisi import pisi.context as ctx @@ -78,9 +82,9 @@ class Installer: # check dependencies if not ctx.config.get_option('ignore_dependency'): if not dependency.installable(self.pkginfo.name): - ctx.ui.error('Dependencies for ' + self.pkginfo.name + - ' not satisfied') - raise InstallError("Package not installable") + ctx.ui.error(_('Dependencies for %s not satisfied') % + self.pkginfo.name) + raise InstallError(_("Package not installable")) def check_reinstall(self): "check reinstall, confirm action, and schedule reinstall" @@ -104,33 +108,33 @@ class Installer: if same_ver: if self.ask_reinstall: - if not ctx.ui.confirm('Re-install same version package?'): - raise InstallError('Package re-install declined') + if not ctx.ui.confirm(_('Re-install same version package?')): + raise InstallError(_('Package re-install declined')) else: upgrade = False # is this an upgrade? # determine and report the kind of upgrade: version, release, build if pkg.version > iversion: - ctx.ui.info('Upgrading to new upstream version') + ctx.ui.info(_('Upgrading to new upstream version')) upgrade = True elif pkg.release > irelease: - ctx.ui.info('Upgrading to new distribution release') + ctx.ui.info(_('Upgrading to new distribution release')) upgrade = True elif ((not ignore_build) and ibuild and pkg.build and pkg.build > ibuild): - ctx.ui.info('Upgrading to new distribution build') + ctx.ui.info(_('Upgrading to new distribution build')) upgrade = True # is this a downgrade? confirm this action. if self.ask_reinstall and (not upgrade): if pkg.version < iversion: - x = 'Downgrade to old upstream version?' + x = _('Downgrade to old upstream version?') elif pkg.release < irelease: - x = 'Downgrade to old distribution release?' + x = _('Downgrade to old distribution release?') else: - x = 'Downgrade to old distribution build?' + x = _('Downgrade to old distribution build?') if not ctx.ui.confirm(x): - raise InstallError('Package downgrade declined') + raise InstallError(_('Package downgrade declined')) # schedule for reinstall self.old_files = ctx.installdb.files(pkg.name) @@ -140,7 +144,7 @@ class Installer: def extract_install(self): "unzip package in place" - ctx.ui.info('Extracting files,') + ctx.ui.info(_('Extracting files')) self.package.extract_dir_flat('install', ctx.config.destdir) if self.reinstall: @@ -158,17 +162,17 @@ class Installer: """put files.xml, metadata.xml, actions.py and COMAR scripts somewhere in the file system. We'll need these in future...""" - ctx.ui.info('Storing %s, ' % ctx.const.files_xml) + ctx.ui.info(_('Storing %s, ') % ctx.const.files_xml) self.package.extract_file(ctx.const.files_xml, self.package.pkg_dir()) - ctx.ui.info('%s.' % ctx.const.metadata_xml) + ctx.ui.info(_('%s.') % ctx.const.metadata_xml) self.package.extract_file(ctx.const.metadata_xml, self.package.pkg_dir()) for pcomar in self.metadata.package.providesComar: fpath = os.path.join(ctx.const.comar_dir, pcomar.script) # comar prefix is added to the pkg_dir while extracting comar # script file. so we'll use pkg_dir as destination. - ctx.ui.info('Storing %s' % fpath) + ctx.ui.info(_('Storing %s') % fpath) self.package.extract_file(fpath, self.package.pkg_dir()) def register_comar_scripts(self): @@ -178,7 +182,7 @@ class Installer: for pcomar in self.metadata.package.providesComar: scriptPath = os.path.join(self.package.comar_dir(),pcomar.script) - ctx.ui.info("Registering COMAR script %s" % pcomar.script) + ctx.ui.info(_("Registering COMAR script %s") % pcomar.script) com.register(pcomar.om, self.metadata.package.name, @@ -188,15 +192,15 @@ class Installer: if reply[0] == com.RESULT: break else: - raise InstallError, "COMAR.register ERROR!" + raise InstallError, _("COMAR.register ERROR!") def comar_run_postinstall(self): "run postinstall scripts trough COMAR" com = ctx.comard - ctx.ui.info("Running postinstall script for %s" % self.metadata.package.name) - com.call_package("System.Package.postInstall", self.metadata.package.name) + ctx.ui.info(_("Running postinstall script for %s") % self.metadata.package.name) + com.call_package(_("System.Package.postInstall"), self.metadata.package.name) while 1: reply = com.read_cmd() if reply[0] == com.RESULT: @@ -204,11 +208,11 @@ class Installer: elif reply[0] == com.NONE: # package has no postInstall script break elif reply[0] == com.FAIL: - e = "COMAR.call_package(System.Pakcage.postInstall, %s) failed!: %s" % ( + e = _("COMAR.call_package(System.Pakcage.postInstall, %s) failed!: %s") % ( self.metadata.package.name, reply[2]) raise InstallError, e else: - raise InstallError, "COMAR.call_package ERROR: %d" % reply[0] + raise InstallError, _("COMAR.call_package ERROR: %d") % reply[0] def update_databases(self): diff --git a/pisi/installdb.py b/pisi/installdb.py index 145e1bf8..16548898 100644 --- a/pisi/installdb.py +++ b/pisi/installdb.py @@ -18,6 +18,10 @@ import os import fcntl +import gettext +__trans = gettext.translation('pisi', fallback=True) +_ = __trans.ugettext + # PiSi import pisi import pisi.context as ctx @@ -52,17 +56,17 @@ class InstallInfo: time_str) return s - state_map = { 'i': 'installed', 'ip':'installed-pending', 'r:removed' - 'p': 'purged' } + state_map = { 'i': _('installed'), 'ip':_('installed-pending'), + 'r':_('removed'), 'p': _('purged') } def __str__(self): - s = "State: %s\nVersion: %s, Release: %s, Build: %s\n" % \ + s = _("State: %s\nVersion: %s, Release: %s, Build: %s\n") % \ (InstallInfo.state_map[self.state], self.version, self.release, self.build) import time time_str = time.strftime("%d %b %Y %H:%M", self.time) - s += 'Distribution: %s, Install Time: %s\n' % (self.distribution, - time_str) + s += _('Distribution: %s, Install Time: %s\n') % (self.distribution, + time_str) return s @@ -132,8 +136,8 @@ class InstallDB: """install package with specific version, release, build""" pkg = str(pkg) if self.is_installed(pkg): - raise InstallDBError("already installed") - if ctx.config.options and ctx.config.options.ignore_comar: + raise InstallDBError(_("Already installed")) + if ctx.config.get_option('ignore_comar'): state = 'ip' self.dp[pkg] = True else: diff --git a/pisi/operations.py b/pisi/operations.py index 33ddb4f0..8b83d1f4 100644 --- a/pisi/operations.py +++ b/pisi/operations.py @@ -55,7 +55,9 @@ def run_preremove(package_name): break elif reply[1] == com.ERROR: raise Error, "COMAR.remove failed!" - + else: + # TODO: store this somewhere + pass def remove_db(package_name): ctx.installdb.remove(package_name) packagedb.remove_package(package_name) #FIXME: this looks like a mistake!