[PackageKit-commit] packagekit: Branch 'master' - 42 commits
Richard Hughes
hughsient at kemper.freedesktop.org
Mon Feb 23 02:35:43 PST 2009
NEWS | 81
RELEASE | 4
backends/apt/Makefile.am | 8
backends/apt/aptDBUSBackend.py | 2234 -------------------
backends/apt/aptbackend.py | 2187 ++++++++++++++++++
backends/apt/debfile.py | 536 ----
backends/apt/pk-backend-apt.py | 28
backends/apt/update-packagekit-app-data | 86
backends/conary/Makefile.am | 5
backends/conary/conaryBackend.py | 48
backends/conary/conaryCallback.py | 380 ++-
backends/conary/conaryEnums.py | 121 +
backends/conary/conaryFilter.py | 3
backends/conary/conaryProgress.py | 105
backends/conary/conarypk.py | 1
backends/zypp/zypp-events.h | 20
client/pk-console.c | 7
client/pk-tools-common.c | 15
configure.ac | 9
contrib/Makefile.am | 4
contrib/app-install/.gitignore | 7
contrib/app-install/Makefile.am | 55
contrib/app-install/egg-debug.c | 1
contrib/app-install/egg-debug.h | 1
contrib/app-install/pk-app-install-add.c | 345 ++
contrib/app-install/pk-app-install-common.h | 33
contrib/app-install/pk-app-install-create.c | 132 +
contrib/app-install/pk-app-install-generate.c | 345 ++
contrib/app-install/pk-app-install-remove.c | 195 +
data/org.freedesktop.PackageKitAptBackend.service.in | 2
docs/api/spec/pk-introduction.xml | 6
docs/app-install-v1.draft | 21
docs/html/pk-download.html | 1
po/POTFILES.in | 4
po/es.po | 868 +++----
po/pl.po | 468 ++-
po/pt_BR.po | 89
po/zh_CN.po | 778 +++---
38 files changed, 5334 insertions(+), 3899 deletions(-)
New commits:
commit 6427e3ba187201fbda49febe48313f1ad64d0425
Author: Richard Hughes <richard at hughsie.com>
Date: Mon Feb 23 10:34:43 2009 +0000
Release version 0.4.4
diff --git a/NEWS b/NEWS
index e615a0f..2ab0e35 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,84 @@
+Version 0.4.4
+~~~~~~~~~~~~~
+Released: 2009-02-23
+
+Translations:
+ - Updated Swedish translation (Daniel Nylander)
+ - Updated Spanish translation (Domingo Becker)
+ - Updated German translation (Fabian Affolter)
+ - Updated Brazilian Portuguese translation (Igor Pires Soares)
+ - Updated Polish translation (Piotr DrÄ
g)
+ - Updated Simplified Chinese translation (zhourongrong)
+
+New Features:
+ - Add a new method GetDaemonState to the main interface to help debugging on
+ live systems (Richard Hughes)
+ - Print the daemon state when using pkmon in verbose mode (Richard Hughes)
+ - Add a draft standard for application install metadata handling (Richard Hughes)
+ - Add a pk-app-install binary for manipulating the sqlite cache (Richard Hughes)
+ - PackageKit-Qt: Sync API for RequireRestart (Adrien BUSTANY)
+ - PackageKit-Qt: Add support for application filter (Adrien BUSTANY)
+ - PackageKit-Qt: Add a searchFromDesktopFile method (Adrien BUSTANY)
+
+Bugfixes:
+ - Updated documentation with UseSyslog parameter (Balaji)
+ - Fix for the updates and obsoletes delimiter (Daniel Nicoletti)
+ - Make the dbus policy more fine grained (Sebastian Heinlein)
+ - Fix compile failure with gcc-4.4.0 and old versions of glib2 (Richard Hughes)
+ - If we fail to exit from the dispatcher, make sure we cleanup the poll as the
+ child check isn't going to be run (Richard Hughes)
+ - The QT lib now depends on QtSql, so add this to the configure (Richard Hughes)
+ - Fix up resolve in pkcon and from libpackagekit-glib (Richard Hughes)
+ - Don't dereference a NULL pointer in pk_console_resolve() which can be done
+ using pkcon list-install (Richard Hughes)
+ - Don't use an local error in pkcon list-install else we'll fail to free it,
+ and it's non-fatal (Richard Hughes)
+ - PackageKit-Qt: Handle daemon errors more gracefully (Adrien BUSTANY)
+ - PackageKit-Qt: Add a getLastError method to get the last daemon error (Adrien BUSTANY)
+ - PackageKit-Qt: Add missing implementation for uid and cmdline (Adrien BUSTANY)
+ - Packagekit-Qt: Fix to make what provides work (Daniel Nicoletti)
+
+Backends:
+ - alpm: Added experimental support for progress indication (Valeriy Lyasotskiy)
+ - alpm: Updated alpm backend status in status matrix (Valeriy Lyasotskiy)
+ - apt: Allow the properties and introspection interface of the backend
+ to everyone (Sebastian Heinlein)
+ - apt: Use the merged debfile module of python-apt (Sebastian Heinlein)
+ - apt: Fix an API change in debfile (Sebastian Heinlein)
+ - apt: Install the main Python module into the packagekit package and use a command
+ wrapper to improve the start time (*.pyc) (Sebastian Heinlein)
+ - apt: Remove code which is now merged with python-apt (Sebastian Heinlein)
+ - apt: Add script to extract information from app-install desktop files (Sebastian Heinlein)
+ - conary: Fix get-updates command (Andres Vargas)
+ - conary: Fix the group search (Andres Vargas)
+ - conary: Change the error signal for groups not found (Andres Vargas)
+ - conary: Add a percent progress on install packages (Andres Vargas)
+ - conary: Remove the subpercent signal only percent signal (Andres Vargas)
+ - conary: Add subpercent for minitasks (Andres Vargas)
+ - conary: Tuning the percent update (Andres Vargas)
+ - conary: Fix step feeling for percent download (Andres Vargas)
+ - conary: Add percent to update/remove/get-updates/update-system (Andres Vargas)
+ - conary: Add a exception for run get-updates first and then update (Andres Vargas)
+ - conary: update-system do a stepdown percent (Andres Vargas)
+ - conary: Fix the search ~installed filter (Andres Vargas)
+ - conary: Add more classify groups (Andres Vargas)
+ - conary: Implement the conaryEnums for classify category in groups fix the
+ backend for search groups (Andres Vargas)
+ - conary: Add more log info to callbacks fix get-files (Andres Vargas)
+ - conary: Fix get-files from many troves (Andres Vargas)
+ - dummy: Use the correct delimiter for the obsoletes in the kernel package (Richard Hughes)
+ - dummy: Add update detail for the blocked package, and raise an error
+ if we can't find a match (Richard Hughes)
+ - dummy: Add a simple rollback action (Richard Hughes)
+ - poldek: Build fix (Patryk Zawadzki)
+ - poldek: For NOT_INSTALLED filter return only available packages that are NOT
+ installed (Marcin Banasiak)
+ - yum: Adds an auto_close attribute to the rpmdb object (Seth Vidal)
+ - yum: Add support for the new font and mimehandler provides (Richard Hughes)
+ - yum: Don't backtrace with an internal error when the filename is not
+ unicode. Fixes rh#480440 (Richard Hughes)
+ - zypp: Fix up virtual callback methods (Scott Reeves)
+
Version 0.4.3
~~~~~~~~~~~~~
Released: 2009-02-02
diff --git a/RELEASE b/RELEASE
index ea39f5a..90b9d07 100644
--- a/RELEASE
+++ b/RELEASE
@@ -3,8 +3,8 @@ PackageKit Release Notes
1. Write NEWS entries for PackageKit and gnome-packagekit in the same
format as usual. Ignore any trivial commits.
-git-shortlog PACKAGEKIT_0_4_3.. | grep -v trivial | grep -v Merge > NEWS.new
-git-shortlog GNOME_PACKAGEKIT_0_4_3.. | grep -v trivial | grep -v Merge > NEWS.new
+git shortlog PACKAGEKIT_0_4_3.. | grep -v trivial | grep -v Merge > NEWS.new
+git shortlog GNOME_PACKAGEKIT_0_4_3.. | grep -v trivial | grep -v Merge > NEWS.new
2. Add download date to docs/html/pk-download.html, save file.
diff --git a/docs/html/pk-download.html b/docs/html/pk-download.html
index 7c1451f..7b30a44 100644
--- a/docs/html/pk-download.html
+++ b/docs/html/pk-download.html
@@ -68,6 +68,7 @@ Releases are normally once every 1-2 weeks.
</p>
<table>
<tr><td><b>Version</b></td><td> </td><td><b>Date</b></td></tr>
+<tr><td>0.4.4</td><td></td><td>2009-02-23</td></tr>
<tr><td>0.4.3</td><td></td><td>2009-02-02</td></tr>
<tr><td>0.4.2</td><td></td><td>2009-01-19</td></tr>
<tr><td>0.4.1</td><td></td><td>2009-01-08</td></tr>
commit dce120bfd93e0f1764c224a55b84898f70e5277c
Merge: 60762c8... fb5748c...
Author: Richard Hughes <richard at hughsie.com>
Date: Mon Feb 23 10:33:15 2009 +0000
Merge branch 'master' of git+ssh://hughsie@git.packagekit.org/srv/git/PackageKit
commit fb5748cfcd25e626937d14130691e8ecb66c4856
Merge: 32fdfa9... 5d60f24...
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Mon Feb 23 11:33:35 2009 +0100
Merge branch 'master' of git+ssh://glatzor@git.packagekit.org/srv/git/PackageKit
commit 32fdfa9cc18245c822cb1d132020cea81be9ff19
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Mon Feb 23 11:32:38 2009 +0100
AppInst: Rename repo_name to repo_id since it makes sense to follow the PackageKit naming
diff --git a/contrib/app-install/pk-app-install-create.c b/contrib/app-install/pk-app-install-create.c
index 1f57cc2..db2c86e 100644
--- a/contrib/app-install/pk-app-install-create.c
+++ b/contrib/app-install/pk-app-install-create.c
@@ -102,7 +102,7 @@ main (int argc, char *argv[])
"application_id TEXT primary key,"
"package_name TEXT,"
"group_id TEXT,"
- "repo_name TEXT,"
+ "repo_id TEXT,"
"application_name TEXT,"
"application_summary TEXT);";
rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
diff --git a/contrib/app-install/pk-app-install-remove.c b/contrib/app-install/pk-app-install-remove.c
index 9c1c408..2ce8b71 100644
--- a/contrib/app-install/pk-app-install-remove.c
+++ b/contrib/app-install/pk-app-install-remove.c
@@ -142,7 +142,7 @@ main (int argc, char *argv[])
}
/* remove icons */
- statement = g_strdup_printf ("SELECT application_id FROM applications WHERE repo_name = '%s'", repo);
+ statement = g_strdup_printf ("SELECT application_id FROM applications WHERE repo_id = '%s'", repo);
rc = sqlite3_exec (db, statement, pk_app_install_remove_icons_sqlite_cb, (void*) icondir, &error_msg);
g_free (statement);
if (rc != SQLITE_OK) {
@@ -151,10 +151,10 @@ main (int argc, char *argv[])
return 0;
}
- /* delete from translations (translations has no repo_name, so key of applications) */
+ /* delete from translations (translations has no repo_id, so key of applications) */
statement = g_strdup_printf ("DELETE FROM translations WHERE EXISTS ( "
"SELECT applications.application_id FROM applications WHERE "
- "applications.application_id = applications.application_id AND applications.repo_name = '%s')", repo);
+ "applications.application_id = applications.application_id AND applications.repo_id = '%s')", repo);
rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
g_free (statement);
if (rc) {
@@ -165,7 +165,7 @@ main (int argc, char *argv[])
egg_debug ("%i removals from translations", sqlite3_changes (db));
/* delete from applications */
- statement = g_strdup_printf ("DELETE FROM applications WHERE repo_name = '%s'", repo);
+ statement = g_strdup_printf ("DELETE FROM applications WHERE repo_id = '%s'", repo);
rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
g_free (statement);
if (rc) {
commit 5a9d1bbc03ad0f36ab50ca346180df49014ec71f
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Mon Feb 23 11:32:01 2009 +0100
AppInst: Update draft to adapt name changes
diff --git a/docs/app-install-v1.draft b/docs/app-install-v1.draft
index 08d4e58..65252fd 100644
--- a/docs/app-install-v1.draft
+++ b/docs/app-install-v1.draft
@@ -77,17 +77,17 @@ This is used, for instance:
== Schema ==
-TABLE localised:
+TABLE translations:
STRING application_id (name of the desktop file, with no extension)
STRING application_name (Name in desktop file, in locale)
STRING application_summary (Comment in desktop file, in locale)
STRING locale
-TABLE general
+TABLE applications:
STRING application_id (name of the desktop file, with no extension)
STRING package_name (the package name, e.g. 'nautilus')
-STRING group_id (Categories from desktop file, _not_ PK groups or PK categories)
-STRING repo_name (for adding and removal)
+STRING categories (Categories from desktop file, _not_ PK groups or PK categories)
+STRING repo_id (for adding and removal)
STRING application_name (Name in desktop file)
STRING application_summary (Comment in desktop file)
commit 57e4eafee993b92489c1f1926b6f9068cb20145e
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Mon Feb 23 11:29:52 2009 +0100
App-Inst: Rename table general to applications and localised to translations
diff --git a/contrib/app-install/pk-app-install-create.c b/contrib/app-install/pk-app-install-create.c
index cfb3b34..1f57cc2 100644
--- a/contrib/app-install/pk-app-install-create.c
+++ b/contrib/app-install/pk-app-install-create.c
@@ -98,7 +98,7 @@ main (int argc, char *argv[])
/* create */
if (create_file == FALSE) {
- statement = "CREATE TABLE general ("
+ statement = "CREATE TABLE applications ("
"application_id TEXT primary key,"
"package_name TEXT,"
"group_id TEXT,"
@@ -107,18 +107,18 @@ main (int argc, char *argv[])
"application_summary TEXT);";
rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
if (rc) {
- egg_warning ("Can't create general table: %s\n", sqlite3_errmsg (db));
+ egg_warning ("Can't create applications table: %s\n", sqlite3_errmsg (db));
retval = 1;
goto out;
}
- statement = "CREATE TABLE localised ("
+ statement = "CREATE TABLE translations ("
"application_id TEXT,"
"application_name TEXT,"
"application_summary TEXT,"
"locale TEXT);";
rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
if (rc) {
- egg_warning ("Can't create localised table: %s\n", sqlite3_errmsg (db));
+ egg_warning ("Can't create translations table: %s\n", sqlite3_errmsg (db));
retval = 1;
goto out;
}
diff --git a/contrib/app-install/pk-app-install-remove.c b/contrib/app-install/pk-app-install-remove.c
index d5f3070..9c1c408 100644
--- a/contrib/app-install/pk-app-install-remove.c
+++ b/contrib/app-install/pk-app-install-remove.c
@@ -142,7 +142,7 @@ main (int argc, char *argv[])
}
/* remove icons */
- statement = g_strdup_printf ("SELECT application_id FROM general WHERE repo_name = '%s'", repo);
+ statement = g_strdup_printf ("SELECT application_id FROM applications WHERE repo_name = '%s'", repo);
rc = sqlite3_exec (db, statement, pk_app_install_remove_icons_sqlite_cb, (void*) icondir, &error_msg);
g_free (statement);
if (rc != SQLITE_OK) {
@@ -151,10 +151,10 @@ main (int argc, char *argv[])
return 0;
}
- /* delete from localised (localised has no repo_name, so key off general) */
- statement = g_strdup_printf ("DELETE FROM localised WHERE EXISTS ( "
- "SELECT general.application_id FROM general WHERE "
- "general.application_id = general.application_id AND general.repo_name = '%s')", repo);
+ /* delete from translations (translations has no repo_name, so key of applications) */
+ statement = g_strdup_printf ("DELETE FROM translations WHERE EXISTS ( "
+ "SELECT applications.application_id FROM applications WHERE "
+ "applications.application_id = applications.application_id AND applications.repo_name = '%s')", repo);
rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
g_free (statement);
if (rc) {
@@ -162,10 +162,10 @@ main (int argc, char *argv[])
ret = FALSE;
goto out;
}
- egg_debug ("%i removals from localised", sqlite3_changes (db));
+ egg_debug ("%i removals from translations", sqlite3_changes (db));
- /* delete from general */
- statement = g_strdup_printf ("DELETE FROM general WHERE repo_name = '%s'", repo);
+ /* delete from applications */
+ statement = g_strdup_printf ("DELETE FROM applications WHERE repo_name = '%s'", repo);
rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
g_free (statement);
if (rc) {
@@ -173,7 +173,7 @@ main (int argc, char *argv[])
ret = FALSE;
goto out;
}
- egg_debug ("%i removals from general", sqlite3_changes (db));
+ egg_debug ("%i removals from applications", sqlite3_changes (db));
/* reclaim memory */
statement = g_strdup ("VACUUM");
commit 60762c854b26fa00724217a2631e9429db163441
Author: Richard Hughes <richard at hughsie.com>
Date: Mon Feb 23 10:28:31 2009 +0000
trivial: build new files
diff --git a/contrib/app-install/Makefile.am b/contrib/app-install/Makefile.am
index c76b7d5..9d39362 100644
--- a/contrib/app-install/Makefile.am
+++ b/contrib/app-install/Makefile.am
@@ -13,6 +13,8 @@ INCLUDES = \
-DEGG_CONSOLE="\"PK_CONSOLE\"" \
-I$(top_srcdir)/lib
+noinst_PROGRAMS = pk-app-install-add pk-app-install-generate
+
sbin_PROGRAMS = pk-app-install-create pk-app-install-remove
pk_app_install_create_SOURCES = \
@@ -33,3 +35,21 @@ pk_app_install_remove_SOURCES = \
pk_app_install_remove_LDADD = $(GLIB_LIBS) $(SQLITE_LIBS)
pk_app_install_remove_CFLAGS = $(WARNINGFLAGS_C)
+pk_app_install_add_SOURCES = \
+ egg-debug.c \
+ egg-debug.h \
+ pk-app-install-add.c \
+ pk-app-install-common.h \
+ $(NULL)
+pk_app_install_add_LDADD = $(GLIB_LIBS) $(SQLITE_LIBS)
+pk_app_install_add_CFLAGS = $(WARNINGFLAGS_C)
+
+pk_app_install_generate_SOURCES = \
+ egg-debug.c \
+ egg-debug.h \
+ pk-app-install-generate.c \
+ pk-app-install-common.h \
+ $(NULL)
+pk_app_install_generate_LDADD = $(GLIB_LIBS) $(SQLITE_LIBS)
+pk_app_install_generate_CFLAGS = $(WARNINGFLAGS_C)
+
commit 5d60f2494c8c07df4434db6842245d13de968869
Author: Richard Hughes <richard at hughsie.com>
Date: Mon Feb 23 09:14:32 2009 +0000
trivial: fix build
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9887fec..c760546 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -7,6 +7,10 @@ client/pk-monitor.c
client/pk-tools-common.c
contrib/command-not-found/pk-command-not-found.c
contrib/browser-plugin/src/contents.cpp
+contrib/app-install/pk-app-install-add.c
+contrib/app-install/pk-app-install-create.c
+contrib/app-install/pk-app-install-generate.c
+contrib/app-install/pk-app-install-remove.c
data/packagekit-catalog.xml.in
data/packagekit-package-list.xml.in
data/packagekit-servicepack.xml.in
commit d98abbf4ace236db09f34c6aea8ca04c8bf61fb9
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Sun Feb 22 23:21:35 2009 -0600
conary: add more classify groups
diff --git a/backends/conary/conaryEnums.py b/backends/conary/conaryEnums.py
index 6584ddd..1089f02 100644
--- a/backends/conary/conaryEnums.py
+++ b/backends/conary/conaryEnums.py
@@ -54,6 +54,127 @@ categoryMap = {
'Utility': GROUP_ACCESSORIES,
'GUIDesigner': GROUP_PROGRAMMING,
'TerminalEmulator': GROUP_ACCESSORIES,
+'Video': GROUP_MULTIMEDIA ,
+'Education': GROUP_EDUCATION,
+'Game': GROUP_GAMES ,
+'Building': GROUP_PROGRAMMING,
+'Debugger': GROUP_PROGRAMMING,
+'IDE': GROUP_PROGRAMMING,
+'GUIDesigner': GROUP_PROGRAMMING,
+'Profiling': GROUP_PROGRAMMING,
+'RevisionControl': GROUP_PROGRAMMING, # Applications like cvs or subversion Development
+'Database': GROUP_PROGRAMMING, # Application to manage a database Office or Development or AudioVideo
+'Translation': GROUP_PROGRAMMING,# A translation tool Development
+'Calendar': GROUP_OFFICE,# Calendar application Office
+'ContactManagement':GROUP_OFFICE,# E.g. an address book Office
+'Dictionary': GROUP_OFFICE,# A dictionary Office;TextTools
+'Chart': GROUP_OFFICE,# Chart application Office
+'Finance':GROUP_OFFICE,# Application to manage your finance Office
+'FlowChart': GROUP_OFFICE,# A flowchart application Office
+'PDA': GROUP_OFFICE, # Tool to manage your PDA Office
+'ProjectManagement': GROUP_OFFICE,# Project management application Office;Development
+'Presentation': GROUP_OFFICE,# Presentation software Office
+'Spreadsheet': GROUP_OFFICE,# A spreadsheet Office
+'WordProcessor':GROUP_OFFICE, # A word processor Office
+'2DGraphics': GROUP_GRAPHICS,# 2D based graphical application Graphics
+'VectorGraphics': GROUP_GRAPHICS,# Vector based graphical application Graphics;2DGraphics
+'RasterGraphics': GROUP_GRAPHICS, # Raster based graphical application Graphics;2DGraphics
+'3DGraphics': GROUP_GRAPHICS, # 3D based graphical application Graphics
+'Scanning': GROUP_GRAPHICS,# Tool to scan a file/text Graphics
+'OCR': GROUP_GRAPHICS, # Optical character recognition application Graphics;Scanning
+'Photography': GROUP_GRAPHICS, #Camera tools, etc. Graphics or Office
+'Publishing' : GROUP_GRAPHICS, # Desktop Publishing applications and Color Management tools Graphics or Office
+'Viewer': GROUP_OFFICE, #Tool to view e.g. a graphic or pdf file Graphics or Office
+'TextTools': GROUP_ACCESSORIES, #A text tool utiliy Utility
+'DesktopSettings': GROUP_SYSTEM,# Configuration tool for the GUI Settings
+'HardwareSettings': GROUP_SYSTEM, # A tool to manage hardware components, like sound cards, video cards or printers Settings
+'Printing': GROUP_SYSTEM, # A tool to manage printers HardwareSettings;Settings
+'PackageManager': GROUP_SYSTEM, # A package manager application Settings
+'Dialup': GROUP_INTERNET,# A dial-up program Network
+'InstantMessaging': GROUP_INTERNET, # An instant messaging client Network
+'Chat': GROUP_INTERNET,# A chat client Network
+'IRCClient': GROUP_INTERNET,# An IRC client Network
+'FileTransfer': GROUP_INTERNET, # Tools like FTP or P2P programs Network
+'HamRadio': GROUP_INTERNET, # HAM radio software Network or Audio
+'News': GROUP_INTERNET, # A news reader or a news ticker Network
+'P2P': GROUP_INTERNET, # A P2P program Network
+'RemoteAccess': GROUP_INTERNET, # A tool to remotely manage your PC Network
+'Telephony': GROUP_INTERNET,# Telephony via PC Network
+'TelephonyTools': GROUP_INTERNET, # Telephony tools, to dial a number, manage PBX, ... Utility
+'VideoConference': GROUP_INTERNET, # Video Conference software Network
+'WebBrowser': GROUP_INTERNET, # A web browser Network
+'WebDevelopment': GROUP_INTERNET, # A tool for web developers Network or Development
+'Midi': GROUP_MULTIMEDIA, # An app related to MIDI AudioVideo;Audio
+'Mixer': GROUP_MULTIMEDIA,# Just a mixer AudioVideo;Audio
+'Sequencer':GROUP_MULTIMEDIA,# A sequencer AuioVideo;Audio
+'Tuner': GROUP_MULTIMEDIA,# A tuner AudioVideo;Audio
+'TV': GROUP_MULTIMEDIA,# A TV application AudioVideo;Video
+'AudioVideoEditing': GROUP_MULTIMEDIA,# Application to edit audio/video files Audio or Video or AudioVideo
+'Player': GROUP_MULTIMEDIA,# Application to play audio/video files Audio or Video or AudioVideo
+'Recorder': GROUP_MULTIMEDIA,# Application to record audio/video files Audio or Video or AudioVideo
+'DiscBurning':GROUP_MULTIMEDIA,# Application to burn a disc AudioVideo
+'ActionGame':GROUP_GAMES,# An action game Game
+'AdventureGame':GROUP_GAMES,# Adventure style game Game
+'ArcadeGame':GROUP_GAMES,# Arcade style game Game
+'BoardGame':GROUP_GAMES,# A board game Game
+'BlocksGame':GROUP_GAMES,# Falling blocks game Game
+'CardGame':GROUP_GAMES,# A card game Game
+'KidsGame': GROUP_GAMES,# A game for kids Game
+'LogicGame':GROUP_GAMES,# Logic games like puzzles, etc Game
+'RolePlaying':GROUP_GAMES,# A role playing game Game
+'Simulation':GROUP_GAMES,# A simulation game Game
+'SportsGame': GROUP_GAMES, #A sports game Game
+'StrategyGame': GROUP_GAMES,# A strategy game Game Art Software to teach arts Education
+'Construction':GROUP_GAMES,# Education
+'Music': GROUP_MULTIMEDIA,# Musical software AudioVideo;Education
+'Languages':GROUP_EDUCATION,# Software to learn foreign languages Education
+'Science': GROUP_EDUCATION,# Scientific software Education
+'ArtificialIntelligence': GROUP_EDUCATION, # Artificial Intelligence software Education;Science
+'Astronomy': GROUP_EDUCATION,# Astronomy software Education;Science
+'Biology':GROUP_SYSTEM,# Biology software Education;Science
+'Chemistry':GROUP_EDUCATION,# Chemistry software Education;Science
+'ComputerScience':GROUP_EDUCATION,# ComputerSience software Education;Science
+'DataVisualization':GROUP_EDUCATION,# Data visualization software Education;Science
+'Economy':GROUP_EDUCATION,# Economy software Education
+'Electricity':GROUP_EDUCATION,# Electricity software Education;Science
+'Geography':GROUP_EDUCATION,# Geography software Education
+'Geology':GROUP_EDUCATION,# Geology software Education;Science
+'Geoscience':GROUP_EDUCATION,# Geoscience software Education;Science
+'History':GROUP_EDUCATION,# History software Education
+'ImageProcessing':GROUP_EDUCATION,# Image Processing software Education;Science
+'Literature':GROUP_EDUCATION,# Literature software Education
+'Math':GROUP_EDUCATION,# Math software Education;Science
+'NumericalAnalysis':GROUP_EDUCATION,# Numerical analysis software Education;Science;Math
+'MedicalSoftware':GROUP_EDUCATION,# Medical software Education;Science
+'Physics':GROUP_EDUCATION,# Physics software Education;Science
+'Robotics':GROUP_EDUCATION,# Robotics software Education;Science
+'Sports':GROUP_GRAPHICS,# Sports software Education
+'ParallelComputing':GROUP_EDUCATION,# Parallel computing software Education;Science;ComputerScience
+#'Amusement' A simple amusement
+'Archiving': GROUP_ACCESSORIES,# A tool to archive/backup data Utility
+'Compression': GROUP_ACCESSORIES,# A tool to manage compressed data/archives Utility;Archiving
+#'Electronics' Electronics software, e.g. a circuit designer
+'Emulator':GROUP_GAMES,# Emulator of another platform, such as a DOS emulator System or Game
+'Engineering':GROUP_EDUCATION,# Engineering software, e.g. CAD programs
+'FileTools':GROUP_ACCESSORIES, # A file tool utility Utility or System
+'FileManager':GROUP_ACCESSORIES,# A file manager System;FileTools
+'TerminalEmulator':GROUP_ACCESSORIES,# A terminal emulator application System
+'Filesystem':GROUP_SYSTEM, # A file system tool System
+'Monitor':GROUP_SYSTEM,# Monitor application/applet that monitors some resource or activity System
+'Security':GROUP_SYSTEM,# A security tool Settings or System
+'Accessibility':GROUP_ACCESSIBILITY,# Accessibility Settings or Utility
+'Calculator':GROUP_ACCESSORIES,# A calculator Utility
+'Clock':GROUP_ACCESSORIES,# A clock application/applet Utility
+'TextEditor':GROUP_ACCESSORIES,# A text editor Utility
+'Documentation':GROUP_EDUCATION,# Help or documentation
+'Core':GROUP_SYSTEM,# Important application, core to the desktop such as a file manager or a help browser
+#KDE Application based on KDE libraries QT
+#GNOME Application based on GNOME libraries GTK
+#GTK Application based on GTK+ libraries
+#Qt Application based on Qt libraries
+#Motif Application based on Motif libraries
+#Java Application based on Java GUI libraries, such as AWT or Swing
+'ConsoleOnly':GROUP_ACCESSORIES,
}
groupMap = {}
commit 9abcc0c03f3815a41992ab009fede6b61bc780ea
Merge: ee0db30... dbc7387...
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Sun Feb 22 20:04:09 2009 -0600
Merge branch 'master' of git+ssh://zodman@git.packagekit.org/srv/git/PackageKit
commit ee0db30b2185fdbecf1f5dac285a4791d7bda0db
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Sun Feb 22 20:03:54 2009 -0600
conary: fix the search ~installed filter
diff --git a/backends/conary/conaryBackend.py b/backends/conary/conaryBackend.py
index fa4f753..537fd61 100755
--- a/backends/conary/conaryBackend.py
+++ b/backends/conary/conaryBackend.py
@@ -180,8 +180,6 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
log.debug((searchlist, where))
troveTupleList = cache.search(searchlist, where )
- log.info("XMLCACHE results:")
- log.info(troveTupleList)
if len(troveTupleList) > 0 :
for i in troveTupleList:
@@ -190,7 +188,7 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
else:
log.info("NOT FOUND %s " % searchlist )
pk = ConaryPk()
- troveTupleList = pk.query( searchlist)
+ troveTupleList = pk.query(searchlist)
log.info(troveTupleList)
if not troveTupleList:
error = {}
@@ -259,10 +257,7 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
version = pkg["version"]
trove = name, None , cli.flavor
specList.append( trove )
- log.info(specList)
trovesList = cli.repos.findTroves(cli.default_label, specList, allowMissing=True )
- log.info(trovesList)
-
pkgFilter = ConaryFilter(filters)
troves = trovesList.values()
for trovelst in troves:
diff --git a/backends/conary/conaryFilter.py b/backends/conary/conaryFilter.py
index 20bd4bf..59cbcfa 100644
--- a/backends/conary/conaryFilter.py
+++ b/backends/conary/conaryFilter.py
@@ -45,9 +45,10 @@ class ConaryFilter(PackagekitFilter):
'''
Return if the packages are installed
'''
+ if type(pkg) == tuple:
+ pkg = pkg[0]
conary_cli = ConaryPk()
result = conary_cli.query(pkg)
-
if result:
return True
else:
diff --git a/backends/conary/conarypk.py b/backends/conary/conarypk.py
index 9ed2545..13a5be5 100644
--- a/backends/conary/conarypk.py
+++ b/backends/conary/conarypk.py
@@ -9,6 +9,7 @@ from conary.versions import Label
from conary.errors import TroveNotFound
from conary.conaryclient.update import NoNewTrovesError
+from pkConaryLog import log
class ConaryPk:
def __init__(self):
commit dbc73873e6719d5eb2bd08b9a87dd3fb3d0ed998
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Sun Feb 22 19:47:54 2009 +0100
Trivial: The application id in the localised table should not be unique
diff --git a/contrib/app-install/pk-app-install-create.c b/contrib/app-install/pk-app-install-create.c
index 9373454..cfb3b34 100644
--- a/contrib/app-install/pk-app-install-create.c
+++ b/contrib/app-install/pk-app-install-create.c
@@ -112,7 +112,7 @@ main (int argc, char *argv[])
goto out;
}
statement = "CREATE TABLE localised ("
- "application_id TEXT primary key,"
+ "application_id TEXT,"
"application_name TEXT,"
"application_summary TEXT,"
"locale TEXT);";
commit 1dec96a93002088ec34c15b3636a7a6f5008fc68
Merge: db0b740... a3630a8...
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Sun Feb 22 16:47:47 2009 +0100
Merge branch 'master' of git+ssh://glatzor@git.packagekit.org/srv/git/PackageKit
commit a3630a8b830494d50377d1a4a935ede06f69b191
Author: zhourongrong <zhourenren at gmail.com>
Date: Sun Feb 22 05:06:02 2009 +0000
updated
Transmitted-via: Transifex (translate.fedoraproject.org)
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 56892d2..a2171b3 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -3,15 +3,15 @@
# This file is distributed under the same license as the package.
# Chen Yu <jcomee at gmail.com>, 2008
# çé²(Gan Lu) <rhythm.gan at gmail.com>, 2008
-# é«ä¸°å (sainry)<sainry at gmail.com> 2008
+# zhou renren <zhourenren at gmail.com>,2009
#
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-01-15 16:57+0000\n"
-"PO-Revision-Date: 2008-11-23 19:47+0800\n"
+"POT-Creation-Date: 2009-02-17 08:37+0000\n"
+"PO-Revision-Date: 2009-02-21 13:48+0700\n"
"Last-Translator: çé²(Gan Lu) <rhythm.gan at gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -21,680 +21,760 @@ msgstr ""
#. TRANSLATORS: this is an atomic transaction
#: ../client/pk-console.c:230
msgid "Transaction"
-msgstr ""
+msgstr "å¤ç"
#. TRANSLATORS: this is the time the transaction was started in system timezone
#: ../client/pk-console.c:232
msgid "System time"
-msgstr ""
+msgstr "ç³»ç»æ¶é´"
#. TRANSLATORS: this is if the transaction succeeded or not
#: ../client/pk-console.c:234
msgid "Succeeded"
-msgstr ""
+msgstr "æå"
#. TRANSLATORS: if the repo is enabled
-#: ../client/pk-console.c:234 ../client/pk-console.c:377
+#: ../client/pk-console.c:234
+#: ../client/pk-console.c:401
msgid "True"
-msgstr ""
+msgstr "æ¯"
-#: ../client/pk-console.c:234 ../client/pk-console.c:377
+#: ../client/pk-console.c:234
+#: ../client/pk-console.c:401
msgid "False"
-msgstr ""
+msgstr "å¦"
#. TRANSLATORS: this is the transactions role, e.g. "update-system"
#: ../client/pk-console.c:236
msgid "Role"
-msgstr ""
+msgstr "æä½"
#. TRANSLATORS: this is The duration of the transaction
#: ../client/pk-console.c:241
msgid "Duration"
-msgstr ""
+msgstr "æç»æ¶é´"
#: ../client/pk-console.c:241
msgid "(seconds)"
-msgstr ""
+msgstr "ç§"
#. TRANSLATORS: this is The command line used to do the action
#: ../client/pk-console.c:245
-#, fuzzy
msgid "Command line"
-msgstr "å½ä»¤å¤±è´¥"
+msgstr "å½ä»¤è¡"
#. TRANSLATORS: this is the user ID of the user that started the action
#: ../client/pk-console.c:247
msgid "User ID"
-msgstr ""
+msgstr "ç¨æ·ID"
#. TRANSLATORS: this is the username, e.g. hughsie
#: ../client/pk-console.c:254
msgid "Username"
-msgstr ""
+msgstr "ç¨æ·å"
#. TRANSLATORS: this is the users real name, e.g. "Richard Hughes"
#: ../client/pk-console.c:258
msgid "Real name"
-msgstr ""
+msgstr "çå®å§å"
#: ../client/pk-console.c:266
msgid "Affected packages:"
-msgstr ""
+msgstr "åå½±åç软件å
"
#: ../client/pk-console.c:268
msgid "Affected packages: None"
-msgstr ""
+msgstr "åå½±åç软件å
:æ "
#. TRANSLATORS: this is the distro, e.g. Fedora 10
#: ../client/pk-console.c:293
msgid "Distribution"
-msgstr ""
+msgstr "åå¸"
#. TRANSLATORS: this is type of update, stable or testing
#: ../client/pk-console.c:295
msgid "Type"
-msgstr ""
+msgstr "ç±»å"
#. TRANSLATORS: this is any summary text describing the upgrade
#. TRANSLATORS: this is the summary of the group
-#: ../client/pk-console.c:297 ../client/pk-console.c:319
+#: ../client/pk-console.c:297
+#: ../client/pk-console.c:320
msgid "Summary"
-msgstr ""
+msgstr "æè¦"
#. TRANSLATORS: this is the group category name
#: ../client/pk-console.c:309
msgid "Category"
-msgstr ""
+msgstr "åç±»"
#. TRANSLATORS: this is group identifier
#: ../client/pk-console.c:311
msgid "ID"
-msgstr ""
+msgstr "ID"
#. TRANSLATORS: this is the parent group
#: ../client/pk-console.c:314
msgid "Parent"
-msgstr ""
+msgstr "ä¸ä¸çº§"
-#: ../client/pk-console.c:316
+#. TRANSLATORS: this is the name of the parent group
+#: ../client/pk-console.c:317
msgid "Name"
-msgstr ""
+msgstr "ä¸ä¸çº§ç»å"
#. TRANSLATORS: this is preferred icon for the group
-#: ../client/pk-console.c:322
+#: ../client/pk-console.c:323
msgid "Icon"
-msgstr ""
+msgstr "å¾æ "
#. TRANSLATORS: this is a header for the package that can be updated
-#: ../client/pk-console.c:337
+#: ../client/pk-console.c:338
msgid "Details about the update:"
msgstr "æ¬æ¬¡æ´æ°è¯¦æ
ï¼"
-#: ../client/pk-console.c:338
-#, fuzzy
+#. TRANSLATORS: details about the update, package name and version
+#: ../client/pk-console.c:340
msgid "Package"
-msgstr "软件å
æ件"
+msgstr "软件å
"
-#: ../client/pk-console.c:340
+#. TRANSLATORS: details about the update, any packages that this update updates
+#: ../client/pk-console.c:343
msgid "Updates"
-msgstr ""
+msgstr "æ´æ°"
-#: ../client/pk-console.c:342
+#. TRANSLATORS: details about the update, any packages that this update obsoletes
+#: ../client/pk-console.c:347
msgid "Obsoletes"
-msgstr ""
+msgstr "è¿æ¶"
-#: ../client/pk-console.c:344
+#. TRANSLATORS: details about the update, the vendor URLs
+#: ../client/pk-console.c:351
msgid "Vendor"
-msgstr ""
+msgstr "åå"
-#: ../client/pk-console.c:346
+#. TRANSLATORS: details about the update, the bugzilla URLs
+#: ../client/pk-console.c:355
msgid "Bugzilla"
-msgstr ""
+msgstr "Bugzilla"
-#: ../client/pk-console.c:348
+#. TRANSLATORS: details about the update, the CVE URLs
+#: ../client/pk-console.c:359
msgid "CVE"
-msgstr ""
+msgstr "CVE"
-#: ../client/pk-console.c:350
+#. TRANSLATORS: details about the update, if the package requires a restart
+#: ../client/pk-console.c:363
msgid "Restart"
-msgstr ""
+msgstr "éå¯"
-#: ../client/pk-console.c:352
+#. TRANSLATORS: details about the update, any description of the update
+#: ../client/pk-console.c:367
msgid "Update text"
-msgstr ""
+msgstr "æ´æ°ææ¡£"
-#: ../client/pk-console.c:354
+#. TRANSLATORS: details about the update, the changelog for the package
+#: ../client/pk-console.c:371
msgid "Changes"
-msgstr ""
+msgstr "åå"
-#: ../client/pk-console.c:356
+#. TRANSLATORS: details about the update, the ongoing state of the update
+#: ../client/pk-console.c:375
msgid "State"
-msgstr ""
+msgstr "ç¶æ"
-#: ../client/pk-console.c:359
+#. TRANSLATORS: details about the update, date the update was issued
+#: ../client/pk-console.c:380
msgid "Issued"
-msgstr ""
+msgstr "åå¸"
-#: ../client/pk-console.c:362
+#. TRANSLATORS: details about the update, date the update was updated
+#: ../client/pk-console.c:385
msgid "Updated"
-msgstr ""
+msgstr "å·²æ´æ°"
-#: ../client/pk-console.c:448 ../client/pk-console.c:450
+#: ../client/pk-console.c:472
+#: ../client/pk-console.c:474
msgid "Percentage"
-msgstr ""
+msgstr "ç¾åæ¯"
-#: ../client/pk-console.c:450
+#: ../client/pk-console.c:474
msgid "Unknown"
-msgstr ""
+msgstr "æªç¥"
#. TRANSLATORS: a package requires the system to be restarted
-#: ../client/pk-console.c:501
+#: ../client/pk-console.c:525
msgid "System restart required by:"
-msgstr ""
+msgstr "è¦æ±ç³»ç»éå¯ç软件å
:"
#. TRANSLATORS: a package requires the session to be restarted
-#: ../client/pk-console.c:504
-#, fuzzy
+#: ../client/pk-console.c:528
msgid "Session restart required:"
-msgstr "è¦æ±è½¯ä»¶åºç¾å"
+msgstr "è¦æ±ä¼è¯éå¯ç软件å
:"
#. TRANSLATORS: a package requires the application to be restarted
-#: ../client/pk-console.c:507
+#: ../client/pk-console.c:531
msgid "Application restart required by:"
-msgstr ""
+msgstr "è¦æ±åºç¨ç¨åºéå¯ç软件å
:"
-#: ../client/pk-console.c:543
+#. TRANSLATORS: a package needs to restart they system
+#: ../client/pk-console.c:568
msgid "Please restart the computer to complete the update."
msgstr "请éæ°å¯å¨è®¡ç®æºä»¥å®ææ¬æ¬¡æ´æ°ã"
-#: ../client/pk-console.c:545
+#. TRANSLATORS: a package needs to restart the session
+#: ../client/pk-console.c:571
msgid "Please logout and login to complete the update."
msgstr "请ç»åºå¹¶ç»å½ä»¥å®ææ¬æ¬¡æ´æ°ã"
-#: ../client/pk-console.c:547
+#. TRANSLATORS: a package needs to restart the application
+#: ../client/pk-console.c:574
msgid "Please restart the application as it is being used."
msgstr "请éæ°å¯å¨æ£å¨ä½¿ç¨ä¸çç¨åºã"
#. TRANSLATORS: The package is already installed on the system
-#: ../client/pk-console.c:659
-#, fuzzy, c-format
+#: ../client/pk-console.c:687
+#, c-format
msgid "The package %s is already installed"
msgstr "该软件å
'%s' å·²ç»å®è£
"
#. TRANSLATORS: The package name was not found in any software sources. The detailed error follows
-#: ../client/pk-console.c:667
-#, fuzzy, c-format
+#: ../client/pk-console.c:695
+#, c-format
msgid "The package %s could not be installed: %s"
msgstr "该软件å
'%s' æ æ³å®è£
ï¼%s"
#. TRANSLATORS: There was a programming error that shouldn't happen. The detailed error follows
-#: ../client/pk-console.c:692 ../client/pk-console.c:719
-#: ../client/pk-console.c:815 ../client/pk-console.c:932
-#: ../client/pk-tools-common.c:61 ../client/pk-tools-common.c:79
+#: ../client/pk-console.c:720
+#: ../client/pk-console.c:747
+#: ../client/pk-console.c:843
+#: ../client/pk-console.c:960
+#: ../client/pk-tools-common.c:61
+#: ../client/pk-tools-common.c:79
#: ../client/pk-tools-common.c:86
#, c-format
msgid "Internal error: %s"
msgstr "å
é¨é误ï¼%s"
#. TRANSLATORS: There was an error installing the packages. The detailed error follows
-#: ../client/pk-console.c:700 ../client/pk-console.c:1327
+#: ../client/pk-console.c:728
+#: ../client/pk-console.c:1355
#, c-format
msgid "This tool could not install the packages: %s"
msgstr "该工å
·æ æ³å®è£
æ¬è½¯ä»¶å
ï¼%s"
#. TRANSLATORS: There was an error installing the files. The detailed error follows
-#: ../client/pk-console.c:727
+#: ../client/pk-console.c:755
#, c-format
msgid "This tool could not install the files: %s"
msgstr "æ¬å·¥å
·æ æ³å®è£
æ件ï¼%s"
#. TRANSLATORS: The package name was not found in the installed list. The detailed error follows
-#: ../client/pk-console.c:783
-#, fuzzy, c-format
+#: ../client/pk-console.c:811
+#, c-format
msgid "This tool could not remove %s: %s"
-msgstr "该工å
·æ æ³å é¤ï¼ '%s': %s"
+msgstr "该工å
·æ æ³å é¤ %sï¼%s"
#. TRANSLATORS: There was an error removing the packages. The detailed error follows
-#: ../client/pk-console.c:806 ../client/pk-console.c:844
-#: ../client/pk-console.c:877
+#: ../client/pk-console.c:834
+#: ../client/pk-console.c:872
+#: ../client/pk-console.c:905
#, c-format
msgid "This tool could not remove the packages: %s"
msgstr "该工å
·æ æ³å é¤æ¬è½¯ä»¶å
ï¼%s"
#. TRANSLATORS: When removing, we might have to remove other dependencies
-#: ../client/pk-console.c:856
+#: ../client/pk-console.c:884
msgid "The following packages have to be removed:"
msgstr "ä¸å软件å
å¿
须被å é¤ï¼"
#. TRANSLATORS: We are checking if it's okay to remove a list of packages
-#: ../client/pk-console.c:863
+#: ../client/pk-console.c:891
msgid "Proceed removing additional packages?"
msgstr "å¼å§è¿è¡å é¤é¢å¤ç软件å
åï¼"
#. TRANSLATORS: We did not remove any packages
-#: ../client/pk-console.c:868
+#: ../client/pk-console.c:896
msgid "The package removal was canceled!"
msgstr "å·²åæ¶å é¤æ¬è½¯ä»¶å
ï¼"
#. TRANSLATORS: The package name was not found in any software sources
-#: ../client/pk-console.c:909
-#, fuzzy, c-format
+#: ../client/pk-console.c:937
+#, c-format
msgid "This tool could not download the package %s as it could not be found"
msgstr "æ¬å·¥å
·æ æ³ä¸è½½è½¯ä»¶å
'%s' (æ æ³æ¾å°)"
#. TRANSLATORS: Could not download the packages for some reason. The detailed error follows
-#: ../client/pk-console.c:940
+#: ../client/pk-console.c:968
#, c-format
msgid "This tool could not download the packages: %s"
msgstr "æ¬å·¥å
·æ æ³ä¸è½½è¯¥è½¯ä»¶å
ï¼%s"
#. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:967 ../client/pk-console.c:976
-#, fuzzy, c-format
+#: ../client/pk-console.c:995
+#: ../client/pk-console.c:1004
+#, c-format
msgid "This tool could not update %s: %s"
-msgstr "该工å
·æ æ³æ´æ° '%s': %s"
+msgstr "该工å
·æ æ³æ´æ° %sï¼%s"
#. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:998 ../client/pk-console.c:1006
-#, fuzzy, c-format
+#: ../client/pk-console.c:1026
+#: ../client/pk-console.c:1034
+#, c-format
msgid "This tool could not get the requirements for %s: %s"
-msgstr "æ¬å·¥å
·æ æ³å¾å° '%s': %s çéæ±"
+msgstr "æ¬å·¥å
·æ æ³å¾å° %s çéæ±ï¼%s "
#. TRANSLATORS: There was an error getting the dependencies for the package. The detailed error follows
-#: ../client/pk-console.c:1028 ../client/pk-console.c:1036
-#, fuzzy, c-format
+#: ../client/pk-console.c:1056
+#: ../client/pk-console.c:1064
+#, c-format
msgid "This tool could not get the dependencies for %s: %s"
-msgstr "æ¬å·¥å
·æ æ³å¾å° '%s' çä¾èµå
³ç³»: %s"
+msgstr "æ¬å·¥å
·æ æ³å¾å° %s çä¾èµå
³ç³»ï¼%s"
#. TRANSLATORS: There was an error getting the details about the package. The detailed error follows
-#: ../client/pk-console.c:1058 ../client/pk-console.c:1066
-#, fuzzy, c-format
+#: ../client/pk-console.c:1086
+#: ../client/pk-console.c:1094
+#, c-format
msgid "This tool could not get package details for %s: %s"
-msgstr "该工å
·æ æ³å¾å° '%s' ç软件å
详æ
ï¼%s"
+msgstr "该工å
·æ æ³å¾å° %s ç软件å
详æ
ï¼%s"
#. TRANSLATORS: The package name was not found in any software sources. The detailed error follows
-#: ../client/pk-console.c:1088
-#, fuzzy, c-format
+#: ../client/pk-console.c:1116
+#, c-format
msgid "This tool could not find the files for %s: %s"
-msgstr "该工å
·æ æ³æ¾å° '%s' çæ件ï¼%s"
+msgstr "该工å
·æ æ³æ¾å° %s çæ件ï¼%s"
#. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:1096
-#, fuzzy, c-format
+#: ../client/pk-console.c:1124
+#, c-format
msgid "This tool could not get the file list for %s: %s"
-msgstr "该工å
·æ æ³å¾å° '%s' çæ件æ¸
åï¼%s"
+msgstr "该工å
·æ æ³å¾å° %s çæ件æ¸
åï¼%s"
#. TRANSLATORS: There was an error getting the list of packages. The filename follows
-#: ../client/pk-console.c:1118
+#: ../client/pk-console.c:1146
#, c-format
msgid "File already exists: %s"
msgstr "æ件已åå¨: %s"
#. TRANSLATORS: follows a list of packages to install
-#: ../client/pk-console.c:1123 ../client/pk-console.c:1179
-#: ../client/pk-console.c:1254
+#: ../client/pk-console.c:1151
+#: ../client/pk-console.c:1207
+#: ../client/pk-console.c:1282
msgid "Getting package list"
msgstr "æ£å¨è·å¾è½¯ä»¶å
å表..."
#. TRANSLATORS: There was an error getting the list of packages. The detailed error follows
-#: ../client/pk-console.c:1129 ../client/pk-console.c:1185
-#: ../client/pk-console.c:1260
+#: ../client/pk-console.c:1157
+#: ../client/pk-console.c:1213
+#: ../client/pk-console.c:1288
#, c-format
msgid "This tool could not get package list: %s"
msgstr "该工å
·æ æ³å¾å°è½¯ä»¶è¡¨å表ï¼%s"
#. TRANSLATORS: There was an error saving the list
-#: ../client/pk-console.c:1140
-#, c-format
+#: ../client/pk-console.c:1168
msgid "Failed to save to disk"
msgstr "åç失败"
#. TRANSLATORS: There was an error getting the list. The filename follows
-#: ../client/pk-console.c:1174 ../client/pk-console.c:1249
+#: ../client/pk-console.c:1202
+#: ../client/pk-console.c:1277
#, c-format
msgid "File does not exist: %s"
msgstr "æ件ä¸åå¨ : %s"
#. TRANSLATORS: header to a list of packages newly added
-#: ../client/pk-console.c:1206
+#: ../client/pk-console.c:1234
msgid "Packages to add"
msgstr "æ·»å 软件å
"
#. TRANSLATORS: header to a list of packages removed
-#: ../client/pk-console.c:1214
+#: ../client/pk-console.c:1242
msgid "Packages to remove"
msgstr "å é¤è½¯ä»¶å
"
#. TRANSLATORS: We didn't find any differences
-#: ../client/pk-console.c:1282
-#, c-format
+#: ../client/pk-console.c:1310
msgid "No new packages need to be installed"
msgstr "没ææ°ç软件å
å®è£
"
#. TRANSLATORS: follows a list of packages to install
-#: ../client/pk-console.c:1288
+#: ../client/pk-console.c:1316
msgid "To install"
msgstr "å®è£
"
#. TRANSLATORS: searching takes some time....
-#: ../client/pk-console.c:1299
+#: ../client/pk-console.c:1327
msgid "Searching for package: "
msgstr "æ索软件å
: "
#. TRANSLATORS: package was not found -- this is the end of a string ended in ...
-#: ../client/pk-console.c:1303
+#: ../client/pk-console.c:1331
msgid "not found."
msgstr "没ææ¾å°"
#. TRANSLATORS: We didn't find any packages to install
-#: ../client/pk-console.c:1314
-#, c-format
+#: ../client/pk-console.c:1342
msgid "No packages can be found to install"
msgstr "æ¾ä¸å°è½¯ä»¶å
å®è£
"
#. TRANSLATORS: installing new packages from package list
-#: ../client/pk-console.c:1320
+#: ../client/pk-console.c:1348
msgid "Installing packages"
msgstr "æ£å¨å®è£
软件å
..."
#. TRANSLATORS: The package name was not found in any software sources. The detailed error follows
-#: ../client/pk-console.c:1356
-#, fuzzy, c-format
+#: ../client/pk-console.c:1384
+#, c-format
msgid "This tool could not find the update details for %s: %s"
-msgstr "该工å
·æ æ³æ¾å° '%s' çæ´æ°è¯¦æ
ï¼%s"
+msgstr "该工å
·æ æ³æ¾å° %s çæ´æ°è¯¦æ
ï¼%s"
#. TRANSLATORS: There was an error getting the details about the update for the package. The detailed error follows
-#: ../client/pk-console.c:1364
-#, fuzzy, c-format
+#: ../client/pk-console.c:1392
+#, c-format
msgid "This tool could not get the update details for %s: %s"
-msgstr "该工å
·æ æ³ä¸º '%s': %s å¾å°æ´æ°è¯¦æ
"
+msgstr "该工å
·æ æ³å¾å° %s çæ´æ°è¯¦æ
ï¼%s"
#. TRANSLATORS: This was an unhandled error, and we don't have _any_ context
-#: ../client/pk-console.c:1410
+#: ../client/pk-console.c:1438
msgid "Error:"
msgstr "é误ï¼"
#. TRANSLATORS: This a list of details about the package
-#: ../client/pk-console.c:1424
+#: ../client/pk-console.c:1452
msgid "Package description"
msgstr "软件å
æè¿°"
#. TRANSLATORS: This a list files contained in the package
-#: ../client/pk-console.c:1458
+#: ../client/pk-console.c:1486
msgid "Package files"
msgstr "软件å
æ件"
#. TRANSLATORS: This where the package has no files
-#: ../client/pk-console.c:1466
+#: ../client/pk-console.c:1494
msgid "No files"
msgstr "没ææ件"
#. TRANSLATORS: This a request for a GPG key signature from the backend, which the client will prompt for later
-#: ../client/pk-console.c:1489
+#: ../client/pk-console.c:1517
msgid "Repository signature required"
msgstr "è¦æ±è½¯ä»¶åºç¾å"
#. TRANSLATORS: This a prompt asking the user to import the security key
-#: ../client/pk-console.c:1499
+#: ../client/pk-console.c:1527
msgid "Do you accept this signature?"
msgstr "ä½ æ¥å该ç¾ååï¼"
#. TRANSLATORS: This is where the user declined the security key
-#: ../client/pk-console.c:1503
+#: ../client/pk-console.c:1531
msgid "The signature was not accepted."
msgstr "没ææ¥åç¾åã"
#. TRANSLATORS: This a request for a EULA
-#: ../client/pk-console.c:1537
+#: ../client/pk-console.c:1565
msgid "End user license agreement required"
msgstr "éè¦æç»ç¨æ·è®¸å¯åè®®"
#. TRANSLATORS: This a prompt asking the user to agree to the license
-#: ../client/pk-console.c:1544
+#: ../client/pk-console.c:1572
msgid "Do you agree to this license?"
msgstr "ä½ åææ¬è®¸å¯åï¼"
#. TRANSLATORS: This is where the user declined the license
-#: ../client/pk-console.c:1548
+#: ../client/pk-console.c:1576
msgid "The license was refused."
msgstr "æç»è¯¥è®¸å¯ã"
#. TRANSLATORS: This is when the daemon crashed, and we are up shit creek without a paddle
-#: ../client/pk-console.c:1577
+#: ../client/pk-console.c:1605
msgid "The daemon crashed mid-transaction!"
msgstr "åå°ç¨åºå¨äºå¡å¤çä¸æå´©æºï¼"
#. TRANSLATORS: This is the header to the --help menu
-#: ../client/pk-console.c:1630
+#: ../client/pk-console.c:1658
msgid "PackageKit Console Interface"
msgstr "PackageKit ç»ç«¯çé¢"
-#: ../client/pk-console.c:1630
+#. these are commands we can use with pkcon
+#: ../client/pk-console.c:1660
msgid "Subcommands:"
msgstr "åå½ä»¤ï¼"
-#: ../client/pk-console.c:1719 ../client/pk-generate-pack.c:184
+#. TRANSLATORS: command line argument, if we should show debugging information
+#. TRANSLATORS: if we should show debugging data
+#: ../client/pk-console.c:1750
+#: ../client/pk-generate-pack.c:185
#: ../client/pk-monitor.c:115
#: ../contrib/command-not-found/pk-command-not-found.c:510
-#: ../src/pk-main.c:192
+#: ../src/pk-main.c:199
msgid "Show extra debugging information"
msgstr "æ¾ç¤ºé¢å¤çè°è¯ä¿¡æ¯"
-#: ../client/pk-console.c:1721 ../client/pk-monitor.c:117
+#. TRANSLATORS: command line argument, just show the version string
+#: ../client/pk-console.c:1753
+#: ../client/pk-monitor.c:117
msgid "Show the program version and exit"
msgstr "æ¾ç¤ºæ¬ç¨åºçæ¬å¹¶éåº"
-#: ../client/pk-console.c:1723
+#. TRANSLATORS: command line argument, use a filter to narrow down results
+#: ../client/pk-console.c:1756
msgid "Set the filter, e.g. installed"
msgstr "设置è¿æ»¤å¨ï¼ä¾å¦å·²å®è£
ç"
-#: ../client/pk-console.c:1725
+#. TRANSLATORS: command line argument, work asynchronously
+#: ../client/pk-console.c:1759
msgid "Exit without waiting for actions to complete"
msgstr "ä¸çæä½å®æå³éåº"
#. TRANSLATORS: This is when we could not connect to the system bus, and is fatal
-#: ../client/pk-console.c:1752
+#: ../client/pk-console.c:1786
msgid "This tool could not connect to system DBUS."
msgstr "该工å
·æ æ³è¿æ¥å°ç³»ç» DBUSã"
#. TRANSLATORS: The user specified an incorrect filter
-#: ../client/pk-console.c:1839
+#: ../client/pk-console.c:1873
msgid "The filter specified was invalid"
msgstr "è¿æ»¤å¨æå®éæ³"
-#: ../client/pk-console.c:1856
-msgid "You need to specify a search type, e.g. name"
-msgstr "ä½ éè¦æå®æ个æ索类åï¼ä¾å¦åå"
-
-#: ../client/pk-console.c:1861 ../client/pk-console.c:1868
-#: ../client/pk-console.c:1875 ../client/pk-console.c:1882
-#: ../client/pk-console.c:1990 ../client/pk-console.c:2000
-#: ../client/pk-console.c:2007 ../client/pk-console.c:2014
-msgid "You need to specify a search term"
-msgstr "ä½ éè¦æå®æ个æç´¢æ¯è¯"
-
-#: ../client/pk-console.c:1887
+#. TRANSLATORS: a search type can be name, details, file, etc
+#: ../client/pk-console.c:1891
+msgid "A search type is required, e.g. name"
+msgstr "ä½ éè¦æå®æ索类åï¼å¦è½¯ä»¶å
å"
+
+#. TRANSLATORS: the user needs to provide a search term
+#: ../client/pk-console.c:1897
+#: ../client/pk-console.c:1905
+#: ../client/pk-console.c:1913
+#: ../client/pk-console.c:1921
+msgid "A search term is required"
+msgstr "ä½ éè¦æå®æç´¢æ¡ä»¶"
+
+#. TRANSLATORS: the search type was provided, but invalid
+#: ../client/pk-console.c:1927
msgid "Invalid search type"
msgstr "æ æçæ索类å"
-#: ../client/pk-console.c:1892
-msgid "You need to specify a package or file to install"
-msgstr "ä½ éè¦æå®æ个软件å
ææ件æ¥å®è£
"
+#. TRANSLATORS: the user did not specify what they wanted to install
+#: ../client/pk-console.c:1933
+msgid "A package name or filename to install is required"
+msgstr "ä½ éè¦ä¸ºå®è£
æå®ä¸ä¸ªè½¯ä»¶å
åææ件å"
-#: ../client/pk-console.c:1899
-msgid "You need to specify a type, key_id and package_id"
-msgstr "ä½ éè¦æå®æ个类åï¼è¯ä¹¦IDæè
软件å
ID"
+#. TRANSLATORS: geeky error, 99.9999% of users won't see this
+#: ../client/pk-console.c:1941
+msgid "A type, key_id and package_id are required"
+msgstr "éè¦æå®æ个类åï¼è¯ä¹¦IDæè
软件å
ID"
-#: ../client/pk-console.c:1906
-msgid "You need to specify a package to remove"
-msgstr "ä½ éè¦æå®æ个软件å
æ¥å é¤"
+#. TRANSLATORS: the user did not specify what they wanted to remove
+#: ../client/pk-console.c:1949
+msgid "A package name to remove is required"
+msgstr "ä½ éè¦ä¸ºå¸è½½æå®ä¸ä¸ªè½¯ä»¶å
å"
-#: ../client/pk-console.c:1912
-msgid ""
-"You need to specify the destination directory and then the packages to "
-"download"
-msgstr "ä½ éè¦æå®ç®çå°ç®å½ä»¥å软件å
æ¥ä¸è½½"
+#. TRANSLATORS: the user did not specify anything about what to download or where
+#: ../client/pk-console.c:1956
+msgid "A destination directory and then the package names to download are required"
+msgstr "éè¦æå®ç®çå°ç®å½ä»¥å软件å
åæ¥ä¸è½½"
-#: ../client/pk-console.c:1917
+#. TRANSLATORS: the directory does not exist, so we can't continue
+#: ../client/pk-console.c:1962
msgid "Directory not found"
msgstr "ç®å½æ²¡ææ¾å°"
-#: ../client/pk-console.c:1923
-msgid "You need to specify a licence identifier (eula-id)"
-msgstr "ä½ éè¦æå®æ个许å¯é´å« (eula-id)"
-
-#: ../client/pk-console.c:1939
-msgid "You need to specify a package name to resolve"
-msgstr "ä½ éè¦æå®æ个软件å
ååæ¥è§£å³ä¾èµå
³ç³»"
-
-#: ../client/pk-console.c:1946 ../client/pk-console.c:1953
-msgid "You need to specify a repository name"
-msgstr "ä½ éè¦æå®æ个软件åºåå"
-
-#: ../client/pk-console.c:1960
-msgid "You need to specify a repo name/parameter and value"
-msgstr "ä½ éè¦æå®æ个软件åºåå/åæ°æå¼"
-
-#: ../client/pk-console.c:1972
-msgid "You need to specify an action, e.g. 'update-system'"
+#. TRANSLATORS: geeky error, 99.9999% of users won't see this
+#: ../client/pk-console.c:1969
+msgid "A licence identifier (eula-id) is required"
+msgstr "éè¦æå®æ个许å¯è¯é´å« (eula-id)"
+
+#. TRANSLATORS: The user did not specify a package name
+#: ../client/pk-console.c:1986
+msgid "A package name to resolve is required"
+msgstr "ä½ éè¦ä¸ºè§£ææå®ä¸ä¸ªè½¯ä»¶å
å"
+
+#. TRANSLATORS: The user did not specify a repository (software source) name
+#: ../client/pk-console.c:1994
+#: ../client/pk-console.c:2002
+msgid "A repository name is required"
+msgstr "è¦æ±è½¯ä»¶åºå"
+
+#. TRANSLATORS: The user didn't provide any data
+#: ../client/pk-console.c:2010
+msgid "A repo name, parameter and value are required"
+msgstr "ä½ éè¦æå®æ个软件åºååï¼åæ°æå¼"
+
+#. TRANSLATORS: The user didn't specify what action to use
+#: ../client/pk-console.c:2023
+msgid "An action, e.g. 'update-system' is required"
msgstr "ä½ éè¦æå®æ个è¡å¨ï¼ä¾å¦âæ´æ°ç³»ç»â"
-#: ../client/pk-console.c:1977
-msgid "You need to specify a correct role"
-msgstr "ä½ éè¦æå®æ个æ£ç¡®çè§è²"
-
-#: ../client/pk-console.c:1982
-msgid "Failed to get last time"
-msgstr "æ æ³å¾å°æåä¸æ¬¡æ¶é´"
-
-#: ../client/pk-console.c:2021
-msgid "You need to specify a package to find the details for"
-msgstr "ä½ éè¦æå®æ个软件å
å·²æ¾å°ç¸å
³è¯¦æ
"
-
-#: ../client/pk-console.c:2028
-msgid "You need to specify a package to find the files for"
-msgstr "ä½ éè¦æå®æ个软件å
å·²æ¾å°ç¸å
³æ件"
+#. TRANSLATORS: The user specified an invalid action
+#: ../client/pk-console.c:2029
+msgid "A correct role is required"
+msgstr "éè¦ä¸ä¸ªæ£ç¡®ååº"
+#. TRANSLATORS: we keep a database updated with the time that an action was last executed
#: ../client/pk-console.c:2035
-msgid "You need to specify a list file to create"
-msgstr "ä½ éè¦æå®ä¸ä¸ªè¦å建çæ件åºå"
-
-#: ../client/pk-console.c:2043 ../client/pk-console.c:2051
-msgid "You need to specify a list file to open"
-msgstr "ä½ éè¦æå®ä¸ä¸ªæ件åºåæ¥æå¼"
+msgid "Failed to get the time since this action was last completed"
+msgstr "æªè·å¾æåä¸æ¬¡æä½çæ¶é´"
+
+#. TRANSLATORS: The user did not provide a package name
+#. TRANSLATORS: This is when the user fails to supply the package name
+#: ../client/pk-console.c:2044
+#: ../client/pk-console.c:2055
+#: ../client/pk-console.c:2063
+#: ../client/pk-console.c:2079
+#: ../client/pk-console.c:2087
+#: ../client/pk-generate-pack.c:241
+msgid "A package name is required"
+msgstr "éè¦è½¯ä»¶å
å"
+
+#. TRANSLATORS: each package "provides" certain things, e.g. mime(gstreamer-decoder-mp3), the user didn't specify it
+#: ../client/pk-console.c:2071
+msgid "A package provide string is required"
+msgstr "ä½ éè¦æå®ç¹å®åæ°"
+
+#. TRANSLATORS: The user didn't specify a filename to create as a list
+#: ../client/pk-console.c:2095
+msgid "A list file name to create is required"
+msgstr "éè¦å»ºç«ä¸ä¸ªæ件å表"
+
+#. TRANSLATORS: The user didn't specify a filename to open as a list
+#: ../client/pk-console.c:2104
+#: ../client/pk-console.c:2113
+msgid "A list file to open is required"
+msgstr "éè¦æå¼ä¸ä¸ªæ件å表"
#. TRANSLATORS: The user tried to use an unsupported option on the command line
-#: ../client/pk-console.c:2104
+#: ../client/pk-console.c:2166
#, c-format
msgid "Option '%s' is not supported"
msgstr "ä¸æ¯æ '%s' é项"
#. TRANSLATORS: User does not have permission to do this
-#: ../client/pk-console.c:2117
-msgid "You don't have the necessary privileges for this operation"
+#: ../client/pk-console.c:2179
+msgid "Incorrect privileges for this operation"
msgstr "ä½ æ²¡ææ¬æ¬¡æä½éè¦çå¿
è¦æé"
#. TRANSLATORS: Generic failure of what they asked to do
-#: ../client/pk-console.c:2120
+#: ../client/pk-console.c:2182
msgid "Command failed"
msgstr "å½ä»¤å¤±è´¥"
#. TRANSLATORS: This is the state of the transaction
-#: ../client/pk-generate-pack.c:100
+#: ../client/pk-generate-pack.c:101
msgid "Downloading"
msgstr "æ£å¨ä¸è½½"
#. TRANSLATORS: This is when the main packages are being downloaded
-#: ../client/pk-generate-pack.c:120
+#: ../client/pk-generate-pack.c:121
msgid "Downloading packages"
msgstr "æ£å¨ä¸è½½è½¯ä»¶å
"
#. TRANSLATORS: This is when the dependency packages are being downloaded
-#: ../client/pk-generate-pack.c:125
+#: ../client/pk-generate-pack.c:126
msgid "Downloading dependencies"
msgstr "æ£å¨ä¸è½½ä¾èµå
³ç³»"
-#: ../client/pk-generate-pack.c:186
+#. TRANSLATORS: we can exclude certain packages (glibc) when we know they'll exist on the target
+#: ../client/pk-generate-pack.c:188
msgid "Set the file name of dependencies to be excluded"
msgstr "设置å°è¢«é¤å¤çä¾èµå
³ç³»çæ件å"
-#: ../client/pk-generate-pack.c:188
-msgid "The output directory (the current directory is used if ommitted)"
-msgstr "è¾åºç®å½(使ç¨å½åç®å½å¦å¿è®°æå®)"
+#. TRANSLATORS: the output location
+#: ../client/pk-generate-pack.c:191
+msgid "The output file or directory (the current directory is used if ommitted)"
+msgstr "è¾åºæ件æç®å½(使ç¨å½åç®å½å¦å¿è®°æå®)"
-#: ../client/pk-generate-pack.c:190
+#. TRANSLATORS: put a list of packages in the pack
+#: ../client/pk-generate-pack.c:194
msgid "The package to be put into the service pack"
msgstr "å°æ¾å
¥æå¡å
ç软件å
"
-#: ../client/pk-generate-pack.c:192
+#. TRANSLATORS: put all pending updates in the pack
+#: ../client/pk-generate-pack.c:197
msgid "Put all updates available in the service pack"
msgstr "å°ææå¯è·å¾çæ´æ°æ¾å
¥æå¡å
"
#. TRANSLATORS: This is when the user fails to supply the correct arguments
-#: ../client/pk-generate-pack.c:220
+#: ../client/pk-generate-pack.c:225
msgid "Neither --package or --updates option selected."
msgstr "è¦ä¹æ¯éå®äº --package é项ï¼è¦ä¹æ¯éå®äº --updates é项"
#. TRANSLATORS: This is when the user fails to supply just one argument
-#: ../client/pk-generate-pack.c:228
+#: ../client/pk-generate-pack.c:233
msgid "Both options selected."
msgstr "éå®äºä¸¤ä¸ªé项"
+#. TRANSLATORS: This is when the user fails to supply the output
+#: ../client/pk-generate-pack.c:249
+msgid "A output directory or file name is required"
+msgstr "ä½ éè¦æå®è¾åºçç®å½åææ件å"
+
+#. TRANSLATORS: This is when the backend doesn't have the capability to get-depends
+#. TRANSLATORS: This is when the backend doesn't have the capability to download
+#: ../client/pk-generate-pack.c:267
+#: ../client/pk-generate-pack.c:273
+msgid "The package manager cannot perform this type of operation."
+msgstr "软件å
管çå¨ä¸è½å¤çå½åç±»åçæä½"
+
+#. TRANSLATORS: the user specified an absolute path, but didn't get the extension correct
+#: ../client/pk-generate-pack.c:285
+msgid "If specifying a file, the service pack name must end with"
+msgstr "å¦ææå®ä¸ä¸ªæ件ï¼æ件åç¼åå¿
é¡»æ¯"
+
#. TRANSLATORS: This is when file already exists
-#: ../client/pk-generate-pack.c:261
+#: ../client/pk-generate-pack.c:301
msgid "A pack with the same name already exists, do you want to overwrite it?"
msgstr "å·²ç»æåå软件å
åå¨ï¼ä½ æ³è¦è¦çå®åï¼"
#. TRANSLATORS: This is when the pack was not overwritten
-#: ../client/pk-generate-pack.c:264
+#: ../client/pk-generate-pack.c:304
msgid "The pack was not overwritten."
msgstr "该软件å
没æ被è¦ç"
#. TRANSLATORS: This is when the temporary directory cannot be created, the directory name follows
-#: ../client/pk-generate-pack.c:276
+#: ../client/pk-generate-pack.c:317
msgid "Failed to create directory:"
msgstr "æ æ³å建ç®å½"
#. TRANSLATORS: This is when the list of packages from the remote computer cannot be opened
-#: ../client/pk-generate-pack.c:285
+#: ../client/pk-generate-pack.c:327
msgid "Failed to open package list."
msgstr "æ æ³æå¼è½¯ä»¶å
æ¸
å"
#. TRANSLATORS: The package name is being matched up to available packages
-#: ../client/pk-generate-pack.c:295
+#: ../client/pk-generate-pack.c:338
msgid "Finding package name."
msgstr "æ£å¨å¯»æ¾è½¯ä»¶å
å"
#. TRANSLATORS: This is when the package cannot be found in any software source. The detailed error follows
-#: ../client/pk-generate-pack.c:299
+#: ../client/pk-generate-pack.c:342
#, c-format
msgid "Failed to find package '%s': %s"
msgstr "æ æ³æ¾å°è½¯ä»¶å
'%s': %s"
#. TRANSLATORS: This is telling the user we are in the process of making the pack
-#: ../client/pk-generate-pack.c:315
+#: ../client/pk-generate-pack.c:359
msgid "Creating service pack..."
msgstr "æ£å¨å建æå¡å
..."
#. TRANSLATORS: we succeeded in making the file
-#: ../client/pk-generate-pack.c:322
+#: ../client/pk-generate-pack.c:366
#, c-format
msgid "Service pack created '%s'"
msgstr "æå¡å
å·²å建 '%s'"
#. TRANSLATORS: we failed to make te file
-#: ../client/pk-generate-pack.c:326
+#: ../client/pk-generate-pack.c:371
#, c-format
msgid "Failed to create '%s': %s"
msgstr "æ æ³å建 '%s': %s"
-#: ../client/pk-monitor.c:132
+#. TRANSLATORS: this is a program that monitors PackageKit
+#: ../client/pk-monitor.c:133
msgid "PackageKit Monitor"
msgstr "PackageKit çè§å¨"
#. TRANSLATORS: The package was not found in any software sources
#: ../client/pk-tools-common.c:114
-#, c-format
msgid "The package could not be found"
msgstr "æ æ³æ¾å°è¯¥è½¯ä»¶å
"
@@ -715,79 +795,72 @@ msgstr "请è¾å
¥ä»1å° %i çæ°åï¼"
#. TRANSLATORS: we failed to find the package, this shouldn't happen
#: ../contrib/command-not-found/pk-command-not-found.c:361
-#, fuzzy
msgid "Failed to search for file"
-msgstr "åç失败"
+msgstr "æªæ¾å°è¯¥è½¯ä»¶å
"
#. TRANSLATORS: we failed to launch the executable, the error follows
#: ../contrib/command-not-found/pk-command-not-found.c:485
-#, fuzzy
msgid "Failed to launch:"
-msgstr "æ æ³å¾å°æåä¸æ¬¡æ¶é´"
+msgstr "æ æ³æ§è¡"
#. TRANSLATORS: tool that gets called when the command is not found
#: ../contrib/command-not-found/pk-command-not-found.c:526
-#, fuzzy
msgid "PackageKit Command Not Found"
-msgstr "PackageKit çè§å¨"
+msgstr "PackageKit å½ä»¤æ²¡ææ¾å°"
#. TRANSLATORS: the prefix of all the output telling the user why it's not executing
#: ../contrib/command-not-found/pk-command-not-found.c:548
-#, fuzzy
msgid "Command not found."
-msgstr "没ææ¾å°"
+msgstr "å½ä»¤æªæ¾å°"
#. TRANSLATORS: tell the user what we think the command is
#: ../contrib/command-not-found/pk-command-not-found.c:555
-#, fuzzy
msgid "Similar command is:"
-msgstr "åå½ä»¤ï¼"
+msgstr "å¯è½å½ä»¤æ¯:"
#. TRANSLATORS: Ask the user if we should run the similar command
#: ../contrib/command-not-found/pk-command-not-found.c:564
msgid "Run similar command:"
-msgstr ""
+msgstr "æ§è¡å¯è½çå½ä»¤:"
#. TRANSLATORS: show the user a list of commands that they could have meant
#. TRANSLATORS: show the user a list of commands we could run
#: ../contrib/command-not-found/pk-command-not-found.c:576
#: ../contrib/command-not-found/pk-command-not-found.c:585
-#, fuzzy
msgid "Similar commands are:"
-msgstr "åå½ä»¤ï¼"
+msgstr "å¯è½å½ä»¤æ¯ï¼"
#. TRANSLATORS: ask the user to choose a file to run
#: ../contrib/command-not-found/pk-command-not-found.c:592
msgid "Please choose a command to run"
-msgstr ""
+msgstr "请éæ©ä¸æ¡å½ä»¤æ§è¡"
#. TRANSLATORS: tell the user what package provides the command
#: ../contrib/command-not-found/pk-command-not-found.c:607
msgid "The package providing this file is:"
-msgstr ""
+msgstr "æä¾è¯¥å½ä»¤ç软件å
æ¯:"
#. TRANSLATORS: as the user if we want to install a package to provide the command
#: ../contrib/command-not-found/pk-command-not-found.c:612
#, c-format
msgid "Install package '%s' to provide command '%s'?"
-msgstr ""
+msgstr "å®è£
å
'%s' æä¾å½ä»¤ '%s'"
#. TRANSLATORS: Show the user a list of packages that provide this command
#: ../contrib/command-not-found/pk-command-not-found.c:633
msgid "Packages providing this file are:"
-msgstr ""
+msgstr "æä¾è¯¥å½ä»¤ç软件å
æ:"
#. TRANSLATORS: Show the user a list of packages that they can install to provide this command
#: ../contrib/command-not-found/pk-command-not-found.c:642
msgid "Suitable packages are:"
-msgstr ""
+msgstr "éåç软件å
æ¯:"
#. get selection
#. TRANSLATORS: ask the user to choose a file to install
#: ../contrib/command-not-found/pk-command-not-found.c:650
-#, fuzzy
msgid "Please choose a package to install"
-msgstr "请éæ©æ£ç¡®ç软件å
ï¼"
+msgstr "请éæ©è¦å®è£
çæ个软件å
"
#. TRANSLATORS: when we are getting data from the daemon
#: ../contrib/browser-plugin/src/contents.cpp:298
@@ -811,6 +884,7 @@ msgstr "å·²å®è£
çæ¬"
msgid "Run version %s now"
msgstr "ç°å¨è¿è¡çæ¬ %s"
+#. TRANSLATORS: run the application now
#: ../contrib/browser-plugin/src/contents.cpp:324
msgid "Run now"
msgstr "ç°å¨è¿è¡"
@@ -854,166 +928,108 @@ msgstr "PackageKit 软件å
æ¸
å"
msgid "PackageKit Service Pack"
msgstr "PackageKit æå¡å
"
-#: ../policy/org.freedesktop.packagekit.policy.in.h:1
-msgid "Accept EULA"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:2
-msgid "Authentication is required to accept a EULA"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:3
-msgid ""
-"Authentication is required to cancel a task that was not started by yourself"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:4
-msgid "Authentication is required to change software source parameters"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:5
-msgid ""
-"Authentication is required to consider a key used for signing packages as "
-"trusted"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:6
-msgid "Authentication is required to install a signed package"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:7
-msgid "Authentication is required to install an untrusted package"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:8
-msgid "Authentication is required to refresh the system sources"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:9
-msgid "Authentication is required to remove packages"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:10
-msgid "Authentication is required to rollback a transaction"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:11
-msgid ""
-"Authentication is required to set the network proxy used for downloading "
-"packages"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:12
-msgid "Authentication is required to update packages"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:13
-msgid "Cancel foreign task"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:14
-msgid "Change software source parameters"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:15
-#, fuzzy
-msgid "Install signed package"
-msgstr "æ£å¨å®è£
软件å
..."
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:16
-msgid "Install untrusted local file"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:17
-msgid "Refresh system sources"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:18
-msgid "Remove package"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:19
-msgid "Rollback to a previous transaction"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:20
-msgid "Set network proxy"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:21
-msgid "Trust a key used for signing packages"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:22
-msgid "Update packages"
-msgstr ""
-
-#: ../src/pk-main.c:86
+#. TRANSLATORS: failed due to DBus security
+#: ../src/pk-main.c:87
msgid "Startup failed due to security policies on this machine."
msgstr "ç±äºæ¬æºçå®å
¨çç¥å¯¼è´å¯å¨å¤±è´¥"
-#: ../src/pk-main.c:87
+#. TRANSLATORS: only two ways this can fail...
+#: ../src/pk-main.c:89
msgid "This can happen for two reasons:"
msgstr "åçè¿ä¸ªå¯è½æ两个åå ï¼"
-#: ../src/pk-main.c:88
+#. TRANSLATORS: only allowed to be owned by root
+#: ../src/pk-main.c:91
msgid "The correct user is not launching the executable (usually root)"
msgstr "ç¨æ·æ£ç¡®ä½æ æ³å¯å¨å¯æ§è¡ç¨åº(é常ä½ä¸ºæ ¹ç¨æ·)"
-#: ../src/pk-main.c:89
-msgid ""
-"The org.freedesktop.PackageKit.conf file is not installed in the system "
-"directory:"
+#. TRANSLATORS: or we are installed in a prefix
+#: ../src/pk-main.c:93
+msgid "The org.freedesktop.PackageKit.conf file is not installed in the system directory:"
msgstr "org.freedesktop.PackageKit.conf 没æå®è£
å°ç³»ç»ç®å½ä¸ï¼"
-#: ../src/pk-main.c:188
+#. TRANSLATORS: a backend is the system package tool, e.g. yum, apt
+#: ../src/pk-main.c:193
msgid "Packaging backend to use, e.g. dummy"
msgstr "使ç¨çæå
å端ï¼ä¾å¦â伪âå端"
-#: ../src/pk-main.c:190
+#. TRANSLATORS: if we should run in the background
+#: ../src/pk-main.c:196
msgid "Daemonize and detach from the terminal"
msgstr "åå°å并ä»ç»ç«¯ä¸å离"
-#: ../src/pk-main.c:194
+#. TRANSLATORS: if we should not monitor how long we are inactive for
+#: ../src/pk-main.c:202
msgid "Disable the idle timer"
-msgstr "ç¦æ¢ç©ºé´è®¡æ¶å¨"
+msgstr "ç¦æ¢è®¡æ¶å¨"
-#: ../src/pk-main.c:196
+#. TRANSLATORS: show version
+#: ../src/pk-main.c:205
msgid "Show version and exit"
msgstr "æ¾ç¤ºçæ¬å¹¶éåº"
-#: ../src/pk-main.c:198
+#. TRANSLATORS: exit after we've started up, used for user profiling
+#: ../src/pk-main.c:208
msgid "Exit after a small delay"
msgstr "ç¨ç¨å»¶è¿åéåº"
-#: ../src/pk-main.c:200
+#. TRANSLATORS: exit straight away, used for automatic profiling
+#: ../src/pk-main.c:211
msgid "Exit after the engine has loaded"
msgstr "å¼æè½½å
¥åéåº"
-#: ../src/pk-main.c:214
+#. TRANSLATORS: describing the service that is running
+#: ../src/pk-main.c:226
msgid "PackageKit service"
msgstr "PackageKit æå¡"
-#: ../src/pk-main.c:250
+#. TRANSLATORS: fatal error, dbus is not running
+#: ../src/pk-main.c:263
msgid "Cannot connect to the system bus"
msgstr "æ æ³è¿æ¥å°ç³»ç»æ»çº¿"
-#: ../src/pk-main.c:299
+#. TRANSLATORS: cannot register on system bus, unknown reason
+#: ../src/pk-main.c:313
#, c-format
msgid "Error trying to start: %s\n"
-msgstr "åºç°é误å½å°è¯å¯å¨ %s\n"
+msgstr "å°è¯å¯å¨æ¶åºé: %s\n"
+
+#~ msgid "You need to specify a search type, e.g. name"
+#~ msgstr "ä½ éè¦æå®æ个æ索类åï¼ä¾å¦åå"
+#~ msgid "You need to specify a search term"
+#~ msgstr "ä½ éè¦æå®æ个æç´¢æ¯è¯"
+#~ msgid "You need to specify a package or file to install"
+#~ msgstr "ä½ éè¦æå®æ个软件å
ææ件æ¥å®è£
"
+#~ msgid "You need to specify a package to remove"
+#~ msgstr "ä½ éè¦æå®æ个软件å
æ¥å é¤"
+#~ msgid "You need to specify a package name to resolve"
+#~ msgstr "ä½ éè¦æå®æ个软件å
ååæ¥è§£å³ä¾èµå
³ç³»"
+#~ msgid "You need to specify a repository name"
+#~ msgstr "ä½ éè¦æå®æ个软件åºåå"
+#~ msgid "You need to specify a correct role"
+#~ msgstr "ä½ éè¦æå®æ个æ£ç¡®çè§è²"
+#~ msgid "Failed to get last time"
+#~ msgstr "æ æ³å¾å°æåä¸æ¬¡æ¶é´"
+#~ msgid "You need to specify a package to find the details for"
+#~ msgstr "ä½ éè¦æå®æ个软件å
å·²æ¾å°ç¸å
³è¯¦æ
"
+#~ msgid "You need to specify a package to find the files for"
+#~ msgstr "ä½ éè¦æå®æ个软件å
å·²æ¾å°ç¸å
³æ件"
+#~ msgid "You need to specify a list file to create"
+#~ msgstr "ä½ éè¦æå®ä¸ä¸ªè¦å建çæ件åºå"
+#~ msgid "You need to specify a list file to open"
+#~ msgstr "ä½ éè¦æå®ä¸ä¸ªæ件åºåæ¥æå¼"
+#, fuzzy
+#~ msgid "Install signed package"
+#~ msgstr "æ£å¨å®è£
软件å
..."
#~ msgid "This tool could not remove the packages: '%s'"
#~ msgstr "该工å
·æ æ³å é¤æ¬è½¯ä»¶å
ï¼ '%s'"
-
#~ msgid "Okay to import key?"
#~ msgstr "å¯ä»¥å¯¼å
¥è¯ä¹¦åï¼"
-
#~ msgid "Did not import key"
#~ msgstr "ä¸å¯¼å
¥è¯ä¹¦"
-
#~ msgid "Eula required"
#~ msgstr "è¦æ±æç»ç¨æ·åè®®"
-
#~ msgid "Do you agree?"
#~ msgstr "ä½ åæåï¼"
+
commit 7007dc9243375fbca11cd49bb7fbe6da237be5bb
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Sat Feb 21 21:18:45 2009 -0600
remove warning
diff --git a/backends/conary/conaryCallback.py b/backends/conary/conaryCallback.py
index a2df848..f241592 100644
--- a/backends/conary/conaryCallback.py
+++ b/backends/conary/conaryCallback.py
@@ -65,7 +65,11 @@ class UpdateSystemCallback(callbacks.UpdateCallback):
#5 >> request> download
def setChangesetHunk(self, num, total):
log.info("callback. .......... set Changeset HUnk %s/%s" % (num, total ) )
- self.progress.set_subpercent( num*100/float(total) )
+ if total > 0:
+ p = num*100/float(total)
+ else:
+ p = 0
+ self.progress.set_subpercent(p)
self.disablepercent = True
self.backend.percentage(self.progress.percent)
log.info(self.progress.percent)
commit 24e86b2ef8542beddca31df012532bba992c9a7f
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Sat Feb 21 11:28:33 2009 -0600
conary: updatesystem do a stepdown percent
diff --git a/backends/conary/conaryCallback.py b/backends/conary/conaryCallback.py
index e7c86e4..a2df848 100644
--- a/backends/conary/conaryCallback.py
+++ b/backends/conary/conaryCallback.py
@@ -36,7 +36,7 @@ class UpdateSystemCallback(callbacks.UpdateCallback):
self.smallUpdate = False
self.error = []
self.progress = PackagekitProgress()
- self.progress.set_steps([ 50,100 ] )
+ self.progress.set_steps([ 50 ] )
self.disablepercent = False
self.dostep = True
#1
commit c37766c79801376a6e09f3948e5964a1a95d0506
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Sat Feb 21 02:48:36 2009 -0600
conary: add a exception for run get-updates first
and then update
diff --git a/backends/conary/conaryBackend.py b/backends/conary/conaryBackend.py
index 81a17aa..fa4f753 100755
--- a/backends/conary/conaryBackend.py
+++ b/backends/conary/conaryBackend.py
@@ -229,8 +229,10 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
else:
updJob = self._get_update(applyList, cache=False)
self.allow_cancel(False)
-
- restartDir = self.client.applyUpdateJob(updJob)
+ try:
+ restartDir = self.client.applyUpdateJob(updJob)
+ except errors.InternalConaryError:
+ self.error(ERROR_NO_PACKAGES_TO_UPDATE,"get-updates first and then update sytem")
return updJob
def _get_package_update(self, name, version, flavor):
@@ -455,7 +457,7 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
applyList = [ (x[0], (None, None), x[1:], True) for x in updateItems ]
log.info(">>>>>>>>>> get update >>>>>>>>>>>>")
- self._get_update(applyList)
+ #self._get_update(applyList)
log.info(">>>>>>>>>> DO Update >>>>>>>>>>>>")
self._do_update(applyList)
log.info(">>>>>>>>>>END DO Update >>>>>>>>>>>>")
diff --git a/backends/conary/conaryCallback.py b/backends/conary/conaryCallback.py
index 8ba4db1..e7c86e4 100644
--- a/backends/conary/conaryCallback.py
+++ b/backends/conary/conaryCallback.py
@@ -36,7 +36,9 @@ class UpdateSystemCallback(callbacks.UpdateCallback):
self.smallUpdate = False
self.error = []
self.progress = PackagekitProgress()
- self.progress.set_steps([ 30,60,65 ] )
+ self.progress.set_steps([ 50,100 ] )
+ self.disablepercent = False
+ self.dostep = True
#1
#3
def requestingChangeSet(self):
@@ -44,10 +46,13 @@ class UpdateSystemCallback(callbacks.UpdateCallback):
self.backend.status(STATUS_DOWNLOAD)
self.backend.percentage(self.progress.percent)
log.info(self.progress.percent)
+ if not self.disablepercent:
+ self.progress.step()
#2
def downloadingChangeSet(self, got, need):
log.info("Callback UpdateSystem........ STATUS_DOWNLOAD Changeset %.2f percent %.2f/%.2f Mbytes" % ( got*100/float(need), got/MEGA,need/MEGA) )
- self.progress.set_subpercent( got*100 / float(need) )
+ if not self.disablepercent:
+ self.progress.set_subpercent( got*100 / float(need) )
self.backend.percentage( self.progress.percent )
log.info( "%s percent" % self.progress.percent)
@@ -57,22 +62,27 @@ class UpdateSystemCallback(callbacks.UpdateCallback):
self.backend.percentage(self.progress.percent)
self.backend.status(STATUS_DEP_RESOLVE)
self.progress.step()
- self.backend.percentage(self.progress.percent)
- log.info(self.progress.percent)
-
+ #5 >> request> download
def setChangesetHunk(self, num, total):
log.info("callback. .......... set Changeset HUnk %s/%s" % (num, total ) )
- self.progress.step()
+ self.progress.set_subpercent( num*100/float(total) )
+ self.disablepercent = True
self.backend.percentage(self.progress.percent)
log.info(self.progress.percent)
-
+ if num == total:
+ self.dostep =True
+ #6
def setUpdateHunk(self, hunk, hunkCount):
log.info("callback. .......... set update HUnk %s/%s" % ( hunk, hunkCount))
- self.progress.step()
+ if self.dostep:
+ self.progress.step()
+ self.disablepercent = True
+ self.dostep = False
+
if hunk < hunkCount:
- p = hunk / float(hunkCount) * 100.0
- self.progress.set_subpercent(p)
+ p = hunk*100/float(hunkCount)
+ self.progress.set_subpercent( p )
else:
self.smallUpdate = True
@@ -80,77 +90,59 @@ class UpdateSystemCallback(callbacks.UpdateCallback):
log.info(self.progress.percent)
def setUpdateJob(self, job):
- log.info("callback. .......... set update Job")
self.currentJob = job
- self.progress.step()
self.backend.percentage(self.progress.percent)
log.info(self.progress.percent)
def creatingRollback(self):
#self.backend.status('Creating Rollback')
- log.info("Callback ........ STATUS_ROLLBACK ")
self.backend.status(STATUS_ROLLBACK)
- self.progress.step()
self.backend.percentage(self.progress.percent)
log.info(self.progress.percent)
def preparingUpdate(self, troveNum, troveCount, add=0):
- log.info("callback ....... preparing Update trove %s/%s" % (troveNum, troveCount) )
#self.progress.step()
if not self.currentJob or len(self.currentJob) == 0 or troveNum > troveCount:
return
- if troveNum > 0 and troveCount > 0:
- sub_percent = (add + troveNum) / (2 * float(troveCount)) * 100
- self.progress.set_subpercent(sub_percent)
self.backend.percentage(self.progress.percent)
if troveNum > 0:
troveNum -= 1
- log.info("currentJob")
- log.info(self.currentJob[troveNum])
job = self.currentJob[troveNum]
name = job[0]
oldVersion, oldFlavor = job[1]
newVersion, newFlavor = job[2]
#log.info("JOB>>>>>>>> %s " % str(job) )
if oldVersion and newVersion:
- log.info("Callback ........ STATUS_UPDATE preparing Update ")
self.backend.status(STATUS_UPDATE)
package_id = self.backend.get_package_id(name, newVersion, newFlavor)
self.backend.package(package_id, INFO_UPDATING, '')
elif oldVersion and not newVersion:
- log.info("Callback ........ STATUS_REMOVE preparing Update ")
self.backend.status(STATUS_REMOVE)
package_id = self.backend.get_package_id(name, oldVersion, oldFlavor)
self.backend.package(package_id, INFO_REMOVING, '')
elif not oldVersion and newVersion:
- log.info("Callback ........ STATUS_INSTALL preparing Update")
self.backend.status(STATUS_INSTALL)
package_id = self.backend.get_package_id(name, newVersion, newFlavor)
self.backend.package(package_id, INFO_INSTALLING, '')
log.info(self.progress.percent)
def creatingDatabaseTransaction(self, troveNum, troveCount):
- log.info("callback. .......... creating Database Transactions")
- self.progress.step()
self.backend.percentage(self.progress.percent)
log.info(self.progress.percent)
self.preparingUpdate(troveNum, troveCount, add=troveCount)
def committingTransaction(self):
#self.backend.status('Committing Transaction')
- log.info("Callback ........ STATUS_COMMIT transactions ")
self.backend.status(STATUS_COMMIT)
- self.progress.step()
self.backend.percentage(self.progress.percent)
log.info(self.progress.percent)
def updateDone(self):
log.info("callback. .......... update done")
- self.progress.step()
self.backend.percentage(self.progress.percent)
self.currentJob = None
log.info(self.progress.percent)
commit 531ad7f4bb6779d4f1af5d884a8fc3b88006dc42
Author: Igor Pires Soares <igorsoares at gmail.com>
Date: Sat Feb 21 01:04:10 2009 +0000
Updated Brazilian Portuguese translation
Transmitted-via: Transifex (translate.fedoraproject.org)
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 2cc76e0..e27483e 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: PackageKit\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-02-17 08:37+0000\n"
-"PO-Revision-Date: 2009-02-18 00:44-0300\n"
+"POT-Creation-Date: 2009-02-18 13:42+0000\n"
+"PO-Revision-Date: 2009-02-19 15:19-0300\n"
"Last-Translator: Igor Pires Soares <igor at projetofedora.org>\n"
"Language-Team: Brazilian Portuguese <fedora-trans-pt_br at redhat.com>\n"
"MIME-Version: 1.0\n"
@@ -503,159 +503,164 @@ msgstr "Subcomandos:"
#. TRANSLATORS: command line argument, if we should show debugging information
#. TRANSLATORS: if we should show debugging data
-#: ../client/pk-console.c:1750
+#: ../client/pk-console.c:1752
#: ../client/pk-generate-pack.c:185
-#: ../client/pk-monitor.c:115
+#: ../client/pk-monitor.c:125
#: ../contrib/command-not-found/pk-command-not-found.c:510
#: ../src/pk-main.c:199
msgid "Show extra debugging information"
msgstr "Mostrar informações extras de depuração"
#. TRANSLATORS: command line argument, just show the version string
-#: ../client/pk-console.c:1753
-#: ../client/pk-monitor.c:117
+#: ../client/pk-console.c:1755
+#: ../client/pk-monitor.c:127
msgid "Show the program version and exit"
msgstr "Mostrar a versão do programa e sair"
#. TRANSLATORS: command line argument, use a filter to narrow down results
-#: ../client/pk-console.c:1756
+#: ../client/pk-console.c:1758
msgid "Set the filter, e.g. installed"
msgstr "Definir o filtro, p. ex.: instalados"
#. TRANSLATORS: command line argument, work asynchronously
-#: ../client/pk-console.c:1759
+#: ../client/pk-console.c:1761
msgid "Exit without waiting for actions to complete"
msgstr "Sair sem esperar pelo término das ações"
#. TRANSLATORS: This is when we could not connect to the system bus, and is fatal
-#: ../client/pk-console.c:1786
+#: ../client/pk-console.c:1788
msgid "This tool could not connect to system DBUS."
msgstr "Esta ferramenta não pôde conectar ao DBUS do sistema."
#. TRANSLATORS: The user specified an incorrect filter
-#: ../client/pk-console.c:1873
+#: ../client/pk-console.c:1875
msgid "The filter specified was invalid"
msgstr "O filtro especificado era inválido"
#. TRANSLATORS: a search type can be name, details, file, etc
-#: ../client/pk-console.c:1891
+#: ../client/pk-console.c:1893
msgid "A search type is required, e.g. name"
msgstr "Um tipo de pesquisa é requerido, p. ex. nome"
#. TRANSLATORS: the user needs to provide a search term
-#: ../client/pk-console.c:1897
-#: ../client/pk-console.c:1905
-#: ../client/pk-console.c:1913
-#: ../client/pk-console.c:1921
+#: ../client/pk-console.c:1899
+#: ../client/pk-console.c:1907
+#: ../client/pk-console.c:1915
+#: ../client/pk-console.c:1923
msgid "A search term is required"
msgstr "Um termo de pesquisa é requerido"
#. TRANSLATORS: the search type was provided, but invalid
-#: ../client/pk-console.c:1927
+#: ../client/pk-console.c:1929
msgid "Invalid search type"
msgstr "Tipo de pesquisa inválido"
#. TRANSLATORS: the user did not specify what they wanted to install
-#: ../client/pk-console.c:1933
+#: ../client/pk-console.c:1935
msgid "A package name or filename to install is required"
msgstr "O nome do pacote ou arquivo é requerido"
#. TRANSLATORS: geeky error, 99.9999% of users won't see this
-#: ../client/pk-console.c:1941
+#: ../client/pk-console.c:1943
msgid "A type, key_id and package_id are required"
msgstr "Um tipo, key_id e package_id são requeridos"
#. TRANSLATORS: the user did not specify what they wanted to remove
-#: ../client/pk-console.c:1949
+#: ../client/pk-console.c:1951
msgid "A package name to remove is required"
msgstr "O nome do pacote para remoção é requerido"
#. TRANSLATORS: the user did not specify anything about what to download or where
-#: ../client/pk-console.c:1956
+#: ../client/pk-console.c:1958
msgid "A destination directory and then the package names to download are required"
msgstr "O diretório de destino seguido dos nomes dos pacotes a serem baixados é requerido"
#. TRANSLATORS: the directory does not exist, so we can't continue
-#: ../client/pk-console.c:1962
+#: ../client/pk-console.c:1964
msgid "Directory not found"
msgstr "Diretório não encontrado"
#. TRANSLATORS: geeky error, 99.9999% of users won't see this
-#: ../client/pk-console.c:1969
+#: ../client/pk-console.c:1971
msgid "A licence identifier (eula-id) is required"
msgstr "Um identificador de licença (eula-id) é requerido"
+#. TRANSLATORS: geeky error, 99.9999% of users won't see this
+#: ../client/pk-console.c:1980
+msgid "A transaction identifier (tid) is required"
+msgstr "Um identificador de transação (tid) é requerido"
+
#. TRANSLATORS: The user did not specify a package name
-#: ../client/pk-console.c:1986
+#: ../client/pk-console.c:1996
msgid "A package name to resolve is required"
msgstr "O nome de pacote a ser analisado é requerido"
#. TRANSLATORS: The user did not specify a repository (software source) name
-#: ../client/pk-console.c:1994
-#: ../client/pk-console.c:2002
+#: ../client/pk-console.c:2004
+#: ../client/pk-console.c:2012
msgid "A repository name is required"
msgstr "O nome do repositório é requerido"
#. TRANSLATORS: The user didn't provide any data
-#: ../client/pk-console.c:2010
+#: ../client/pk-console.c:2020
msgid "A repo name, parameter and value are required"
msgstr "Um nome de repositório, parâmetro e um valor são requeridos"
#. TRANSLATORS: The user didn't specify what action to use
-#: ../client/pk-console.c:2023
+#: ../client/pk-console.c:2033
msgid "An action, e.g. 'update-system' is required"
msgstr "Uma ação, p. ex. \"update-system\" é requerida"
#. TRANSLATORS: The user specified an invalid action
-#: ../client/pk-console.c:2029
+#: ../client/pk-console.c:2039
msgid "A correct role is required"
msgstr "Um modo correto é requerido"
#. TRANSLATORS: we keep a database updated with the time that an action was last executed
-#: ../client/pk-console.c:2035
+#: ../client/pk-console.c:2045
msgid "Failed to get the time since this action was last completed"
msgstr "Falha ao obter o tempo em que essa ação foi completada pela última vez"
#. TRANSLATORS: The user did not provide a package name
#. TRANSLATORS: This is when the user fails to supply the package name
-#: ../client/pk-console.c:2044
-#: ../client/pk-console.c:2055
-#: ../client/pk-console.c:2063
-#: ../client/pk-console.c:2079
-#: ../client/pk-console.c:2087
+#: ../client/pk-console.c:2054
+#: ../client/pk-console.c:2065
+#: ../client/pk-console.c:2073
+#: ../client/pk-console.c:2089
+#: ../client/pk-console.c:2097
#: ../client/pk-generate-pack.c:241
msgid "A package name is required"
msgstr "O nome do pacote é requerido"
#. TRANSLATORS: each package "provides" certain things, e.g. mime(gstreamer-decoder-mp3), the user didn't specify it
-#: ../client/pk-console.c:2071
+#: ../client/pk-console.c:2081
msgid "A package provide string is required"
msgstr "à necessário especificar o que o pacote fornece"
#. TRANSLATORS: The user didn't specify a filename to create as a list
-#: ../client/pk-console.c:2095
+#: ../client/pk-console.c:2105
msgid "A list file name to create is required"
msgstr "O nome de arquivo da lista a ser criada é requerido"
#. TRANSLATORS: The user didn't specify a filename to open as a list
-#: ../client/pk-console.c:2104
-#: ../client/pk-console.c:2113
+#: ../client/pk-console.c:2114
+#: ../client/pk-console.c:2123
msgid "A list file to open is required"
msgstr "Uma lista de arquivos a serem abertos é requerida"
#. TRANSLATORS: The user tried to use an unsupported option on the command line
-#: ../client/pk-console.c:2166
+#: ../client/pk-console.c:2176
#, c-format
msgid "Option '%s' is not supported"
msgstr "A opção \"%s\" não é suportada"
#. TRANSLATORS: User does not have permission to do this
-#: ../client/pk-console.c:2179
+#: ../client/pk-console.c:2189
msgid "Incorrect privileges for this operation"
msgstr "Privilégios incorretos para esta operação"
#. TRANSLATORS: Generic failure of what they asked to do
-#: ../client/pk-console.c:2182
+#: ../client/pk-console.c:2192
msgid "Command failed"
msgstr "O comando falhou"
@@ -770,7 +775,7 @@ msgid "Failed to create '%s': %s"
msgstr "Falha ao criar \"%s\": %s"
#. TRANSLATORS: this is a program that monitors PackageKit
-#: ../client/pk-monitor.c:133
+#: ../client/pk-monitor.c:143
msgid "PackageKit Monitor"
msgstr "Monitor do PackageKit"
commit 8bdf46db3153c3f3756f464c301179d198abc909
Author: Piotr DrÄ
g <piotrdrag at gmail.com>
Date: Fri Feb 20 23:59:37 2009 +0000
Updated Polish translation
Transmitted-via: Transifex (translate.fedoraproject.org)
diff --git a/po/pl.po b/po/pl.po
index dc85e0f..13e8e73 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -5,8 +5,8 @@ msgid ""
msgstr ""
"Project-Id-Version: pl\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-01-15 16:57+0000\n"
-"PO-Revision-Date: 2009-01-16 20:32+0100\n"
+"POT-Creation-Date: 2009-02-21 00:57+0100\n"
+"PO-Revision-Date: 2009-02-21 00:59+0100\n"
"Last-Translator: Piotr DrÄ
g <piotrdrag at gmail.com>\n"
"Language-Team: Polish <pl at li.org>\n"
"MIME-Version: 1.0\n"
@@ -29,11 +29,11 @@ msgid "Succeeded"
msgstr "Powodzenie"
#. TRANSLATORS: if the repo is enabled
-#: ../client/pk-console.c:234 ../client/pk-console.c:377
+#: ../client/pk-console.c:234 ../client/pk-console.c:401
msgid "True"
msgstr "Prawda"
-#: ../client/pk-console.c:234 ../client/pk-console.c:377
+#: ../client/pk-console.c:234 ../client/pk-console.c:401
msgid "False"
msgstr "FaÅsz"
@@ -91,7 +91,7 @@ msgstr "Typ"
#. TRANSLATORS: this is any summary text describing the upgrade
#. TRANSLATORS: this is the summary of the group
-#: ../client/pk-console.c:297 ../client/pk-console.c:319
+#: ../client/pk-console.c:297 ../client/pk-console.c:320
msgid "Summary"
msgstr "Podsumowanie"
@@ -110,118 +110,134 @@ msgstr "Identyfikator"
msgid "Parent"
msgstr "NadrzÄdna"
-#: ../client/pk-console.c:316
+#. TRANSLATORS: this is the name of the parent group
+#: ../client/pk-console.c:317
msgid "Name"
msgstr "Nazwa"
#. TRANSLATORS: this is preferred icon for the group
-#: ../client/pk-console.c:322
+#: ../client/pk-console.c:323
msgid "Icon"
msgstr "Ikona"
#. TRANSLATORS: this is a header for the package that can be updated
-#: ../client/pk-console.c:337
+#: ../client/pk-console.c:338
msgid "Details about the update:"
msgstr "SzczegóÅy aktualizacji:"
-#: ../client/pk-console.c:338
+#. TRANSLATORS: details about the update, package name and version
+#: ../client/pk-console.c:340
msgid "Package"
msgstr "Pakiet"
-#: ../client/pk-console.c:340
+#. TRANSLATORS: details about the update, any packages that this update updates
+#: ../client/pk-console.c:343
msgid "Updates"
msgstr "Aktualizuje"
-#: ../client/pk-console.c:342
+#. TRANSLATORS: details about the update, any packages that this update obsoletes
+#: ../client/pk-console.c:347
msgid "Obsoletes"
msgstr "ZastÄpuje"
-#: ../client/pk-console.c:344
+#. TRANSLATORS: details about the update, the vendor URLs
+#: ../client/pk-console.c:351
msgid "Vendor"
msgstr "Producent"
-#: ../client/pk-console.c:346
+#. TRANSLATORS: details about the update, the bugzilla URLs
+#: ../client/pk-console.c:355
msgid "Bugzilla"
msgstr "Bugzilla"
-#: ../client/pk-console.c:348
+#. TRANSLATORS: details about the update, the CVE URLs
+#: ../client/pk-console.c:359
msgid "CVE"
msgstr "CVE"
-#: ../client/pk-console.c:350
+#. TRANSLATORS: details about the update, if the package requires a restart
+#: ../client/pk-console.c:363
msgid "Restart"
msgstr "Uruchom ponownie"
-#: ../client/pk-console.c:352
+#. TRANSLATORS: details about the update, any description of the update
+#: ../client/pk-console.c:367
msgid "Update text"
msgstr "Tekst aktualizacji"
-#: ../client/pk-console.c:354
+#. TRANSLATORS: details about the update, the changelog for the package
+#: ../client/pk-console.c:371
msgid "Changes"
msgstr "Zmiany"
-#: ../client/pk-console.c:356
+#. TRANSLATORS: details about the update, the ongoing state of the update
+#: ../client/pk-console.c:375
msgid "State"
msgstr "Stan"
-#: ../client/pk-console.c:359
+#. TRANSLATORS: details about the update, date the update was issued
+#: ../client/pk-console.c:380
msgid "Issued"
msgstr "Wydano"
-#: ../client/pk-console.c:362
+#. TRANSLATORS: details about the update, date the update was updated
+#: ../client/pk-console.c:385
msgid "Updated"
msgstr "Zaktualizowano"
-#: ../client/pk-console.c:448 ../client/pk-console.c:450
+#: ../client/pk-console.c:472 ../client/pk-console.c:474
msgid "Percentage"
msgstr "Procentowo"
-#: ../client/pk-console.c:450
+#: ../client/pk-console.c:474
msgid "Unknown"
msgstr "Nieznane"
#. TRANSLATORS: a package requires the system to be restarted
-#: ../client/pk-console.c:501
+#: ../client/pk-console.c:525
msgid "System restart required by:"
msgstr "Ponowne uruchomienie systemu jest wymagane przez:"
#. TRANSLATORS: a package requires the session to be restarted
-#: ../client/pk-console.c:504
+#: ../client/pk-console.c:528
msgid "Session restart required:"
msgstr "Wymagane jest ponowne uruchomienie sesji:"
#. TRANSLATORS: a package requires the application to be restarted
-#: ../client/pk-console.c:507
+#: ../client/pk-console.c:531
msgid "Application restart required by:"
msgstr "Ponowne uruchomienie programu jest wymagane przez:"
-#: ../client/pk-console.c:543
+#. TRANSLATORS: a package needs to restart they system
+#: ../client/pk-console.c:568
msgid "Please restart the computer to complete the update."
msgstr "ProszÄ uruchomiÄ ponownie komputer, aby zakoÅczyÄ aktualizacjÄ."
-#: ../client/pk-console.c:545
+#. TRANSLATORS: a package needs to restart the session
+#: ../client/pk-console.c:571
msgid "Please logout and login to complete the update."
msgstr "ProszÄ wylogowaÄ siÄ i zalogowaÄ, aby zakoÅczyÄ aktualizacjÄ."
-#: ../client/pk-console.c:547
+#. TRANSLATORS: a package needs to restart the application
+#: ../client/pk-console.c:574
msgid "Please restart the application as it is being used."
msgstr "ProszÄ uruchomiÄ program ponownie, ponieważ jest używany."
#. TRANSLATORS: The package is already installed on the system
-#: ../client/pk-console.c:659
+#: ../client/pk-console.c:687
#, c-format
msgid "The package %s is already installed"
msgstr "Pakiet %s jest już zainstalowany"
#. TRANSLATORS: The package name was not found in any software sources. The detailed error follows
-#: ../client/pk-console.c:667
+#: ../client/pk-console.c:695
#, c-format
msgid "The package %s could not be installed: %s"
msgstr "Nie można zainstalowaÄ pakietu %s: %s"
#. TRANSLATORS: There was a programming error that shouldn't happen. The detailed error follows
-#: ../client/pk-console.c:692 ../client/pk-console.c:719
-#: ../client/pk-console.c:815 ../client/pk-console.c:932
+#: ../client/pk-console.c:720 ../client/pk-console.c:747
+#: ../client/pk-console.c:843 ../client/pk-console.c:960
#: ../client/pk-tools-common.c:61 ../client/pk-tools-common.c:79
#: ../client/pk-tools-common.c:86
#, c-format
@@ -229,459 +245,513 @@ msgid "Internal error: %s"
msgstr "WewnÄtrzny bÅÄ
d: %s"
#. TRANSLATORS: There was an error installing the packages. The detailed error follows
-#: ../client/pk-console.c:700 ../client/pk-console.c:1327
+#: ../client/pk-console.c:728 ../client/pk-console.c:1355
#, c-format
msgid "This tool could not install the packages: %s"
msgstr "To narzÄdzie nie może zainstalowaÄ pakietów: %s"
#. TRANSLATORS: There was an error installing the files. The detailed error follows
-#: ../client/pk-console.c:727
+#: ../client/pk-console.c:755
#, c-format
msgid "This tool could not install the files: %s"
msgstr "To narzÄdzie nie może zainstalowaÄ plików: %s"
#. TRANSLATORS: The package name was not found in the installed list. The detailed error follows
-#: ../client/pk-console.c:783
+#: ../client/pk-console.c:811
#, c-format
msgid "This tool could not remove %s: %s"
msgstr "To narzÄdzie nie może usunÄ
Ä %s: %s"
#. TRANSLATORS: There was an error removing the packages. The detailed error follows
-#: ../client/pk-console.c:806 ../client/pk-console.c:844
-#: ../client/pk-console.c:877
+#: ../client/pk-console.c:834 ../client/pk-console.c:872
+#: ../client/pk-console.c:905
#, c-format
msgid "This tool could not remove the packages: %s"
msgstr "To narzÄdzie nie może usunÄ
Ä pakietów: %s"
#. TRANSLATORS: When removing, we might have to remove other dependencies
-#: ../client/pk-console.c:856
+#: ../client/pk-console.c:884
msgid "The following packages have to be removed:"
msgstr "NastÄpujÄ
ce pakiety muszÄ
zostaÄ usuniÄte:"
#. TRANSLATORS: We are checking if it's okay to remove a list of packages
-#: ../client/pk-console.c:863
+#: ../client/pk-console.c:891
msgid "Proceed removing additional packages?"
msgstr "KontynuowaÄ usuwanie dodatkowych pakietów?"
#. TRANSLATORS: We did not remove any packages
-#: ../client/pk-console.c:868
+#: ../client/pk-console.c:896
msgid "The package removal was canceled!"
msgstr "Anulowano usuniÄcie pakietu!"
#. TRANSLATORS: The package name was not found in any software sources
-#: ../client/pk-console.c:909
+#: ../client/pk-console.c:937
#, c-format
msgid "This tool could not download the package %s as it could not be found"
msgstr "To narzÄdzie nie może pobraÄ pakietu %s, ponieważ nie można go znaleźÄ"
#. TRANSLATORS: Could not download the packages for some reason. The detailed error follows
-#: ../client/pk-console.c:940
+#: ../client/pk-console.c:968
#, c-format
msgid "This tool could not download the packages: %s"
msgstr "To narzÄdzie nie może pobraÄ pakietów: %s"
#. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:967 ../client/pk-console.c:976
+#: ../client/pk-console.c:995 ../client/pk-console.c:1004
#, c-format
msgid "This tool could not update %s: %s"
msgstr "To narzÄdzie nie może zaktualizowaÄ %s: %s"
#. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:998 ../client/pk-console.c:1006
+#: ../client/pk-console.c:1026 ../client/pk-console.c:1034
#, c-format
msgid "This tool could not get the requirements for %s: %s"
msgstr "To narzÄdzie nie może uzyskaÄ wymagaÅ dla %s: %s"
#. TRANSLATORS: There was an error getting the dependencies for the package. The detailed error follows
-#: ../client/pk-console.c:1028 ../client/pk-console.c:1036
+#: ../client/pk-console.c:1056 ../client/pk-console.c:1064
#, c-format
msgid "This tool could not get the dependencies for %s: %s"
msgstr "To narzÄdzie nie może uzyskaÄ zależnoÅci dla %s: %s"
#. TRANSLATORS: There was an error getting the details about the package. The detailed error follows
-#: ../client/pk-console.c:1058 ../client/pk-console.c:1066
+#: ../client/pk-console.c:1086 ../client/pk-console.c:1094
#, c-format
msgid "This tool could not get package details for %s: %s"
msgstr "To narzÄdzie nie może uzyskaÄ szczegóÅów pakietu %s: %s"
#. TRANSLATORS: The package name was not found in any software sources. The detailed error follows
-#: ../client/pk-console.c:1088
+#: ../client/pk-console.c:1116
#, c-format
msgid "This tool could not find the files for %s: %s"
msgstr "To narzÄdzie nie może znaleÅºÄ plików dla %s: %s"
#. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:1096
+#: ../client/pk-console.c:1124
#, c-format
msgid "This tool could not get the file list for %s: %s"
msgstr "To narzÄdzie nie może uzyskaÄ listy plików dla %s: %s"
#. TRANSLATORS: There was an error getting the list of packages. The filename follows
-#: ../client/pk-console.c:1118
+#: ../client/pk-console.c:1146
#, c-format
msgid "File already exists: %s"
msgstr "Plik już istnieje: %s"
#. TRANSLATORS: follows a list of packages to install
-#: ../client/pk-console.c:1123 ../client/pk-console.c:1179
-#: ../client/pk-console.c:1254
+#: ../client/pk-console.c:1151 ../client/pk-console.c:1207
+#: ../client/pk-console.c:1282
msgid "Getting package list"
msgstr "Pobieranie listy pakietów"
#. TRANSLATORS: There was an error getting the list of packages. The detailed error follows
-#: ../client/pk-console.c:1129 ../client/pk-console.c:1185
-#: ../client/pk-console.c:1260
+#: ../client/pk-console.c:1157 ../client/pk-console.c:1213
+#: ../client/pk-console.c:1288
#, c-format
msgid "This tool could not get package list: %s"
msgstr "To narzÄdzie nie może pobraÄ listy pakietów: %s"
#. TRANSLATORS: There was an error saving the list
-#: ../client/pk-console.c:1140
+#: ../client/pk-console.c:1168
#, c-format
msgid "Failed to save to disk"
msgstr "Zapisanie na dysku nie powiodÅo siÄ"
#. TRANSLATORS: There was an error getting the list. The filename follows
-#: ../client/pk-console.c:1174 ../client/pk-console.c:1249
+#: ../client/pk-console.c:1202 ../client/pk-console.c:1277
#, c-format
msgid "File does not exist: %s"
msgstr "Plik nie istnieje: %s"
#. TRANSLATORS: header to a list of packages newly added
-#: ../client/pk-console.c:1206
+#: ../client/pk-console.c:1234
msgid "Packages to add"
msgstr "Pakiety do dodania"
#. TRANSLATORS: header to a list of packages removed
-#: ../client/pk-console.c:1214
+#: ../client/pk-console.c:1242
msgid "Packages to remove"
msgstr "Pakiety do usuniÄcia"
#. TRANSLATORS: We didn't find any differences
-#: ../client/pk-console.c:1282
+#: ../client/pk-console.c:1310
#, c-format
msgid "No new packages need to be installed"
msgstr "Nie trzeba instalowaÄ nowych pakietów"
#. TRANSLATORS: follows a list of packages to install
-#: ../client/pk-console.c:1288
+#: ../client/pk-console.c:1316
msgid "To install"
msgstr "Do zainstalowania"
#. TRANSLATORS: searching takes some time....
-#: ../client/pk-console.c:1299
+#: ../client/pk-console.c:1327
msgid "Searching for package: "
msgstr "Wyszukiwanie pakietu: "
#. TRANSLATORS: package was not found -- this is the end of a string ended in ...
-#: ../client/pk-console.c:1303
+#: ../client/pk-console.c:1331
msgid "not found."
msgstr "nie znaleziono."
#. TRANSLATORS: We didn't find any packages to install
-#: ../client/pk-console.c:1314
+#: ../client/pk-console.c:1342
#, c-format
msgid "No packages can be found to install"
msgstr "Nie można znaleÅºÄ pakietów do zainstalowania"
#. TRANSLATORS: installing new packages from package list
-#: ../client/pk-console.c:1320
+#: ../client/pk-console.c:1348
msgid "Installing packages"
msgstr "Instalowanie pakietów"
#. TRANSLATORS: The package name was not found in any software sources. The detailed error follows
-#: ../client/pk-console.c:1356
+#: ../client/pk-console.c:1384
#, c-format
msgid "This tool could not find the update details for %s: %s"
msgstr "To narzÄdzie nie może znaleÅºÄ szczegóÅów aktualizacji dla %s: %s"
#. TRANSLATORS: There was an error getting the details about the update for the package. The detailed error follows
-#: ../client/pk-console.c:1364
+#: ../client/pk-console.c:1392
#, c-format
msgid "This tool could not get the update details for %s: %s"
msgstr "To narzÄdzie nie może uzyskaÄ szczegóÅów aktualizacji dla %s: %s"
#. TRANSLATORS: This was an unhandled error, and we don't have _any_ context
-#: ../client/pk-console.c:1410
+#: ../client/pk-console.c:1438
msgid "Error:"
msgstr "BÅÄ
d:"
#. TRANSLATORS: This a list of details about the package
-#: ../client/pk-console.c:1424
+#: ../client/pk-console.c:1452
msgid "Package description"
msgstr "Opis pakietu"
#. TRANSLATORS: This a list files contained in the package
-#: ../client/pk-console.c:1458
+#: ../client/pk-console.c:1486
msgid "Package files"
msgstr "Pliki pakietu"
#. TRANSLATORS: This where the package has no files
-#: ../client/pk-console.c:1466
+#: ../client/pk-console.c:1494
msgid "No files"
msgstr "Brak plików"
#. TRANSLATORS: This a request for a GPG key signature from the backend, which the client will prompt for later
-#: ../client/pk-console.c:1489
+#: ../client/pk-console.c:1517
msgid "Repository signature required"
msgstr "Wymagany jest podpis repozytorium"
#. TRANSLATORS: This a prompt asking the user to import the security key
-#: ../client/pk-console.c:1499
+#: ../client/pk-console.c:1527
msgid "Do you accept this signature?"
msgstr "ZaakceptowaÄ ten podpis?"
#. TRANSLATORS: This is where the user declined the security key
-#: ../client/pk-console.c:1503
+#: ../client/pk-console.c:1531
msgid "The signature was not accepted."
msgstr "Podpis nie zostaÅ zaakceptowany."
#. TRANSLATORS: This a request for a EULA
-#: ../client/pk-console.c:1537
+#: ../client/pk-console.c:1565
msgid "End user license agreement required"
msgstr "Licencja jest wymagana"
#. TRANSLATORS: This a prompt asking the user to agree to the license
-#: ../client/pk-console.c:1544
+#: ../client/pk-console.c:1572
msgid "Do you agree to this license?"
msgstr "ZaakceptowaÄ tÄ licencjÄ?"
#. TRANSLATORS: This is where the user declined the license
-#: ../client/pk-console.c:1548
+#: ../client/pk-console.c:1576
msgid "The license was refused."
msgstr "Odrzucono licencjÄ."
#. TRANSLATORS: This is when the daemon crashed, and we are up shit creek without a paddle
-#: ../client/pk-console.c:1577
+#: ../client/pk-console.c:1605
msgid "The daemon crashed mid-transaction!"
msgstr "Demon zawiesiÅ siÄ w poÅowie transakcji!"
#. TRANSLATORS: This is the header to the --help menu
-#: ../client/pk-console.c:1630
+#: ../client/pk-console.c:1658
msgid "PackageKit Console Interface"
msgstr "Interfejs konsoli PackageKit"
-#: ../client/pk-console.c:1630
+#. these are commands we can use with pkcon
+#: ../client/pk-console.c:1660
msgid "Subcommands:"
msgstr "Podpolecenia:"
-#: ../client/pk-console.c:1719 ../client/pk-generate-pack.c:184
-#: ../client/pk-monitor.c:115
+#. TRANSLATORS: command line argument, if we should show debugging information
+#. TRANSLATORS: if we should show debugging data
+#: ../client/pk-console.c:1752 ../client/pk-generate-pack.c:185
+#: ../client/pk-monitor.c:125
#: ../contrib/command-not-found/pk-command-not-found.c:510
-#: ../src/pk-main.c:192
+#: ../src/pk-main.c:199
msgid "Show extra debugging information"
msgstr "WyÅwietla dodatkowe informacje o debugowaniu"
-#: ../client/pk-console.c:1721 ../client/pk-monitor.c:117
+#. TRANSLATORS: command line argument, just show the version string
+#: ../client/pk-console.c:1755 ../client/pk-monitor.c:127
msgid "Show the program version and exit"
msgstr "WyÅwietla wersjÄ programu i wyÅÄ
cza"
-#: ../client/pk-console.c:1723
+#. TRANSLATORS: command line argument, use a filter to narrow down results
+#: ../client/pk-console.c:1758
msgid "Set the filter, e.g. installed"
msgstr "Ustawia filtr, np. zainstalowane"
-#: ../client/pk-console.c:1725
+#. TRANSLATORS: command line argument, work asynchronously
+#: ../client/pk-console.c:1761
msgid "Exit without waiting for actions to complete"
msgstr "WyÅÄ
cza bez oczekiwania na zakoÅczenie dziaÅaÅ"
#. TRANSLATORS: This is when we could not connect to the system bus, and is fatal
-#: ../client/pk-console.c:1752
+#: ../client/pk-console.c:1788
msgid "This tool could not connect to system DBUS."
msgstr "To narzÄdzie nie może poÅÄ
czyÄ siÄ z systemowym D-Bus."
#. TRANSLATORS: The user specified an incorrect filter
-#: ../client/pk-console.c:1839
+#: ../client/pk-console.c:1875
msgid "The filter specified was invalid"
msgstr "Podany filtr jest nieprawidÅowy"
-#: ../client/pk-console.c:1856
-msgid "You need to specify a search type, e.g. name"
-msgstr "Należy podaÄ typ wyszukiwania, np. po nazwie"
+#. TRANSLATORS: a search type can be name, details, file, etc
+#: ../client/pk-console.c:1893
+msgid "A search type is required, e.g. name"
+msgstr "Wymagany jest typ wyszukiwania, np. nazwa"
-#: ../client/pk-console.c:1861 ../client/pk-console.c:1868
-#: ../client/pk-console.c:1875 ../client/pk-console.c:1882
-#: ../client/pk-console.c:1990 ../client/pk-console.c:2000
-#: ../client/pk-console.c:2007 ../client/pk-console.c:2014
-msgid "You need to specify a search term"
-msgstr "Należy podaÄ termin wyszukiwania"
+#. TRANSLATORS: the user needs to provide a search term
+#: ../client/pk-console.c:1899 ../client/pk-console.c:1907
+#: ../client/pk-console.c:1915 ../client/pk-console.c:1923
+msgid "A search term is required"
+msgstr "Wymagany jest wyszukiwany termin"
-#: ../client/pk-console.c:1887
+#. TRANSLATORS: the search type was provided, but invalid
+#: ../client/pk-console.c:1929
msgid "Invalid search type"
msgstr "NieprawidÅowy typ wyszukiwania"
-#: ../client/pk-console.c:1892
-msgid "You need to specify a package or file to install"
-msgstr "Należy podaÄ pakiet lub plik do zainstalowania"
+#. TRANSLATORS: the user did not specify what they wanted to install
+#: ../client/pk-console.c:1935
+msgid "A package name or filename to install is required"
+msgstr "Wymagana jest nazwa pakietu lub pliku do zainstalowania"
-#: ../client/pk-console.c:1899
-msgid "You need to specify a type, key_id and package_id"
-msgstr "Należy podaÄ typ, key_id i package_id"
+#. TRANSLATORS: geeky error, 99.9999% of users won't see this
+#: ../client/pk-console.c:1943
+msgid "A type, key_id and package_id are required"
+msgstr "Wymagany jest typ, key_id i package_id"
-#: ../client/pk-console.c:1906
-msgid "You need to specify a package to remove"
-msgstr "Należy podaÄ pakiet do usuniÄcia"
+#. TRANSLATORS: the user did not specify what they wanted to remove
+#: ../client/pk-console.c:1951
+msgid "A package name to remove is required"
+msgstr "Wymagana jest nazwa pakietu do usuniÄcia"
-#: ../client/pk-console.c:1912
+#. TRANSLATORS: the user did not specify anything about what to download or where
+#: ../client/pk-console.c:1958
msgid ""
-"You need to specify the destination directory and then the packages to "
-"download"
-msgstr "Należy podaÄ katalog docelowy, a nastÄpnie pakiety do pobrania"
+"A destination directory and then the package names to download are required"
+msgstr "Wymagany jest katalog docelowy, a nastÄpnie nazwy pakietów do pobrania"
-#: ../client/pk-console.c:1917
+#. TRANSLATORS: the directory does not exist, so we can't continue
+#: ../client/pk-console.c:1964
msgid "Directory not found"
msgstr "Nie znaleziono katalogu"
-#: ../client/pk-console.c:1923
-msgid "You need to specify a licence identifier (eula-id)"
-msgstr "Należy podaÄ identyfikator licencji (eula-id)"
-
-#: ../client/pk-console.c:1939
-msgid "You need to specify a package name to resolve"
-msgstr "Należy podaÄ nazwÄ pakietu do rozwiÄ
zania"
-
-#: ../client/pk-console.c:1946 ../client/pk-console.c:1953
-msgid "You need to specify a repository name"
-msgstr "Należy podaÄ nazwÄ repozytorium"
-
-#: ../client/pk-console.c:1960
-msgid "You need to specify a repo name/parameter and value"
-msgstr "Należy podaÄ nazwÄ/parametr repozytorium i wartoÅÄ"
-
-#: ../client/pk-console.c:1972
-msgid "You need to specify an action, e.g. 'update-system'"
-msgstr "Należy podaÄ dziaÅanie, np. \"update-system\""
-
-#: ../client/pk-console.c:1977
-msgid "You need to specify a correct role"
-msgstr "Należy podaÄ poprawnÄ
rolÄ"
-
-#: ../client/pk-console.c:1982
-msgid "Failed to get last time"
-msgstr "Uzyskanie ostatniego czasu nie powiodÅo siÄ"
-
-#: ../client/pk-console.c:2021
-msgid "You need to specify a package to find the details for"
-msgstr "Należy podaÄ pakiet do znalezienia szczegóÅów dla"
-
-#: ../client/pk-console.c:2028
-msgid "You need to specify a package to find the files for"
-msgstr "Należy podaÄ pakiet do znalezienia plików dla"
-
-#: ../client/pk-console.c:2035
-msgid "You need to specify a list file to create"
-msgstr "Należy podaÄ plik listy do utworzenia"
-
-#: ../client/pk-console.c:2043 ../client/pk-console.c:2051
-msgid "You need to specify a list file to open"
-msgstr "Należy podaÄ plik listy do otwarcia"
+#. TRANSLATORS: geeky error, 99.9999% of users won't see this
+#: ../client/pk-console.c:1971
+msgid "A licence identifier (eula-id) is required"
+msgstr "Wymagany jest identyfikator licencji (eula-id)"
+
+#. TRANSLATORS: geeky error, 99.9999% of users won't see this
+#: ../client/pk-console.c:1980
+msgid "A transaction identifier (tid) is required"
+msgstr "Wymagany jest identyfikator transakcji (tid)"
+
+#. TRANSLATORS: The user did not specify a package name
+#: ../client/pk-console.c:1996
+msgid "A package name to resolve is required"
+msgstr "Wymagana jest nazwa pakietu do rozwiÄ
zania"
+
+#. TRANSLATORS: The user did not specify a repository (software source) name
+#: ../client/pk-console.c:2004 ../client/pk-console.c:2012
+msgid "A repository name is required"
+msgstr "Wymagana jest nazwa repozytorium"
+
+#. TRANSLATORS: The user didn't provide any data
+#: ../client/pk-console.c:2020
+msgid "A repo name, parameter and value are required"
+msgstr "Wymagana jest nazwa, parametr i wartoÅÄ repozytorium"
+
+#. TRANSLATORS: The user didn't specify what action to use
+#: ../client/pk-console.c:2033
+msgid "An action, e.g. 'update-system' is required"
+msgstr "Wymagane jest dziaÅanie, np. \"update-system\""
+
+#. TRANSLATORS: The user specified an invalid action
+#: ../client/pk-console.c:2039
+msgid "A correct role is required"
+msgstr "Wymagana jest bieżÄ
ca rola"
+
+#. TRANSLATORS: we keep a database updated with the time that an action was last executed
+#: ../client/pk-console.c:2045
+msgid "Failed to get the time since this action was last completed"
+msgstr ""
+"Uzyskanie czasu od ostatniego zakoÅczenia tego dziaÅania nie powiodÅo siÄ"
+
+#. TRANSLATORS: The user did not provide a package name
+#. TRANSLATORS: This is when the user fails to supply the package name
+#: ../client/pk-console.c:2054 ../client/pk-console.c:2065
+#: ../client/pk-console.c:2073 ../client/pk-console.c:2089
+#: ../client/pk-console.c:2097 ../client/pk-generate-pack.c:241
+msgid "A package name is required"
+msgstr "Wymagana jest nazwa pakietu"
+
+#. TRANSLATORS: each package "provides" certain things, e.g. mime(gstreamer-decoder-mp3), the user didn't specify it
+#: ../client/pk-console.c:2081
+msgid "A package provide string is required"
+msgstr "Wymagany jest ÅaÅcuch dostarczania pakietu"
+
+#. TRANSLATORS: The user didn't specify a filename to create as a list
+#: ../client/pk-console.c:2105
+msgid "A list file name to create is required"
+msgstr "Wymagana jest lista nazw plików do utworzenia"
+
+#. TRANSLATORS: The user didn't specify a filename to open as a list
+#: ../client/pk-console.c:2114 ../client/pk-console.c:2123
+msgid "A list file to open is required"
+msgstr "Wymagana jest lista plików do otwarcia"
#. TRANSLATORS: The user tried to use an unsupported option on the command line
-#: ../client/pk-console.c:2104
+#: ../client/pk-console.c:2176
#, c-format
msgid "Option '%s' is not supported"
msgstr "Opcja \"%s\" nie jest obsÅugiwana"
#. TRANSLATORS: User does not have permission to do this
-#: ../client/pk-console.c:2117
-msgid "You don't have the necessary privileges for this operation"
-msgstr "Nie posiadasz niezbÄdnych uprawnieÅ dla tej operacji"
+#: ../client/pk-console.c:2189
+msgid "Incorrect privileges for this operation"
+msgstr "Niepoprawne uprawnienia dla tego dziaÅania"
#. TRANSLATORS: Generic failure of what they asked to do
-#: ../client/pk-console.c:2120
+#: ../client/pk-console.c:2192
msgid "Command failed"
msgstr "Polecenie nie powiodÅo siÄ"
#. TRANSLATORS: This is the state of the transaction
-#: ../client/pk-generate-pack.c:100
+#: ../client/pk-generate-pack.c:101
msgid "Downloading"
msgstr "Pobieranie"
#. TRANSLATORS: This is when the main packages are being downloaded
-#: ../client/pk-generate-pack.c:120
+#: ../client/pk-generate-pack.c:121
msgid "Downloading packages"
msgstr "Pobieranie pakietów"
#. TRANSLATORS: This is when the dependency packages are being downloaded
-#: ../client/pk-generate-pack.c:125
+#: ../client/pk-generate-pack.c:126
msgid "Downloading dependencies"
msgstr "Pobieranie zależnoÅci"
-#: ../client/pk-generate-pack.c:186
+#. TRANSLATORS: we can exclude certain packages (glibc) when we know they'll exist on the target
+#: ../client/pk-generate-pack.c:188
msgid "Set the file name of dependencies to be excluded"
msgstr "ProszÄ ustawiÄ nazwy plików zależnoÅci do wykluczenia"
-#: ../client/pk-generate-pack.c:188
-msgid "The output directory (the current directory is used if ommitted)"
+#. TRANSLATORS: the output location
+#: ../client/pk-generate-pack.c:191
+msgid ""
+"The output file or directory (the current directory is used if ommitted)"
msgstr ""
-"Katalog wyjÅcia (użyty zostanie bieżÄ
cy katalog, jeÅli zostanie pominiÄty)"
+"Plik lub katalog wyjÅcia (użyty zostanie bieżÄ
cy katalog, jeÅli zostanie "
+"pominiÄte)"
-#: ../client/pk-generate-pack.c:190
+#. TRANSLATORS: put a list of packages in the pack
+#: ../client/pk-generate-pack.c:194
msgid "The package to be put into the service pack"
msgstr "Pakiet do umieszczenia w pakiecie serwisowym"
-#: ../client/pk-generate-pack.c:192
+#. TRANSLATORS: put all pending updates in the pack
+#: ../client/pk-generate-pack.c:197
msgid "Put all updates available in the service pack"
msgstr "Wszystkie dostÄpne aktualizacje w pakiecie serwisowym"
#. TRANSLATORS: This is when the user fails to supply the correct arguments
-#: ../client/pk-generate-pack.c:220
+#: ../client/pk-generate-pack.c:225
msgid "Neither --package or --updates option selected."
msgstr "Nie wybrano żadnej z opcji --package lub --updates."
#. TRANSLATORS: This is when the user fails to supply just one argument
-#: ../client/pk-generate-pack.c:228
+#: ../client/pk-generate-pack.c:233
msgid "Both options selected."
msgstr "Wybrano obie opcje."
+#. TRANSLATORS: This is when the user fails to supply the output
+#: ../client/pk-generate-pack.c:249
+msgid "A output directory or file name is required"
+msgstr "Wymagany jest katalog lub nazwa pliku wyjÅcia"
+
+#. TRANSLATORS: This is when the backend doesn't have the capability to get-depends
+#. TRANSLATORS: This is when the backend doesn't have the capability to download
+#: ../client/pk-generate-pack.c:267 ../client/pk-generate-pack.c:273
+msgid "The package manager cannot perform this type of operation."
+msgstr "Menedżer pakietów nie może wykonaÄ tego typu dziaÅania."
+
+#. TRANSLATORS: the user specified an absolute path, but didn't get the extension correct
+#: ../client/pk-generate-pack.c:285
+msgid "If specifying a file, the service pack name must end with"
+msgstr "JeÅli podano plik, nazwa pakietu serwisowego musi koÅczyÄ siÄ"
+
#. TRANSLATORS: This is when file already exists
-#: ../client/pk-generate-pack.c:261
+#: ../client/pk-generate-pack.c:301
msgid "A pack with the same name already exists, do you want to overwrite it?"
msgstr "Pakiet serwisowy o tej samej nazwie już istnieje, zastÄ
piÄ go?"
#. TRANSLATORS: This is when the pack was not overwritten
-#: ../client/pk-generate-pack.c:264
+#: ../client/pk-generate-pack.c:304
msgid "The pack was not overwritten."
msgstr "Pakiet nie zostaÅ zastÄ
piony."
#. TRANSLATORS: This is when the temporary directory cannot be created, the directory name follows
-#: ../client/pk-generate-pack.c:276
+#: ../client/pk-generate-pack.c:317
msgid "Failed to create directory:"
msgstr "Utworzenie katalogu nie powiodÅo siÄ:"
#. TRANSLATORS: This is when the list of packages from the remote computer cannot be opened
-#: ../client/pk-generate-pack.c:285
+#: ../client/pk-generate-pack.c:327
msgid "Failed to open package list."
msgstr "Otwarcie listy pakietów nie powiodÅo siÄ."
#. TRANSLATORS: The package name is being matched up to available packages
-#: ../client/pk-generate-pack.c:295
+#: ../client/pk-generate-pack.c:338
msgid "Finding package name."
msgstr "Wyszukiwanie nazwy pakietu."
#. TRANSLATORS: This is when the package cannot be found in any software source. The detailed error follows
-#: ../client/pk-generate-pack.c:299
+#: ../client/pk-generate-pack.c:342
#, c-format
msgid "Failed to find package '%s': %s"
msgstr "Nie można znaleÅºÄ pakietu \"%s\": %s"
#. TRANSLATORS: This is telling the user we are in the process of making the pack
-#: ../client/pk-generate-pack.c:315
+#: ../client/pk-generate-pack.c:359
msgid "Creating service pack..."
msgstr "Tworzenie pakietu serwisowego..."
#. TRANSLATORS: we succeeded in making the file
-#: ../client/pk-generate-pack.c:322
+#: ../client/pk-generate-pack.c:366
#, c-format
msgid "Service pack created '%s'"
msgstr "Utworzono pakiet serwisowy \"%s\""
#. TRANSLATORS: we failed to make te file
-#: ../client/pk-generate-pack.c:326
+#: ../client/pk-generate-pack.c:371
#, c-format
msgid "Failed to create '%s': %s"
msgstr "Utworzenie \"%s\" nie powiodÅo siÄ: %s"
-#: ../client/pk-monitor.c:132
+#. TRANSLATORS: this is a program that monitors PackageKit
+#: ../client/pk-monitor.c:143
msgid "PackageKit Monitor"
msgstr "Monitor PackageKit"
@@ -797,6 +867,7 @@ msgstr "Zainstalowana wersja"
msgid "Run version %s now"
msgstr "Uruchom wersjÄ %s"
+#. TRANSLATORS: run the application now
#: ../contrib/browser-plugin/src/contents.cpp:324
msgid "Run now"
msgstr "Uruchom teraz"
@@ -940,21 +1011,25 @@ msgstr "Oznaczenie klucza używanego do podpisywania pakietów jako zaufanego"
msgid "Update packages"
msgstr "Aktualizacja pakietów"
-#: ../src/pk-main.c:86
+#. TRANSLATORS: failed due to DBus security
+#: ../src/pk-main.c:87
msgid "Startup failed due to security policies on this machine."
msgstr ""
"Uruchomienie nie powiodÅo siÄ z powodu polityk bezpieczeÅstwa tego komputera."
-#: ../src/pk-main.c:87
+#. TRANSLATORS: only two ways this can fail...
+#: ../src/pk-main.c:89
msgid "This can happen for two reasons:"
msgstr "MogÅo siÄ to wydarzyÄ z dwóch powodów:"
-#: ../src/pk-main.c:88
+#. TRANSLATORS: only allowed to be owned by root
+#: ../src/pk-main.c:91
msgid "The correct user is not launching the executable (usually root)"
msgstr ""
"PrawidÅowy użytkownik nie uruchamiania pliku wykonywalnego (zwykle root)"
-#: ../src/pk-main.c:89
+#. TRANSLATORS: or we are installed in a prefix
+#: ../src/pk-main.c:93
msgid ""
"The org.freedesktop.PackageKit.conf file is not installed in the system "
"directory:"
@@ -962,39 +1037,48 @@ msgstr ""
"Plik org.freedesktop.PackageKit.conf nie jest zainstalowany w katalogu "
"systemowym:"
-#: ../src/pk-main.c:188
+#. TRANSLATORS: a backend is the system package tool, e.g. yum, apt
+#: ../src/pk-main.c:193
msgid "Packaging backend to use, e.g. dummy"
msgstr "Używany moduÅ przetwarzajÄ
cy, np. dummy"
-#: ../src/pk-main.c:190
+#. TRANSLATORS: if we should run in the background
+#: ../src/pk-main.c:196
msgid "Daemonize and detach from the terminal"
msgstr "Tworzy demona i odÅÄ
cza z terminala"
-#: ../src/pk-main.c:194
+#. TRANSLATORS: if we should not monitor how long we are inactive for
+#: ../src/pk-main.c:202
msgid "Disable the idle timer"
msgstr "WyÅÄ
cza licznik czasu bezczynnoÅci"
-#: ../src/pk-main.c:196
+#. TRANSLATORS: show version
+#: ../src/pk-main.c:205
msgid "Show version and exit"
msgstr "WyÅwietla wersjÄ i wyÅÄ
cza"
-#: ../src/pk-main.c:198
+#. TRANSLATORS: exit after we've started up, used for user profiling
+#: ../src/pk-main.c:208
msgid "Exit after a small delay"
msgstr "WyÅÄ
cza po maÅej przerwie"
-#: ../src/pk-main.c:200
+#. TRANSLATORS: exit straight away, used for automatic profiling
+#: ../src/pk-main.c:211
msgid "Exit after the engine has loaded"
msgstr "WyÅÄ
cza po wczytaniu mechanizmu"
-#: ../src/pk-main.c:214
+#. TRANSLATORS: describing the service that is running
+#: ../src/pk-main.c:226
msgid "PackageKit service"
msgstr "UsÅuga PackageKit"
-#: ../src/pk-main.c:250
+#. TRANSLATORS: fatal error, dbus is not running
+#: ../src/pk-main.c:263
msgid "Cannot connect to the system bus"
msgstr "Nie można poÅÄ
czyÄ siÄ z magistralÄ
systemowÄ
"
-#: ../src/pk-main.c:299
+#. TRANSLATORS: cannot register on system bus, unknown reason
+#: ../src/pk-main.c:313
#, c-format
msgid "Error trying to start: %s\n"
msgstr "BÅÄ
d podczas próbowania uruchomienia: %s\n"
commit 4aab96ee5f0aaa263cdb0d449130dfe40545e62b
Author: Domingo Becker <domingobecker at gmail.com>
Date: Fri Feb 20 23:02:19 2009 +0000
updated Spanish translation
Transmitted-via: Transifex (translate.fedoraproject.org)
diff --git a/po/es.po b/po/es.po
index 8880f23..dfb9f7a 100644
--- a/po/es.po
+++ b/po/es.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: packagekit\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-01-15 16:57+0000\n"
-"PO-Revision-Date: 2008-12-12 09:37-0300\n"
+"POT-Creation-Date: 2009-02-18 13:42+0000\n"
+"PO-Revision-Date: 2009-02-20 15:45-0300\n"
"Last-Translator: Domingo Becker <domingobecker at gmail.com>\n"
"Language-Team: Spanish <fedora-trans-es at redhat.com>\n"
"MIME-Version: 1.0\n"
@@ -19,691 +19,765 @@ msgstr ""
#. TRANSLATORS: this is an atomic transaction
#: ../client/pk-console.c:230
msgid "Transaction"
-msgstr ""
+msgstr "Transacción"
#. TRANSLATORS: this is the time the transaction was started in system timezone
#: ../client/pk-console.c:232
msgid "System time"
-msgstr ""
+msgstr "Hora del sistema"
#. TRANSLATORS: this is if the transaction succeeded or not
#: ../client/pk-console.c:234
msgid "Succeeded"
-msgstr ""
+msgstr "Existosa"
#. TRANSLATORS: if the repo is enabled
-#: ../client/pk-console.c:234 ../client/pk-console.c:377
+#: ../client/pk-console.c:234
+#: ../client/pk-console.c:401
msgid "True"
-msgstr ""
+msgstr "Verdadero"
-#: ../client/pk-console.c:234 ../client/pk-console.c:377
+#: ../client/pk-console.c:234
+#: ../client/pk-console.c:401
msgid "False"
-msgstr ""
+msgstr "Falso"
#. TRANSLATORS: this is the transactions role, e.g. "update-system"
#: ../client/pk-console.c:236
msgid "Role"
-msgstr ""
+msgstr "Rol"
#. TRANSLATORS: this is The duration of the transaction
#: ../client/pk-console.c:241
msgid "Duration"
-msgstr ""
+msgstr "Duración"
#: ../client/pk-console.c:241
msgid "(seconds)"
-msgstr ""
+msgstr "(segundos)"
#. TRANSLATORS: this is The command line used to do the action
#: ../client/pk-console.c:245
-#, fuzzy
msgid "Command line"
-msgstr "Commando falló"
+msgstr "LÃnea de Comando"
#. TRANSLATORS: this is the user ID of the user that started the action
#: ../client/pk-console.c:247
msgid "User ID"
-msgstr ""
+msgstr "ID del Usuario"
#. TRANSLATORS: this is the username, e.g. hughsie
#: ../client/pk-console.c:254
msgid "Username"
-msgstr ""
+msgstr "Nombre de Usuario"
#. TRANSLATORS: this is the users real name, e.g. "Richard Hughes"
#: ../client/pk-console.c:258
msgid "Real name"
-msgstr ""
+msgstr "Nombre real"
#: ../client/pk-console.c:266
-#, fuzzy
msgid "Affected packages:"
-msgstr "Actualizar paquete"
+msgstr "Paquete afectados:"
#: ../client/pk-console.c:268
msgid "Affected packages: None"
-msgstr ""
+msgstr "Paquetes afectados: Ninguno"
#. TRANSLATORS: this is the distro, e.g. Fedora 10
#: ../client/pk-console.c:293
msgid "Distribution"
-msgstr ""
+msgstr "Distribución"
#. TRANSLATORS: this is type of update, stable or testing
#: ../client/pk-console.c:295
msgid "Type"
-msgstr ""
+msgstr "Tipo"
#. TRANSLATORS: this is any summary text describing the upgrade
#. TRANSLATORS: this is the summary of the group
-#: ../client/pk-console.c:297 ../client/pk-console.c:319
+#: ../client/pk-console.c:297
+#: ../client/pk-console.c:320
msgid "Summary"
-msgstr ""
+msgstr "Resúmen"
#. TRANSLATORS: this is the group category name
#: ../client/pk-console.c:309
msgid "Category"
-msgstr ""
+msgstr "categorÃa"
#. TRANSLATORS: this is group identifier
#: ../client/pk-console.c:311
msgid "ID"
-msgstr ""
+msgstr "ID"
#. TRANSLATORS: this is the parent group
#: ../client/pk-console.c:314
msgid "Parent"
-msgstr ""
+msgstr "Padre"
-#: ../client/pk-console.c:316
+#. TRANSLATORS: this is the name of the parent group
+#: ../client/pk-console.c:317
msgid "Name"
-msgstr ""
+msgstr "Nombre"
#. TRANSLATORS: this is preferred icon for the group
-#: ../client/pk-console.c:322
+#: ../client/pk-console.c:323
msgid "Icon"
-msgstr ""
+msgstr "Icono"
#. TRANSLATORS: this is a header for the package that can be updated
-#: ../client/pk-console.c:337
+#: ../client/pk-console.c:338
msgid "Details about the update:"
msgstr "Detalles acerca de la actualización:"
-#: ../client/pk-console.c:338
-#, fuzzy
+#. TRANSLATORS: details about the update, package name and version
+#: ../client/pk-console.c:340
msgid "Package"
-msgstr "Archivos del paquete"
+msgstr "Paquete"
-#: ../client/pk-console.c:340
-#, fuzzy
+#. TRANSLATORS: details about the update, any packages that this update updates
+#: ../client/pk-console.c:343
msgid "Updates"
-msgstr "Actualizar paquete"
+msgstr "Actualizaciones"
-#: ../client/pk-console.c:342
+#. TRANSLATORS: details about the update, any packages that this update obsoletes
+#: ../client/pk-console.c:347
msgid "Obsoletes"
-msgstr ""
+msgstr "Sustituye"
-#: ../client/pk-console.c:344
+#. TRANSLATORS: details about the update, the vendor URLs
+#: ../client/pk-console.c:351
msgid "Vendor"
-msgstr ""
+msgstr "Vendedor"
-#: ../client/pk-console.c:346
+#. TRANSLATORS: details about the update, the bugzilla URLs
+#: ../client/pk-console.c:355
msgid "Bugzilla"
-msgstr ""
+msgstr "Bugzilla"
-#: ../client/pk-console.c:348
+#. TRANSLATORS: details about the update, the CVE URLs
+#: ../client/pk-console.c:359
msgid "CVE"
-msgstr ""
+msgstr "CVE"
-#: ../client/pk-console.c:350
+#. TRANSLATORS: details about the update, if the package requires a restart
+#: ../client/pk-console.c:363
msgid "Restart"
-msgstr ""
+msgstr "Reiniciar"
-#: ../client/pk-console.c:352
-#, fuzzy
+#. TRANSLATORS: details about the update, any description of the update
+#: ../client/pk-console.c:367
msgid "Update text"
-msgstr "Actualizar detalle"
+msgstr "Texto de actualización"
-#: ../client/pk-console.c:354
+#. TRANSLATORS: details about the update, the changelog for the package
+#: ../client/pk-console.c:371
msgid "Changes"
-msgstr ""
+msgstr "Cambios"
-#: ../client/pk-console.c:356
+#. TRANSLATORS: details about the update, the ongoing state of the update
+#: ../client/pk-console.c:375
msgid "State"
-msgstr ""
+msgstr "Estado"
-#: ../client/pk-console.c:359
+#. TRANSLATORS: details about the update, date the update was issued
+#: ../client/pk-console.c:380
msgid "Issued"
-msgstr ""
+msgstr "Emitido"
-#: ../client/pk-console.c:362
-#, fuzzy
+#. TRANSLATORS: details about the update, date the update was updated
+#: ../client/pk-console.c:385
msgid "Updated"
-msgstr "Actualizar detalle"
+msgstr "Actualizado"
-#: ../client/pk-console.c:448 ../client/pk-console.c:450
+#: ../client/pk-console.c:472
+#: ../client/pk-console.c:474
msgid "Percentage"
-msgstr ""
+msgstr "Porcentaje"
-#: ../client/pk-console.c:450
+#: ../client/pk-console.c:474
msgid "Unknown"
-msgstr ""
+msgstr "Desconocido"
#. TRANSLATORS: a package requires the system to be restarted
-#: ../client/pk-console.c:501
-#, fuzzy
+#: ../client/pk-console.c:525
msgid "System restart required by:"
-msgstr "Se requiere reiniciar el sistema"
+msgstr "Se necesita reiniciar el sistema debido a:"
#. TRANSLATORS: a package requires the session to be restarted
-#: ../client/pk-console.c:504
-#, fuzzy
+#: ../client/pk-console.c:528
msgid "Session restart required:"
-msgstr "Se requiere reiniciar el sistema"
+msgstr "Se necesita reiniciar la sesión:"
#. TRANSLATORS: a package requires the application to be restarted
-#: ../client/pk-console.c:507
-#, fuzzy
+#: ../client/pk-console.c:531
msgid "Application restart required by:"
-msgstr "Se requiere reiniciar una aplicación"
+msgstr "Se necesita reiniciar una aplicación debido a:"
-#: ../client/pk-console.c:543
+#. TRANSLATORS: a package needs to restart they system
+#: ../client/pk-console.c:568
msgid "Please restart the computer to complete the update."
msgstr "Por favor, reinicie la computadora para completar la actualización"
-#: ../client/pk-console.c:545
+#. TRANSLATORS: a package needs to restart the session
+#: ../client/pk-console.c:571
msgid "Please logout and login to complete the update."
msgstr "Por favor, salga y vuelva a entrar para completar la actualización."
-#: ../client/pk-console.c:547
+#. TRANSLATORS: a package needs to restart the application
+#: ../client/pk-console.c:574
msgid "Please restart the application as it is being used."
msgstr "Por favor, reinicie la aplicación que está usando."
#. TRANSLATORS: The package is already installed on the system
-#: ../client/pk-console.c:659
+#: ../client/pk-console.c:687
#, c-format
msgid "The package %s is already installed"
msgstr "El paquete %s ya está instalado"
#. TRANSLATORS: The package name was not found in any software sources. The detailed error follows
-#: ../client/pk-console.c:667
+#: ../client/pk-console.c:695
#, c-format
msgid "The package %s could not be installed: %s"
msgstr "El paquete %s no se pudo instalar: %s"
#. TRANSLATORS: There was a programming error that shouldn't happen. The detailed error follows
-#: ../client/pk-console.c:692 ../client/pk-console.c:719
-#: ../client/pk-console.c:815 ../client/pk-console.c:932
-#: ../client/pk-tools-common.c:61 ../client/pk-tools-common.c:79
+#: ../client/pk-console.c:720
+#: ../client/pk-console.c:747
+#: ../client/pk-console.c:843
+#: ../client/pk-console.c:960
+#: ../client/pk-tools-common.c:61
+#: ../client/pk-tools-common.c:79
#: ../client/pk-tools-common.c:86
#, c-format
msgid "Internal error: %s"
msgstr "Error interno: %s"
#. TRANSLATORS: There was an error installing the packages. The detailed error follows
-#: ../client/pk-console.c:700 ../client/pk-console.c:1327
+#: ../client/pk-console.c:728
+#: ../client/pk-console.c:1355
#, c-format
msgid "This tool could not install the packages: %s"
msgstr "Esta herramienta no pudo instalar los paquetes: %s"
#. TRANSLATORS: There was an error installing the files. The detailed error follows
-#: ../client/pk-console.c:727
+#: ../client/pk-console.c:755
#, c-format
msgid "This tool could not install the files: %s"
msgstr "Esta herramienta no pudo instalar los archivos: %s"
#. TRANSLATORS: The package name was not found in the installed list. The detailed error follows
-#: ../client/pk-console.c:783
+#: ../client/pk-console.c:811
#, c-format
msgid "This tool could not remove %s: %s"
msgstr "Esta herramienta no pudo eliminar %s: %s"
#. TRANSLATORS: There was an error removing the packages. The detailed error follows
-#: ../client/pk-console.c:806 ../client/pk-console.c:844
-#: ../client/pk-console.c:877
+#: ../client/pk-console.c:834
+#: ../client/pk-console.c:872
+#: ../client/pk-console.c:905
#, c-format
msgid "This tool could not remove the packages: %s"
msgstr "Esta herramienta no pudo eliminar los paquetes: %s"
#. TRANSLATORS: When removing, we might have to remove other dependencies
-#: ../client/pk-console.c:856
+#: ../client/pk-console.c:884
msgid "The following packages have to be removed:"
msgstr "Los siguientes paquetes se eliminarán:"
#. TRANSLATORS: We are checking if it's okay to remove a list of packages
-#: ../client/pk-console.c:863
+#: ../client/pk-console.c:891
msgid "Proceed removing additional packages?"
msgstr "¿De acuerdo con eliminar los paquetes adicionales?"
#. TRANSLATORS: We did not remove any packages
-#: ../client/pk-console.c:868
+#: ../client/pk-console.c:896
msgid "The package removal was canceled!"
msgstr "¡La eliminación de paquetes fue cancelada!"
#. TRANSLATORS: The package name was not found in any software sources
-#: ../client/pk-console.c:909
+#: ../client/pk-console.c:937
#, c-format
msgid "This tool could not download the package %s as it could not be found"
-msgstr ""
-"Esta herramienta no pudo descargar el paquete %s debido a que no fue "
-"encontrado"
+msgstr "Esta herramienta no pudo descargar el paquete %s debido a que no fue encontrado"
#. TRANSLATORS: Could not download the packages for some reason. The detailed error follows
-#: ../client/pk-console.c:940
+#: ../client/pk-console.c:968
#, c-format
msgid "This tool could not download the packages: %s"
msgstr "Esta herramienta no pudo descargar los paquetes: %s"
#. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:967 ../client/pk-console.c:976
+#: ../client/pk-console.c:995
+#: ../client/pk-console.c:1004
#, c-format
msgid "This tool could not update %s: %s"
msgstr "Esta herramienta no pudo actualizar %s: %s"
#. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:998 ../client/pk-console.c:1006
+#: ../client/pk-console.c:1026
+#: ../client/pk-console.c:1034
#, c-format
msgid "This tool could not get the requirements for %s: %s"
msgstr "Esta herramienta no pudo obtener los requerimientos de %s: %s"
#. TRANSLATORS: There was an error getting the dependencies for the package. The detailed error follows
-#: ../client/pk-console.c:1028 ../client/pk-console.c:1036
+#: ../client/pk-console.c:1056
+#: ../client/pk-console.c:1064
#, c-format
msgid "This tool could not get the dependencies for %s: %s"
msgstr "Esta herramienta no pudo obtener las dependencias de %s: %s"
#. TRANSLATORS: There was an error getting the details about the package. The detailed error follows
-#: ../client/pk-console.c:1058 ../client/pk-console.c:1066
+#: ../client/pk-console.c:1086
+#: ../client/pk-console.c:1094
#, c-format
msgid "This tool could not get package details for %s: %s"
msgstr "Esta herramienta no pudo obtener los detalles del paquete %s: %s"
#. TRANSLATORS: The package name was not found in any software sources. The detailed error follows
-#: ../client/pk-console.c:1088
+#: ../client/pk-console.c:1116
#, c-format
msgid "This tool could not find the files for %s: %s"
msgstr "Esta herramienta no pudo encontrar los archivos de %s: %s"
#. TRANSLATORS: There was an error getting the list of files for the package. The detailed error follows
-#: ../client/pk-console.c:1096
+#: ../client/pk-console.c:1124
#, c-format
msgid "This tool could not get the file list for %s: %s"
msgstr "Esta herramienta no pudo obtener la lista de archivos de %s: %s"
#. TRANSLATORS: There was an error getting the list of packages. The filename follows
-#: ../client/pk-console.c:1118
+#: ../client/pk-console.c:1146
#, c-format
msgid "File already exists: %s"
msgstr "El archivo ya existe: %s"
#. TRANSLATORS: follows a list of packages to install
-#: ../client/pk-console.c:1123 ../client/pk-console.c:1179
-#: ../client/pk-console.c:1254
+#: ../client/pk-console.c:1151
+#: ../client/pk-console.c:1207
+#: ../client/pk-console.c:1282
msgid "Getting package list"
msgstr "Obteniendo la lista de paquetes"
#. TRANSLATORS: There was an error getting the list of packages. The detailed error follows
-#: ../client/pk-console.c:1129 ../client/pk-console.c:1185
-#: ../client/pk-console.c:1260
+#: ../client/pk-console.c:1157
+#: ../client/pk-console.c:1213
+#: ../client/pk-console.c:1288
#, c-format
msgid "This tool could not get package list: %s"
msgstr "Esta herramienta no pudo obtener la lista de paquetes: %s"
#. TRANSLATORS: There was an error saving the list
-#: ../client/pk-console.c:1140
-#, c-format
+#: ../client/pk-console.c:1168
msgid "Failed to save to disk"
msgstr "Falló al guardar en el disco"
#. TRANSLATORS: There was an error getting the list. The filename follows
-#: ../client/pk-console.c:1174 ../client/pk-console.c:1249
+#: ../client/pk-console.c:1202
+#: ../client/pk-console.c:1277
#, c-format
msgid "File does not exist: %s"
msgstr "El archivo no existe: %s"
#. TRANSLATORS: header to a list of packages newly added
-#: ../client/pk-console.c:1206
+#: ../client/pk-console.c:1234
msgid "Packages to add"
msgstr "Paquetes a agregar"
#. TRANSLATORS: header to a list of packages removed
-#: ../client/pk-console.c:1214
+#: ../client/pk-console.c:1242
msgid "Packages to remove"
msgstr "Paquetes a eliminar"
#. TRANSLATORS: We didn't find any differences
-#: ../client/pk-console.c:1282
-#, c-format
+#: ../client/pk-console.c:1310
msgid "No new packages need to be installed"
msgstr "No hay paquetes nuevos para instalar"
#. TRANSLATORS: follows a list of packages to install
-#: ../client/pk-console.c:1288
+#: ../client/pk-console.c:1316
msgid "To install"
msgstr "A instalar"
#. TRANSLATORS: searching takes some time....
-#: ../client/pk-console.c:1299
+#: ../client/pk-console.c:1327
msgid "Searching for package: "
msgstr "Buscando el paquete:"
#. TRANSLATORS: package was not found -- this is the end of a string ended in ...
-#: ../client/pk-console.c:1303
+#: ../client/pk-console.c:1331
msgid "not found."
msgstr "no encontrado."
#. TRANSLATORS: We didn't find any packages to install
-#: ../client/pk-console.c:1314
-#, c-format
+#: ../client/pk-console.c:1342
msgid "No packages can be found to install"
msgstr "No se encontró ningún paquete para instalar"
#. TRANSLATORS: installing new packages from package list
-#: ../client/pk-console.c:1320
+#: ../client/pk-console.c:1348
msgid "Installing packages"
msgstr "Instalando paquetes"
#. TRANSLATORS: The package name was not found in any software sources. The detailed error follows
-#: ../client/pk-console.c:1356
+#: ../client/pk-console.c:1384
#, c-format
msgid "This tool could not find the update details for %s: %s"
-msgstr ""
-"Esta herramienta no pudo encontrar los detalles de actualización de %s: %s"
+msgstr "Esta herramienta no pudo encontrar los detalles de actualización de %s: %s"
#. TRANSLATORS: There was an error getting the details about the update for the package. The detailed error follows
-#: ../client/pk-console.c:1364
+#: ../client/pk-console.c:1392
#, c-format
msgid "This tool could not get the update details for %s: %s"
-msgstr ""
-"Esta herramienta no pudo obtener los detalles de actualización de %s: %s"
+msgstr "Esta herramienta no pudo obtener los detalles de actualización de %s: %s"
#. TRANSLATORS: This was an unhandled error, and we don't have _any_ context
-#: ../client/pk-console.c:1410
+#: ../client/pk-console.c:1438
msgid "Error:"
msgstr "Error:"
#. TRANSLATORS: This a list of details about the package
-#: ../client/pk-console.c:1424
+#: ../client/pk-console.c:1452
msgid "Package description"
msgstr "Descripción del paquete"
#. TRANSLATORS: This a list files contained in the package
-#: ../client/pk-console.c:1458
+#: ../client/pk-console.c:1486
msgid "Package files"
msgstr "Archivos del paquete"
#. TRANSLATORS: This where the package has no files
-#: ../client/pk-console.c:1466
+#: ../client/pk-console.c:1494
msgid "No files"
msgstr "No hay archivos"
#. TRANSLATORS: This a request for a GPG key signature from the backend, which the client will prompt for later
-#: ../client/pk-console.c:1489
+#: ../client/pk-console.c:1517
msgid "Repository signature required"
msgstr "Se requiere la firma del repositorio"
#. TRANSLATORS: This a prompt asking the user to import the security key
-#: ../client/pk-console.c:1499
+#: ../client/pk-console.c:1527
msgid "Do you accept this signature?"
msgstr "¿Acepta esta firma?"
#. TRANSLATORS: This is where the user declined the security key
-#: ../client/pk-console.c:1503
+#: ../client/pk-console.c:1531
msgid "The signature was not accepted."
msgstr "La firma no fue aceptada."
#. TRANSLATORS: This a request for a EULA
-#: ../client/pk-console.c:1537
+#: ../client/pk-console.c:1565
msgid "End user license agreement required"
msgstr "Se requiere un acuerdo de licencia de usuario final"
#. TRANSLATORS: This a prompt asking the user to agree to the license
-#: ../client/pk-console.c:1544
+#: ../client/pk-console.c:1572
msgid "Do you agree to this license?"
msgstr "¿Está de acuerdo con esta licencia?"
#. TRANSLATORS: This is where the user declined the license
-#: ../client/pk-console.c:1548
+#: ../client/pk-console.c:1576
msgid "The license was refused."
msgstr "La licencia fue rechazada."
#. TRANSLATORS: This is when the daemon crashed, and we are up shit creek without a paddle
-#: ../client/pk-console.c:1577
+#: ../client/pk-console.c:1605
msgid "The daemon crashed mid-transaction!"
msgstr "El servicio terminó en medio de una transacción!"
#. TRANSLATORS: This is the header to the --help menu
-#: ../client/pk-console.c:1630
+#: ../client/pk-console.c:1658
msgid "PackageKit Console Interface"
msgstr "Interfaz de Consola de PackageKit"
-#: ../client/pk-console.c:1630
+#. these are commands we can use with pkcon
+#: ../client/pk-console.c:1660
msgid "Subcommands:"
msgstr "Subcomandos:"
-#: ../client/pk-console.c:1719 ../client/pk-generate-pack.c:184
-#: ../client/pk-monitor.c:115
+#. TRANSLATORS: command line argument, if we should show debugging information
+#. TRANSLATORS: if we should show debugging data
+#: ../client/pk-console.c:1752
+#: ../client/pk-generate-pack.c:185
+#: ../client/pk-monitor.c:125
#: ../contrib/command-not-found/pk-command-not-found.c:510
-#: ../src/pk-main.c:192
+#: ../src/pk-main.c:199
msgid "Show extra debugging information"
msgstr "Mostrar información extra de depuración"
-#: ../client/pk-console.c:1721 ../client/pk-monitor.c:117
+#. TRANSLATORS: command line argument, just show the version string
+#: ../client/pk-console.c:1755
+#: ../client/pk-monitor.c:127
msgid "Show the program version and exit"
msgstr "Mostrar la versión del programa y salir"
-#: ../client/pk-console.c:1723
+#. TRANSLATORS: command line argument, use a filter to narrow down results
+#: ../client/pk-console.c:1758
msgid "Set the filter, e.g. installed"
msgstr "Defina el filtro, ej. installado"
-#: ../client/pk-console.c:1725
+#. TRANSLATORS: command line argument, work asynchronously
+#: ../client/pk-console.c:1761
msgid "Exit without waiting for actions to complete"
msgstr "Salir sin esperar que las acciones se completen"
#. TRANSLATORS: This is when we could not connect to the system bus, and is fatal
-#: ../client/pk-console.c:1752
+#: ../client/pk-console.c:1788
msgid "This tool could not connect to system DBUS."
msgstr "Esta herramienta no se pudo conectar al DBUS del sistema."
#. TRANSLATORS: The user specified an incorrect filter
-#: ../client/pk-console.c:1839
+#: ../client/pk-console.c:1875
msgid "The filter specified was invalid"
msgstr "El filtro especificado fue inválido"
-#: ../client/pk-console.c:1856
-msgid "You need to specify a search type, e.g. name"
-msgstr "Debe especificar el tipo de búsqueda, por ejemplo, nombre"
+#. TRANSLATORS: a search type can be name, details, file, etc
+#: ../client/pk-console.c:1893
+msgid "A search type is required, e.g. name"
+msgstr "Se necesita un tipo de búsqueda, por ejemplo, nombre"
-#: ../client/pk-console.c:1861 ../client/pk-console.c:1868
-#: ../client/pk-console.c:1875 ../client/pk-console.c:1882
-#: ../client/pk-console.c:1990 ../client/pk-console.c:2000
-#: ../client/pk-console.c:2007 ../client/pk-console.c:2014
-msgid "You need to specify a search term"
-msgstr "Debe especificar un término de búsqueda"
+#. TRANSLATORS: the user needs to provide a search term
+#: ../client/pk-console.c:1899
+#: ../client/pk-console.c:1907
+#: ../client/pk-console.c:1915
+#: ../client/pk-console.c:1923
+msgid "A search term is required"
+msgstr "Se necesita un término de búsqueda"
-#: ../client/pk-console.c:1887
+#. TRANSLATORS: the search type was provided, but invalid
+#: ../client/pk-console.c:1929
msgid "Invalid search type"
msgstr "Tipo de búsqueda inválido"
-#: ../client/pk-console.c:1892
-msgid "You need to specify a package or file to install"
-msgstr "Debe especificar un paquete o archivo a instalar"
+#. TRANSLATORS: the user did not specify what they wanted to install
+#: ../client/pk-console.c:1935
+msgid "A package name or filename to install is required"
+msgstr "Se requiere un nombre de paquete o nombre de archivo a instalar"
-#: ../client/pk-console.c:1899
-msgid "You need to specify a type, key_id and package_id"
-msgstr "Debe especificar un tipo, key_id y package_id"
+#. TRANSLATORS: geeky error, 99.9999% of users won't see this
+#: ../client/pk-console.c:1943
+msgid "A type, key_id and package_id are required"
+msgstr "Se necesita un tipo, key_id y package_id"
-#: ../client/pk-console.c:1906
-msgid "You need to specify a package to remove"
-msgstr "Debe especificar un paquete a eliminar"
+#. TRANSLATORS: the user did not specify what they wanted to remove
+#: ../client/pk-console.c:1951
+msgid "A package name to remove is required"
+msgstr "Necesita dar un nombre de paquete a eliminar"
-#: ../client/pk-console.c:1912
-msgid ""
-"You need to specify the destination directory and then the packages to "
-"download"
-msgstr ""
-"Debe especificar el directorio destino y luego los paquetes a descargar"
+#. TRANSLATORS: the user did not specify anything about what to download or where
+#: ../client/pk-console.c:1958
+msgid "A destination directory and then the package names to download are required"
+msgstr "Debe especificar el directorio destino y luego los nombres paquetes a descargar"
-#: ../client/pk-console.c:1917
+#. TRANSLATORS: the directory does not exist, so we can't continue
+#: ../client/pk-console.c:1964
msgid "Directory not found"
msgstr "Directorio no encontrado"
-#: ../client/pk-console.c:1923
-msgid "You need to specify a licence identifier (eula-id)"
-msgstr "Debe especificar un identificador de licencia (eula-id)"
-
-#: ../client/pk-console.c:1939
-msgid "You need to specify a package name to resolve"
-msgstr "Debe especificar un nombre de paquete a resolver"
-
-#: ../client/pk-console.c:1946 ../client/pk-console.c:1953
-msgid "You need to specify a repository name"
-msgstr "Debe especificar un nombre de repositorio"
-
-#: ../client/pk-console.c:1960
-msgid "You need to specify a repo name/parameter and value"
-msgstr "Debe especificar un nombre/parametro de repositorio y valor"
-
-#: ../client/pk-console.c:1972
-msgid "You need to specify an action, e.g. 'update-system'"
+#. TRANSLATORS: geeky error, 99.9999% of users won't see this
+#: ../client/pk-console.c:1971
+msgid "A licence identifier (eula-id) is required"
+msgstr "Se necesita un identificador de licencia (eula-id)"
+
+#. TRANSLATORS: geeky error, 99.9999% of users won't see this
+#: ../client/pk-console.c:1980
+msgid "A transaction identifier (tid) is required"
+msgstr "Se necesita un identificador de transacción (tid)"
+
+#. TRANSLATORS: The user did not specify a package name
+#: ../client/pk-console.c:1996
+msgid "A package name to resolve is required"
+msgstr "Se necesita un nombre de paquete a resolver"
+
+#. TRANSLATORS: The user did not specify a repository (software source) name
+#: ../client/pk-console.c:2004
+#: ../client/pk-console.c:2012
+msgid "A repository name is required"
+msgstr "Se necesita un nombre de repositorio"
+
+#. TRANSLATORS: The user didn't provide any data
+#: ../client/pk-console.c:2020
+msgid "A repo name, parameter and value are required"
+msgstr "Debe especificar un nombre de repositorio, parametro y valor"
+
+#. TRANSLATORS: The user didn't specify what action to use
+#: ../client/pk-console.c:2033
+msgid "An action, e.g. 'update-system' is required"
msgstr "Debe especificar una acción, por ejemplo, 'update-system'"
-#: ../client/pk-console.c:1977
-msgid "You need to specify a correct role"
-msgstr "Debe especificar un rol correcto"
-
-#: ../client/pk-console.c:1982
-msgid "Failed to get last time"
-msgstr "Fállo al obtener última hora"
-
-#: ../client/pk-console.c:2021
-msgid "You need to specify a package to find the details for"
-msgstr "Debe especificar un paquete para el que buscar la descripción"
-
-#: ../client/pk-console.c:2028
-msgid "You need to specify a package to find the files for"
-msgstr "Debe especificar un paquete para el que buscar los archivos"
-
-#: ../client/pk-console.c:2035
-msgid "You need to specify a list file to create"
-msgstr "Debe especificar un archivo de lista a crear"
-
-#: ../client/pk-console.c:2043 ../client/pk-console.c:2051
-msgid "You need to specify a list file to open"
-msgstr "Debe especificar un archivo de lista a abrir"
+#. TRANSLATORS: The user specified an invalid action
+#: ../client/pk-console.c:2039
+msgid "A correct role is required"
+msgstr "Se necesita el rol correcto"
+
+#. TRANSLATORS: we keep a database updated with the time that an action was last executed
+#: ../client/pk-console.c:2045
+msgid "Failed to get the time since this action was last completed"
+msgstr "Falló al obtener la hora de la última vez que se completó esta acción"
+
+#. TRANSLATORS: The user did not provide a package name
+#. TRANSLATORS: This is when the user fails to supply the package name
+#: ../client/pk-console.c:2054
+#: ../client/pk-console.c:2065
+#: ../client/pk-console.c:2073
+#: ../client/pk-console.c:2089
+#: ../client/pk-console.c:2097
+#: ../client/pk-generate-pack.c:241
+msgid "A package name is required"
+msgstr "Se necesita un nombre de paquete"
+
+#. TRANSLATORS: each package "provides" certain things, e.g. mime(gstreamer-decoder-mp3), the user didn't specify it
+#: ../client/pk-console.c:2081
+msgid "A package provide string is required"
+msgstr "Se necesita la cadena de lo que provee el paquete"
+
+#. TRANSLATORS: The user didn't specify a filename to create as a list
+#: ../client/pk-console.c:2105
+msgid "A list file name to create is required"
+msgstr "Se necesita un nombre de archivo de la lista"
+
+#. TRANSLATORS: The user didn't specify a filename to open as a list
+#: ../client/pk-console.c:2114
+#: ../client/pk-console.c:2123
+msgid "A list file to open is required"
+msgstr "Se necesita un archivo de lista a abrir"
#. TRANSLATORS: The user tried to use an unsupported option on the command line
-#: ../client/pk-console.c:2104
+#: ../client/pk-console.c:2176
#, c-format
msgid "Option '%s' is not supported"
msgstr "La opción '%s' no está soportada"
#. TRANSLATORS: User does not have permission to do this
-#: ../client/pk-console.c:2117
-msgid "You don't have the necessary privileges for this operation"
-msgstr "No tiene los privilegios necesarios para esta operación"
+#: ../client/pk-console.c:2189
+msgid "Incorrect privileges for this operation"
+msgstr "Privilegios incorrectos para esta operación"
#. TRANSLATORS: Generic failure of what they asked to do
-#: ../client/pk-console.c:2120
+#: ../client/pk-console.c:2192
msgid "Command failed"
msgstr "Commando falló"
#. TRANSLATORS: This is the state of the transaction
-#: ../client/pk-generate-pack.c:100
+#: ../client/pk-generate-pack.c:101
msgid "Downloading"
msgstr "Descargando"
#. TRANSLATORS: This is when the main packages are being downloaded
-#: ../client/pk-generate-pack.c:120
+#: ../client/pk-generate-pack.c:121
msgid "Downloading packages"
msgstr "Descargando paquetes"
#. TRANSLATORS: This is when the dependency packages are being downloaded
-#: ../client/pk-generate-pack.c:125
+#: ../client/pk-generate-pack.c:126
msgid "Downloading dependencies"
msgstr "Descargando dependencias"
-#: ../client/pk-generate-pack.c:186
+#. TRANSLATORS: we can exclude certain packages (glibc) when we know they'll exist on the target
+#: ../client/pk-generate-pack.c:188
msgid "Set the file name of dependencies to be excluded"
msgstr "Ponga el nombre del archivo de dependencias a excluir"
-#: ../client/pk-generate-pack.c:188
-msgid "The output directory (the current directory is used if ommitted)"
-msgstr "El directorio de salida (el directorio actual se usará si se omite)"
+#. TRANSLATORS: the output location
+#: ../client/pk-generate-pack.c:191
+msgid "The output file or directory (the current directory is used if ommitted)"
+msgstr "El directorio o archivo de salida (el directorio actual se usará si se omite)"
-#: ../client/pk-generate-pack.c:190
+#. TRANSLATORS: put a list of packages in the pack
+#: ../client/pk-generate-pack.c:194
msgid "The package to be put into the service pack"
msgstr "El paquete será puesto en el paquete de servicio"
-#: ../client/pk-generate-pack.c:192
+#. TRANSLATORS: put all pending updates in the pack
+#: ../client/pk-generate-pack.c:197
msgid "Put all updates available in the service pack"
msgstr "Poner todas las actualizaciones disponibles en el paquete de servicio"
#. TRANSLATORS: This is when the user fails to supply the correct arguments
-#: ../client/pk-generate-pack.c:220
+#: ../client/pk-generate-pack.c:225
msgid "Neither --package or --updates option selected."
msgstr "No se seleccionó ni la opción --package o --updates."
#. TRANSLATORS: This is when the user fails to supply just one argument
-#: ../client/pk-generate-pack.c:228
+#: ../client/pk-generate-pack.c:233
msgid "Both options selected."
msgstr "Se seleccionaron ambas opciones."
+#. TRANSLATORS: This is when the user fails to supply the output
+#: ../client/pk-generate-pack.c:249
+msgid "A output directory or file name is required"
+msgstr "Se necesita un directorio o nombre de archivo de salida"
+
+#. TRANSLATORS: This is when the backend doesn't have the capability to get-depends
+#. TRANSLATORS: This is when the backend doesn't have the capability to download
+#: ../client/pk-generate-pack.c:267
+#: ../client/pk-generate-pack.c:273
+msgid "The package manager cannot perform this type of operation."
+msgstr "El administrador de paquetes no puede realizar este tipo de operación."
+
+#. TRANSLATORS: the user specified an absolute path, but didn't get the extension correct
+#: ../client/pk-generate-pack.c:285
+msgid "If specifying a file, the service pack name must end with"
+msgstr "Si especifica un archivo, el nombre del paquete de servicio debe finalizar con"
+
#. TRANSLATORS: This is when file already exists
-#: ../client/pk-generate-pack.c:261
+#: ../client/pk-generate-pack.c:301
msgid "A pack with the same name already exists, do you want to overwrite it?"
msgstr "Ya existe un paquete con ese nombre, ¿desea sobreescribirlo ?"
#. TRANSLATORS: This is when the pack was not overwritten
-#: ../client/pk-generate-pack.c:264
+#: ../client/pk-generate-pack.c:304
msgid "The pack was not overwritten."
msgstr "El paquete no fue sobrescrito."
#. TRANSLATORS: This is when the temporary directory cannot be created, the directory name follows
-#: ../client/pk-generate-pack.c:276
+#: ../client/pk-generate-pack.c:317
msgid "Failed to create directory:"
msgstr "No se pudo crear el directorio:"
#. TRANSLATORS: This is when the list of packages from the remote computer cannot be opened
-#: ../client/pk-generate-pack.c:285
+#: ../client/pk-generate-pack.c:327
msgid "Failed to open package list."
msgstr "Falló al abrir la lista de paquetes."
#. TRANSLATORS: The package name is being matched up to available packages
-#: ../client/pk-generate-pack.c:295
+#: ../client/pk-generate-pack.c:338
msgid "Finding package name."
msgstr "Buscando el nombre de paquete."
#. TRANSLATORS: This is when the package cannot be found in any software source. The detailed error follows
-#: ../client/pk-generate-pack.c:299
+#: ../client/pk-generate-pack.c:342
#, c-format
msgid "Failed to find package '%s': %s"
msgstr "Falló al buscar el paquete '%s': %s"
#. TRANSLATORS: This is telling the user we are in the process of making the pack
-#: ../client/pk-generate-pack.c:315
+#: ../client/pk-generate-pack.c:359
msgid "Creating service pack..."
msgstr "Creando el paquete de servicios..."
#. TRANSLATORS: we succeeded in making the file
-#: ../client/pk-generate-pack.c:322
+#: ../client/pk-generate-pack.c:366
#, c-format
msgid "Service pack created '%s'"
msgstr "El paqute de servicio '%s' fue creado"
#. TRANSLATORS: we failed to make te file
-#: ../client/pk-generate-pack.c:326
+#: ../client/pk-generate-pack.c:371
#, c-format
msgid "Failed to create '%s': %s"
msgstr "Falló al crear '%s': %s"
-#: ../client/pk-monitor.c:132
+#. TRANSLATORS: this is a program that monitors PackageKit
+#: ../client/pk-monitor.c:143
msgid "PackageKit Monitor"
msgstr "Monitor de PackageKit"
#. TRANSLATORS: The package was not found in any software sources
#: ../client/pk-tools-common.c:114
-#, c-format
msgid "The package could not be found"
msgstr "No se pudo encontrar el paquete"
@@ -724,80 +798,72 @@ msgstr "Por favor ingrese un número de 1 a %i:"
#. TRANSLATORS: we failed to find the package, this shouldn't happen
#: ../contrib/command-not-found/pk-command-not-found.c:361
-#, fuzzy
msgid "Failed to search for file"
-msgstr "Falló al guardar en el disco"
+msgstr "Falló al buscar el archivo"
#. TRANSLATORS: we failed to launch the executable, the error follows
#: ../contrib/command-not-found/pk-command-not-found.c:485
-#, fuzzy
msgid "Failed to launch:"
-msgstr "Fállo al obtener última hora"
+msgstr "Fállo al iniciar:"
#. TRANSLATORS: tool that gets called when the command is not found
#: ../contrib/command-not-found/pk-command-not-found.c:526
-#, fuzzy
msgid "PackageKit Command Not Found"
-msgstr "Monitor de PackageKit"
+msgstr "Comando PackageKit no encontrado"
#. TRANSLATORS: the prefix of all the output telling the user why it's not executing
#: ../contrib/command-not-found/pk-command-not-found.c:548
-#, fuzzy
msgid "Command not found."
-msgstr "no encontrado."
+msgstr "Comando no encontrado."
#. TRANSLATORS: tell the user what we think the command is
#: ../contrib/command-not-found/pk-command-not-found.c:555
-#, fuzzy
msgid "Similar command is:"
-msgstr "Subcomandos:"
+msgstr "Un comando similar es:"
#. TRANSLATORS: Ask the user if we should run the similar command
#: ../contrib/command-not-found/pk-command-not-found.c:564
msgid "Run similar command:"
-msgstr ""
+msgstr "Ejecutar un comando similar:"
#. TRANSLATORS: show the user a list of commands that they could have meant
#. TRANSLATORS: show the user a list of commands we could run
#: ../contrib/command-not-found/pk-command-not-found.c:576
#: ../contrib/command-not-found/pk-command-not-found.c:585
-#, fuzzy
msgid "Similar commands are:"
-msgstr "Subcomandos:"
+msgstr "Los comandos similares son:"
#. TRANSLATORS: ask the user to choose a file to run
#: ../contrib/command-not-found/pk-command-not-found.c:592
msgid "Please choose a command to run"
-msgstr ""
+msgstr "Por favor, elija un comando a ejecutar"
#. TRANSLATORS: tell the user what package provides the command
#: ../contrib/command-not-found/pk-command-not-found.c:607
-#, fuzzy
msgid "The package providing this file is:"
-msgstr "El paquete %s ya está instalado"
+msgstr "El paquete que provee este archivo es:"
#. TRANSLATORS: as the user if we want to install a package to provide the command
#: ../contrib/command-not-found/pk-command-not-found.c:612
#, c-format
msgid "Install package '%s' to provide command '%s'?"
-msgstr ""
+msgstr "Instalar el paquete '%s' para proveer el comando '%s'?"
#. TRANSLATORS: Show the user a list of packages that provide this command
#: ../contrib/command-not-found/pk-command-not-found.c:633
msgid "Packages providing this file are:"
-msgstr ""
+msgstr "Los paquetes que proveen este archivo son:"
#. TRANSLATORS: Show the user a list of packages that they can install to provide this command
#: ../contrib/command-not-found/pk-command-not-found.c:642
msgid "Suitable packages are:"
-msgstr ""
+msgstr "Los paquetes posibles son:"
#. get selection
#. TRANSLATORS: ask the user to choose a file to install
#: ../contrib/command-not-found/pk-command-not-found.c:650
-#, fuzzy
msgid "Please choose a package to install"
-msgstr "No se pudo encontrar un paquete para instalar"
+msgstr "Por favor, elija un paquete a instalar"
#. TRANSLATORS: when we are getting data from the daemon
#: ../contrib/browser-plugin/src/contents.cpp:298
@@ -821,6 +887,7 @@ msgstr "Versión instalada"
msgid "Run version %s now"
msgstr "Correr la versión %s ahora"
+#. TRANSLATORS: run the application now
#: ../contrib/browser-plugin/src/contents.cpp:324
msgid "Run now"
msgstr "Correr ahora"
@@ -864,307 +931,260 @@ msgstr "Lista de Paquetes de PackageKit"
msgid "PackageKit Service Pack"
msgstr "Grupo de Servicio de PackageKit"
-#: ../policy/org.freedesktop.packagekit.policy.in.h:1
-msgid "Accept EULA"
-msgstr "Aceptar EULA"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:2
-msgid "Authentication is required to accept a EULA"
-msgstr "Se requiere autenticación para aceptar una EULA"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:3
-#, fuzzy
-msgid ""
-"Authentication is required to cancel a task that was not started by yourself"
-msgstr ""
-"Se requiere autenticación para cambiar los parametros de fuente de software"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:4
-msgid "Authentication is required to change software source parameters"
-msgstr ""
-"Se requiere autenticación para cambiar los parametros de fuente de software"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:5
-#, fuzzy
-msgid ""
-"Authentication is required to consider a key used for signing packages as "
-"trusted"
-msgstr "Se requiere autenticación para refrescar la lista de paquetes"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:6
-#, fuzzy
-msgid "Authentication is required to install a signed package"
-msgstr "Se requiere autenticación para instalar un paquete"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:7
-#, fuzzy
-msgid "Authentication is required to install an untrusted package"
-msgstr "Se requiere autenticación para instalar un paquete"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:8
-#, fuzzy
-msgid "Authentication is required to refresh the system sources"
-msgstr "Se requiere autenticación para refrescar la lista de paquetes"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:9
-msgid "Authentication is required to remove packages"
-msgstr "Se requiere autenticación para eliminar paquetes"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:10
-msgid "Authentication is required to rollback a transaction"
-msgstr "Se requiere autenticación para deshacer una transaccion"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:11
-#, fuzzy
-msgid ""
-"Authentication is required to set the network proxy used for downloading "
-"packages"
-msgstr "Se requiere autenticación para eliminar paquetes"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:12
-msgid "Authentication is required to update packages"
-msgstr "Se requiere autenticación para actualizar paquetes"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:13
-msgid "Cancel foreign task"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:14
-msgid "Change software source parameters"
-msgstr "Cambiar los parametros de fuente de software"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:15
-#, fuzzy
-msgid "Install signed package"
-msgstr "Instalando paquetes"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:16
-#, fuzzy
-msgid "Install untrusted local file"
-msgstr "Instalar archivo local"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:17
-msgid "Refresh system sources"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:18
-msgid "Remove package"
-msgstr "Eliminar paquete"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:19
-msgid "Rollback to a previous transaction"
-msgstr "Deshacer hasta una transaccion previa"
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:20
-msgid "Set network proxy"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:21
-msgid "Trust a key used for signing packages"
-msgstr ""
-
-#: ../policy/org.freedesktop.packagekit.policy.in.h:22
-#, fuzzy
-msgid "Update packages"
-msgstr "Actualizar paquete"
-
-#: ../src/pk-main.c:86
+#. TRANSLATORS: failed due to DBus security
+#: ../src/pk-main.c:87
msgid "Startup failed due to security policies on this machine."
msgstr "El arranque falló debito a polÃticas de seguridad en esta máquina."
-#: ../src/pk-main.c:87
+#. TRANSLATORS: only two ways this can fail...
+#: ../src/pk-main.c:89
msgid "This can happen for two reasons:"
msgstr "Esto puede pasar por dos razones:"
-#: ../src/pk-main.c:88
+#. TRANSLATORS: only allowed to be owned by root
+#: ../src/pk-main.c:91
msgid "The correct user is not launching the executable (usually root)"
msgstr "El usuario correcto no esta lanzando el ejecutable (usualmente root)"
-#: ../src/pk-main.c:89
-msgid ""
-"The org.freedesktop.PackageKit.conf file is not installed in the system "
-"directory:"
-msgstr ""
-"El archivo org.freedesktop.PackageKit.conf no está instalado en el "
-"directorio del sistema:"
+#. TRANSLATORS: or we are installed in a prefix
+#: ../src/pk-main.c:93
+msgid "The org.freedesktop.PackageKit.conf file is not installed in the system directory:"
+msgstr "El archivo org.freedesktop.PackageKit.conf no está instalado en el directorio del sistema:"
-#: ../src/pk-main.c:188
+#. TRANSLATORS: a backend is the system package tool, e.g. yum, apt
+#: ../src/pk-main.c:193
msgid "Packaging backend to use, e.g. dummy"
msgstr "Administrador de paquetes a usar, ej. dummy"
-#: ../src/pk-main.c:190
+#. TRANSLATORS: if we should run in the background
+#: ../src/pk-main.c:196
msgid "Daemonize and detach from the terminal"
msgstr "Demonizar y desadjuntar de la terminal"
-#: ../src/pk-main.c:194
+#. TRANSLATORS: if we should not monitor how long we are inactive for
+#: ../src/pk-main.c:202
msgid "Disable the idle timer"
msgstr "Deshabilitar el idle timer"
-#: ../src/pk-main.c:196
+#. TRANSLATORS: show version
+#: ../src/pk-main.c:205
msgid "Show version and exit"
msgstr "Mostrar version y salir"
-#: ../src/pk-main.c:198
+#. TRANSLATORS: exit after we've started up, used for user profiling
+#: ../src/pk-main.c:208
msgid "Exit after a small delay"
msgstr "Salir luego de una pequeña pausa"
-#: ../src/pk-main.c:200
+#. TRANSLATORS: exit straight away, used for automatic profiling
+#: ../src/pk-main.c:211
msgid "Exit after the engine has loaded"
msgstr "Salir luego de que el motor este cargado"
-#: ../src/pk-main.c:214
+#. TRANSLATORS: describing the service that is running
+#: ../src/pk-main.c:226
msgid "PackageKit service"
msgstr "Servicio PackageKit"
-#: ../src/pk-main.c:250
+#. TRANSLATORS: fatal error, dbus is not running
+#: ../src/pk-main.c:263
msgid "Cannot connect to the system bus"
msgstr "No se pudo conectar al bus del sistema"
-#: ../src/pk-main.c:299
+#. TRANSLATORS: cannot register on system bus, unknown reason
+#: ../src/pk-main.c:313
#, c-format
msgid "Error trying to start: %s\n"
msgstr "Error intentando arrancar: %s\n"
+#~ msgid "You need to specify a search type, e.g. name"
+#~ msgstr "Debe especificar el tipo de búsqueda, por ejemplo, nombre"
+#~ msgid "You need to specify a search term"
+#~ msgstr "Debe especificar un término de búsqueda"
+#~ msgid "You need to specify a package or file to install"
+#~ msgstr "Debe especificar un paquete o archivo a instalar"
+#~ msgid "You need to specify a package to remove"
+#~ msgstr "Debe especificar un paquete a eliminar"
+#~ msgid "You need to specify a package name to resolve"
+#~ msgstr "Debe especificar un nombre de paquete a resolver"
+#~ msgid "You need to specify a repository name"
+#~ msgstr "Debe especificar un nombre de repositorio"
+#~ msgid "You need to specify a correct role"
+#~ msgstr "Debe especificar un rol correcto"
+#~ msgid "Failed to get last time"
+#~ msgstr "Fállo al obtener última hora"
+#~ msgid "You need to specify a package to find the details for"
+#~ msgstr "Debe especificar un paquete para el que buscar la descripción"
+#~ msgid "You need to specify a package to find the files for"
+#~ msgstr "Debe especificar un paquete para el que buscar los archivos"
+#~ msgid "You need to specify a list file to create"
+#~ msgstr "Debe especificar un archivo de lista a crear"
+#~ msgid "You need to specify a list file to open"
+#~ msgstr "Debe especificar un archivo de lista a abrir"
+#~ msgid "Accept EULA"
+#~ msgstr "Aceptar EULA"
+#~ msgid "Authentication is required to accept a EULA"
+#~ msgstr "Se requiere autenticación para aceptar una EULA"
+
+#, fuzzy
+#~ msgid ""
+#~ "Authentication is required to cancel a task that was not started by "
+#~ "yourself"
+#~ msgstr ""
+#~ "Se requiere autenticación para cambiar los parametros de fuente de "
+#~ "software"
+#~ msgid "Authentication is required to change software source parameters"
+#~ msgstr ""
+#~ "Se requiere autenticación para cambiar los parametros de fuente de "
+#~ "software"
+
+#, fuzzy
+#~ msgid ""
+#~ "Authentication is required to consider a key used for signing packages as "
+#~ "trusted"
+#~ msgstr "Se requiere autenticación para refrescar la lista de paquetes"
+
+#, fuzzy
+#~ msgid "Authentication is required to install a signed package"
+#~ msgstr "Se requiere autenticación para instalar un paquete"
+
+#, fuzzy
+#~ msgid "Authentication is required to install an untrusted package"
+#~ msgstr "Se requiere autenticación para instalar un paquete"
+
+#, fuzzy
+#~ msgid "Authentication is required to refresh the system sources"
+#~ msgstr "Se requiere autenticación para refrescar la lista de paquetes"
+#~ msgid "Authentication is required to remove packages"
+#~ msgstr "Se requiere autenticación para eliminar paquetes"
+#~ msgid "Authentication is required to rollback a transaction"
+#~ msgstr "Se requiere autenticación para deshacer una transaccion"
+
+#, fuzzy
+#~ msgid ""
+#~ "Authentication is required to set the network proxy used for downloading "
+#~ "packages"
+#~ msgstr "Se requiere autenticación para eliminar paquetes"
+#~ msgid "Authentication is required to update packages"
+#~ msgstr "Se requiere autenticación para actualizar paquetes"
+#~ msgid "Change software source parameters"
+#~ msgstr "Cambiar los parametros de fuente de software"
+
+#, fuzzy
+#~ msgid "Install signed package"
+#~ msgstr "Instalando paquetes"
+
+#, fuzzy
+#~ msgid "Install untrusted local file"
+#~ msgstr "Instalar archivo local"
+#~ msgid "Remove package"
+#~ msgstr "Eliminar paquete"
+#~ msgid "Rollback to a previous transaction"
+#~ msgstr "Deshacer hasta una transaccion previa"
+
+#, fuzzy
+#~ msgid "Update packages"
+#~ msgstr "Actualizar paquete"
#~ msgid "This tool could not remove the packages: '%s'"
#~ msgstr "Esta herramienta no pudo eliminar los paquetes: '%s'"
-
#~ msgid "Install local file"
#~ msgstr "Instalar archivo local"
-
#~ msgid "Okay to import key?"
#~ msgstr "¿De acuerto con importer la clave?"
-
#~ msgid "Did not import key"
#~ msgstr "No se importó la clave"
-
#~ msgid "Do you agree?"
#~ msgstr "¿Está de acuerdo?"
-
-#~ msgid "A logout and login is required"
-#~ msgstr "Se requiere reiniciar la sesión"
-
#~ msgid "Could not find package to remove"
#~ msgstr "No se pudo encontrar el paquete a eliminar"
-
#~ msgid "Cancelled!"
#~ msgstr "Cancelado!"
-
#~ msgid "Could not find package to update"
#~ msgstr "No se pudo encontrar el paquete a actualizar"
-
#~ msgid "Could not find what packages require"
#~ msgstr "No se pudo encontrar cuales paquetes requiere este paquete"
-
#~ msgid "Could not find details for"
#~ msgstr "No se pudieron obtener los detalles de "
-
#~ msgid "Could not find a package match"
#~ msgstr "No se pudo encontrar un paquete coincidente"
#, fuzzy
-#~ msgid "Resolving package name to remote object"
-#~ msgstr "Los siguientes paquetes deben ser removidos"
-
-#, fuzzy
#~ msgid "Could not set database readonly"
#~ msgstr "No se pudo abrir la base de datos: %s"
-
#~ msgid "Could not open database: %s"
#~ msgstr "No se pudo abrir la base de datos: %s"
-
#~ msgid "You probably need to run this program as the root user"
#~ msgstr "Probablemente necesita ejecutar este programa como el usuario root"
-
#~ msgid "<span color='#%06x' underline='single' size='larger'>Run %s</span>"
#~ msgstr ""
#~ "<span color='#%06x' underline='single' size='larger'>Ejecutar %s</span>"
-
#~ msgid "<big>%s</big>"
#~ msgstr "<big>%s</big>"
-
#~ msgid ""
#~ "\n"
#~ "<span color='#%06x' underline='single'>Run version %s now</span>"
#~ msgstr ""
#~ "\n"
#~ "<span color='#%06x' underline='single'>Ejecutar versión %s ahora</span>"
-
#~ msgid ""
#~ "\n"
#~ "<span color='#%06x' underline='single'>Run now</span>"
#~ msgstr ""
#~ "\n"
#~ "<span color='#%06x' underline='single'>Ejecutar ahora</span>"
-
#~ msgid ""
#~ "\n"
#~ "<span color='#%06x' underline='single'>Upgrade to version %s</span>"
#~ msgstr ""
#~ "\n"
#~ "<span color='#%06x' underline='single'>Actualizar a la versión %s</span>"
-
#~ msgid ""
#~ "<span color='#%06x' underline='single' size='larger'>Install %s Now</span>"
#~ msgstr ""
#~ "<span color='#%06x' underline='single' size='larger'>Instalar %s Ahora</"
#~ "span>"
-
#~ msgid ""
#~ "\n"
#~ "<small>Version: %s</small>"
#~ msgstr ""
#~ "\n"
#~ "<small>Versión: %s</small>"
-
#~ msgid "failed to download: invalid package_id and/or directory"
#~ msgstr "falló la descarga: id de paquete inválido y/o directorio"
-
#~ msgid "Could not find a valid metadata file"
#~ msgstr "No se pudo encontrar un archivo de metadatos válido"
-
#~ msgid "Okay to download the additional packages"
#~ msgstr "Listo para descargar los paquetes adicionales"
-
#~ msgid "You need to specify the pack name and packages to be packed\n"
#~ msgstr "Debe especificar el nombre de grupo y los paquetes a agrupar\n"
-
#~ msgid ""
#~ "Invalid name for the service pack, Specify a name with .servicepack "
#~ "extension\n"
#~ msgstr ""
#~ "Nombre inválido para el paquete de servicio. Especifique un nombre con la "
#~ "extensión .servicepack\n"
-
#~ msgid "Authentication is required to install a local file"
#~ msgstr "Se requiere autenticación para instalar un archivo local"
-
#~ msgid "Authentication is required to install a security signature"
#~ msgstr "Se requiere autenticación para instalar una firma de seguridad"
-
#~ msgid "Authentication is required to update all packages"
#~ msgstr "Se requiere autenticación para actualizar todos los paquetes"
-
#~ msgid "Install security signature"
#~ msgstr "Instalar firma de seguridad"
-
#~ msgid "Refresh package lists"
#~ msgstr "Refrescar lista de paquetes"
-
#~ msgid "Update all packages"
#~ msgstr "Actualizar todos los paquetes"
-
#~ msgid ""
#~ "Could not find a package with that name to install, or package already "
#~ "installed"
#~ msgstr ""
#~ "No se pudo encontrar un paquete con ese nombre para instalar, o el "
#~ "paquete ya está instalado"
-
#~ msgid "Could not find a package with that name to update"
#~ msgstr "No se pudo encontrar un paquete con ese nombre para actualizar"
-
#~ msgid "Could not find a description for this package"
#~ msgstr "No se pudo encontrar una descripcion para este paquete"
-
#~ msgid "You need to specify a package to find the description for"
#~ msgstr "Debe especificar un paquete para el que buscar la descripción"
+
commit fa6527d04e76c5cc116aa3fadb68aa8e8a0f0cbb
Author: Richard Hughes <richard at hughsie.com>
Date: Fri Feb 20 15:21:02 2009 +0000
trivial: fix a build issue with the documentation
diff --git a/docs/api/spec/pk-introduction.xml b/docs/api/spec/pk-introduction.xml
index 7696c54..d67838e 100644
--- a/docs/api/spec/pk-introduction.xml
+++ b/docs/api/spec/pk-introduction.xml
@@ -76,7 +76,7 @@
daemon debugging output can be observed.
</para>
</sect2>
- <sect2 id="config-main-timeout">
+ <sect2 id="config-main-shutdown-timeout">
<title>ShutdownTimeout</title>
<para>
This is the time that the daemon waits when idle before shutting down.
@@ -86,13 +86,13 @@
although the daemon will start and stop less often.
</para>
</sect2>
- <sect2 id="config-main-timeout">
+ <sect2 id="config-main-use-syslog">
<title>UseSyslog</title>
<para>
Syslog is used to audit and log actions wherever its available.
</para>
</sect2>
- <sect2 id="config-main-default">
+ <sect2 id="config-main-default-backend">
<title>DefaultBackend</title>
<para>
The default backend that the daemon should use.
commit bf1b34e6dd9ebaf2d5c0892c54212fb134ab905b
Author: Richard Hughes <richard at hughsie.com>
Date: Fri Feb 20 15:04:46 2009 +0000
bugfix: don't use an local error in pkcon list-install else we'll fail to free it, and it's non-fatal
diff --git a/client/pk-console.c b/client/pk-console.c
index 8346b4b..bd10a13 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -1316,8 +1316,9 @@ pk_console_list_install (PkClient *client, const gchar *file, GError **error)
g_print ("%s:\n", _("To install"));
for (i=0; i<length; i++) {
obj = pk_package_list_get_obj (new, i);
- g_print ("%i\t%s\n", i+1, obj->id->name);
+ g_print ("%s ", obj->id->name);
}
+ g_print ("\n");
/* resolve */
filters = pk_bitfield_from_enums (PK_FILTER_ENUM_NOT_INSTALLED, PK_FILTER_ENUM_NEWEST, -1);
@@ -1325,12 +1326,12 @@ pk_console_list_install (PkClient *client, const gchar *file, GError **error)
obj = pk_package_list_get_obj (new, i);
/* TRANSLATORS: searching takes some time.... */
g_print ("%.0f%%\t%s %s...", (100.0f/length)*i, _("Searching for package: "), obj->id->name);
- package_id = pk_console_perhaps_resolve (client, filters, obj->id->name, &error_local);
+ package_id = pk_console_perhaps_resolve (client, filters, obj->id->name, NULL);
if (package_id == NULL) {
/* TRANSLATORS: package was not found -- this is the end of a string ended in ... */
g_print (" %s\n", _("not found."));
} else {
- g_print (" %s\n", package_id);
+ g_print (" %s\n", obj->id->version);
g_ptr_array_add (array, package_id);
/* no need to free */
}
commit 1d7eaa073d883a093423b7131cfd9dad948a9f85
Author: Richard Hughes <richard at hughsie.com>
Date: Fri Feb 20 15:03:12 2009 +0000
bugfix: don't dereference a NULL pointer in pk_console_resolve() which can be done using pkcon list-install
diff --git a/client/pk-tools-common.c b/client/pk-tools-common.c
index dc7d33f..ebd8f9d 100644
--- a/client/pk-tools-common.c
+++ b/client/pk-tools-common.c
@@ -58,7 +58,8 @@ pk_console_resolve (PkBitfield filter, const gchar *package, GError **error)
ret = pk_client_resolve (client, filter, packages, &error_local);
g_strfreev (packages);
if (!ret) {
- *error = g_error_new (1, 0, _("Internal error: %s"), error_local->message);
+ if (error != NULL)
+ *error = g_error_new (1, 0, _("Internal error: %s"), error_local->message);
g_error_free (error_local);
goto out;
}
@@ -76,14 +77,16 @@ pk_console_resolve (PkBitfield filter, const gchar *package, GError **error)
/* reset */
ret = pk_client_reset (client, &error_local);
if (!ret) {
- *error = g_error_new (1, 0, _("Internal error: %s"), error_local->message);
+ if (error != NULL)
+ *error = g_error_new (1, 0, _("Internal error: %s"), error_local->message);
g_error_free (error_local);
goto out;
}
/* anything provide it? */
ret = pk_client_what_provides (client, filter, PK_PROVIDES_ENUM_ANY, package, &error_local);
if (!ret) {
- *error = g_error_new (1, 0, _("Internal error: %s"), error_local->message);
+ if (error != NULL)
+ *error = g_error_new (1, 0, _("Internal error: %s"), error_local->message);
g_error_free (error_local);
goto out;
}
@@ -110,8 +113,10 @@ pk_console_resolve_package_id (const PkPackageList *list, GError **error)
length = pk_package_list_get_size (list);
if (length == 0) {
- /* TRANSLATORS: The package was not found in any software sources */
- *error = g_error_new (1, 0, _("The package could not be found"));
+ if (error != NULL) {
+ /* TRANSLATORS: The package was not found in any software sources */
+ *error = g_error_new (1, 0, _("The package could not be found"));
+ }
return NULL;
}
commit 1b7e562c5548e9c930cad28a9014d228a7894b55
Author: Richard Hughes <richard at hughsie.com>
Date: Fri Feb 20 15:01:21 2009 +0000
trivial: more app-install playing
diff --git a/contrib/app-install/.gitignore b/contrib/app-install/.gitignore
index c651369..b4df60c 100644
--- a/contrib/app-install/.gitignore
+++ b/contrib/app-install/.gitignore
@@ -1,6 +1,7 @@
.deps
.libs
*.o
-pk-app-install
+pk-app-install-create
+pk-app-install-remove
*.db
diff --git a/contrib/app-install/Makefile.am b/contrib/app-install/Makefile.am
index 8b39051..c76b7d5 100644
--- a/contrib/app-install/Makefile.am
+++ b/contrib/app-install/Makefile.am
@@ -13,20 +13,23 @@ INCLUDES = \
-DEGG_CONSOLE="\"PK_CONSOLE\"" \
-I$(top_srcdir)/lib
-sbin_PROGRAMS = pk-app-install
+sbin_PROGRAMS = pk-app-install-create pk-app-install-remove
-pk_app_install_SOURCES = \
+pk_app_install_create_SOURCES = \
egg-debug.c \
egg-debug.h \
- pk-app-install.c \
+ pk-app-install-create.c \
+ pk-app-install-common.h \
$(NULL)
+pk_app_install_create_LDADD = $(GLIB_LIBS) $(SQLITE_LIBS)
+pk_app_install_create_CFLAGS = $(WARNINGFLAGS_C)
-pk_app_install_LDADD = \
- $(GLIB_LIBS) \
- $(SQLITE_LIBS) \
- $(NULL)
-
-pk_app_install_CFLAGS = \
- $(WARNINGFLAGS_C) \
+pk_app_install_remove_SOURCES = \
+ egg-debug.c \
+ egg-debug.h \
+ pk-app-install-remove.c \
+ pk-app-install-common.h \
$(NULL)
+pk_app_install_remove_LDADD = $(GLIB_LIBS) $(SQLITE_LIBS)
+pk_app_install_remove_CFLAGS = $(WARNINGFLAGS_C)
diff --git a/contrib/app-install/pk-app-install-add.c b/contrib/app-install/pk-app-install-add.c
new file mode 100644
index 0000000..357ab74
--- /dev/null
+++ b/contrib/app-install/pk-app-install-add.c
@@ -0,0 +1,345 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <sqlite3.h>
+
+#include "egg-debug.h"
+
+#if PK_BUILD_LOCAL
+#define PK_APP_INSTALL_DEFAULT_DATABASE "./desktop.db"
+#else
+#define PK_APP_INSTALL_DEFAULT_DATABASE DATADIR "/app-install/cache/desktop.db"
+#endif
+
+/**
+ * pk_app_install_create:
+ **/
+static gboolean
+pk_app_install_create (const gchar *cache)
+{
+ gboolean ret = TRUE;
+ gboolean create_file;
+ const gchar *statement;
+ sqlite3 *db = NULL;
+ gint rc;
+
+ /* if the database file was not installed (or was nuked) recreate it */
+ create_file = g_file_test (cache, G_FILE_TEST_EXISTS);
+ if (create_file == TRUE) {
+ egg_warning ("already exists");
+ goto out;
+ }
+
+ egg_debug ("exists: %i", create_file);
+
+ /* open database */
+ rc = sqlite3_open (cache, &db);
+ if (rc) {
+ egg_warning ("Can't open database: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+
+ /* don't sync */
+ statement = "PRAGMA synchronous=OFF";
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't turn off sync: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+
+ egg_debug ("create");
+ if (create_file == FALSE) {
+ statement = "CREATE TABLE general ("
+ "application_id TEXT primary key,"
+ "package_name TEXT,"
+ "group_id TEXT,"
+ "repo_name TEXT,"
+ "application_name TEXT,"
+ "application_summary TEXT);";
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't create general table: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ statement = "CREATE TABLE localised ("
+ "application_id TEXT primary key,"
+ "application_name TEXT,"
+ "application_summary TEXT,"
+ "locale TEXT);";
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't create localised table: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ }
+
+out:
+ if (db != NULL)
+ sqlite3_close (db);
+ return ret;
+}
+
+/**
+ * pk_app_install_remove_icons_sqlite_cb:
+ **/
+static gint
+pk_app_install_remove_icons_sqlite_cb (void *data, gint argc, gchar **argv, gchar **col_name)
+{
+ gint i;
+ gchar *col;
+ gchar *value;
+ const gchar *application_id = NULL;
+ gchar *path;
+ gchar *filename;
+ const gchar *icondir = (const gchar *) data;
+
+ for (i=0; i<argc; i++) {
+ col = col_name[i];
+ value = argv[i];
+ if (g_strcmp0 (col, "application_id") == 0)
+ application_id = value;
+ }
+ if (application_id == NULL)
+ goto out;
+
+ egg_warning ("application_id=%s", application_id);
+ filename = g_strdup_printf ("%s.png", application_id);
+ path = g_build_filename (icondir, "48x48", filename, NULL);
+
+// g_unlink (path);
+ egg_warning ("path=%s", path);
+
+ g_free (filename);
+ g_free (path);
+out:
+ return 0;
+}
+
+/**
+ * pk_app_install_remove:
+ **/
+static gboolean
+pk_app_install_remove (const gchar *cache, const gchar *icondir, const gchar *repo)
+{
+ gboolean ret = TRUE;
+ gchar *statement = NULL;
+ sqlite3 *db = NULL;
+ gchar *error_msg;
+ gint rc;
+
+ /* open database */
+ rc = sqlite3_open (cache, &db);
+ if (rc) {
+ egg_warning ("Can't open database: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+
+ /* remove icons */
+ if (icondir != NULL) {
+ statement = g_strdup_printf ("SELECT application_id FROM general WHERE repo_name = '%s'", repo);
+ rc = sqlite3_exec (db, statement, pk_app_install_remove_icons_sqlite_cb, (void*) icondir, &error_msg);
+ g_free (statement);
+ if (rc != SQLITE_OK) {
+ egg_warning ("SQL error: %s\n", error_msg);
+ sqlite3_free (error_msg);
+ return 0;
+ }
+ }
+
+ /* delete from localised (localised has no repo_name, so key off general) */
+ statement = g_strdup_printf ("DELETE FROM localised WHERE EXISTS ( "
+ "SELECT general.application_id FROM general WHERE "
+ "general.application_id = general.application_id AND general.repo_name = '%s')", repo);
+// statement = g_strdup_printf ("SELECT general.application_id FROM general WHERE general.application_id == general.application_id AND general.repo_name == '%s'", repo);
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't remove rows: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ egg_debug ("%i removals from localised", sqlite3_changes (db));
+ g_free (statement);
+
+ /* delete from general */
+ statement = g_strdup_printf ("DELETE FROM general WHERE repo_name = '%s'", repo);
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't remove rows: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ egg_debug ("%i removals from general", sqlite3_changes (db));
+ g_free (statement);
+
+ /* reclaim memory */
+ statement = g_strdup ("VACUUM");
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't vacuum: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+
+out:
+ g_free (statement);
+ if (db != NULL)
+ sqlite3_close (db);
+ return ret;
+}
+
+/**
+ * pk_app_install_add:
+ **/
+static gboolean
+pk_app_install_add (const gchar *cache, const gchar *icondir, const gchar *repo, const gchar *source)
+{
+ egg_warning ("cache=%s, source=%s, repo=%s, icondir=%s", cache, source, repo, icondir);
+ return TRUE;
+}
+
+/**
+ * main:
+ **/
+int
+main (int argc, char *argv[])
+{
+ gboolean verbose = FALSE;
+ GOptionContext *context;
+ gint retval = 0;
+ gchar *action = NULL;
+ gchar *cache = NULL;
+ gchar *repo = NULL;
+ gchar *source = NULL;
+ gchar *icondir = NULL;
+
+ const GOptionEntry options[] = {
+ { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
+ _("Show extra debugging information"), NULL },
+ { "action", 'c', 0, G_OPTION_ARG_STRING, &action,
+ /* TRANSLATORS: the action is non-localised */
+ _("The action, one of 'create', 'add', or 'remove'"), NULL},
+ { "cache", 'c', 0, G_OPTION_ARG_STRING, &cache,
+ /* TRANSLATORS: if we are specifing a out-of-tree database */
+ _("Main cache file to use (if not specififed, default is used)"), NULL},
+ { "source", 's', 0, G_OPTION_ARG_STRING, &source,
+ /* TRANSLATORS: the source database, typically used for adding */
+ _("Source cache file to add to the main database"), NULL},
+ { "icondir", 'i', 0, G_OPTION_ARG_STRING, &icondir,
+ /* TRANSLATORS: the icon directory */
+ _("Icon directory"), NULL},
+ { "repo", 'n', 0, G_OPTION_ARG_STRING, &repo,
+ /* TRANSLATORS: the repo of the software source, e.g. fedora */
+ _("Name of the remote repo"), NULL},
+ { NULL}
+ };
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ context = g_option_context_new (NULL);
+ /* TRANSLATORS: tool that gets called when the command is not found */
+ g_option_context_set_summary (context, _("PackageKit Application Database Installer"));
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_parse (context, &argc, &argv, NULL);
+ g_option_context_free (context);
+
+ egg_debug_init (verbose);
+
+ egg_debug ("cache=%s, source=%s, repo=%s, icondir=%s", cache, source, repo, icondir);
+
+ /* use default */
+ if (cache == NULL) {
+ egg_debug ("cache not specified, using %s", PK_APP_INSTALL_DEFAULT_DATABASE);
+ cache = g_strdup (PK_APP_INSTALL_DEFAULT_DATABASE);
+ }
+
+ if (g_strcmp0 (action, "create") == 0) {
+ pk_app_install_create (cache);
+ } else if (g_strcmp0 (action, "add") == 0) {
+ if (repo == NULL) {
+ egg_warning ("A repo name is required");
+ retval = 1;
+ goto out;
+ }
+ if (source == NULL) {
+ egg_warning ("A source filename is required");
+ retval = 1;
+ goto out;
+ }
+ if (!g_file_test (source, G_FILE_TEST_EXISTS)) {
+ egg_warning ("The source filename '%s' could not be found", source);
+ retval = 1;
+ goto out;
+ }
+ if (icondir == NULL || !g_file_test (icondir, G_FILE_TEST_IS_DIR)) {
+ egg_warning ("The icon directory '%s' could not be found", icondir);
+ retval = 1;
+ goto out;
+ }
+ pk_app_install_add (cache, icondir, repo, source);
+ } else if (g_strcmp0 (action, "remove") == 0) {
+ if (repo == NULL) {
+ egg_warning ("A repo name is required");
+ retval = 1;
+ goto out;
+ }
+ if (icondir == NULL || !g_file_test (icondir, G_FILE_TEST_IS_DIR)) {
+ egg_warning ("The icon directory '%s' could not be found", icondir);
+ retval = 1;
+ goto out;
+ }
+ pk_app_install_remove (cache, icondir, repo);
+ } else if (g_strcmp0 (action, "generate") == 0) {
+ if (repo == NULL) {
+ egg_warning ("A repo name is required");
+ retval = 1;
+ goto out;
+ }
+ if (icondir == NULL || !g_file_test (icondir, G_FILE_TEST_IS_DIR)) {
+ egg_warning ("The icon directory '%s' could not be found", icondir);
+ retval = 1;
+ goto out;
+ }
+ pk_app_install_remove (cache, icondir, repo);
+ } else {
+ egg_warning ("An action is required");
+ retval = 1;
+ }
+
+out:
+ g_free (cache);
+ g_free (repo);
+ g_free (source);
+ g_free (icondir);
+ return 0;
+}
+
diff --git a/contrib/app-install/pk-app-install-common.h b/contrib/app-install/pk-app-install-common.h
new file mode 100644
index 0000000..f74710c
--- /dev/null
+++ b/contrib/app-install/pk-app-install-common.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PK_APP_INSTALL_COMMON_H
+#define __PK_APP_INSTALL_COMMON_H
+
+#if PK_BUILD_LOCAL
+#define PK_APP_INSTALL_DEFAULT_DATABASE "./desktop.db"
+#define PK_APP_INSTALL_DEFAULT_ICONDIR "./icons"
+#else
+#define PK_APP_INSTALL_DEFAULT_DATABASE DATADIR "/app-install/cache/desktop.db"
+#define PK_APP_INSTALL_DEFAULT_ICONDIR DATADIR "/app-install/icons"
+#endif
+
+#endif /* __PK_APP_INSTALL_COMMON_H */
diff --git a/contrib/app-install/pk-app-install-create.c b/contrib/app-install/pk-app-install-create.c
new file mode 100644
index 0000000..9373454
--- /dev/null
+++ b/contrib/app-install/pk-app-install-create.c
@@ -0,0 +1,132 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <sqlite3.h>
+
+#include "pk-app-install-common.h"
+#include "egg-debug.h"
+
+/**
+ * main:
+ **/
+int
+main (int argc, char *argv[])
+{
+ gboolean verbose = FALSE;
+ GOptionContext *context;
+ gchar *cache = NULL;
+ gboolean create_file;
+ const gchar *statement;
+ sqlite3 *db = NULL;
+ gint retval;
+ gint rc;
+
+ const GOptionEntry options[] = {
+ { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
+ _("Show extra debugging information"), NULL },
+ { "cache", 'c', 0, G_OPTION_ARG_STRING, &cache,
+ /* TRANSLATORS: if we are specifing a out-of-tree database */
+ _("Main database file to use (if not specififed, default is used)"), NULL},
+ { NULL}
+ };
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ context = g_option_context_new (NULL);
+ /* TRANSLATORS: tool that gets called when the command is not found */
+ g_option_context_set_summary (context, _("PackageKit Application Database Installer"));
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_parse (context, &argc, &argv, NULL);
+ g_option_context_free (context);
+
+ egg_debug_init (verbose);
+
+ /* use default */
+ if (cache == NULL) {
+ egg_debug ("cache not specified, using %s", PK_APP_INSTALL_DEFAULT_DATABASE);
+ cache = g_strdup (PK_APP_INSTALL_DEFAULT_DATABASE);
+ }
+
+ /* if the database file was not installed (or was nuked) recreate it */
+ create_file = g_file_test (cache, G_FILE_TEST_EXISTS);
+ if (create_file == TRUE) {
+ egg_warning ("already exists");
+ goto out;
+ }
+
+ /* open database */
+ rc = sqlite3_open (cache, &db);
+ if (rc) {
+ egg_warning ("Can't open database: %s\n", sqlite3_errmsg (db));
+ retval = 1;
+ goto out;
+ }
+
+ /* don't sync */
+ statement = "PRAGMA synchronous=OFF";
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't turn off sync: %s\n", sqlite3_errmsg (db));
+ retval = 1;
+ goto out;
+ }
+
+ /* create */
+ if (create_file == FALSE) {
+ statement = "CREATE TABLE general ("
+ "application_id TEXT primary key,"
+ "package_name TEXT,"
+ "group_id TEXT,"
+ "repo_name TEXT,"
+ "application_name TEXT,"
+ "application_summary TEXT);";
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't create general table: %s\n", sqlite3_errmsg (db));
+ retval = 1;
+ goto out;
+ }
+ statement = "CREATE TABLE localised ("
+ "application_id TEXT primary key,"
+ "application_name TEXT,"
+ "application_summary TEXT,"
+ "locale TEXT);";
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't create localised table: %s\n", sqlite3_errmsg (db));
+ retval = 1;
+ goto out;
+ }
+ }
+out:
+ if (db != NULL)
+ sqlite3_close (db);
+ g_free (cache);
+ return retval;
+}
+
diff --git a/contrib/app-install/pk-app-install-generate.c b/contrib/app-install/pk-app-install-generate.c
new file mode 100644
index 0000000..357ab74
--- /dev/null
+++ b/contrib/app-install/pk-app-install-generate.c
@@ -0,0 +1,345 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <sqlite3.h>
+
+#include "egg-debug.h"
+
+#if PK_BUILD_LOCAL
+#define PK_APP_INSTALL_DEFAULT_DATABASE "./desktop.db"
+#else
+#define PK_APP_INSTALL_DEFAULT_DATABASE DATADIR "/app-install/cache/desktop.db"
+#endif
+
+/**
+ * pk_app_install_create:
+ **/
+static gboolean
+pk_app_install_create (const gchar *cache)
+{
+ gboolean ret = TRUE;
+ gboolean create_file;
+ const gchar *statement;
+ sqlite3 *db = NULL;
+ gint rc;
+
+ /* if the database file was not installed (or was nuked) recreate it */
+ create_file = g_file_test (cache, G_FILE_TEST_EXISTS);
+ if (create_file == TRUE) {
+ egg_warning ("already exists");
+ goto out;
+ }
+
+ egg_debug ("exists: %i", create_file);
+
+ /* open database */
+ rc = sqlite3_open (cache, &db);
+ if (rc) {
+ egg_warning ("Can't open database: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+
+ /* don't sync */
+ statement = "PRAGMA synchronous=OFF";
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't turn off sync: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+
+ egg_debug ("create");
+ if (create_file == FALSE) {
+ statement = "CREATE TABLE general ("
+ "application_id TEXT primary key,"
+ "package_name TEXT,"
+ "group_id TEXT,"
+ "repo_name TEXT,"
+ "application_name TEXT,"
+ "application_summary TEXT);";
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't create general table: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ statement = "CREATE TABLE localised ("
+ "application_id TEXT primary key,"
+ "application_name TEXT,"
+ "application_summary TEXT,"
+ "locale TEXT);";
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't create localised table: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ }
+
+out:
+ if (db != NULL)
+ sqlite3_close (db);
+ return ret;
+}
+
+/**
+ * pk_app_install_remove_icons_sqlite_cb:
+ **/
+static gint
+pk_app_install_remove_icons_sqlite_cb (void *data, gint argc, gchar **argv, gchar **col_name)
+{
+ gint i;
+ gchar *col;
+ gchar *value;
+ const gchar *application_id = NULL;
+ gchar *path;
+ gchar *filename;
+ const gchar *icondir = (const gchar *) data;
+
+ for (i=0; i<argc; i++) {
+ col = col_name[i];
+ value = argv[i];
+ if (g_strcmp0 (col, "application_id") == 0)
+ application_id = value;
+ }
+ if (application_id == NULL)
+ goto out;
+
+ egg_warning ("application_id=%s", application_id);
+ filename = g_strdup_printf ("%s.png", application_id);
+ path = g_build_filename (icondir, "48x48", filename, NULL);
+
+// g_unlink (path);
+ egg_warning ("path=%s", path);
+
+ g_free (filename);
+ g_free (path);
+out:
+ return 0;
+}
+
+/**
+ * pk_app_install_remove:
+ **/
+static gboolean
+pk_app_install_remove (const gchar *cache, const gchar *icondir, const gchar *repo)
+{
+ gboolean ret = TRUE;
+ gchar *statement = NULL;
+ sqlite3 *db = NULL;
+ gchar *error_msg;
+ gint rc;
+
+ /* open database */
+ rc = sqlite3_open (cache, &db);
+ if (rc) {
+ egg_warning ("Can't open database: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+
+ /* remove icons */
+ if (icondir != NULL) {
+ statement = g_strdup_printf ("SELECT application_id FROM general WHERE repo_name = '%s'", repo);
+ rc = sqlite3_exec (db, statement, pk_app_install_remove_icons_sqlite_cb, (void*) icondir, &error_msg);
+ g_free (statement);
+ if (rc != SQLITE_OK) {
+ egg_warning ("SQL error: %s\n", error_msg);
+ sqlite3_free (error_msg);
+ return 0;
+ }
+ }
+
+ /* delete from localised (localised has no repo_name, so key off general) */
+ statement = g_strdup_printf ("DELETE FROM localised WHERE EXISTS ( "
+ "SELECT general.application_id FROM general WHERE "
+ "general.application_id = general.application_id AND general.repo_name = '%s')", repo);
+// statement = g_strdup_printf ("SELECT general.application_id FROM general WHERE general.application_id == general.application_id AND general.repo_name == '%s'", repo);
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't remove rows: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ egg_debug ("%i removals from localised", sqlite3_changes (db));
+ g_free (statement);
+
+ /* delete from general */
+ statement = g_strdup_printf ("DELETE FROM general WHERE repo_name = '%s'", repo);
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't remove rows: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ egg_debug ("%i removals from general", sqlite3_changes (db));
+ g_free (statement);
+
+ /* reclaim memory */
+ statement = g_strdup ("VACUUM");
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't vacuum: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+
+out:
+ g_free (statement);
+ if (db != NULL)
+ sqlite3_close (db);
+ return ret;
+}
+
+/**
+ * pk_app_install_add:
+ **/
+static gboolean
+pk_app_install_add (const gchar *cache, const gchar *icondir, const gchar *repo, const gchar *source)
+{
+ egg_warning ("cache=%s, source=%s, repo=%s, icondir=%s", cache, source, repo, icondir);
+ return TRUE;
+}
+
+/**
+ * main:
+ **/
+int
+main (int argc, char *argv[])
+{
+ gboolean verbose = FALSE;
+ GOptionContext *context;
+ gint retval = 0;
+ gchar *action = NULL;
+ gchar *cache = NULL;
+ gchar *repo = NULL;
+ gchar *source = NULL;
+ gchar *icondir = NULL;
+
+ const GOptionEntry options[] = {
+ { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
+ _("Show extra debugging information"), NULL },
+ { "action", 'c', 0, G_OPTION_ARG_STRING, &action,
+ /* TRANSLATORS: the action is non-localised */
+ _("The action, one of 'create', 'add', or 'remove'"), NULL},
+ { "cache", 'c', 0, G_OPTION_ARG_STRING, &cache,
+ /* TRANSLATORS: if we are specifing a out-of-tree database */
+ _("Main cache file to use (if not specififed, default is used)"), NULL},
+ { "source", 's', 0, G_OPTION_ARG_STRING, &source,
+ /* TRANSLATORS: the source database, typically used for adding */
+ _("Source cache file to add to the main database"), NULL},
+ { "icondir", 'i', 0, G_OPTION_ARG_STRING, &icondir,
+ /* TRANSLATORS: the icon directory */
+ _("Icon directory"), NULL},
+ { "repo", 'n', 0, G_OPTION_ARG_STRING, &repo,
+ /* TRANSLATORS: the repo of the software source, e.g. fedora */
+ _("Name of the remote repo"), NULL},
+ { NULL}
+ };
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ context = g_option_context_new (NULL);
+ /* TRANSLATORS: tool that gets called when the command is not found */
+ g_option_context_set_summary (context, _("PackageKit Application Database Installer"));
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_parse (context, &argc, &argv, NULL);
+ g_option_context_free (context);
+
+ egg_debug_init (verbose);
+
+ egg_debug ("cache=%s, source=%s, repo=%s, icondir=%s", cache, source, repo, icondir);
+
+ /* use default */
+ if (cache == NULL) {
+ egg_debug ("cache not specified, using %s", PK_APP_INSTALL_DEFAULT_DATABASE);
+ cache = g_strdup (PK_APP_INSTALL_DEFAULT_DATABASE);
+ }
+
+ if (g_strcmp0 (action, "create") == 0) {
+ pk_app_install_create (cache);
+ } else if (g_strcmp0 (action, "add") == 0) {
+ if (repo == NULL) {
+ egg_warning ("A repo name is required");
+ retval = 1;
+ goto out;
+ }
+ if (source == NULL) {
+ egg_warning ("A source filename is required");
+ retval = 1;
+ goto out;
+ }
+ if (!g_file_test (source, G_FILE_TEST_EXISTS)) {
+ egg_warning ("The source filename '%s' could not be found", source);
+ retval = 1;
+ goto out;
+ }
+ if (icondir == NULL || !g_file_test (icondir, G_FILE_TEST_IS_DIR)) {
+ egg_warning ("The icon directory '%s' could not be found", icondir);
+ retval = 1;
+ goto out;
+ }
+ pk_app_install_add (cache, icondir, repo, source);
+ } else if (g_strcmp0 (action, "remove") == 0) {
+ if (repo == NULL) {
+ egg_warning ("A repo name is required");
+ retval = 1;
+ goto out;
+ }
+ if (icondir == NULL || !g_file_test (icondir, G_FILE_TEST_IS_DIR)) {
+ egg_warning ("The icon directory '%s' could not be found", icondir);
+ retval = 1;
+ goto out;
+ }
+ pk_app_install_remove (cache, icondir, repo);
+ } else if (g_strcmp0 (action, "generate") == 0) {
+ if (repo == NULL) {
+ egg_warning ("A repo name is required");
+ retval = 1;
+ goto out;
+ }
+ if (icondir == NULL || !g_file_test (icondir, G_FILE_TEST_IS_DIR)) {
+ egg_warning ("The icon directory '%s' could not be found", icondir);
+ retval = 1;
+ goto out;
+ }
+ pk_app_install_remove (cache, icondir, repo);
+ } else {
+ egg_warning ("An action is required");
+ retval = 1;
+ }
+
+out:
+ g_free (cache);
+ g_free (repo);
+ g_free (source);
+ g_free (icondir);
+ return 0;
+}
+
diff --git a/contrib/app-install/pk-app-install-remove.c b/contrib/app-install/pk-app-install-remove.c
new file mode 100644
index 0000000..d5f3070
--- /dev/null
+++ b/contrib/app-install/pk-app-install-remove.c
@@ -0,0 +1,195 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <sqlite3.h>
+
+#include "pk-app-install-common.h"
+#include "egg-debug.h"
+
+/**
+ * pk_app_install_remove_icons_sqlite_cb:
+ **/
+static gint
+pk_app_install_remove_icons_sqlite_cb (void *data, gint argc, gchar **argv, gchar **col_name)
+{
+ gint i;
+ gchar *col;
+ gchar *value;
+ const gchar *application_id = NULL;
+ gchar *path;
+ gchar *filename;
+ const gchar *icondir = (const gchar *) data;
+
+ for (i=0; i<argc; i++) {
+ col = col_name[i];
+ value = argv[i];
+ if (g_strcmp0 (col, "application_id") == 0)
+ application_id = value;
+ }
+ if (application_id == NULL)
+ goto out;
+
+ egg_warning ("application_id=%s", application_id);
+ filename = g_strdup_printf ("%s.png", application_id);
+ path = g_build_filename (icondir, "48x48", filename, NULL);
+
+// g_unlink (path);
+ egg_warning ("path=%s", path);
+
+ g_free (filename);
+ g_free (path);
+out:
+ return 0;
+}
+
+/**
+ * main:
+ **/
+int
+main (int argc, char *argv[])
+{
+ gboolean verbose = FALSE;
+ GOptionContext *context;
+ gint retval = 0;
+ gchar *cache = NULL;
+ gchar *repo = NULL;
+ gchar *icondir = NULL;
+ gboolean ret = TRUE;
+ gchar *statement = NULL;
+ sqlite3 *db = NULL;
+ gchar *error_msg;
+ gint rc;
+
+ const GOptionEntry options[] = {
+ { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
+ _("Show extra debugging information"), NULL },
+ { "cache", 'c', 0, G_OPTION_ARG_STRING, &cache,
+ /* TRANSLATORS: if we are specifing a out-of-tree database */
+ _("Main cache file to use (if not specififed, default is used)"), NULL},
+ { "icondir", 'i', 0, G_OPTION_ARG_STRING, &icondir,
+ /* TRANSLATORS: the icon directory */
+ _("Icon directory"), NULL},
+ { "repo", 'n', 0, G_OPTION_ARG_STRING, &repo,
+ /* TRANSLATORS: the repo of the software source, e.g. fedora */
+ _("Name of the remote repo"), NULL},
+ { NULL}
+ };
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ context = g_option_context_new (NULL);
+ /* TRANSLATORS: tool that gets called when the command is not found */
+ g_option_context_set_summary (context, _("PackageKit Application Database Installer"));
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_parse (context, &argc, &argv, NULL);
+ g_option_context_free (context);
+
+ egg_debug_init (verbose);
+
+ /* use default */
+ if (cache == NULL) {
+ egg_debug ("cache not specified, using %s", PK_APP_INSTALL_DEFAULT_DATABASE);
+ cache = g_strdup (PK_APP_INSTALL_DEFAULT_DATABASE);
+ }
+ if (icondir == NULL) {
+ egg_debug ("icondir not specified, using %s", PK_APP_INSTALL_DEFAULT_ICONDIR);
+ icondir = g_strdup (PK_APP_INSTALL_DEFAULT_ICONDIR);
+ }
+
+ /* check */
+ if (repo == NULL) {
+ egg_warning ("A repo name is required");
+ retval = 1;
+ goto out;
+ }
+ if (!g_file_test (icondir, G_FILE_TEST_IS_DIR)) {
+ egg_warning ("The icon directory '%s' could not be found", icondir);
+ retval = 1;
+ goto out;
+ }
+
+ /* open database */
+ rc = sqlite3_open (cache, &db);
+ if (rc) {
+ egg_warning ("Can't open database: %s\n", sqlite3_errmsg (db));
+ retval = 1;
+ goto out;
+ }
+
+ /* remove icons */
+ statement = g_strdup_printf ("SELECT application_id FROM general WHERE repo_name = '%s'", repo);
+ rc = sqlite3_exec (db, statement, pk_app_install_remove_icons_sqlite_cb, (void*) icondir, &error_msg);
+ g_free (statement);
+ if (rc != SQLITE_OK) {
+ egg_warning ("SQL error: %s\n", error_msg);
+ sqlite3_free (error_msg);
+ return 0;
+ }
+
+ /* delete from localised (localised has no repo_name, so key off general) */
+ statement = g_strdup_printf ("DELETE FROM localised WHERE EXISTS ( "
+ "SELECT general.application_id FROM general WHERE "
+ "general.application_id = general.application_id AND general.repo_name = '%s')", repo);
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ g_free (statement);
+ if (rc) {
+ egg_warning ("Can't remove rows: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ egg_debug ("%i removals from localised", sqlite3_changes (db));
+
+ /* delete from general */
+ statement = g_strdup_printf ("DELETE FROM general WHERE repo_name = '%s'", repo);
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ g_free (statement);
+ if (rc) {
+ egg_warning ("Can't remove rows: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ egg_debug ("%i removals from general", sqlite3_changes (db));
+
+ /* reclaim memory */
+ statement = g_strdup ("VACUUM");
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't vacuum: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+out:
+ if (db != NULL)
+ sqlite3_close (db);
+ g_free (statement);
+ g_free (cache);
+ g_free (repo);
+ g_free (icondir);
+ return 0;
+}
+
diff --git a/contrib/app-install/pk-app-install.c b/contrib/app-install/pk-app-install.c
deleted file mode 100644
index f8a6263..0000000
--- a/contrib/app-install/pk-app-install.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2009 Richard Hughes <richard at hughsie.com>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <glib/gi18n.h>
-#include <sqlite3.h>
-
-#include "egg-debug.h"
-
-#if PK_BUILD_LOCAL
-#define PK_APP_INSTALL_DEFAULT_DATABASE "./desktop.db"
-#else
-#define PK_APP_INSTALL_DEFAULT_DATABASE DATADIR "/app-install/cache/desktop.db"
-#endif
-
-/**
- * pk_app_install_create:
- **/
-static gboolean
-pk_app_install_create (const gchar *cache)
-{
- gboolean ret = TRUE;
- gboolean create_file;
- const gchar *statement;
- sqlite3 *db = NULL;
- gint rc;
-
- /* if the database file was not installed (or was nuked) recreate it */
- create_file = g_file_test (cache, G_FILE_TEST_EXISTS);
- if (create_file == TRUE) {
- egg_warning ("already exists");
- goto out;
- }
-
- egg_debug ("exists: %i", create_file);
-
- /* open database */
- rc = sqlite3_open (cache, &db);
- if (rc) {
- egg_warning ("Can't open database: %s\n", sqlite3_errmsg (db));
- ret = FALSE;
- goto out;
- }
-
- /* don't sync */
- statement = "PRAGMA synchronous=OFF";
- rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
- if (rc) {
- egg_warning ("Can't turn off sync: %s\n", sqlite3_errmsg (db));
- ret = FALSE;
- goto out;
- }
-
- egg_debug ("create");
- if (create_file == FALSE) {
- statement = "CREATE TABLE general ("
- "application_id TEXT primary key,"
- "package_name TEXT,"
- "icon_name TEXT,"
- "group_id TEXT,"
- "repo_name TEXT,"
- "application_name TEXT,"
- "application_summary TEXT);";
- rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
- if (rc) {
- egg_warning ("Can't create general table: %s\n", sqlite3_errmsg (db));
- ret = FALSE;
- goto out;
- }
- statement = "CREATE TABLE localised ("
- "application_id TEXT primary key,"
- "application_name TEXT,"
- "application_summary TEXT,"
- "locale TEXT);";
- rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
- if (rc) {
- egg_warning ("Can't create localised table: %s\n", sqlite3_errmsg (db));
- ret = FALSE;
- goto out;
- }
- }
-
-out:
- if (db != NULL)
- sqlite3_close (db);
- return ret;
-}
-
-/**
- * pk_app_install_remove:
- **/
-static gboolean
-pk_app_install_remove (const gchar *cache, const gchar *repo)
-{
- gboolean ret = TRUE;
- gchar *statement = NULL;
- sqlite3 *db = NULL;
- gint rc;
-
- /* open database */
- rc = sqlite3_open (cache, &db);
- if (rc) {
- egg_warning ("Can't open database: %s\n", sqlite3_errmsg (db));
- ret = FALSE;
- goto out;
- }
-
- /* delete from localised (localised has no repo_name, so key off general) */
- statement = g_strdup_printf ("DELETE FROM localised WHERE EXISTS ( "
- "SELECT general.application_id FROM general WHERE "
- "general.application_id = general.application_id AND general.repo_name = '%s')", repo);
-// statement = g_strdup_printf ("SELECT general.application_id FROM general WHERE general.application_id == general.application_id AND general.repo_name == '%s'", repo);
- rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
- if (rc) {
- egg_warning ("Can't remove rows: %s\n", sqlite3_errmsg (db));
- ret = FALSE;
- goto out;
- }
- egg_debug ("%i removals from localised", sqlite3_changes (db));
- g_free (statement);
-
- /* delete from general */
- statement = g_strdup_printf ("DELETE FROM general WHERE repo_name = '%s'", repo);
- rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
- if (rc) {
- egg_warning ("Can't remove rows: %s\n", sqlite3_errmsg (db));
- ret = FALSE;
- goto out;
- }
- egg_debug ("%i removals from general", sqlite3_changes (db));
- g_free (statement);
-
- /* reclaim memory */
- statement = g_strdup ("VACUUM");
- rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
- if (rc) {
- egg_warning ("Can't vacuum: %s\n", sqlite3_errmsg (db));
- ret = FALSE;
- goto out;
- }
-
-out:
- g_free (statement);
- if (db != NULL)
- sqlite3_close (db);
- return ret;
-}
-
-/**
- * pk_app_install_add:
- **/
-static gboolean
-pk_app_install_add (const gchar *cache, const gchar *repo, const gchar *source)
-{
- egg_debug ("add");
- return TRUE;
-}
-
-/**
- * main:
- **/
-int
-main (int argc, char *argv[])
-{
- gboolean verbose = FALSE;
- GOptionContext *context;
- gint retval = 0;
- gchar *action = NULL;
- gchar *cache = NULL;
- gchar *repo = NULL;
- gchar *source = NULL;
-
- const GOptionEntry options[] = {
- { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
- _("Show extra debugging information"), NULL },
- { "action", 'c', 0, G_OPTION_ARG_STRING, &action,
- /* TRANSLATORS: the action is non-localised */
- _("The action, one of 'create', 'add', or 'remove'"), NULL},
- { "cache", 'c', 0, G_OPTION_ARG_STRING, &cache,
- /* TRANSLATORS: if we are specifing a out-of-tree database */
- _("Main cache file to use (if not specififed, default is used)"), NULL},
- { "source", 's', 0, G_OPTION_ARG_STRING, &source,
- /* TRANSLATORS: the source database, typically used for adding */
- _("Source cache file to add to the main database"), NULL},
- { "repo", 'n', 0, G_OPTION_ARG_STRING, &repo,
- /* TRANSLATORS: the repo of the software source, e.g. fedora */
- _("Name of the remote repo"), NULL},
- { NULL}
- };
-
- setlocale (LC_ALL, "");
- bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
- textdomain (GETTEXT_PACKAGE);
-
- context = g_option_context_new (NULL);
- /* TRANSLATORS: tool that gets called when the command is not found */
- g_option_context_set_summary (context, _("PackageKit Application Database Installer"));
- g_option_context_add_main_entries (context, options, NULL);
- g_option_context_parse (context, &argc, &argv, NULL);
- g_option_context_free (context);
-
- egg_debug_init (verbose);
-
- egg_debug ("cache=%s, source=%s, repo=%s", cache, source, repo);
-
- /* use default */
- if (cache == NULL) {
- egg_debug ("cache not specified, using %s", PK_APP_INSTALL_DEFAULT_DATABASE);
- cache = g_strdup (PK_APP_INSTALL_DEFAULT_DATABASE);
- }
-
- if (g_strcmp0 (action, "create") == 0) {
- pk_app_install_create (cache);
- } else if (g_strcmp0 (action, "add") == 0) {
- if (repo == NULL) {
- egg_warning ("A repo name is required");
- retval = 1;
- goto out;
- }
- if (source == NULL) {
- egg_warning ("A source filename is required");
- retval = 1;
- goto out;
- }
- if (!g_file_test (source, G_FILE_TEST_EXISTS)) {
- egg_warning ("The source filename '%s' could not be found", source);
- retval = 1;
- goto out;
- }
- pk_app_install_remove (cache, repo, source);
- } else if (g_strcmp0 (action, "remove") == 0) {
- if (repo == NULL) {
- egg_warning ("A repo name is required");
- retval = 1;
- goto out;
- }
- pk_app_install_remove (cache, repo);
- } else {
- egg_warning ("An action is required");
- retval = 1;
- }
-
-out:
- g_free (cache);
- g_free (repo);
- g_free (source);
- return 0;
-}
-
diff --git a/docs/app-install-v1.draft b/docs/app-install-v1.draft
index fc4d7d0..08d4e58 100644
--- a/docs/app-install-v1.draft
+++ b/docs/app-install-v1.draft
@@ -85,21 +85,24 @@ STRING locale
TABLE general
STRING application_id (name of the desktop file, with no extension)
-STRING package_name (to save on expensive SearchFile's)
-STRING icon_name (without path or extension)
+STRING package_name (the package name, e.g. 'nautilus')
STRING group_id (Categories from desktop file, _not_ PK groups or PK categories)
STRING repo_name (for adding and removal)
STRING application_name (Name in desktop file)
STRING application_summary (Comment in desktop file)
+icon_name is not needed as it will be renamed to ${application_id}.png
+
== Possible Commands ==
-pk-app-install action=create --cache=/usr/share/app-install/cache/desktop.db
-pk-app-install action=add --repo=livna --source=/var/cache/yum/livna-apps.db --cache=/usr/share/app-install/cache/desktop.db
-pk-app-install action=remove --repo=livna --cache=/usr/share/app-install/cache/desktop.db
+pk-app-install-create --cache=/usr/share/app-install/cache/desktop.db
+pk-app-install-add --repo=livna --source=./livna/desktop.db --icondir=./livna/icons --cache=/usr/share/app-install/cache/desktop.db
+pk-app-install-remove --repo=livna --icondir=/usr/share/app-install/icons --cache=/usr/share/app-install/cache/desktop.db
* need to do the latter then former in a spec file on upgrade
all distro specific stuff to live in backends/, but typically:
yum-app-install-generate --name=livna --cache=~/livna-apps.db
+pk-app-install-generate --repo=livna --desktopdir=/usr/share/icons --icondir=/usr/share/icons --outputdir=./icons
+
== Open questions ===
commit db0b74055b2b5fc131a8aa16d5c4186deb11384e
Merge: 5281a5b... e69e0c2...
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Fri Feb 20 15:57:16 2009 +0100
Merge branch 'master' of git+ssh://glatzor@git.packagekit.org/srv/git/PackageKit
commit e69e0c2ad0b4fe6c9d683672ea8b20e056200219
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Fri Feb 20 00:46:15 2009 -0600
conary:
add Own progress module
add percent to update/remove/get-updates/update-system
diff --git a/backends/conary/Makefile.am b/backends/conary/Makefile.am
index 6d7dd38..a605db6 100644
--- a/backends/conary/Makefile.am
+++ b/backends/conary/Makefile.am
@@ -4,9 +4,10 @@ dist_helper_DATA = \
conaryFilter.py \
conaryCallback.py \
conaryInit.py \
- XMLCache.py \
+ XMLCache.py \
pkConaryLog.py \
- conarypk.py \
+ conarypk.py \
+ conaryProgress.py \
conaryEnums.py
plugindir = $(PK_PLUGIN_DIR)
diff --git a/backends/conary/conaryBackend.py b/backends/conary/conaryBackend.py
index f54928d..81a17aa 100755
--- a/backends/conary/conaryBackend.py
+++ b/backends/conary/conaryBackend.py
@@ -33,7 +33,7 @@ from conary.conaryclient import cmdline
from packagekit.backend import *
from packagekit.package import *
from packagekit.progress import PackagekitProgress
-from conaryCallback import UpdateCallback, GetUpdateCallback, RemoveCallback
+from conaryCallback import UpdateCallback, GetUpdateCallback, RemoveCallback, UpdateSystemCallback
from conaryFilter import *
from XMLCache import XMLCache as Cache
from conaryInit import *
@@ -448,12 +448,18 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
@ExceptionHandler
def update_system(self):
self.allow_cancel(True)
+ self.status(STATUS_UPDATE)
+ self.client.setUpdateCallback( UpdateSystemCallback(self, self.cfg) )
updateItems = self.client.fullUpdateItemList()
pprint(updateItems)
applyList = [ (x[0], (None, None), x[1:], True) for x in updateItems ]
- pprint(applyList)
- upJob, suggMap = self._get_update(applyList)
- updJob, suggMap = self._do_update(applyList)
+
+ log.info(">>>>>>>>>> get update >>>>>>>>>>>>")
+ self._get_update(applyList)
+ log.info(">>>>>>>>>> DO Update >>>>>>>>>>>>")
+ self._do_update(applyList)
+ log.info(">>>>>>>>>>END DO Update >>>>>>>>>>>>")
+ self.client.setUpdateCallback(self.callback )
# @ExceptionHandler
def refresh_cache(self):
@@ -525,6 +531,7 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
log.info("========== Remove Packages ============ ")
log.info( allowDeps )
self.client.setUpdateCallback(RemoveCallback(self, self.cfg))
+ errors = ""
#for package_id in package_ids.split('%'):
for package_id in package_ids:
name, version, flavor, installed = self._findPackage(package_id)
@@ -535,6 +542,10 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
name = '-%s' % name
self.status(STATUS_REMOVE)
self._get_package_update(name, version, flavor)
+ callback = self.client.getUpdateCallback()
+ if callback.error:
+ self.error(ERROR_DEP_RESOLUTION_FAILED,', '.join(callback.error))
+
self._do_package_update(name, version, flavor)
else:
self.error(ERROR_PACKAGE_ALREADY_INSTALLED, 'The package was not found')
diff --git a/backends/conary/conaryCallback.py b/backends/conary/conaryCallback.py
index 2dd99c8..8ba4db1 100644
--- a/backends/conary/conaryCallback.py
+++ b/backends/conary/conaryCallback.py
@@ -19,11 +19,175 @@
# Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
from conary import callbacks
from packagekit.backend import *
-from packagekit.progress import PackagekitProgress
+from conaryProgress import PackagekitProgress
from pkConaryLog import log
MEGA = 1048576.0
+class UpdateSystemCallback(callbacks.UpdateCallback):
+ def __init__(self, backend, cfg=None):
+ callbacks.UpdateCallback.__init__(self)
+ log.info("==== callback ==== ")
+ if cfg:
+ self.setTrustThreshold(cfg.trustThreshold)
+
+ self.backend = backend
+ self.currentJob = None
+ self.smallUpdate = False
+ self.error = []
+ self.progress = PackagekitProgress()
+ self.progress.set_steps([ 30,60,65 ] )
+ #1
+ #3
+ def requestingChangeSet(self):
+ log.info("Callback UpdateSystem........ STATUS_REQUEST changeset ")
+ self.backend.status(STATUS_DOWNLOAD)
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+ #2
+ def downloadingChangeSet(self, got, need):
+ log.info("Callback UpdateSystem........ STATUS_DOWNLOAD Changeset %.2f percent %.2f/%.2f Mbytes" % ( got*100/float(need), got/MEGA,need/MEGA) )
+ self.progress.set_subpercent( got*100 / float(need) )
+ self.backend.percentage( self.progress.percent )
+ log.info( "%s percent" % self.progress.percent)
+
+ #4
+ def resolvingDependencies(self):
+ log.info("Callback UpdateSystem........ STATUS_DEP_RESOLVE ")
+ self.backend.percentage(self.progress.percent)
+ self.backend.status(STATUS_DEP_RESOLVE)
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+
+ def setChangesetHunk(self, num, total):
+ log.info("callback. .......... set Changeset HUnk %s/%s" % (num, total ) )
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+
+ def setUpdateHunk(self, hunk, hunkCount):
+ log.info("callback. .......... set update HUnk %s/%s" % ( hunk, hunkCount))
+ self.progress.step()
+
+ if hunk < hunkCount:
+ p = hunk / float(hunkCount) * 100.0
+ self.progress.set_subpercent(p)
+ else:
+ self.smallUpdate = True
+
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+
+ def setUpdateJob(self, job):
+ log.info("callback. .......... set update Job")
+ self.currentJob = job
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+
+ def creatingRollback(self):
+ #self.backend.status('Creating Rollback')
+ log.info("Callback ........ STATUS_ROLLBACK ")
+ self.backend.status(STATUS_ROLLBACK)
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+
+
+ def preparingUpdate(self, troveNum, troveCount, add=0):
+ log.info("callback ....... preparing Update trove %s/%s" % (troveNum, troveCount) )
+ #self.progress.step()
+ if not self.currentJob or len(self.currentJob) == 0 or troveNum > troveCount:
+ return
+
+ if troveNum > 0 and troveCount > 0:
+ sub_percent = (add + troveNum) / (2 * float(troveCount)) * 100
+ self.progress.set_subpercent(sub_percent)
+
+ self.backend.percentage(self.progress.percent)
+ if troveNum > 0:
+ troveNum -= 1
+ log.info("currentJob")
+ log.info(self.currentJob[troveNum])
+ job = self.currentJob[troveNum]
+ name = job[0]
+ oldVersion, oldFlavor = job[1]
+ newVersion, newFlavor = job[2]
+ #log.info("JOB>>>>>>>> %s " % str(job) )
+ if oldVersion and newVersion:
+ log.info("Callback ........ STATUS_UPDATE preparing Update ")
+ self.backend.status(STATUS_UPDATE)
+ package_id = self.backend.get_package_id(name, newVersion, newFlavor)
+ self.backend.package(package_id, INFO_UPDATING, '')
+ elif oldVersion and not newVersion:
+ log.info("Callback ........ STATUS_REMOVE preparing Update ")
+ self.backend.status(STATUS_REMOVE)
+ package_id = self.backend.get_package_id(name, oldVersion, oldFlavor)
+ self.backend.package(package_id, INFO_REMOVING, '')
+ elif not oldVersion and newVersion:
+ log.info("Callback ........ STATUS_INSTALL preparing Update")
+ self.backend.status(STATUS_INSTALL)
+ package_id = self.backend.get_package_id(name, newVersion, newFlavor)
+ self.backend.package(package_id, INFO_INSTALLING, '')
+ log.info(self.progress.percent)
+
+ def creatingDatabaseTransaction(self, troveNum, troveCount):
+ log.info("callback. .......... creating Database Transactions")
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+ self.preparingUpdate(troveNum, troveCount, add=troveCount)
+
+ def committingTransaction(self):
+ #self.backend.status('Committing Transaction')
+ log.info("Callback ........ STATUS_COMMIT transactions ")
+
+ self.backend.status(STATUS_COMMIT)
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+
+ def updateDone(self):
+ log.info("callback. .......... update done")
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ self.currentJob = None
+ log.info(self.progress.percent)
+
+ def downloadingFileContents(self, got, need):
+ #self.backend.status('Downloading files for changeset')
+ log.info("Callback ........ STATUS_DOWNLOAD FIle Contents %s " % str( got*100/need ))
+ self.backend.status(STATUS_DOWNLOAD)
+ #self.backend.sub_percentage(got*100/need)
+
+ def requestingFileContents(self):
+ #self.backend.status('Requesting File Contents')
+ log.info("Callback ........ STATUS_REQUEST request File contents ")
+ self.backend.status(STATUS_REQUEST)
+
+ def removeFiles(self, filenum, total):
+ log.info("Callback ........ STATUS_REMOVE %s/%sfiles" %( filenum, total) )
+ self.backend.status(STATUS_REMOVE)
+ self.preparingUpdate(filenum, total, add=total)
+
+ def done(self):
+ #self.backend.status('Done')
+ # self.progress.step()
+ log.info("DONEEEEEEEEEEEE")
+
+ def warning(self, msg, *args, **kwargs):
+ e = msg %args
+ log.error("<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
+ log.error(e)
+ self.backend.error(ERROR_DEP_RESOLUTION_FAILED, e, False )
+
+ def tagHandlerOutput(self, tag, msg, stderr = False):
+ pass
+
+ def troveScriptOutput(self, typ, msg):
+ pass
+
class GetUpdateCallback(callbacks.UpdateCallback):
def __init__(self, backend, cfg=None):
callbacks.UpdateCallback.__init__(self)
@@ -36,7 +200,7 @@ class GetUpdateCallback(callbacks.UpdateCallback):
self.smallUpdate = False
self.error = []
self.progress = PackagekitProgress()
- self.progress.set_steps([1,2,50, 100 ] )
+ self.progress.set_steps([1,50, 100 ] )
# 1 >> downloadingChangeSet
# 2 >> downloadingChangeSet
def requestingChangeSet(self):
@@ -47,7 +211,7 @@ class GetUpdateCallback(callbacks.UpdateCallback):
self.progress.step()
def downloadingChangeSet(self, got, need):
- log.info("Callback getUpdates. Changeset %s percent of %s/%s bytes" % ( int( got*100/float(need)), got/MEGA,need/MEGA) )
+ log.info("Callback getUpdates. Changeset %s percent of %.2f/%.2f bytes" % ( int( got*100/float(need)), got/MEGA,need/MEGA) )
self.backend.status(STATUS_DOWNLOAD)
self.progress.set_subpercent( got*100 / float(need) )
self.backend.percentage( self.progress.percent )
@@ -76,9 +240,16 @@ class UpdateCallback(callbacks.UpdateCallback):
self.smallUpdate = False
self.error = []
self.progress = PackagekitProgress()
- self.progress.set_steps([ 0,5,8,10,12,20,35,80,90,100 ] )
- # 1
- # 4
+ self.progress.set_steps([
+ 1, # requestingChangeSet 1
+ 50, # resolveDeps2
+ 51, # SetChangesetHunk3
+ 52, # requestingChangeSet4
+ 80,# setUpdateHUnk5
+ 81,# setUpdateJob6
+ ] )
+ # 1 >> download
+ # 4 >> download
def requestingChangeSet(self):
log.info("Callback ........ STATUS_REQUEST changeset ")
self.backend.status(STATUS_DOWNLOAD)
@@ -87,14 +258,14 @@ class UpdateCallback(callbacks.UpdateCallback):
self.progress.step()
def downloadingChangeSet(self, got, need):
- log.info("Callback ........ STATUS_DOWNLOAD Changeset %s percent %s/%s bytes" % ( got*100/float(need), got/MEGA,need/MEGA) )
+ log.info("Callback ........ STATUS_DOWNLOAD Changeset %s percent %.2f/%.2f bytes" % ( got*100/float(need), got/MEGA,need/MEGA) )
self.progress.set_subpercent( got*100 / float(need) )
self.backend.percentage( self.progress.percent )
log.info( "%s percent" % self.progress.percent)
- # 2
+ # 2
def resolvingDependencies(self):
#self.backend.status('Resolving Dependencies')
log.info("Callback ........ STATUS_DEP_RESOLVE ")
@@ -127,16 +298,14 @@ class UpdateCallback(callbacks.UpdateCallback):
def setUpdateJob(self, job):
log.info("callback. .......... set update Job")
self.currentJob = job
- self.progress.step()
self.backend.percentage(self.progress.percent)
log.info(self.progress.percent)
- #7
+ #7 >> preparing update
def creatingRollback(self):
#self.backend.status('Creating Rollback')
log.info("Callback ........ STATUS_ROLLBACK ")
self.backend.status(STATUS_ROLLBACK)
- self.progress.step()
self.backend.percentage(self.progress.percent)
log.info(self.progress.percent)
@@ -166,11 +335,6 @@ class UpdateCallback(callbacks.UpdateCallback):
self.backend.status(STATUS_UPDATE)
package_id = self.backend.get_package_id(name, newVersion, newFlavor)
self.backend.package(package_id, INFO_UPDATING, '')
- elif oldVersion and not newVersion:
- log.info("Callback ........ STATUS_REMOVE preparing Update ")
- self.backend.status(STATUS_REMOVE)
- package_id = self.backend.get_package_id(name, oldVersion, oldFlavor)
- self.backend.package(package_id, INFO_REMOVING, '')
elif not oldVersion and newVersion:
log.info("Callback ........ STATUS_INSTALL preparing Update")
self.backend.status(STATUS_INSTALL)
@@ -180,7 +344,6 @@ class UpdateCallback(callbacks.UpdateCallback):
#8
def creatingDatabaseTransaction(self, troveNum, troveCount):
log.info("callback. .......... creating Database Transactions")
- self.progress.step()
self.backend.percentage(self.progress.percent)
log.info(self.progress.percent)
self.preparingUpdate(troveNum, troveCount, add=troveCount)
@@ -198,7 +361,6 @@ class UpdateCallback(callbacks.UpdateCallback):
#10
def updateDone(self):
log.info("callback. .......... update done")
- self.progress.step()
self.backend.percentage(self.progress.percent)
self.currentJob = None
log.info(self.progress.percent)
@@ -253,7 +415,7 @@ class RemoveCallback(callbacks.UpdateCallback):
self.smallUpdate = False
self.error = []
self.progress = PackagekitProgress()
- self.progress.set_steps([ 0,5,10,15,20,60,75,100 ] )
+ self.progress.set_steps([ 2,5,7,8,90,100 ] )
# 1
def resolvingDependencies(self):
#self.backend.status('Resolving Dependencies')
@@ -272,8 +434,6 @@ class RemoveCallback(callbacks.UpdateCallback):
#3
def setUpdateHunk(self, hunk, hunkCount):
log.info("callback. .......... set update HUnk %s/%s" % ( hunk, hunkCount))
- self.progress.step()
-
if hunk < hunkCount:
p = hunk / float(hunkCount) * 100.0
self.progress.set_subpercent(p)
@@ -295,26 +455,23 @@ class RemoveCallback(callbacks.UpdateCallback):
log.info("Callback ........ STATUS_ROLLBACK ")
self.backend.status(STATUS_ROLLBACK)
self.progress.step()
- self.backend.percentage(self.progress.percent)
+ #self.backend.percentage(self.progress.percent)
log.info(self.progress.percent)
#6
def removeFiles(self, filenum, total):
- log.info("Callback ........ STATUS_REMOVE %s/%sfiles" %( filenum, total) )
+ log.info("Callback ........ STATUS_REMOVE %s percent %s/%s files" %(filenum*100/float(total), filenum, total) )
+ self.progress.set_subpercent( filenum*100/float(total) )
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
self.backend.status(STATUS_REMOVE)
self.preparingUpdate(filenum, total, add=total)
- #7
def preparingUpdate(self, troveNum, troveCount, add=0):
log.info("callback ....... preparing Update trove %s/%s" % (troveNum, troveCount) )
#self.progress.step()
if not self.currentJob or len(self.currentJob) == 0 or troveNum > troveCount:
return
- if troveNum > 0 and troveCount > 0:
- sub_percent = (add + troveNum) / (2 * float(troveCount)) * 100
- self.progress.set_subpercent(sub_percent)
-
- self.backend.percentage(self.progress.percent)
log.info("currentJob %s" % troveNum)
log.info("job %s" % self.currentJob)
if len(self.currentJob) > troveNum:
@@ -335,12 +492,7 @@ class RemoveCallback(callbacks.UpdateCallback):
self.backend.status(STATUS_REMOVE)
package_id = self.backend.get_package_id(name, oldVersion, oldFlavor)
self.backend.package(package_id, INFO_REMOVING, '')
- elif not oldVersion and newVersion:
- log.info("Callback ........ STATUS_INSTALL preparing Update")
- self.backend.status(STATUS_INSTALL)
- package_id = self.backend.get_package_id(name, newVersion, newFlavor)
- self.backend.package(package_id, INFO_INSTALLING, '')
- log.info(self.progress.percent)
+
def creatingDatabaseTransaction(self, troveNum, troveCount):
log.info("callback. .......... creating Database Transactions")
self.progress.step()
@@ -365,14 +517,14 @@ class RemoveCallback(callbacks.UpdateCallback):
log.info(self.progress.percent)
def done(self):
- #self.backend.status('Done')
# self.progress.step()
- log.info("DONEEEEEEEEEEEE")
+ log.info("Some Problem ...............>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
+ log.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
def warning(self, msg, *args, **kwargs):
e = msg %args
+ self.error.append(e)
log.error("<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
- log.error(e)
- self.backend.error(ERROR_DEP_RESOLUTION_FAILED, e, False )
+ log.error( args )
diff --git a/backends/conary/conaryProgress.py b/backends/conary/conaryProgress.py
new file mode 100644
index 0000000..644ba98
--- /dev/null
+++ b/backends/conary/conaryProgress.py
@@ -0,0 +1,105 @@
+# Licensed under the GNU General Public License Version 2
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright (C) 2008
+# Richard Hughes <richard at hughsie.com>
+
+class PackagekitProgress:
+ '''
+ Progress class there controls the total progress of a transaction
+ the transaction is divided in n milestones. the class contains a subpercentage
+ of the current step (milestone n -> n+1) and the percentage of the whole transaction
+
+ Usage:
+
+ from packagekit import PackagekitProgress
+
+ steps = [10, 30, 50, 70] # Milestones in %
+ progress = PackagekitProgress()
+ progress.set_steps(steps)
+ for milestone in range(len(steps)):
+ # do the action is this step
+ for i in range(100):
+ # do some action
+ progress.set_subpercent(i+1)
+ print "progress : %s " % progress.percent
+ progress.step() # step to next milestone
+
+
+ *** NOTE! a BIGNOTE:
+ if you do a progress.step() and if the next is a sub_percent() _not print the percente_ first
+ set_subpercent an then print progress.percent.
+ '''
+
+ #TODO: Add support for elapsed/remaining time
+
+ def __init__(self):
+ self.percent = 0
+ self.steps = []
+ self.current_step = 0
+ self.subpercent = 0
+
+ def set_steps(self, steps):
+ '''
+ Set the steps for the whole transaction
+ @param steps: list of int representing the percentage of each step in the transaction
+ '''
+ self.reset()
+ self.steps = steps
+ self.current_step = 0
+
+ def reset(self):
+ self.percent = 0
+ self.steps = []
+ self.current_step = 0
+ self.subpercent = 0
+
+ def step(self):
+ '''
+ Step to the next step in the transaction
+ '''
+ if self.current_step < len(self.steps)-1:
+ self.current_step += 1
+ self.percent = self.steps[self.current_step]
+ self.subpercent = 0
+ else:
+ self.percent = 100
+ self.subpercent = 0
+
+ def set_subpercent(self, pct):
+ '''
+ Set subpercentage and update percentage
+ '''
+ self.subpercent = pct
+ self._update_percent()
+
+ def _update_percent(self):
+ '''
+ Increment percentage based on current step and subpercentage
+ '''
+ if self.current_step == 0:
+ startpct = 0
+ else:
+ startpct = self.steps[self.current_step-1]
+ if self.current_step < len(self.steps)-1:
+ endpct = self.steps[self.current_step]
+ else:
+ endpct = 100
+ deltapct = endpct -startpct
+ f = float(self.subpercent)/100.0
+ incr = int(f*deltapct)
+ self.percent = startpct + incr
+
commit 5281a5b43ebc837c6e883b70aa720615233efe9b
Merge: 6fe3a08... 28085b0...
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Fri Feb 20 05:06:42 2009 +0100
Merge branch 'master' of git+ssh://glatzor@git.packagekit.org/srv/git/PackageKit
commit 9b898a676135d9c181f88fd4df6554309cf58d06
Merge: 1b8b519... 28085b0...
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Wed Feb 18 23:04:50 2009 -0600
Merge branch 'master' of git+ssh://zodman@git.packagekit.org/srv/git/PackageKit
commit 6fe3a080792ce881cf5a8280d4e003a5abac5d90
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Thu Feb 19 05:07:23 2009 +0100
APT: Add script to extract information from app-install desktop files
diff --git a/backends/apt/update-packagekit-app-data b/backends/apt/update-packagekit-app-data
new file mode 100755
index 0000000..b0e6a57
--- /dev/null
+++ b/backends/apt/update-packagekit-app-data
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+# update-packagekit-app-data - Generate a cache of mime type and codec handlers
+# Authors: Michael Vogt <mvo at ubuntu.com>
+# Sebastian Heinlein <devel at glatzor.de>
+
+import sys
+import glob
+import os
+import os.path
+import re
+import sys
+
+from optparse import OptionParser
+
+import gdbm
+
+try:
+ import xdg.DesktopEntry
+except ImportError, e:
+ print "WARNING: can not import xdg.DesktopEntry, aborting"
+ sys.exit(0)
+
+def generate_mime_map(desktop_dir, cache_dir):
+ dicts = { 'mime':{}, 'codec':{} }
+
+ def record_provider(de, cp, defield,dictname):
+ try:
+ keys = de.get(defield, list=True)
+ except keyError:
+ return
+ if not keys: return
+ dict = dicts[dictname]
+ for key in keys:
+ # gst-caps support
+ if dictname == 'codec' and ',' in key:
+ key = key.split(",")[0]
+ try:
+ l = dict[key]
+ except KeyError:
+ l = []; dict[key] = l
+ l.append(cp)
+
+ for fn in glob.glob(os.path.join(desktop_dir, 'desktop/*.desktop')):
+ try:
+ de = xdg.DesktopEntry.DesktopEntry(fn)
+ except Exception, e:
+ print >>sys.stderr, "bad .desktop file: %s: %s" % (fn, e)
+ try:
+ component = de.get('X-AppInstall-Section')
+ package = de.get('X-AppInstall-Package')
+ except KeyError:
+ continue
+ cp = component+"/"+package
+ record_provider(de, cp, 'MimeType','mime')
+ record_provider(de, cp, 'X-AppInstall-Codecs','codec')
+
+ for (dictname, dict) in dicts.iteritems():
+ g = gdbm.open(os.path.join(cache_dir,
+ dictname+"-map.gdbm"),
+ 'nfu')
+ for (key,l) in dict.iteritems():
+ g[key] = ' '.join(l)
+ g.sync()
+ g.close()
+
+def main():
+ parser = OptionParser()
+ parser.add_option ("-d", "--desktop-dir", action="store",
+ dest="desktop_dir",
+ default="/usr/share/app-install",
+ help="Directory that contains the desktop files "
+ "of the applications")
+ parser.add_option ("-c", "--cache-dir", action="store",
+ dest="cache_dir",
+ default="/var/lib/PackageKit",
+ help="Directory where the data should be cached in")
+ (options, args) = parser.parse_args()
+ for path in (options.desktop_dir, options.cache_dir):
+ if not os.path.isdir(path):
+ print "%s is not a valid directory" % path
+ sys.exit(1)
+ print "Generating mime/codec maps..."
+ generate_mime_map(options.desktop_dir, options.cache_dir)
+
+if __name__ == "__main__":
+ main()
commit 28085b0cb87658d19f1e888f53a5b1a9d21b049b
Author: Scott Reeves <sreeves at novell.com>
Date: Wed Feb 18 11:38:51 2009 -0700
zypp - fix up virtual callback methods
diff --git a/backends/zypp/zypp-events.h b/backends/zypp/zypp-events.h
index fa8f52e..1c7973e 100644
--- a/backends/zypp/zypp-events.h
+++ b/backends/zypp/zypp-events.h
@@ -273,7 +273,7 @@ struct RepoProgressReportReceiver : public zypp::callback::ReceiveReport<zypp::P
struct RepoReportReceiver : public zypp::callback::ReceiveReport<zypp::repo::RepoReport>, ZyppBackendReceiver
{
- virtual void start (const zypp::ProgressData &data)
+ virtual void start (const zypp::ProgressData &data, const zypp::RepoInfo)
{
egg_debug ("______________________ RepoReportReceiver::start()________________________");
reset_sub_percentage ();
@@ -286,7 +286,7 @@ struct RepoReportReceiver : public zypp::callback::ReceiveReport<zypp::repo::Rep
return true;
}
- virtual void finish (const zypp::ProgressData &data)
+ virtual void finish (zypp::Repository source, const std::string &task, zypp::repo::RepoReport::Error error, const std::string &reason)
{
//fprintf (stderr, "\n\n----> RepoReportReceiver::finish()\n");
}
@@ -310,7 +310,7 @@ struct DownloadProgressReportReceiver : public zypp::callback::ReceiveReport<zyp
}
}
- virtual bool progress (int value, const zypp::Url &file)
+ virtual bool progress (int value, const zypp::Url &file, double dbps_avg, double dbps_current)
{
//fprintf (stderr, "\n\n----> DownloadProgressReportReceiver::progress(), %s:%d\n\n", _package_id == NULL ? "unknown" : _package_id, value);
if (_package_id != NULL)
@@ -386,14 +386,12 @@ struct DigestReportReceiver : public zypp::callback::ReceiveReport<zypp::DigestR
struct MediaChangeReportReceiver : public zypp::callback::ReceiveReport<zypp::media::MediaChangeReport>, ZyppBackendReceiver
{
- virtual Action requestMedia (zypp::Url &url, unsigned mediaNr, zypp::media::MediaChangeReport::Error error, const std::string &probl)
- {
- pk_backend_error_code (_backend,
- PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED,
- probl.c_str ());
- // We've to abort here, because there is currently no feasible way to inform the user to insert/change media
- return ABORT;
- }
+ virtual Action requestMedia (zypp::Url &url, unsigned mediaNr, const std::string &label, zypp::media::MediaChangeReport::Error error, const std::string &description, const std::vector<std::string> & devices, unsigned int &dev_current)
+ {
+ pk_backend_error_code (_backend, PK_ERROR_ENUM_REPO_NOT_AVAILABLE, description.c_str ());
+ // We've to abort here, because there is currently no feasible way to inform the user to insert/change media
+ return ABORT;
+ }
};
struct ProgressReportReceiver : public zypp::callback::ReceiveReport<zypp::ProgressReport>, ZyppBackendReceiver
commit fe25123c8ea95416f8640a6b923b548dd1c427f0
Author: Richard Hughes <richard at hughsie.com>
Date: Wed Feb 18 15:13:34 2009 +0000
feature: add a pk-app-install binary for manipulating the sqlite cache
diff --git a/configure.ac b/configure.ac
index 1ce261c..e4478ab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -393,6 +393,13 @@ fi
AM_CONDITIONAL(PK_BUILD_GSTREAMER_PLUGIN, test $build_gstreamer_plugin = "yes")
dnl ---------------------------------------------------------------------------
+dnl - Able to build gstreamer plugin
+dnl ---------------------------------------------------------------------------
+AC_ARG_ENABLE(app_install, AS_HELP_STRING([--enable-app-install],[Build application installer functionality]),
+ enable_app_install=$enableval,enable_app_install=no)
+AM_CONDITIONAL(PK_BUILD_APP_INSTALL, test $enable_app_install = "yes")
+
+dnl ---------------------------------------------------------------------------
dnl - Able to build GTK module
dnl ---------------------------------------------------------------------------
AC_ARG_ENABLE(gtk_module, AS_HELP_STRING([--enable-gtk-module],[Build GTK module functionality]),
@@ -690,6 +697,7 @@ contrib/gstreamer-plugin/Makefile
contrib/gtk-module/Makefile
contrib/yum-packagekit/Makefile
contrib/command-not-found/Makefile
+contrib/app-install/Makefile
contrib/ruck/Makefile
contrib/ruck/src/Makefile
backends/Makefile
@@ -754,6 +762,7 @@ echo "
GIO support: ${with_gio}
Browser plugin: ${build_browser_plugin}
GStreamer plugin: ${build_gstreamer_plugin}
+ Application install: ${enable_app_install}
Pango module: ${build_gtk_module}
BASH Command not found: ${build_command_not_found}
RUCK client: ${build_ruck}
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
index 4e47d70..843479a 100644
--- a/contrib/Makefile.am
+++ b/contrib/Makefile.am
@@ -12,6 +12,10 @@ if PK_BUILD_BROWSER_PLUGIN
SUBDIRS += browser-plugin
endif
+if PK_BUILD_APP_INSTALL
+SUBDIRS += app-install
+endif
+
if PK_BUILD_GSTREAMER_PLUGIN
SUBDIRS += gstreamer-plugin
endif
diff --git a/contrib/app-install/.gitignore b/contrib/app-install/.gitignore
new file mode 100644
index 0000000..c651369
--- /dev/null
+++ b/contrib/app-install/.gitignore
@@ -0,0 +1,6 @@
+.deps
+.libs
+*.o
+pk-app-install
+*.db
+
diff --git a/contrib/app-install/Makefile.am b/contrib/app-install/Makefile.am
new file mode 100644
index 0000000..8b39051
--- /dev/null
+++ b/contrib/app-install/Makefile.am
@@ -0,0 +1,32 @@
+## We require new-style dependency handling.
+AUTOMAKE_OPTIONS = 1.7
+
+INCLUDES = \
+ $(GLIB_CFLAGS) \
+ $(SQLITE_CFLAGS) \
+ -DPACKAGE_LOCALE_DIR=\"$(localedir)\" \
+ -DSYSCONFDIR=\""$(sysconfdir)"\" \
+ -DDATADIR=\""$(datadir)"\" \
+ -DEGG_LOG_FILE=\""$(PK_LOG_DIR)/PackageKit"\" \
+ -DEGG_VERBOSE="\"PK_VERBOSE\"" \
+ -DEGG_LOGGING="\"PK_LOGGING\"" \
+ -DEGG_CONSOLE="\"PK_CONSOLE\"" \
+ -I$(top_srcdir)/lib
+
+sbin_PROGRAMS = pk-app-install
+
+pk_app_install_SOURCES = \
+ egg-debug.c \
+ egg-debug.h \
+ pk-app-install.c \
+ $(NULL)
+
+pk_app_install_LDADD = \
+ $(GLIB_LIBS) \
+ $(SQLITE_LIBS) \
+ $(NULL)
+
+pk_app_install_CFLAGS = \
+ $(WARNINGFLAGS_C) \
+ $(NULL)
+
diff --git a/contrib/app-install/egg-debug.c b/contrib/app-install/egg-debug.c
new file mode 120000
index 0000000..663c6cd
--- /dev/null
+++ b/contrib/app-install/egg-debug.c
@@ -0,0 +1 @@
+../command-not-found/egg-debug.c
\ No newline at end of file
diff --git a/contrib/app-install/egg-debug.h b/contrib/app-install/egg-debug.h
new file mode 120000
index 0000000..51c7d17
--- /dev/null
+++ b/contrib/app-install/egg-debug.h
@@ -0,0 +1 @@
+../command-not-found/egg-debug.h
\ No newline at end of file
diff --git a/contrib/app-install/pk-app-install.c b/contrib/app-install/pk-app-install.c
new file mode 100644
index 0000000..f8a6263
--- /dev/null
+++ b/contrib/app-install/pk-app-install.c
@@ -0,0 +1,270 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2009 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <sqlite3.h>
+
+#include "egg-debug.h"
+
+#if PK_BUILD_LOCAL
+#define PK_APP_INSTALL_DEFAULT_DATABASE "./desktop.db"
+#else
+#define PK_APP_INSTALL_DEFAULT_DATABASE DATADIR "/app-install/cache/desktop.db"
+#endif
+
+/**
+ * pk_app_install_create:
+ **/
+static gboolean
+pk_app_install_create (const gchar *cache)
+{
+ gboolean ret = TRUE;
+ gboolean create_file;
+ const gchar *statement;
+ sqlite3 *db = NULL;
+ gint rc;
+
+ /* if the database file was not installed (or was nuked) recreate it */
+ create_file = g_file_test (cache, G_FILE_TEST_EXISTS);
+ if (create_file == TRUE) {
+ egg_warning ("already exists");
+ goto out;
+ }
+
+ egg_debug ("exists: %i", create_file);
+
+ /* open database */
+ rc = sqlite3_open (cache, &db);
+ if (rc) {
+ egg_warning ("Can't open database: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+
+ /* don't sync */
+ statement = "PRAGMA synchronous=OFF";
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't turn off sync: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+
+ egg_debug ("create");
+ if (create_file == FALSE) {
+ statement = "CREATE TABLE general ("
+ "application_id TEXT primary key,"
+ "package_name TEXT,"
+ "icon_name TEXT,"
+ "group_id TEXT,"
+ "repo_name TEXT,"
+ "application_name TEXT,"
+ "application_summary TEXT);";
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't create general table: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ statement = "CREATE TABLE localised ("
+ "application_id TEXT primary key,"
+ "application_name TEXT,"
+ "application_summary TEXT,"
+ "locale TEXT);";
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't create localised table: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ }
+
+out:
+ if (db != NULL)
+ sqlite3_close (db);
+ return ret;
+}
+
+/**
+ * pk_app_install_remove:
+ **/
+static gboolean
+pk_app_install_remove (const gchar *cache, const gchar *repo)
+{
+ gboolean ret = TRUE;
+ gchar *statement = NULL;
+ sqlite3 *db = NULL;
+ gint rc;
+
+ /* open database */
+ rc = sqlite3_open (cache, &db);
+ if (rc) {
+ egg_warning ("Can't open database: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+
+ /* delete from localised (localised has no repo_name, so key off general) */
+ statement = g_strdup_printf ("DELETE FROM localised WHERE EXISTS ( "
+ "SELECT general.application_id FROM general WHERE "
+ "general.application_id = general.application_id AND general.repo_name = '%s')", repo);
+// statement = g_strdup_printf ("SELECT general.application_id FROM general WHERE general.application_id == general.application_id AND general.repo_name == '%s'", repo);
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't remove rows: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ egg_debug ("%i removals from localised", sqlite3_changes (db));
+ g_free (statement);
+
+ /* delete from general */
+ statement = g_strdup_printf ("DELETE FROM general WHERE repo_name = '%s'", repo);
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't remove rows: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+ egg_debug ("%i removals from general", sqlite3_changes (db));
+ g_free (statement);
+
+ /* reclaim memory */
+ statement = g_strdup ("VACUUM");
+ rc = sqlite3_exec (db, statement, NULL, NULL, NULL);
+ if (rc) {
+ egg_warning ("Can't vacuum: %s\n", sqlite3_errmsg (db));
+ ret = FALSE;
+ goto out;
+ }
+
+out:
+ g_free (statement);
+ if (db != NULL)
+ sqlite3_close (db);
+ return ret;
+}
+
+/**
+ * pk_app_install_add:
+ **/
+static gboolean
+pk_app_install_add (const gchar *cache, const gchar *repo, const gchar *source)
+{
+ egg_debug ("add");
+ return TRUE;
+}
+
+/**
+ * main:
+ **/
+int
+main (int argc, char *argv[])
+{
+ gboolean verbose = FALSE;
+ GOptionContext *context;
+ gint retval = 0;
+ gchar *action = NULL;
+ gchar *cache = NULL;
+ gchar *repo = NULL;
+ gchar *source = NULL;
+
+ const GOptionEntry options[] = {
+ { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose,
+ _("Show extra debugging information"), NULL },
+ { "action", 'c', 0, G_OPTION_ARG_STRING, &action,
+ /* TRANSLATORS: the action is non-localised */
+ _("The action, one of 'create', 'add', or 'remove'"), NULL},
+ { "cache", 'c', 0, G_OPTION_ARG_STRING, &cache,
+ /* TRANSLATORS: if we are specifing a out-of-tree database */
+ _("Main cache file to use (if not specififed, default is used)"), NULL},
+ { "source", 's', 0, G_OPTION_ARG_STRING, &source,
+ /* TRANSLATORS: the source database, typically used for adding */
+ _("Source cache file to add to the main database"), NULL},
+ { "repo", 'n', 0, G_OPTION_ARG_STRING, &repo,
+ /* TRANSLATORS: the repo of the software source, e.g. fedora */
+ _("Name of the remote repo"), NULL},
+ { NULL}
+ };
+
+ setlocale (LC_ALL, "");
+ bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+
+ context = g_option_context_new (NULL);
+ /* TRANSLATORS: tool that gets called when the command is not found */
+ g_option_context_set_summary (context, _("PackageKit Application Database Installer"));
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_parse (context, &argc, &argv, NULL);
+ g_option_context_free (context);
+
+ egg_debug_init (verbose);
+
+ egg_debug ("cache=%s, source=%s, repo=%s", cache, source, repo);
+
+ /* use default */
+ if (cache == NULL) {
+ egg_debug ("cache not specified, using %s", PK_APP_INSTALL_DEFAULT_DATABASE);
+ cache = g_strdup (PK_APP_INSTALL_DEFAULT_DATABASE);
+ }
+
+ if (g_strcmp0 (action, "create") == 0) {
+ pk_app_install_create (cache);
+ } else if (g_strcmp0 (action, "add") == 0) {
+ if (repo == NULL) {
+ egg_warning ("A repo name is required");
+ retval = 1;
+ goto out;
+ }
+ if (source == NULL) {
+ egg_warning ("A source filename is required");
+ retval = 1;
+ goto out;
+ }
+ if (!g_file_test (source, G_FILE_TEST_EXISTS)) {
+ egg_warning ("The source filename '%s' could not be found", source);
+ retval = 1;
+ goto out;
+ }
+ pk_app_install_remove (cache, repo, source);
+ } else if (g_strcmp0 (action, "remove") == 0) {
+ if (repo == NULL) {
+ egg_warning ("A repo name is required");
+ retval = 1;
+ goto out;
+ }
+ pk_app_install_remove (cache, repo);
+ } else {
+ egg_warning ("An action is required");
+ retval = 1;
+ }
+
+out:
+ g_free (cache);
+ g_free (repo);
+ g_free (source);
+ return 0;
+}
+
diff --git a/docs/app-install-v1.draft b/docs/app-install-v1.draft
index 4894dc3..fc4d7d0 100644
--- a/docs/app-install-v1.draft
+++ b/docs/app-install-v1.draft
@@ -81,21 +81,21 @@ TABLE localised:
STRING application_id (name of the desktop file, with no extension)
STRING application_name (Name in desktop file, in locale)
STRING application_summary (Comment in desktop file, in locale)
-STRING repo_name (for adding and removal)
STRING locale
TABLE general
STRING application_id (name of the desktop file, with no extension)
STRING package_name (to save on expensive SearchFile's)
STRING icon_name (without path or extension)
-STRING group (Categories from desktop file, _not_ PK groups or PK categories)
+STRING group_id (Categories from desktop file, _not_ PK groups or PK categories)
STRING repo_name (for adding and removal)
STRING application_name (Name in desktop file)
STRING application_summary (Comment in desktop file)
== Possible Commands ==
-pk-app-install-merge-cache --name=livna --source=/var/cache/yum/livna-apps.db --cache=/usr/share/app-install/cache/desktop.db
-pk-app-install-remove-cache --name=livna --cache=/usr/share/app-install/cache/desktop.db
+pk-app-install action=create --cache=/usr/share/app-install/cache/desktop.db
+pk-app-install action=add --repo=livna --source=/var/cache/yum/livna-apps.db --cache=/usr/share/app-install/cache/desktop.db
+pk-app-install action=remove --repo=livna --cache=/usr/share/app-install/cache/desktop.db
* need to do the latter then former in a spec file on upgrade
all distro specific stuff to live in backends/, but typically:
commit 1b8b51939f31868549cc6c93038f3ec63549eebd
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Wed Feb 18 04:57:00 2009 -0600
conary: fix step feeling for percent download
diff --git a/backends/conary/conaryCallback.py b/backends/conary/conaryCallback.py
index fd8d327..2dd99c8 100644
--- a/backends/conary/conaryCallback.py
+++ b/backends/conary/conaryCallback.py
@@ -76,7 +76,7 @@ class UpdateCallback(callbacks.UpdateCallback):
self.smallUpdate = False
self.error = []
self.progress = PackagekitProgress()
- self.progress.set_steps([ 0,5,10,15,20,60,75,80,90,100 ] )
+ self.progress.set_steps([ 0,5,8,10,12,20,35,80,90,100 ] )
# 1
# 4
def requestingChangeSet(self):
commit c629201183f3c280ea73358e83d355785812220b
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Wed Feb 18 04:53:28 2009 -0600
conary: add callback fix for remove/update
replace status signals invalid
diff --git a/backends/conary/conaryBackend.py b/backends/conary/conaryBackend.py
index 1d2fe8e..f54928d 100755
--- a/backends/conary/conaryBackend.py
+++ b/backends/conary/conaryBackend.py
@@ -506,7 +506,7 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
self.error(ERROR_PACKAGE_ALREADY_INSTALLED,
'Package already installed')
- self.status(INFO_INSTALLING)
+ self.status(STATUS_INSTALL)
log.info(">>> Prepare Update")
self._get_package_update(name, version, flavor)
log.info(">>> end Prepare Update")
@@ -533,7 +533,7 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
self.error(ERROR_PACKAGE_NOT_INSTALLED, 'The package %s is not installed' % name)
name = '-%s' % name
- self.status(INFO_REMOVING)
+ self.status(STATUS_REMOVE)
self._get_package_update(name, version, flavor)
self._do_package_update(name, version, flavor)
else:
diff --git a/backends/conary/conaryCallback.py b/backends/conary/conaryCallback.py
index 2a259ed..fd8d327 100644
--- a/backends/conary/conaryCallback.py
+++ b/backends/conary/conaryCallback.py
@@ -253,7 +253,7 @@ class RemoveCallback(callbacks.UpdateCallback):
self.smallUpdate = False
self.error = []
self.progress = PackagekitProgress()
- self.progress.set_steps([ 0,5,10,15,20,60,75,80,90,100 ] )
+ self.progress.set_steps([ 0,5,10,15,20,60,75,100 ] )
# 1
def resolvingDependencies(self):
#self.backend.status('Resolving Dependencies')
@@ -315,11 +315,12 @@ class RemoveCallback(callbacks.UpdateCallback):
self.progress.set_subpercent(sub_percent)
self.backend.percentage(self.progress.percent)
- if troveNum > 0:
- troveNum -= 1
- log.info("currentJob")
- log.info(self.currentJob[troveNum])
- job = self.currentJob[troveNum]
+ log.info("currentJob %s" % troveNum)
+ log.info("job %s" % self.currentJob)
+ if len(self.currentJob) > troveNum:
+ job = self.currentJob[troveNum]
+ else:
+ return
name = job[0]
oldVersion, oldFlavor = job[1]
newVersion, newFlavor = job[2]
@@ -345,7 +346,7 @@ class RemoveCallback(callbacks.UpdateCallback):
self.progress.step()
self.backend.percentage(self.progress.percent)
log.info(self.progress.percent)
- self.preparingUpdate(troveNum, troveCount, add=troveCount)
+ #self.preparingUpdate(troveNum, troveCount, add=troveCount)
#8
def committingTransaction(self):
#self.backend.status('Committing Transaction')
commit b9d40eeab0bd3c0b3d0613147a25a45134ca83cf
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Wed Feb 18 04:11:42 2009 -0600
add getUpdate Callback.. work the percent
diff --git a/backends/conary/conaryBackend.py b/backends/conary/conaryBackend.py
index dfdf10a..1d2fe8e 100755
--- a/backends/conary/conaryBackend.py
+++ b/backends/conary/conaryBackend.py
@@ -33,7 +33,7 @@ from conary.conaryclient import cmdline
from packagekit.backend import *
from packagekit.package import *
from packagekit.progress import PackagekitProgress
-from conaryCallback import UpdateCallback
+from conaryCallback import UpdateCallback, GetUpdateCallback, RemoveCallback
from conaryFilter import *
from XMLCache import XMLCache as Cache
from conaryInit import *
@@ -524,6 +524,7 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
self.status(STATUS_RUNNING)
log.info("========== Remove Packages ============ ")
log.info( allowDeps )
+ self.client.setUpdateCallback(RemoveCallback(self, self.cfg))
#for package_id in package_ids.split('%'):
for package_id in package_ids:
name, version, flavor, installed = self._findPackage(package_id)
@@ -537,6 +538,7 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
self._do_package_update(name, version, flavor)
else:
self.error(ERROR_PACKAGE_ALREADY_INSTALLED, 'The package was not found')
+ self.client.setUpdateCallback(self.callback)
def _get_metadata(self, package_id, field):
'''
@@ -705,13 +707,15 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
self.allow_cancel(True)
self.percentage(0)
self.status(STATUS_INFO)
+ getUpdateC= GetUpdateCallback(self,self.cfg)
+ self.client.setUpdateCallback(getUpdateC)
+ log.info("callback changed")
log.info("============== get_updates ========================")
cli = ConaryPk()
updateItems =cli.cli.fullUpdateItemList()
# updateItems = cli.cli.getUpdateItemList()
for i in updateItems:
log.info(i[0])
- log.info("============== end get_updates ========================")
applyList = [ (x[0], (None, None), x[1:], True) for x in updateItems ]
log.info("_get_update ....")
updJob, suggMap = self._get_update(applyList)
@@ -740,7 +744,8 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
troveTuple.append(version)
installed = self.check_installed(troveTuple)
self._show_package(name, version, flavor, INFO_NORMAL)
-
+ log.info("============== end get_updates ========================")
+ self.client.setUpdateCallback(self.callback)
def _findPackage(self, package_id):
'''
diff --git a/backends/conary/conaryCallback.py b/backends/conary/conaryCallback.py
index dd056b5..2a259ed 100644
--- a/backends/conary/conaryCallback.py
+++ b/backends/conary/conaryCallback.py
@@ -22,8 +22,49 @@ from packagekit.backend import *
from packagekit.progress import PackagekitProgress
from pkConaryLog import log
-class UpdateCallback(callbacks.UpdateCallback):
+MEGA = 1048576.0
+
+class GetUpdateCallback(callbacks.UpdateCallback):
+ def __init__(self, backend, cfg=None):
+ callbacks.UpdateCallback.__init__(self)
+ log.info("==== callback ==== ")
+ if cfg:
+ self.setTrustThreshold(cfg.trustThreshold)
+
+ self.backend = backend
+ self.currentJob = None
+ self.smallUpdate = False
+ self.error = []
+ self.progress = PackagekitProgress()
+ self.progress.set_steps([1,2,50, 100 ] )
+ # 1 >> downloadingChangeSet
+ # 2 >> downloadingChangeSet
+ def requestingChangeSet(self):
+ log.info("Callback getUpdates ........ STATUS_REQUEST changeset ")
+ self.backend.status(STATUS_REQUEST)
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+ self.progress.step()
+
+ def downloadingChangeSet(self, got, need):
+ log.info("Callback getUpdates. Changeset %s percent of %s/%s bytes" % ( int( got*100/float(need)), got/MEGA,need/MEGA) )
+ self.backend.status(STATUS_DOWNLOAD)
+ self.progress.set_subpercent( got*100 / float(need) )
+ self.backend.percentage( self.progress.percent )
+ log.info( "%s percent" % self.progress.percent)
+ # 3
+ def resolvingDependencies(self):
+ #self.backend.status('Resolving Dependencies')
+ self.backend.status(STATUS_DEP_RESOLVE)
+ self.progress.step()
+ log.info("Callback getUpdates........ STATUS_DEP_RESOLVE ")
+ self.backend.percentage(self.progress.percent)
+ log.info("do a step>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+
+class UpdateCallback(callbacks.UpdateCallback):
def __init__(self, backend, cfg=None):
callbacks.UpdateCallback.__init__(self)
log.info("==== callback ==== ")
@@ -46,7 +87,7 @@ class UpdateCallback(callbacks.UpdateCallback):
self.progress.step()
def downloadingChangeSet(self, got, need):
- log.info("Callback ........ STATUS_DOWNLOAD Changeset %s percent %s/%s bytes" % ( got*100/float(need), got,need) )
+ log.info("Callback ........ STATUS_DOWNLOAD Changeset %s percent %s/%s bytes" % ( got*100/float(need), got/MEGA,need/MEGA) )
self.progress.set_subpercent( got*100 / float(need) )
self.backend.percentage( self.progress.percent )
log.info( "%s percent" % self.progress.percent)
@@ -184,14 +225,6 @@ class UpdateCallback(callbacks.UpdateCallback):
#self.backend.status('Done')
# self.progress.step()
log.info("DONEEEEEEEEEEEE")
- """
- e = ""
- for i in self.error:
- e = e + i
- log.error(i)
- if self.error:
- self.backend.error(ERROR_DEP_RESOLUTION_FAILED, e)
- """
def warning(self, msg, *args, **kwargs):
e = msg %args
@@ -208,4 +241,137 @@ class UpdateCallback(callbacks.UpdateCallback):
def troveScriptFailure(self, typ, errcode):
pass
+class RemoveCallback(callbacks.UpdateCallback):
+ def __init__(self, backend, cfg=None):
+ callbacks.UpdateCallback.__init__(self)
+ log.info("==== callback ==== ")
+ if cfg:
+ self.setTrustThreshold(cfg.trustThreshold)
+
+ self.backend = backend
+ self.currentJob = None
+ self.smallUpdate = False
+ self.error = []
+ self.progress = PackagekitProgress()
+ self.progress.set_steps([ 0,5,10,15,20,60,75,80,90,100 ] )
+ # 1
+ def resolvingDependencies(self):
+ #self.backend.status('Resolving Dependencies')
+ log.info("Callback ........ STATUS_DEP_RESOLVE ")
+ self.backend.percentage(self.progress.percent)
+ self.backend.status(STATUS_DEP_RESOLVE)
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+ #2
+ def setChangesetHunk(self, num, total):
+ log.info("callback. .......... set Changeset HUnk %s/%s" % (num, total ) )
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+ #3
+ def setUpdateHunk(self, hunk, hunkCount):
+ log.info("callback. .......... set update HUnk %s/%s" % ( hunk, hunkCount))
+ self.progress.step()
+
+ if hunk < hunkCount:
+ p = hunk / float(hunkCount) * 100.0
+ self.progress.set_subpercent(p)
+ else:
+ self.smallUpdate = True
+
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+ #4
+ def setUpdateJob(self, job):
+ log.info("callback. .......... set update Job")
+ self.currentJob = job
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+ #5
+ def creatingRollback(self):
+ #self.backend.status('Creating Rollback')
+ log.info("Callback ........ STATUS_ROLLBACK ")
+ self.backend.status(STATUS_ROLLBACK)
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+ #6
+ def removeFiles(self, filenum, total):
+ log.info("Callback ........ STATUS_REMOVE %s/%sfiles" %( filenum, total) )
+ self.backend.status(STATUS_REMOVE)
+ self.preparingUpdate(filenum, total, add=total)
+
+ #7
+ def preparingUpdate(self, troveNum, troveCount, add=0):
+ log.info("callback ....... preparing Update trove %s/%s" % (troveNum, troveCount) )
+ #self.progress.step()
+ if not self.currentJob or len(self.currentJob) == 0 or troveNum > troveCount:
+ return
+
+ if troveNum > 0 and troveCount > 0:
+ sub_percent = (add + troveNum) / (2 * float(troveCount)) * 100
+ self.progress.set_subpercent(sub_percent)
+
+ self.backend.percentage(self.progress.percent)
+ if troveNum > 0:
+ troveNum -= 1
+ log.info("currentJob")
+ log.info(self.currentJob[troveNum])
+ job = self.currentJob[troveNum]
+ name = job[0]
+ oldVersion, oldFlavor = job[1]
+ newVersion, newFlavor = job[2]
+ #log.info("JOB>>>>>>>> %s " % str(job) )
+ if oldVersion and newVersion:
+ log.info("Callback ........ STATUS_UPDATE preparing Update ")
+ self.backend.status(STATUS_UPDATE)
+ package_id = self.backend.get_package_id(name, newVersion, newFlavor)
+ self.backend.package(package_id, INFO_UPDATING, '')
+ elif oldVersion and not newVersion:
+ log.info("Callback ........ STATUS_REMOVE preparing Update ")
+ self.backend.status(STATUS_REMOVE)
+ package_id = self.backend.get_package_id(name, oldVersion, oldFlavor)
+ self.backend.package(package_id, INFO_REMOVING, '')
+ elif not oldVersion and newVersion:
+ log.info("Callback ........ STATUS_INSTALL preparing Update")
+ self.backend.status(STATUS_INSTALL)
+ package_id = self.backend.get_package_id(name, newVersion, newFlavor)
+ self.backend.package(package_id, INFO_INSTALLING, '')
+ log.info(self.progress.percent)
+ def creatingDatabaseTransaction(self, troveNum, troveCount):
+ log.info("callback. .......... creating Database Transactions")
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+ self.preparingUpdate(troveNum, troveCount, add=troveCount)
+ #8
+ def committingTransaction(self):
+ #self.backend.status('Committing Transaction')
+ log.info("Callback ........ STATUS_COMMIT transactions ")
+
+ self.backend.status(STATUS_COMMIT)
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ log.info(self.progress.percent)
+ #9
+ def updateDone(self):
+ log.info("callback. .......... update done")
+ self.progress.step()
+ self.backend.percentage(self.progress.percent)
+ self.currentJob = None
+ log.info(self.progress.percent)
+ def done(self):
+ #self.backend.status('Done')
+ # self.progress.step()
+ log.info("DONEEEEEEEEEEEE")
+
+ def warning(self, msg, *args, **kwargs):
+ e = msg %args
+ log.error("<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
+ log.error(e)
+ self.backend.error(ERROR_DEP_RESOLUTION_FAILED, e, False )
+
+
commit 28bfa161725b1c0c2af3050d09535f8eaaa409ab
Merge: afba3b6... 50d3943...
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Wed Feb 18 01:56:10 2009 -0600
Merge branch 'master' of git+ssh://zodman@git.packagekit.org/srv/git/PackageKit
commit afba3b69d18c1f39ecc14d53f03a6a78250b1391
Merge: 6b8525f... 1fbc53f...
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Tue Feb 17 15:41:43 2009 -0600
Merge branch 'master' of git+ssh://zodman@git.packagekit.org/srv/git/PackageKit
commit 6b8525f0289ce0329b1e00ebdabdde658e877d10
Author: Andres Vargas ( zodman ) <zodman at foresightlinux.org>
Date: Tue Feb 17 01:57:11 2009 -0600
conary: tunning the percent update
diff --git a/backends/conary/conaryBackend.py b/backends/conary/conaryBackend.py
index 70687a5..dfdf10a 100755
--- a/backends/conary/conaryBackend.py
+++ b/backends/conary/conaryBackend.py
@@ -295,6 +295,7 @@ class PackageKitConaryBackend(PackageKitBaseBackend):
solved = False
if pkg_dict is None:
# verifica si esta en repositorios
+ log.info("doing a rq")
troveTuple = conary_cli.query(package[0])
if not troveTuple:
self.error(ERROR_INTERNAL_ERROR, "Package Not found")
@@ -782,7 +783,7 @@ from pkConaryLog import pdb
def main():
backend = PackageKitConaryBackend('')
log.info("======== argv =========== ")
- log.info(sys.argv[1:])
+ log.info(sys.argv)
backend.dispatcher(sys.argv[1:])
if __name__ == "__main__":
diff --git a/backends/conary/conaryCallback.py b/backends/conary/conaryCallback.py
index 712fdd3..dd056b5 100644
--- a/backends/conary/conaryCallback.py
+++ b/backends/conary/conaryCallback.py
@@ -35,7 +35,7 @@ class UpdateCallback(callbacks.UpdateCallback):
self.smallUpdate = False
self.error = []
self.progress = PackagekitProgress()
- self.progress.set_steps( range( 1, 101,10) )
+ self.progress.set_steps([ 0,5,10,15,20,60,75,80,90,100 ] )
# 1
# 4
def requestingChangeSet(self):
@@ -47,8 +47,8 @@ class UpdateCallback(callbacks.UpdateCallback):
def downloadingChangeSet(self, got, need):
log.info("Callback ........ STATUS_DOWNLOAD Changeset %s percent %s/%s bytes" % ( got*100/float(need), got,need) )
- #self.progress.set_subpercent( got*100 / float(need) )
- self.backend.sub_percentage( got*100/float(need) )
+ self.progress.set_subpercent( got*100 / float(need) )
+ self.backend.percentage( self.progress.percent )
log.info( "%s percent" % self.progress.percent)
@@ -76,11 +76,11 @@ class UpdateCallback(callbacks.UpdateCallback):
if hunk < hunkCount:
p = hunk / float(hunkCount) * 100.0
- #self.progress.set_subpercent(p)
- self.backend.percentage(self.progress.percent)
+ self.progress.set_subpercent(p)
else:
self.smallUpdate = True
+ self.backend.percentage(self.progress.percent)
log.info(self.progress.percent)
# 6
def setUpdateJob(self, job):
@@ -102,18 +102,15 @@ class UpdateCallback(callbacks.UpdateCallback):
def preparingUpdate(self, troveNum, troveCount, add=0):
log.info("callback ....... preparing Update trove %s/%s" % (troveNum, troveCount) )
- self.progress.step()
+ #self.progress.step()
if not self.currentJob or len(self.currentJob) == 0 or troveNum > troveCount:
return
if troveNum > 0 and troveCount > 0:
sub_percent = (add + troveNum) / (2 * float(troveCount)) * 100
self.progress.set_subpercent(sub_percent)
- self.backend.sub_percentage(sub_percent)
-
- if self.smallUpdate:
- self.backend.percentage(self.progress.percent)
+ self.backend.percentage(self.progress.percent)
if troveNum > 0:
troveNum -= 1
log.info("currentJob")
commit ffe532d3661e10fcd46d5d1be4d4d1702062a04c
Merge: af113a6... 1ab2a9f...
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Mon Feb 16 18:24:41 2009 +0100
Merge branch 'master' of git+ssh://glatzor@git.packagekit.org/srv/git/PackageKit
commit af113a6d7bcac632508f99fb543f28f85a7b0f92
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Mon Feb 9 06:15:20 2009 +0100
APT: Remove code which is now merged with python-apt
diff --git a/backends/apt/aptbackend.py b/backends/apt/aptbackend.py
index 700c325..c24d20a 100755
--- a/backends/apt/aptbackend.py
+++ b/backends/apt/aptbackend.py
@@ -196,55 +196,6 @@ class PackageKitCache(apt.cache.Cache):
yield self._dict[pkgname]
raise StopIteration
- def isVirtualPackage(self, name):
- """
- Return True if the package of the given name is a virtual package
- """
- try:
- virtual_pkg = self._cache[name]
- except KeyError:
- return False
- if len(virtual_pkg.VersionList) == 0:
- return True
- return False
-
- def getProvidingPackages(self, virtual):
- """
- Return a list of packages which provide the virtual package of the
- specified name
- """
- providers = []
- try:
- vp = self._cache[virtual]
- if len(vp.VersionList) != 0:
- return providers
- except KeyError:
- return providers
- for pkg in self:
- v = self._depcache.GetCandidateVer(pkg._pkg)
- if v == None:
- continue
- for p in v.ProvidesList:
- #print virtual
- #print p[0]
- if virtual == p[0]:
- # we found a pkg that provides this virtual
- # pkg, check if the proivdes is any good
- providers.append(pkg)
- #cand = self._cache[pkg.name]
- #candver = self._cache._depcache.GetCandidateVer(cand._pkg)
- #instver = cand._pkg.CurrentVer
- #res = apt_pkg.CheckDep(candver.VerStr,oper,ver)
- #if res == True:
- # self._dbg(1,"we can use %s" % pkg.name)
- # or_found = True
- # break
- return providers
-
- def clear(self):
- """ Unmark all changes """
- self._depcache.Init()
-
class DpkgInstallProgress(apt.progress.InstallProgress):
"""
commit 708a1710cd2324fa9e8d47fa1489a543703e6a1d
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Mon Feb 9 05:46:48 2009 +0100
APT: Install the main Python module into the packagekit package and use a command wrapper to improve the start time (*.pyc)
diff --git a/backends/apt/Makefile.am b/backends/apt/Makefile.am
index 6f390d4..fbec9b2 100644
--- a/backends/apt/Makefile.am
+++ b/backends/apt/Makefile.am
@@ -9,8 +9,12 @@ libpk_backend_apt_la_CFLAGS = $(PK_PLUGIN_CFLAGS) $(WARNINGFLAGS_C)
dbusinstancedir = $(LIBEXECDIR)
dbusinstance_DATA = \
- aptDBUSBackend.py \
- debfile.py \
+ pk-backend-apt.py \
+ $(NULL)
+
+packagekitpythondir = ${PYTHON_PACKAGE_DIR}
+packagekitpython_PYTHON = \
+ aptbackend.py \
$(NULL)
EXTRA_DIST = \
diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
deleted file mode 100755
index 700c325..0000000
--- a/backends/apt/aptDBUSBackend.py
+++ /dev/null
@@ -1,2236 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-Provides an apt backend to PackageKit
-
-Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
-Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
-Copyright (C) 2008 Sebastian Heinlein <glatzor at ubuntu.com>
-
-Licensed under the GNU General Public License Version 2
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-"""
-
-__author__ = "Sebastian Heinlein <devel at glatzor.de>"
-
-import errno
-import fcntl
-import gdbm
-import httplib
-import locale
-import logging
-import optparse
-import os
-import pty
-import re
-import signal
-import shutil
-import socket
-import stat
-import string
-import subprocess
-import sys
-import time
-import threading
-import urllib2
-import warnings
-
-import apt
-import apt.debfile
-import apt_pkg
-import dbus
-import dbus.glib
-import dbus.service
-import dbus.mainloop.glib
-import gobject
-
-from packagekit.daemonBackend import PACKAGEKIT_DBUS_INTERFACE, PACKAGEKIT_DBUS_PATH, PackageKitBaseBackend, PackagekitProgress, pklog, threaded, serialize
-from packagekit.enums import *
-
-
-warnings.filterwarnings(action='ignore', category=FutureWarning)
-
-PACKAGEKIT_DBUS_SERVICE = 'org.freedesktop.PackageKitAptBackend'
-
-apt_pkg.InitConfig()
-apt_pkg.Config.Set("DPkg::Options::", '--force-confdef')
-apt_pkg.Config.Set("DPkg::Options::", '--force-confold')
-
-# Xapian database is optionally used to speed up package description search
-XAPIAN_DB_PATH = os.environ.get("AXI_DB_PATH", "/var/lib/apt-xapian-index")
-XAPIAN_DB = XAPIAN_DB_PATH + "/index"
-XAPIAN_DB_VALUES = XAPIAN_DB_PATH + "/values"
-XAPIAN_SUPPORT = False
-try:
- import xapian
-except ImportError:
- pass
-else:
- if os.access(XAPIAN_DB, os.R_OK):
- pklog.debug("Use XAPIAN for the search")
- XAPIAN_SUPPORT = True
-
-# SoftwareProperties is required to proivde information about repositories
-try:
- import softwareproperties.SoftwareProperties
-except ImportError:
- REPOS_SUPPORT = False
-else:
- REPOS_SUPPORT = True
-
-# Check if update-manager-core is installed to get aware of the
-# latest distro releases
-try:
- from UpdateManager.Core.MetaRelease import MetaReleaseCore
-except ImportError:
- META_RELEASE_SUPPORT = False
-else:
- META_RELEASE_SUPPORT = True
-
-
-# Set a timeout for the changelog download
-socket.setdefaulttimeout(2)
-
-# Required for daemon mode
-os.putenv("PATH",
- "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")
-# Avoid questions from the maintainer scripts as far as possible
-os.putenv("DEBIAN_FRONTEND", "noninteractive")
-os.putenv("APT_LISTCHANGES_FRONTEND", "none")
-
-# Setup threading support
-gobject.threads_init()
-dbus.glib.threads_init()
-
-# Map Debian sections to the PackageKit group name space
-SECTION_GROUP_MAP = {
- "admin" : GROUP_ADMIN_TOOLS,
- "base" : GROUP_SYSTEM,
- "comm" : GROUP_COMMUNICATION,
- "devel" : GROUP_PROGRAMMING,
- "doc" : GROUP_DOCUMENTATION,
- "editors" : GROUP_PUBLISHING,
- "electronics" : GROUP_ELECTRONICS,
- "embedded" : GROUP_SYSTEM,
- "games" : GROUP_GAMES,
- "gnome" : GROUP_DESKTOP_GNOME,
- "graphics" : GROUP_GRAPHICS,
- "hamradio" : GROUP_COMMUNICATION,
- "interpreters" : GROUP_PROGRAMMING,
- "kde" : GROUP_DESKTOP_KDE,
- "libdevel" : GROUP_PROGRAMMING,
- "libs" : GROUP_SYSTEM,
- "mail" : GROUP_INTERNET,
- "math" : GROUP_SCIENCE,
- "misc" : GROUP_OTHER,
- "net" : GROUP_NETWORK,
- "news" : GROUP_INTERNET,
- "oldlibs" : GROUP_LEGACY,
- "otherosfs" : GROUP_SYSTEM,
- "perl" : GROUP_PROGRAMMING,
- "python" : GROUP_PROGRAMMING,
- "science" : GROUP_SCIENCE,
- "shells" : GROUP_SYSTEM,
- "sound" : GROUP_MULTIMEDIA,
- "tex" : GROUP_PUBLISHING,
- "text" : GROUP_PUBLISHING,
- "utils" : GROUP_ACCESSORIES,
- "web" : GROUP_INTERNET,
- "x11" : GROUP_DESKTOP_OTHER,
- "unknown" : GROUP_UNKNOWN,
- "alien" : GROUP_UNKNOWN,
- "translations" : GROUP_LOCALIZATION,
- "metapackages" : GROUP_COLLECTIONS }
-
-# Regular expressions to detect bug numbers in changelogs according to the
-# Debian Policy Chapter 4.4. For details see the footnote 16:
-# http://www.debian.org/doc/debian-policy/footnotes.html#f16
-MATCH_BUG_CLOSES_DEBIAN=r"closes:\s*(?:bug)?\#?\s?\d+(?:,\s*(?:bug)?\#?\s?\d+)*"
-MATCH_BUG_NUMBERS=r"\#?\s?(\d+)"
-# URL pointing to a bug in the Debian bug tracker
-HREF_BUG_DEBIAN="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s"
-
-# Regular expression to find cve references
-MATCH_CVE="CVE-\d{4}-\d{4}"
-HREF_CVE="http://web.nvd.nist.gov/view/vuln/detail?vulnId=%s"
-
-def unlock_cache_afterwards(func):
- '''
- Make sure that the package cache is unlocked after the decorated function
- was called
- '''
- def wrapper(*args, **kwargs):
- backend = args[0]
- func(*args, **kwargs)
- backend._unlock_cache()
- wrapper.__name__ = func.__name__
- return wrapper
-
-
-class PKError(Exception):
- pass
-
-class PackageManagerFailedPKError(PKError):
- def __init__(self, msg, pkg, output):
- self.message = msg
- self.package = pkg
- self.output = output
-
-class InstallTimeOutPKError(PKError):
- pass
-
-class PackageKitCache(apt.cache.Cache):
- """
- Enhanced version of the apt.cache.Cache class which supports some features
- which can only be found in the consolidate branch of python-apt
- """
- def __iter__(self):
- """
- Let the cache behave like a sorted list of packages
- """
- for pkgname in sorted(self._dict.keys()):
- yield self._dict[pkgname]
- raise StopIteration
-
- def isVirtualPackage(self, name):
- """
- Return True if the package of the given name is a virtual package
- """
- try:
- virtual_pkg = self._cache[name]
- except KeyError:
- return False
- if len(virtual_pkg.VersionList) == 0:
- return True
- return False
-
- def getProvidingPackages(self, virtual):
- """
- Return a list of packages which provide the virtual package of the
- specified name
- """
- providers = []
- try:
- vp = self._cache[virtual]
- if len(vp.VersionList) != 0:
- return providers
- except KeyError:
- return providers
- for pkg in self:
- v = self._depcache.GetCandidateVer(pkg._pkg)
- if v == None:
- continue
- for p in v.ProvidesList:
- #print virtual
- #print p[0]
- if virtual == p[0]:
- # we found a pkg that provides this virtual
- # pkg, check if the proivdes is any good
- providers.append(pkg)
- #cand = self._cache[pkg.name]
- #candver = self._cache._depcache.GetCandidateVer(cand._pkg)
- #instver = cand._pkg.CurrentVer
- #res = apt_pkg.CheckDep(candver.VerStr,oper,ver)
- #if res == True:
- # self._dbg(1,"we can use %s" % pkg.name)
- # or_found = True
- # break
- return providers
-
- def clear(self):
- """ Unmark all changes """
- self._depcache.Init()
-
-
-class DpkgInstallProgress(apt.progress.InstallProgress):
- """
- Class to initiate and monitor installation of local package files with dpkg
- """
- #FIXME: Use the merged DpkgInstallProgress of python-apt
- def recover(self):
- """
- Run "dpkg --configure -a"
- """
- cmd = ["/usr/bin/dpkg", "--status-fd", str(self.writefd),
- "--root", apt_pkg.Config["Dir"],
- "--force-confdef", "--force-confold",
- "--configure", "-a"]
- self.run(cmd)
-
- def install(self, filenames):
- """
- Install the given package using a dpkg command line call
- """
- cmd = ["/usr/bin/dpkg", "--force-confdef", "--force-confold",
- "--status-fd", str(self.writefd),
- "--root", apt_pkg.Config["Dir"], "-i"]
- cmd.extend(map(lambda f: str(f), filenames))
- self.run(cmd)
-
- def run(self, cmd):
- """
- Run and monitor a dpkg command line call
- """
- pklog.debug("Executing: %s" % cmd)
- (self.master_fd, slave) = pty.openpty()
- fcntl.fcntl(self.master_fd, fcntl.F_SETFL, os.O_NONBLOCK)
- p = subprocess.Popen(cmd, stdout=slave, stdin=slave)
- self.child_pid = p.pid
- res = self.waitChild()
- return res
-
- def updateInterface(self):
- """
- Process status messages from dpkg
- """
- if self.statusfd == None:
- return
- try:
- while not self.read.endswith("\n"):
- self.read += os.read(self.statusfd.fileno(), 1)
- except OSError, (error_no, error_str):
- # resource temporarly unavailable is ignored
- if error_no not in [errno.EAGAIN, errno.EWOULDBLOCK]:
- print error_str
- if self.read.endswith("\n"):
- statusl = string.split(self.read, ":")
- if len(statusl) < 3:
- pklog.warn("got garbage from dpkg: '%s'" % self.read)
- self.read = ""
- status = statusl[2].strip()
- pkg = statusl[1].strip()
- #print status
- if status == "error":
- self.error(pkg, status)
- elif status == "conffile-prompt":
- # we get a string like this:
- # 'current-conffile' 'new-conffile' useredited distedited
- match = re.search(".+conffile-prompt : '(.+)' '(.+)'",
- self.read)
- self.conffile(match.group(1), match.group(2))
- else:
- pklog.debug("Dpkg status: %s" % status)
- self.status = status
- self.read = ""
-
-
-class PackageKitOpProgress(apt.progress.OpProgress):
- '''
- Handle the cache opening process
- '''
- def __init__(self, backend, prange=(0,100), progress=True):
- self._backend = backend
- apt.progress.OpProgress.__init__(self)
- self.steps = []
- for v in [0.12, 0.25, 0.50, 0.75, 1.00]:
- s = prange[0] + (prange[1] - prange[0]) * v
- self.steps.append(s)
- self.pstart = float(prange[0])
- self.pend = self.steps.pop(0)
- self.pprev = None
- self.show_progress = progress
-
- # OpProgress callbacks
- def update(self, percent):
- progress = int(self.pstart + percent / 100 * (self.pend - self.pstart))
- if self.show_progress == True and self.pprev < progress:
- self._backend.PercentageChanged(progress)
- self.pprev = progress
-
- def done(self):
- self.pstart = self.pend
- try:
- self.pend = self.steps.pop(0)
- except:
- pklog.warning("An additional step to open the cache is required")
-
-
-class PackageKitFetchProgress(apt.progress.FetchProgress):
- '''
- Handle the package download process
- '''
- def __init__(self, backend, prange=(0,100)):
- self._backend = backend
- apt.progress.FetchProgress.__init__(self)
- self.pstart = prange[0]
- self.pend = prange[1]
- self.pprev = None
-
- def pulse(self):
- apt.progress.FetchProgress.pulse(self)
- # Strange, but we seem to need this to detect a cancel immediately
- time.sleep(0.01)
- if self._backend._canceled.isSet():
- return False
- progress = int(self.pstart + self.percent/100 * \
- (self.pend - self.pstart))
- if self.pprev < progress:
- self._backend.PercentageChanged(progress)
- self.pprev = progress
- return True
-
- def start(self):
- self._backend.StatusChanged(STATUS_DOWNLOAD)
- self._backend.AllowCancel(True)
-
- def stop(self):
- self._backend.PercentageChanged(self.pend)
- self._backend.AllowCancel(False)
-
- def mediaChange(self, medium, drive):
- #FIXME: Raise an expcetion and handle it in _commit_changes
- # Strangly _commit_changes does not catch the expcetion
- self._backend.Message(MESSAGE_UNKNOWN,
- "Installing from CD-Rom (%s) is not "
- "supported." % medium)
- return False
-
-
-class PackageKitInstallProgress(apt.progress.InstallProgress):
- '''
- Handle the installation and removal process. Bits taken from
- DistUpgradeViewNonInteractive.
- '''
- def __init__(self, backend, prange=(0,100)):
- apt.progress.InstallProgress.__init__(self)
- self._backend = backend
- self.pstart = prange[0]
- self.pend = prange[1]
- self.pprev = None
- self.last_activity = None
- self.conffile_prompts = set()
- # insanly long timeout to be able to kill hanging maintainer scripts
- self.timeout = 10 * 60
- self.start_time = None
- self.output = ""
- self.master_fd = None
- self.child_pid = None
-
- def statusChange(self, pkg, percent, status):
- self.last_activity = time.time()
- progress = self.pstart + percent/100 * (self.pend - self.pstart)
- if self.pprev < progress:
- self._backend.PercentageChanged(int(progress))
- self.pprev = progress
- pklog.debug("APT status: %s" % status)
-
- def startUpdate(self):
- # The apt system lock was set by _lock_cache() before
- self._backend._unlock_cache()
- self._backend.StatusChanged(STATUS_COMMIT)
- self.last_activity = time.time()
- self.start_time = time.time()
-
- def fork(self):
- pklog.debug("fork()")
- (pid, self.master_fd) = pty.fork()
- if pid != 0:
- fcntl.fcntl(self.master_fd, fcntl.F_SETFL, os.O_NONBLOCK)
- return pid
-
- def updateInterface(self):
- apt.progress.InstallProgress.updateInterface(self)
- # Collect the output from the package manager
- try:
- out = os.read(self.master_fd, 512)
- self.output = self.output + out
- pklog.debug("APT out: %s " % out)
- except OSError:
- pass
- # catch a time out by sending crtl+c
- if self.last_activity + self.timeout < time.time():
- pklog.critical("no activity for %s time sending ctrl-c" \
- % self.timeout)
- os.write(self.master_fd, chr(3))
- #FIXME: include this into the normal install progress and add
- # correct package information
- raise InstallTimeOutPKError(self.output)
-
- def conffile(self, current, new):
- pklog.warning("Config file prompt: '%s' (sending no)" % current)
- self.conffile_prompts.add(new)
-
- def error(self, pkg, msg):
- raise PackageManagerFailedPKError(pkg, msg, self.output)
-
- def finishUpdate(self):
- pklog.debug("finishUpdate()")
- if self.conffile_prompts:
- self._backend.Message(MESSAGE_CONFIG_FILES_CHANGED,
- "The following conffile prompts were found "
- "and need investiagtion: %s" % \
- "\n".join(self.conffile_prompts))
- # Check for required restarts
- if os.path.exists("/var/run/reboot-required") and \
- os.path.getmtime("/var/run/reboot-required") > self.start_time:
- self._backend.RequireRestart(RESTART_SYSTEM, "")
-
-
-class PackageKitDpkgInstallProgress(DpkgInstallProgress,
- PackageKitInstallProgress):
- """
- Class to integrate the progress of core dpkg operations into PackageKit
- """
- def run(self, filenames):
- return DpkgInstallProgress.run(self, filenames)
-
- def updateInterface(self):
- DpkgInstallProgress.updateInterface(self)
- try:
- out = os.read(self.master_fd, 512)
- self.output += out
- if out != "": pklog.debug("Dpkg out: %s" % out)
- except OSError:
- pass
- # we timed out, send ctrl-c
- if self.last_activity + self.timeout < time.time():
- pklog.critical("no activity for %s time sending "
- "ctrl-c" % self.timeout)
- os.write(self.master_fd, chr(3))
- raise InstallTimeOutPKError(self.output)
-
-
-if REPOS_SUPPORT == True:
- class PackageKitSoftwareProperties(softwareproperties.SoftwareProperties.SoftwareProperties):
- """
- Helper class to fix a siily bug in python-software-properties
- """
- def set_modified_sourceslist(self):
- self.save_sourceslist()
-
-
-class PackageKitAptBackend(PackageKitBaseBackend):
- '''
- PackageKit backend for apt
- '''
- def __init__(self, bus_name, dbus_path):
- pklog.info("Initializing APT backend")
- signal.signal(signal.SIGQUIT, sigquit)
- self._cache = None
- self._canceled = threading.Event()
- self._canceled.clear()
- self._lock = threading.Lock()
- self._last_cache_refresh = None
- PackageKitBaseBackend.__init__(self, bus_name, dbus_path)
-
- # Methods ( client -> engine -> backend )
-
- def doInit(self):
- pklog.info("Initializing cache")
- self.StatusChanged(STATUS_RUNNING)
- self.AllowCancel(False)
- self.NoPercentageUpdates()
- self._open_cache(progress=False)
-
- @serialize
- def doExit(self):
- gobject.idle_add(self._doExitDelay)
-
- def doCancel(self):
- pklog.info("Canceling current action")
- self.StatusChanged(STATUS_CANCEL)
- self._canceled.set()
- self._canceled.wait()
-
- @serialize
- @threaded
- def doSearchFile(self, filters, filename):
- '''
- Implement the apt2-search-file functionality
-
- Apt specific: Works only for installed files. Since config files are
- not removed by default even not installed packages can be reported.
- '''
- pklog.info("Searching for file: %s" % filename)
- self.StatusChanged(STATUS_QUERY)
- self.NoPercentageUpdates()
- self._check_init(progress=False)
- self.AllowCancel(True)
-
- for pkg in self._cache:
- if self._check_canceled(): return False
- for installed_file in self._get_installed_files(pkg):
- if filename in installed_file:
- self._emit_visible_package(filters, pkg)
- break
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doSearchGroup(self, filters, group):
- '''
- Implement the apt2-search-group functionality
- '''
- pklog.info("Searching for group: %s" % group)
- self.StatusChanged(STATUS_QUERY)
- self.NoPercentageUpdates()
- self._check_init(progress=False)
- self.AllowCancel(True)
-
- for pkg in self._cache:
- if self._check_canceled(): return False
- elif self._get_package_group(pkg) == group:
- self._emit_visible_package(filters, pkg)
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doSearchName(self, filters, search):
- '''
- Implement the apt2-search-name functionality
- '''
- pklog.info("Searching for package name: %s" % search)
- self.StatusChanged(STATUS_QUERY)
- self.NoPercentageUpdates()
- self._check_init(progress=False)
- self.AllowCancel(True)
-
- for pkg in self._cache:
- if self._check_canceled(): return False
- elif search in pkg.name:
- self._emit_visible_package(filters, pkg)
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doSearchDetails(self, filters, search):
- '''
- Implement the apt2-search-details functionality
- '''
- pklog.info("Searching for package name: %s" % search)
- self.StatusChanged(STATUS_QUERY)
- self.NoPercentageUpdates()
- self._check_init(progress=False)
- self.AllowCancel(True)
- results = []
-
- if XAPIAN_SUPPORT == True:
- search_flags = (xapian.QueryParser.FLAG_BOOLEAN |
- xapian.QueryParser.FLAG_PHRASE |
- xapian.QueryParser.FLAG_LOVEHATE |
- xapian.QueryParser.FLAG_BOOLEAN_ANY_CASE)
- pklog.debug("Performing xapian db based search")
- db = xapian.Database(XAPIAN_DB)
- parser = xapian.QueryParser()
- query = parser.parse_query(unicode(search),
- search_flags)
- enquire = xapian.Enquire(db)
- enquire.set_query(query)
- matches = enquire.get_mset(0, 1000)
- for r in map(lambda m: m[xapian.MSET_DOCUMENT].get_data(),
- enquire.get_mset(0,1000)):
- if self._cache.has_key(r):
- results.append(self._cache[r])
- else:
- pklog.debug("Performing apt cache based search")
- for p in self._cache._dict.values():
- if self._check_canceled(): return
- needle = search.strip().lower()
- haystack = p.description.lower()
- if p.name.find(needle) >= 0 or haystack.find(needle) >= 0:
- results.append(p)
-
- for r in results:
- if self._check_canceled(): return
- self._emit_visible_package(filters, r)
-
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doGetDistroUpgrades(self):
- '''
- Implement the {backend}-get-distro-upgrades functionality
- '''
- pklog.info("Get distro upgrades")
- self.StatusChanged(STATUS_INFO)
- self.AllowCancel(False)
- self.NoPercentageUpdates()
-
- if META_RELEASE_SUPPORT == False:
- if self._cache.has_key("update-manager-core") and \
- self._cache["update-manager-core"].isInstalled == False:
- self.ErrorCode(ERROR_UNKNOWN,
- "Please install the package update-manager-core to get notified "
- "of the latest distribution releases.")
- else:
- self.ErrorCode(ERROR_UNKNOWN,
- "Please make sure that update-manager-core is"
- "correctly installed.")
- self.Finished(EXIT_FAILED)
- return
-
- #FIXME Evil to start the download during init
- meta_release = MetaReleaseCore(False, False)
- #FIXME: should use a lock
- while meta_release.downloading:
- time.sleep(1)
- #FIXME: Add support for description
- if meta_release.new_dist != None:
- self.DistroUpgrade("stable",
- "%s %s" % (meta_release.new_dist.name,
- meta_release.new_dist.version),
- "The latest stable release")
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doGetUpdates(self, filters):
- '''
- Implement the {backend}-get-update functionality
- '''
- def succeeds_security_update(pkg):
- """
- Return True if an update succeeds a previous security update
-
- An example would be a package with version 1.1 in the security
- archive and 1.1.1 in the archive of proposed updates or the
- same version in both archives.
- """
- inst_ver = pkg._pkg.CurrentVer
- for ver in pkg._pkg.VersionList:
- # Skip versions which are not later
- if inst_ver and \
- apt_pkg.VersionCompare(ver.VerStr, inst_ver.VerStr) <= 0:
- continue
- for(verFileIter, index) in ver.FileList:
- if verFileIter.Origin in ["Debian", "Ubuntu"] and \
- (verFileIter.Archive.endswith("-security") or \
- verFileIter.Label == "Debian-Security"):
- indexfile = pkg._list.FindIndex(verFileIter)
- if indexfile and indexfile.IsTrusted:
- return True
- return False
- #FIXME: Implment the basename filter
- pklog.info("Get updates")
- self.StatusChanged(STATUS_QUERY)
- self.AllowCancel(True)
- self.NoPercentageUpdates()
- self._check_init(progress=False)
- self._cache.upgrade(False)
- updates = filter(lambda p: self._cache[p].isUpgradable,
- self._cache.keys())
- for pkg in self._cache.getChanges():
- if self._check_canceled(): return False
- else:
- updates.remove(pkg.name)
- info = INFO_NORMAL
- archive = pkg.candidateOrigin[0].archive
- origin = pkg.candidateOrigin[0].origin
- trusted = pkg.candidateOrigin[0].trusted
- label = pkg.candidateOrigin[0].label
- if origin in ["Debian", "Ubuntu"] and trusted == True:
- if archive.endswith("-security") or \
- label == "Debian-Security":
- info = INFO_SECURITY
- elif succeeds_security_update(pkg):
- pklog.debug("Update of %s succeeds a security "
- "update. Raising its priority." % pkg.name)
- info = INFO_SECURITY
- elif archive.endswith("-backports"):
- info = INFO_ENHANCEMENT
- elif archive.endswith("-updates"):
- info = INFO_BUGFIX
- if origin in ["Backports.org archive"] and trusted == True:
- info = INFO_ENHANCEMENT
- self._emit_package(pkg, info, force_candidate=True)
- # Report packages that are upgradable but cannot be upgraded
- for missed in updates:
- self._emit_package(self._cache[missed], INFO_BLOCKED)
- self._cache.clear()
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doGetUpdateDetail(self, pkg_ids):
- '''
- Implement the {backend}-get-update-details functionality
- '''
- def get_bug_urls(changelog):
- """
- Create a list of urls pointing to closed bugs in the changelog
- """
- urls = []
- #FIXME: Add support for Launchpad/Ubuntu
- for r in re.findall(MATCH_BUG_CLOSES_DEBIAN, changelog,
- re.IGNORECASE | re.MULTILINE):
- urls.extend(map(lambda b: HREF_BUG_DEBIAN % b,
- re.findall(MATCH_BUG_NUMBERS, r)))
- return urls
-
- def get_cve_urls(changelog):
- """
- Create a list of urls pointing to cves referred in the changelog
- """
- return map(lambda c: HREF_CVE % c,
- re.findall(MATCH_CVE, changelog, re.MULTILINE))
-
- pklog.info("Get update details of %s" % pkg_ids)
- self.StatusChanged(STATUS_INFO)
- self.NoPercentageUpdates()
- self.AllowCancel(True)
- self._check_init(progress=False)
- for pkg_id in pkg_ids:
- if self._check_canceled(): return
- pkg = self._find_package_by_id(pkg_id)
- if pkg == None:
- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
- "Package %s isn't available" % id)
- self.Finished(EXIT_FAILED)
- return
- # FIXME add some real data
- updates = self.get_id_from_package(pkg, force_candidate=False)
- obsoletes = ""
- vendor_url = ""
- restart = ""
- update_text = ""
- state = ""
- issued = ""
- updated = ""
- #FIXME: Replace this method with the python-apt one as soon as the
- # consolidate branch gets merged
- self.StatusChanged(STATUS_DOWNLOAD_CHANGELOG)
- changelog = self._get_changelog(pkg)
- self.StatusChanged(STATUS_INFO)
- bugzilla_url = ";".join(get_bug_urls(changelog))
- cve_url = ";".join(get_cve_urls(changelog))
- self.UpdateDetail(pkg_id, updates, obsoletes, vendor_url,
- bugzilla_url, cve_url, restart, update_text,
- changelog, state, issued, updated)
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doGetDetails(self, pkg_ids):
- '''
- Implement the {backend}-get-details functionality
- '''
- pklog.info("Get details of %s" % pkg_ids)
- self.StatusChanged(STATUS_DEP_RESOLVE)
- self.NoPercentageUpdates()
- self.AllowCancel(True)
- self._check_init(progress=False)
- for pkg_id in pkg_ids:
- if self._check_canceled(): return
- pkg = self._find_package_by_id(pkg_id)
- if pkg == None:
- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
- "Package %s isn't available" % id)
- self.Finished(EXIT_FAILED)
- return
- desc = self._get_package_description(pkg)
- #FIXME: We need more fine grained license information!
- candidate = pkg.candidateOrigin
- if candidate != None and \
- candidate[0].component in ["main", "universe"] and \
- candidate[0].origin in ["Debian", "Ubuntu"]:
- license = "free"
- else:
- license = "unknown"
- group = self._get_package_group(pkg)
- self.Details(pkg_id, license, group, desc,
- pkg.homepage, pkg.packageSize)
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- @unlock_cache_afterwards
- def doUpdateSystem(self):
- '''
- Implement the {backend}-update-system functionality
- '''
- pklog.info("Upgrading system")
- if not self._lock_cache(): return
- self.StatusChanged(STATUS_UPDATE)
- self.AllowCancel(False)
- self.PercentageChanged(0)
- self._check_init(prange=(0,5))
- try:
- self._cache.upgrade(distUpgrade=False)
- except:
- self._cache.clear()
- self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
- "Failed to upgrade the system.")
- self.Finished(EXIT_FAILED)
- return
- if not self._commit_changes(): return False
- self.PercentageChanged(100)
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- @unlock_cache_afterwards
- def doRemovePackages(self, ids, deps=True, auto=False):
- '''
- Implement the {backend}-remove functionality
- '''
- pklog.info("Removing package(s): id %s" % ids)
- if not self._lock_cache(): return
- self.StatusChanged(STATUS_REMOVE)
- self.AllowCancel(False)
- self.PercentageChanged(0)
- self._check_init(prange=(0,10))
- pkgs=[]
- for id in ids:
- pkg = self._find_package_by_id(id)
- if pkg == None:
- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
- "Package %s isn't available" % id)
- self.Finished(EXIT_FAILED)
- return
- if not pkg.isInstalled:
- self.ErrorCode(ERROR_PACKAGE_NOT_INSTALLED,
- "Package %s isn't installed" % pkg.name)
- self.Finished(EXIT_FAILED)
- return
- pkgs.append(pkg.name[:])
- if pkg._pkg.Essential == True:
- self.ErrorCode(ERROR_CANNOT_REMOVE_SYSTEM_PACKAGE,
- "Package %s cannot be removed." % pkg.name)
- self.Finished(EXIT_FAILED)
- return
- try:
- pkg.markDelete()
- except:
- self._open_cache(prange=(90,99))
- self.ErrorCode(ERROR_UNKNOWN, "Removal of %s failed" % pkg.name)
- self.Finished(EXIT_FAILED)
- return
- if not self._commit_changes(fetch_range=(10,10),
- install_range=(10,90)):
- return False
- self._open_cache(prange=(90,99))
- for p in pkgs:
- if self._cache.has_key(p) and self._cache[p].isInstalled:
- self.ErrorCode(ERROR_UNKNOWN, "%s is still installed" % p)
- self.Finished(EXIT_FAILED)
- return
- self.PercentageChanged(100)
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doGetRepoList(self, filters):
- '''
- Implement the {backend}-get-repo-list functionality
-
- FIXME: should we use the abstration of software-properties or provide
- low level access using pure aptsources?
- '''
- pklog.info("Getting repository list: %s" % filters)
- self.StatusChanged(STATUS_INFO)
- self.AllowCancel(False)
- self.PercentageChanged(0)
- if REPOS_SUPPORT == False:
- if self._cache.has_key("python-software-properties") and \
- self._cache["python-software-properties"].isInstalled == False:
- self.ErrorCode(ERROR_UNKNOWN,
- "Please install the package "
- "python-software-properties to handle repositories")
- else:
- self.ErrorCode(ERROR_UNKNOWN,
- "Please make sure that python-software-properties is"
- "correctly installed.")
- self.Finished(EXIT_FAILED)
- return
- filter_list = filters.split(";")
- repos = PackageKitSoftwareProperties()
- # Emit distro components as virtual repositories
- for comp in repos.distro.source_template.components:
- repo_id = "%s_comp_%s" % (repos.distro.id, comp.name)
- description = "%s %s - %s (%s)" % (repos.distro.id,
- repos.distro.release,
- comp.get_description(),
- comp.name)
- #FIXME: There is no inconsitent state in PackageKit
- enabled = repos.get_comp_download_state(comp)[0]
- if not FILTER_DEVELOPMENT in filter_list:
- self.RepoDetail(repo_id, description, enabled)
- # Emit distro's virtual update repositories
- for template in repos.distro.source_template.children:
- repo_id = "%s_child_%s" % (repos.distro.id, template.name)
- description = "%s %s - %s (%s)" % (repos.distro.id,
- repos.distro.release,
- template.description,
- template.name)
- #FIXME: There is no inconsitent state in PackageKit
- enabled = repos.get_comp_child_state(template)[0]
- if not FILTER_DEVELOPMENT in filter_list:
- self.RepoDetail(repo_id, description, enabled)
- # Emit distro's cdrom sources
- for source in repos.get_cdrom_sources():
- if FILTER_NOT_DEVELOPMENT in filter_list and \
- source.type in ("deb-src", "rpm-src"):
- continue
- enabled = not source.disabled
- # Remove markups from the description
- description = re.sub(r"</?b>", "", repos.render_source(source))
- repo_id = "cdrom_%s_%s" % (source.uri, source.dist)
- repo_id.join(map(lambda c: "_%s" % c, source.comps))
- self.RepoDetail(repo_id, description, enabled)
- # Emit distro's virtual source code repositoriy
- if not FILTER_NOT_DEVELOPMENT in filter_list:
- repo_id = "%s_source" % repos.distro.id
- enabled = repos.get_source_code_state() or False
- #FIXME: no translation :(
- description = "%s %s - Source code" % (repos.distro.id,
- repos.distro.release)
- self.RepoDetail(repo_id, description, enabled)
- # Emit third party repositories
- for source in repos.get_isv_sources():
- if FILTER_NOT_DEVELOPMENT in filter_list and \
- source.type in ("deb-src", "rpm-src"):
- continue
- enabled = not source.disabled
- # Remove markups from the description
- description = re.sub(r"</?b>", "", repos.render_source(source))
- repo_id = "isv_%s_%s" % (source.uri, source.dist)
- repo_id.join(map(lambda c: "_%s" % c, source.comps))
- self.RepoDetail(repo_id, description, enabled)
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doRepoEnable(self, repo_id, enable):
- '''
- Implement the {backend}-repo-enable functionality
-
- FIXME: should we use the abstration of software-properties or provide
- low level access using pure aptsources?
- '''
- pklog.info("Enabling repository: %s %s" % (repo_id, enable))
- self.StatusChanged(STATUS_RUNNING)
- self.AllowCancel(False)
- self.PercentageChanged(0)
- if REPOS_SUPPORT == False:
- if self._cache.has_key("python-software-properties") and \
- self._cache["python-software-properties"].isInstalled == False:
- self.ErrorCode(ERROR_UNKNOWN,
- "Please install the package "
- "python-software-properties to handle repositories")
- else:
- self.ErrorCode(ERROR_UNKNOWN,
- "Please make sure that python-software-properties is"
- "correctly installed.")
- self.Finished(EXIT_FAILED)
- return
- repos = PackageKitSoftwareProperties()
-
- found = False
- # Check if the repo_id matches a distro component, e.g. main
- if repo_id.startswith("%s_comp_" % repos.distro.id):
- for comp in repos.distro.source_template.components:
- if repo_id == "%s_comp_%s" % (repos.distro.id, comp.name):
- if enable == repos.get_comp_download_state(comp)[0]:
- pklog.debug("Repository is already enabled")
- pass
- if enable == True:
- repos.enable_component(comp.name)
- else:
- repos.disable_component(comp.name)
- found = True
- break
- # Check if the repo_id matches a distro child repository, e.g. hardy-updates
- elif repo_id.startswith("%s_child_" % repos.distro.id):
- for template in repos.distro.source_template.children:
- if repo_id == "%s_child_%s" % (repos.distro.id, template.name):
- if enable == repos.get_comp_child_state(template)[0]:
- pklog.debug("Repository is already enabled")
- pass
- elif enable == True:
- repos.enable_child_source(template)
- else:
- repos.disable_child_source(template)
- found = True
- break
- # Check if the repo_id matches a cdrom repository
- elif repo_id.startswith("cdrom_"):
- for source in repos.get_isv_sources():
- source_id = "cdrom_%s_%s" % (source.uri, source.dist)
- source_id.join(map(lambda c: "_%s" % c, source.comps))
- if repo_id == source_id:
- if source.disabled == enable:
- source.disabled = not enable
- repos.save_sourceslist()
- else:
- pklog.debug("Repository is already enabled")
- found = True
- break
- # Check if the repo_id matches an isv repository
- elif repo_id.startswith("isv_"):
- for source in repos.get_isv_sources():
- source_id = "isv_%s_%s" % (source.uri, source.dist)
- source_id.join(map(lambda c: "_%s" % c, source.comps))
- if repo_id == source_id:
- if source.disabled == enable:
- source.disabled = not enable
- repos.save_sourceslist()
- else:
- pklog.debug("Repository is already enabled")
- found = True
- break
- if found == False:
- self.ErrorCode(ERROR_REPO_NOT_AVAILABLE,
- "The repository of the id %s isn't available" % repo_id)
- self.Finished(EXIT_FAILED)
- return
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- @unlock_cache_afterwards
- def doUpdatePackages(self, ids):
- '''
- Implement the {backend}-update functionality
- '''
- pklog.info("Updating package with id %s" % ids)
- if not self._lock_cache(): return
- self.StatusChanged(STATUS_UPDATE)
- self.AllowCancel(False)
- self.PercentageChanged(0)
- self._check_init(prange=(0,10))
- pkgs=[]
- for id in ids:
- pkg = self._find_package_by_id(id)
- if pkg == None:
- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
- "Package %s isn't available" % id)
- self.Finished(EXIT_FAILED)
- return
- if not pkg.isUpgradable:
- self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,
- "Package %s is already up-to-date" % pkg.name)
- self.Finished(EXIT_FAILED)
- return
- pkgs.append(pkg.name[:])
- try:
- pkg.markUpgrade()
- except:
- self._open_cache(prange=(90,100))
- self.ErrorCode(ERROR_UNKNOWN, "%s could not be queued for "
- "update" % pkg.name)
- self.Finished(EXIT_FAILED)
- return
- if not self._commit_changes(): return False
- self._open_cache(prange=(90,100))
- self.PercentageChanged(100)
- pklog.debug("Checking success of operation")
- for p in pkgs:
- if not self._cache.has_key(p) or not self._cache[p].isInstalled \
- or self._cache[p].isUpgradable:
- self.ErrorCode(ERROR_UNKNOWN, "%s was not updated" % p)
- self.Finished(EXIT_FAILED)
- return
- pklog.debug("Sending success signal")
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doDownloadPackages(self, ids, dest):
- '''
- Implement the {backend}-download-packages functionality
- '''
- pklog.info("Downloading packages: %s" % ids)
- self.StatusChanged(STATUS_DOWNLOAD)
- self.AllowCancel(True)
- self.PercentageChanged(0)
- # Check the destination directory
- if not os.path.isdir(dest) or not os.access(dest, os.W_OK):
- self.ErrorCode(ERROR_UNKNOWN,
- "The directory '%s' is not writable" % dest)
- self.Finished(EXIT_FAILED)
- return
- # Setup the fetcher
- self._check_init(prange=(0,10))
- progress = PackageKitFetchProgress(self, prange=(10,90))
- fetcher = apt_pkg.GetAcquire(progress)
- pm = apt_pkg.GetPackageManager(self._cache._depcache)
- recs = apt_pkg.GetPkgRecords(self._cache._cache)
- list = apt_pkg.GetPkgSourceList()
- list.ReadMainList()
- # Mark installed packages for reinstallation and not installed packages
- # for installation without dependencies
- for id in ids:
- if self._check_canceled(): return
- pkg = self._find_package_by_id(id)
- if pkg == None:
- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
- "There is no package %s" % id)
- self.Finished(EXIT_FAILED)
- return
- if pkg.isInstalled:
- self._cache._depcache.SetReInstall(pkg._pkg, True)
- else:
- self._cache._depcache.MarkInstall(pkg._pkg, False)
- # Download
- pm.GetArchives(fetcher, list, recs)
- res = fetcher.Run()
- self._cache.clear()
- self.PercentageChanged(95)
- # Copy files from cache to final destination
- for item in fetcher.Items:
- if self._check_canceled(): return
- pklog.debug("Download item: %s" % item)
- if (item.Status != item.StatDone and not item.StatIdle) or \
- res == fetcher.ResultCancelled:
- self.ErrorCode(ERROR_PACKAGE_DOWNLOAD_FAILED,
- "Failed to download %s" % item.DescURI)
- self.Finished(EXIT_FAILED)
- return
- pklog.debug("Copying %s to %s ..." % (item.DestFile, dest))
- try:
- shutil.copy(item.DestFile, dest)
- except Exception, e:
- self.ErrorCode(ERROR_INTERNAL_ERROR,
- "Failed to copy %s to %s: %s" % (item.DestFile,
- dest, e))
- self.Finished(EXIT_FAILED)
- return
- self.PercentageChanged(100)
- pklog.debug("Sending success signal")
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- @unlock_cache_afterwards
- def doInstallPackages(self, ids):
- '''
- Implement the {backend}-install functionality
- '''
- pklog.info("Installing package with id %s" % ids)
- if not self._lock_cache(): return
- self.StatusChanged(STATUS_INSTALL)
- self.AllowCancel(False)
- self.PercentageChanged(0)
- self._check_init(prange=(0,10))
- pkgs=[]
- for id in ids:
- pkg = self._find_package_by_id(id)
- if pkg == None:
- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
- "Package %s isn't available" % id)
- self.Finished(EXIT_FAILED)
- return
- if pkg.isInstalled:
- self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,
- "Package %s is already installed" % pkg.name)
- self.Finished(EXIT_FAILED)
- return
- pkgs.append(pkg.name[:])
- try:
- pkg.markInstall()
- except Exception, e:
- self._open_cache(prange=(90,100))
- self.ErrorCode(ERROR_UNKNOWN, "%s could not be queued for "
- "installation: %s" % (pkg.name,e))
- self.Finished(EXIT_FAILED)
- return
- if not self._commit_changes(): return False
- self._open_cache(prange=(90,100))
- self.PercentageChanged(100)
- pklog.debug("Checking success of operation")
- for p in pkgs:
- if not self._cache.has_key(p) or not self._cache[p].isInstalled:
- self.ErrorCode(ERROR_UNKNOWN, "%s was not installed" % p)
- self.Finished(EXIT_FAILED)
- return
- pklog.debug("Sending success signal")
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- @unlock_cache_afterwards
- def doInstallFiles(self, trusted, full_paths):
- '''
- Implement install-files for the apt backend
- Install local Debian package files
- '''
- pklog.info("Installing package files: %s" % full_paths)
- if not self._lock_cache(): return
- self.StatusChanged(STATUS_INSTALL)
- self.AllowCancel(False)
- self.PercentageChanged(0)
- self._check_init(prange=(0,10))
- packages = []
- # Collect all dependencies which need to be installed
- self.StatusChanged(STATUS_DEP_RESOLVE)
- for path in full_paths:
- deb = apt.debfile.DebPackage(path, self._cache)
- packages.append(deb)
- if not deb.check():
- self.ErrorCode(ERROR_UNKNOWN, deb._failureString)
- self.Finished(EXIT_FAILED)
- return
- (install, remove, unauthenticated) = deb.requiredChanges
- pklog.debug("Changes: Install %s, Remove %s, Unauthenticated "
- "%s" % (install, remove, unauthenticated))
- if len(remove) > 0:
- self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
- "Remove the following packages "
- "before: %s" % remove)
- self.Finished(EXIT_FAILED)
- return
- if deb.compare_to_version_in_cache() == \
- apt.debfile.VERSION_OUTDATED:
- self.Message(MESSAGE_NEWER_PACKAGE_EXISTS,
- "There is a later version of %s "
- "available in the repositories." % deb.pkgname)
- if len(self._cache.getChanges()) > 0 and not \
- self._commit_changes((10,25), (25,50)):
- return False
- # Install the Debian package files
- d = PackageKitDpkgInstallProgress(self)
- try:
- d.startUpdate()
- d.install(full_paths)
- d.finishUpdate()
- except InstallTimeOutPKError, e:
- self._recover()
- #FIXME: should provide more information
- self.ErrorCode(ERROR_UNKNOWN,
- "Transaction was cancelled since the installation "
- "of a package hung.\n"
- "This can be caused by maintainer scripts which "
- "require input on the terminal:\n%s" % e.message)
- self.Finished(EXIT_KILLED)
- return
- except PackageManagerFailedPKError, e:
- self._recover()
- self.ErrorCode(ERROR_UNKNOWN, "%s\n%s" % (e.message, e.output))
- self.Finished(EXIT_FAILED)
- return
- except Exception, e:
- self._recover()
- self.ErrorCode(ERROR_INTERNAL_ERROR, e.message)
- self.Finished(EXIT_FAILED)
- return
- self.PercentageChanged(100)
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- @unlock_cache_afterwards
- def doRefreshCache(self, force):
- '''
- Implement the {backend}-refresh_cache functionality
- '''
- pklog.info("Refresh cache")
- if not self._lock_cache(): return
- self.StatusChanged(STATUS_REFRESH_CACHE)
- self.last_action_time = time.time()
- self.AllowCancel(False);
- self.PercentageChanged(0)
- self._check_init((0,10))
- try:
- self._cache.update(PackageKitFetchProgress(self, prange=(10,95)))
- except Exception, e:
- self._open_cache(prange=(95,100))
- if self._check_canceled(): return False
- self.ErrorCode(ERROR_UNKNOWN, "Refreshing cache failed: %s" % e)
- self.Finished(EXIT_FAILED)
- return
- self._open_cache(prange=(95,100))
- self.PercentageChanged(100)
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doGetPackages(self, filters):
- '''
- Implement the apt2-get-packages functionality
- '''
- pklog.info("Get all packages")
- self.StatusChanged(STATUS_QUERY)
- self.NoPercentageUpdates()
- self._check_init(progress=False)
- self.AllowCancel(True)
-
- for pkg in self._cache:
- if self._check_canceled(): return False
- elif self._is_package_visible(pkg, filters):
- self._emit_package(pkg)
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doResolve(self, filters, names):
- '''
- Implement the apt2-resolve functionality
- '''
- pklog.info("Resolve")
- self.StatusChanged(STATUS_QUERY)
- self.NoPercentageUpdates()
- self._check_init(progress=False)
- self.AllowCancel(False)
-
- for name in names:
- if self._cache.has_key(name):
- self._emit_visible_package(filters, self._cache[name])
- else:
- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
- "Package name %s could not be resolved" % name)
- self.Finished(EXIT_FAILED)
- return
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doGetDepends(self, filter, ids, recursive=False):
- '''
- Implement the apt2-get-depends functionality
-
- Emit all packages that need to be installed or updated to install
- the given package ids. It behaves like a preview of the changes
- required for the installation. An error will be emitted if the
- dependecies cannot be satisfied.
- In contrast to the yum backend the whole dependency resoltions is done
- by the package manager. Therefor the list of satisfied packages cannot
- be computed easily. GDebi features this. Perhaps this should be moved
- to python-apt.
- '''
- pklog.info("Get depends (%s,%s,%s)" % (filter, ids, recursive))
- #FIXME: recursive is not yet implemented
- if recursive == True:
- pklog.warn("Recursive dependencies are not implemented")
- self.StatusChanged(STATUS_QUERY)
- self.NoPercentageUpdates()
- self._check_init(progress=False)
- self.AllowCancel(True)
-
- # Mark all packages for installation
- pkgs = []
- for id in ids:
- if self._check_canceled(): return
- pkg = self._find_package_by_id(id)
- if pkg == None:
- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
- "Package %s isn't available" % id)
- self.Finished(EXIT_FAILED)
- return
- try:
- pkg.markInstall()
- except Exception, e:
- #FIXME: Introduce a new info enumerate PK_INFO_MISSING for
- # missing dependecies
- self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
- "Dependecies for %s cannot be satisfied: %s" % e)
- self.Finished(EXIT_FAILED)
- return
- pkgs.append(pkg)
- # Check the status of the resulting changes
- for p in self._cache.getChanges():
- if self._check_canceled(): return
- if p in pkgs: continue
- if p.markedDelete:
- # Packagekit policy forbids removing packages for installation
- self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
- "Remove the package %s before" % p.name)
- self.Finished(EXIT_FAILED)
- return
- elif p.markedInstall or p.markedUpgrade:
- if self._is_package_visible(p, filter):
- self._emit_package(p)
- else:
- self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
- "Please use an advanced package management tool "
- "e.g. Synaptic or aptitude, since there is a "
- "complex dependency situation.")
- self.Finished(EXIT_FAILED)
- return
- # Clean up
- self._cache.clear()
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doGetRequires(self, filter, ids, recursive=False):
- '''
- Implement the apt2-get-requires functionality
- '''
- pklog.info("Get requires (%s,%s,%s)" % (filter, ids, recursive))
- #FIXME: recursive is not yet implemented
- if recursive == True:
- pklog.warn("Recursive dependencies are not implemented")
- self.StatusChanged(STATUS_DEP_RESOLVE)
- self.NoPercentageUpdates()
- self._check_init(progress=False)
- self.AllowCancel(True)
- pkgs = []
-
- # Mark all packages for installation
- for id in ids:
- if self._check_canceled(): return
- pkg = self._find_package_by_id(id)
- if pkg == None:
- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
- "Package %s isn't available" % id)
- self.Finished(EXIT_FAILED)
- return
- if pkg._pkg.Essential == True:
- self.ErrorCode(ERROR_CANNOT_REMOVE_SYSTEM_PACKAGE,
- "Package %s cannot be removed." % pkg.name)
- self.Finished(EXIT_FAILED)
- return
- pkgs.append(pkg)
- try:
- pkg.markDelete()
- except Exception, e:
- #FIXME: Introduce a new info enumerate PK_INFO_MISSING for
- # missing dependecies
- self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
- "Error removing %s: %s" % (pkg.name, e))
- self.Finished(EXIT_FAILED)
- return
- # Check the status of the resulting changes
- for p in self._cache.getChanges():
- if self._check_canceled(): return
- if p.markedDelete:
- if not p in pkgs and self._is_package_visible(p, filter):
- self._emit_package(p)
- else:
- self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
- "Please use an advanced package management tool "
- "e.g. Synaptic or aptitude, since there is a "
- "complex dependency situation.")
- self.Finished(EXIT_FAILED)
- return
- # Clean up
- self._cache.clear()
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doWhatProvides(self, filters, provides_type, search):
- def get_mapping_db(path):
- """
- Return the gdbm database at the given path or send an
- appropriate error message
- """
- if not os.access(path, os.R_OK):
- if self._cache.has_key("app-install-data") and \
- self._cache["app-install-data"].isInstalled == False:
- self.ErrorCode(ERROR_UNKNOWN,
- "Please install the package "
- "app-install data for a list of "
- "applications that can handle files of "
- "the given type")
- else:
- self.ErrorCode(ERROR_UNKNOWN,
- "The list of applications that can handle "
- "files of the given type cannot be opened.\n"
- "Try to reinstall the package "
- "app-install-data.")
- return None
- try:
- db = gdbm.open(path)
- except:
- self.ErrorCode(ERROR_UNKNOWN,
- "The list of applications that can handle "
- "files of the given type cannot be opened.\n"
- "Try to reinstall the package "
- "app-install-data.")
- return None
- else:
- return db
-
- self.StatusChanged(STATUS_QUERY)
- self.NoPercentageUpdates()
- self._check_init(progress=False)
- self.AllowCancel(False)
- if provides_type == PROVIDES_CODEC:
- # The search term from the codec helper looks like this one:
- match = re.match(r"gstreamer([0-9\.]+)\((.+?)\)", search)
- if not match:
- self.ErrorCode(ERROR_UNKNOWN,
- "The search term is invalid")
- self.Finished(EXIT_FAILED)
- return
- codec = "%s:%s" % (match.group(1), match.group(2))
- db = get_mapping_db("/var/cache/app-install/gai-codec-map.gdbm")
- if db == None:
- self.ErrorCode(ERROR_INTERNAL_ERROR,
- "Failed to open codec mapping database")
- self.Finished(EXIT_FAILED)
- return
- if db.has_key(codec):
- # The codec mapping db stores the packages as a string
- # separated by spaces. Each package has its section
- # prefixed and separated by a slash
- # FIXME: Should make use of the section and emit a
- # RepositoryRequired signal if the package does
- # not exist
- pkgs = map(lambda s: s.split("/")[1],
- db[codec].split(" "))
- self._emit_visible_packages_by_name(filters, pkgs)
- elif provides_type == PROVIDES_MIMETYPE:
- # Emit packages that contain an application that can handle
- # the given mime type
- handlers = set()
- db = get_mapping_db("/var/cache/app-install/gai-mime-map.gdbm")
- if db == None:
- self.Finished(EXIT_FAILED)
- return
- if db.has_key(search):
- pklog.debug("Mime type is registered: %s" % db[search])
- # The mime type handler db stores the packages as a string
- # separated by spaces. Each package has its section
- # prefixed and separated by a slash
- # FIXME: Should make use of the section and emit a
- # RepositoryRequired signal if the package does not exist
- handlers = map(lambda s: s.split("/")[1],
- db[search].split(" "))
- self._emit_visible_packages_by_name(filters, handlers)
- else:
- self.ErrorCode(ERROR_NOT_SUPPORTED,
- "This function is not implemented in this backend")
- self.Finished(EXIT_FAILED)
- return
- self.Finished(EXIT_SUCCESS)
-
- @serialize
- @threaded
- def doGetFiles(self, package_ids):
- """
- Emit the Files signal which includes the files included in a package
- Apt only supports this for installed packages
- """
- self.StatusChanged(STATUS_INFO)
- for id in package_ids:
- pkg = self._find_package_by_id(id)
- if pkg == None:
- self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
- "Package %s doesn't exist" % pkg.name)
- self.Finished(EXIT_FAILED)
- return
- files = string.join(self._get_installed_files(pkg), ";")
- self.Files(id, files)
- self.Finished(EXIT_SUCCESS)
-
- def doSetProxy(self, http_proxy, ftp_proxy):
- '''
- Set a proxy server for http and ftp transfer
- '''
- if http_proxy:
- pklog.debug("Set http proxy to %s" % http_proxy)
- apt_pkg.Config.set("http::Proxy", http_proxy)
- if ftp_proxy:
- pklog.debug("Set ftp proxy to %s" % ftp_proxy)
- apt_pkg.Config.set("ftp::Proxy", ftp_proxy)
-
- def doSetLocale(self, code):
- '''
- Set the locale of the daemon
-
- '''
- #FIXME: Needs testing
- if code != "":
- pklog.debug("Setting language to %s" % code)
- locale.setlocale("LANG", code)
-
- # Helpers
-
- def _lock_cache(self):
- """
- Emit an error message and return true if the apt system lock cannot
- be acquired.
- """
- try:
- apt_pkg.PkgSystemLock()
- except SystemError:
- self.ErrorCode(ERROR_CANNOT_GET_LOCK,
- "Only use one package management programme at the "
- "the same time.")
- self.Finished(EXIT_FAILED)
- return False
- return True
-
- def _unlock_cache(self):
- """
- Unlock the system package cache
- """
- try:
- apt_pkg.PkgSystemUnLock()
- except SystemError:
- return False
- return True
-
- def _open_cache(self, prange=(0,100), progress=True):
- '''
- (Re)Open the APT cache
- '''
- pklog.debug("Open APT cache")
- self.StatusChanged(STATUS_LOADING_CACHE)
- try:
- self._cache = PackageKitCache(PackageKitOpProgress(self, prange,
- progress))
- except:
- self.ErrorCode(ERROR_NO_CACHE, "Package cache could not be opened")
- self.Finished(EXIT_FAILED)
- self.Exit()
- return
- if self._cache._depcache.BrokenCount > 0:
- self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
- "There are broken dependecies on your system. "
- "Please use an advanced package manage e.g. "
- "Synaptic or aptitude to resolve this situation.")
- self.Finished(EXIT_FAILED)
- self.Exit()
- return
- self._last_cache_refresh = time.time()
-
- def _recover(self, prange=(95,100)):
- """
- Try to recover from a package manager failure
- """
- self.StatusChanged(STATUS_CLEANUP)
- self.NoPercentageUpdates()
- try:
- d = PackageKitDpkgInstallProgress(self)
- d.startUpdate()
- d.recover()
- d.finishUpdate()
- except:
- pass
- self._open_cache(prange)
-
- def _commit_changes(self, fetch_range=(5,50), install_range=(50,90)):
- """
- Commit changes to the cache and handle errors
- """
- try:
- self._cache.commit(PackageKitFetchProgress(self, fetch_range),
- PackageKitInstallProgress(self, install_range))
- except apt.cache.FetchFailedException, e:
- self._open_cache(prange=(95,100))
- self.ErrorCode(ERROR_PACKAGE_DOWNLOAD_FAILED, e.message)
- self.Finished(EXIT_FAILED)
- except apt.cache.FetchCancelledException:
- self._open_cache(prange=(95,100))
- self.Finished(EXIT_CANCELLED)
- self._canceled.clear()
- except InstallTimeOutPKError, e:
- self._recover()
- self._open_cache(prange=(95,100))
- #FIXME: should provide more information
- self.ErrorCode(ERROR_UNKNOWN,
- "Transaction was cancelled since the installation "
- "of a package hung.\n"
- "This can be caused by maintainer scripts which "
- "require input on the terminal:\n%s" % e.message)
- self.Finished(EXIT_KILLED)
- except PackageManagerFailedPKError, e:
- self._recover()
- self.ErrorCode(ERROR_UNKNOWN, "%s\n%s" % (e.message, e.output))
- self.Finished(EXIT_FAILED)
- else:
- return True
- return False
-
- def _check_init(self, prange=(0,10), progress=True):
- '''
- Check if the backend was initialized well and try to recover from
- a broken setup
- '''
- pklog.debug("Checking apt cache and xapian database")
- pkg_cache = os.path.join(apt_pkg.Config["Dir"],
- apt_pkg.Config["Dir::Cache"],
- apt_pkg.Config["Dir::Cache::pkgcache"])
- src_cache = os.path.join(apt_pkg.Config["Dir"],
- apt_pkg.Config["Dir::Cache"],
- apt_pkg.Config["Dir::Cache::srcpkgcache"])
- # Check if the cache instance is of the coorect class type, contains
- # any broken packages and if the dpkg status or apt cache files have
- # been changed since the last refresh
- if not isinstance(self._cache, apt.cache.Cache) or \
- (self._cache._depcache.BrokenCount > 0) or \
- (os.stat(apt_pkg.Config["Dir::State::status"])[stat.ST_MTIME] > \
- self._last_cache_refresh) or \
- (os.stat(pkg_cache)[stat.ST_MTIME] > self._last_cache_refresh) or \
- (os.stat(src_cache)[stat.ST_MTIME] > self._last_cache_refresh):
- pklog.debug("Reloading the cache is required")
- self._open_cache(prange, progress)
- else:
- self._cache.clear()
-
- def _check_canceled(self):
- '''
- Check if the current transaction was canceled. If so send the
- corresponding error message and return True
- '''
- if self._canceled.isSet():
- self.Finished(EXIT_CANCELLED)
- self._canceled.clear()
- return True
- return False
-
- def get_id_from_package(self, pkg, force_candidate=False):
- '''
- Return the packagekit id of package. By default this will be the
- installed version for installed packages and the candidate version
- for not installed packages.
-
- The force_candidate option will also report the id of the candidate
- version for installed packages.
- '''
- origin = ""
- cand_origin = pkg.candidateOrigin
- if not pkg.isInstalled or force_candidate:
- version = pkg.candidateVersion
- if cand_origin:
- origin = cand_origin[0].label
- else:
- version = pkg.installedVersion
- if cand_origin and cand_origin[0].site != "" and \
- pkg.installedVersion == pkg.candidateVersion:
- origin = cand_origin[0].label
- id = self._get_package_id(pkg.name, version, pkg.architecture, origin)
- return id
-
- def _emit_package(self, pkg, info=None, force_candidate=False):
- '''
- Send the Package signal for a given apt package
- '''
- id = self.get_id_from_package(pkg, force_candidate)
- section = pkg.section.split("/")[-1]
- if info == None:
- if pkg.isInstalled:
- if section == "metapackages":
- info = INFO_COLLECTION_INSTALLED
- else:
- info = INFO_INSTALLED
- else:
- if section == "metapackages":
- info = INFO_COLLECTION_AVAILABLE
- else:
- info = INFO_AVAILABLE
- summary = pkg.summary
- self.Package(info, id, summary)
-
- def _emit_visible_package(self, filters, pkg, info=None):
- """
- Filter and emit a package
- """
- if self._is_package_visible(pkg, filters):
- self._emit_package(pkg, info)
-
- def _emit_visible_packages(self, filters, pkgs, info=None):
- """
- Filter and emit packages
- """
- for p in pkgs:
- if self._is_package_visible(p, filters):
- self._emit_package(p, info)
-
- def _emit_visible_packages_by_name(self, filters, pkgs, info=None):
- """
- Find the packages with the given namens. Afterwards filter and emit
- them
- """
- for name in pkgs:
- if self._cache.has_key(name) and \
- self._is_package_visible(self._cache[name], filters):
- self._emit_package(self._cache[name], info)
-
-
- def _is_package_visible(self, pkg, filters):
- '''
- Return True if the package should be shown in the user interface
- '''
- if filters == FILTER_NONE:
- return True
- for filter in filters.split(";"):
- if (filter == FILTER_INSTALLED and not pkg.isInstalled) or \
- (filter == FILTER_NOT_INSTALLED and pkg.isInstalled) or \
- (filter == FILTER_SUPPORTED and not \
- self._is_package_supported(pkg)) or \
- (filter == FILTER_NOT_SUPPORTED and \
- self._is_package_supported(pkg)) or \
- (filter == FILTER_FREE and not self._is_package_free(pkg)) or \
- (filter == FILTER_NOT_FREE and \
- not self._is_package_not_free(pkg)) or \
- (filter == FILTER_GUI and not self._has_package_gui(pkg)) or \
- (filter == FILTER_NOT_GUI and self._has_package_gui(pkg)) or \
- (filter == FILTER_COLLECTIONS and not \
- self._is_package_collection(pkg)) or \
- (filter == FILTER_NOT_COLLECTIONS and \
- self._is_package_collection(pkg)) or\
- (filter == FILTER_DEVELOPMENT and not \
- self._is_package_devel(pkg)) or \
- (filter == FILTER_NOT_DEVELOPMENT and \
- self._is_package_devel(pkg)):
- return False
- return True
-
- def _is_package_not_free(self, pkg):
- """
- Return True if we can be sure that the package's license isn't any
- free one
- """
- candidate = pkg.candidateOrigin
- return candidate != None and \
- ((candidate[0].origin == "Ubuntu" and \
- candidate[0].component in ["multiverse", "restricted"]) or \
- (candidate[0].origin == "Debian" and \
- candidate[0].component in ["contrib", "non-free"])) and \
- candidate[0].trusted == True
-
- def _is_package_collection(self, pkg):
- """
- Return True if the package is a metapackge
- """
- section = pkg.section.split("/")[-1]
- return section == "metapackages"
-
- def _is_package_free(self, pkg):
- """
- Return True if we can be sure that the package has got a free license
- """
- candidate = pkg.candidateOrigin
- return candidate != None and \
- ((candidate[0].origin == "Ubuntu" and \
- candidate[0].component in ["main", "universe"]) or \
- (candidate[0].origin == "Debian" and \
- candidate[0].component == "main")) and\
- candidate[0].trusted == True
-
- def _has_package_gui(self, pkg):
- #FIXME: should go to a modified Package class
- #FIXME: take application data into account. perhaps checking for
- # property in the xapian database
- return pkg.section.split('/')[-1].lower() in ['x11', 'gnome', 'kde']
-
- def _is_package_devel(self, pkg):
- #FIXME: should go to a modified Package class
- return pkg.name.endswith("-dev") or pkg.name.endswith("-dbg") or \
- pkg.section.split('/')[-1].lower() in ['devel', 'libdevel']
-
- def _is_package_supported(self, pkg):
- candidate = pkg.candidateOrigin[0]
- return candidate != None and \
- candidate[0].origin == "Ubuntu" and \
- candidate[0].component in ["main", "restricted"] and \
- candidate[0].trusted == True
-
- def _find_package_by_id(self, id):
- '''
- Return a package matching to the given package id
- '''
- # FIXME: Perform more checks
- name, version, arch, data = self.get_package_from_id(id)
- if self._cache.has_key(name):
- return self._cache[name]
- else:
- return None
-
- def _get_installed_files(self, pkg):
- """
- Return the list of unicode names of the files which have
- been installed by the package
-
- This method should be obsolete by the apt.package.Package.installedFiles
- attribute as soon as the consolidate branch of python-apt gets merged
- """
- path = os.path.join(apt_pkg.Config["Dir"],
- "var/lib/dpkg/info/%s.list" % pkg.name)
- try:
- list = open(path)
- files = list.read().decode().split("\n")
- list.close()
- except:
- return []
- return files
-
- def _get_changelog(self, pkg, uri=None, cancel_lock=None):
- """
- Download the changelog of the package and return it as unicode
- string
-
- This method is already part of the consolidate branch of python-apt
-
- uri: Is the uri to the changelog file. The following named variables
- will be substituted: src_section, prefix, src_pkg and src_ver
- For example the Ubuntu changelog:
- uri = "http://changelogs.ubuntu.com/changelogs/pool" \\
- "/%(src_section)s/%(prefix)s/%(src_pkg)s" \\
- "/%(src_pkg)s_%(src_ver)s/changelog"
- cancel_lock: If this threading.Lock() is set, the download will be
- canceled
- """
- if uri == None:
- if pkg.candidateOrigin[0].origin == "Debian":
- uri = "http://packages.debian.org/changelogs/pool" \
- "/%(src_section)s/%(prefix)s/%(src_pkg)s" \
- "/%(src_pkg)s_%(src_ver)s/changelog"
- elif pkg.candidateOrigin[0].origin == "Ubuntu":
- uri = "http://changelogs.ubuntu.com/changelogs/pool" \
- "/%(src_section)s/%(prefix)s/%(src_pkg)s" \
- "/%(src_pkg)s_%(src_ver)s/changelog"
- else:
- return "The list of changes is not available"
-
- # get the src package name
- src_pkg = pkg.sourcePackageName
-
- # assume "main" section
- src_section = "main"
- # use the section of the candidate as a starting point
- section = pkg._depcache.GetCandidateVer(pkg._pkg).Section
-
- # get the source version, start with the binaries version
- bin_ver = pkg.candidateVersion
- src_ver = pkg.candidateVersion
- #print "bin: %s" % binver
- try:
- # try to get the source version of the pkg, this differs
- # for some (e.g. libnspr4 on ubuntu)
- # this feature only works if the correct deb-src are in the
- # sources.list
- # otherwise we fall back to the binary version number
- src_records = apt_pkg.GetPkgSrcRecords()
- src_rec = src_records.Lookup(src_pkg)
- if src_rec:
- src_ver = src_records.Version
- #if apt_pkg.VersionCompare(binver, srcver) > 0:
- # srcver = binver
- if not src_ver:
- src_ver = bin_ver
- #print "srcver: %s" % src_ver
- section = src_records.Section
- #print "srcsect: %s" % section
- else:
- # fail into the error handler
- raise SystemError
- except SystemError, e:
- src_ver = bin_ver
-
- l = section.split("/")
- if len(l) > 1:
- src_section = l[0]
-
- # lib is handled special
- prefix = src_pkg[0]
- if src_pkg.startswith("lib"):
- prefix = "lib" + src_pkg[3]
-
- # stip epoch
- l = src_ver.split(":")
- if len(l) > 1:
- src_ver = "".join(l[1:])
-
- uri = uri % {"src_section" : src_section,
- "prefix" : prefix,
- "src_pkg" : src_pkg,
- "src_ver" : src_ver}
- try:
- # Check if the download was canceled
- if cancel_lock and cancel_lock.isSet(): return ""
- changelog_file = urllib2.urlopen(uri)
- # do only get the lines that are new
- changelog = ""
- regexp = "^%s \((.*)\)(.*)$" % (re.escape(src_pkg))
-
- i=0
- while True:
- # Check if the download was canceled
- if cancel_lock and cancel_lock.isSet(): return ""
- # Read changelog line by line
- line_raw = changelog_file.readline()
- if line_raw == "":
- break
- # The changelog is encoded in utf-8, but since there isn't any
- # http header, urllib2 seems to treat it as ascii
- line = line_raw.decode("utf-8")
-
- #print line.encode('utf-8')
- match = re.match(regexp, line)
- if match:
- # strip epoch from installed version
- # and from changelog too
- installed = pkg.installedVersion
- if installed and ":" in installed:
- installed = installed.split(":",1)[1]
- changelog_ver = match.group(1)
- if changelog_ver and ":" in changelog_ver:
- changelog_ver = changelog_ver.split(":", 1)[1]
- if installed and \
- apt_pkg.VersionCompare(changelog_ver, installed) <= 0:
- break
- # EOF (shouldn't really happen)
- changelog += line
-
- # Print an error if we failed to extract a changelog
- if len(changelog) == 0:
- changelog = "The list of changes is not available"
- except urllib2.HTTPError,e:
- return "The list of changes is not available yet.\n\n" \
- "Please use http://launchpad.net/ubuntu/+source/%s/%s/" \
- "+changelog\n" \
- "until the changes become available or try again " \
- "later." % (src_pkg, src_ver)
- except IOError, httplib.BadStatusLine:
- return "Failed to download the list of changes.\nPlease " \
- "check your Internet connection."
- return changelog
-
- def _get_package_group(self, pkg):
- """
- Return the packagekit group corresponding to the package's section
- """
- section = pkg.section.split("/")[-1]
- if SECTION_GROUP_MAP.has_key(section):
- return SECTION_GROUP_MAP[section]
- else:
- pklog.debug("Unkown package section %s of %s" % (pkg.section,
- pkg.name))
- return GROUP_UNKNOWN
-
- def _get_package_description(self, pkg):
- """
- Return the formated long description according to the Debian policy
- (Chapter 5.6.13).
- See http://www.debian.org/doc/debian-policy/ch-controlfields.html
- for more information.
- """
- if not pkg._lookupRecord():
- return ""
- # get the translated description
- ver = pkg._depcache.GetCandidateVer(pkg._pkg)
- desc_iter = ver.TranslatedDescription
- pkg._records.Lookup(desc_iter.FileList.pop(0))
- desc = ""
- try:
- s = unicode(pkg._records.LongDesc,"utf-8")
- except UnicodeDecodeError,e:
- s = "Invalid unicode in description for '%s' (%s)" % (pkg.name, e)
- lines = string.split(s, "\n")
- for i in range(len(lines)):
- # Skip the first line, since its a duplication of the summary
- if i == 0: continue
- raw_line = lines[i]
- if raw_line.strip() == ".":
- # The line is just line break
- if not desc.endswith("\n"):
- desc += "\n"
- continue
- elif raw_line.startswith(" "):
- # The line should be displayed verbatim without word wrapping
- if not desc.endswith("\n"):
- line = "\n%s\n" % raw_line[2:]
- else:
- line = "%s\n" % raw_line[2:]
- elif raw_line.startswith(" "):
- # The line is part of a paragraph.
- if desc.endswith("\n") or desc == "":
- # Skip the leading white space
- line = raw_line[1:]
- else:
- line = raw_line
- else:
- line = raw_line
- pklog.debug("invalid line %s in description for %s:\n%s" % \
- (i, pkg.name, pkg.rawDescription))
- # Use dots for lists
- line = re.sub(r"^(\s*)(\*|0|o|-) ", ur"\1\u2022 ", line, 1)
- # Add current line to the description
- desc += line
- return desc
-
-
-def sigquit(signum, frame):
- pklog.error("Was killed")
- sys.exit(1)
-
-def debug_exception(type, value, tb):
- """
- Provides an interactive debugging session on unhandled exceptions
- See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65287
- """
- if hasattr(sys, 'ps1') or not sys.stderr.isatty() or \
- not sys.stdin.isatty() or not sys.stdout.isatty() or type==SyntaxError:
- # Calls the default handler in interactive mode, if output is·
- # redirected or on syntax errors
- sys.__excepthook__(type, value, tb)
- else:
- import traceback, pdb
- traceback.print_exception(type, value, tb)
- print
- pdb.pm()
-
-def takeover():
- """
- Exit the currently running backend
- """
- PACKAGEKIT_DBUS_SERVICE = 'org.freedesktop.PackageKitAptBackend'
- PACKAGEKIT_DBUS_INTERFACE = 'org.freedesktop.PackageKitBackend'
- PACKAGEKIT_DBUS_PATH = '/org/freedesktop/PackageKitBackend'
- try:
- bus = dbus.SystemBus()
- except dbus.DBusException, e:
- pklog.critical("Unable to connect to dbus: %s" % e)
- sys.exit(1)
- proxy = bus.get_object(PACKAGEKIT_DBUS_SERVICE, PACKAGEKIT_DBUS_PATH)
- iface = dbus.Interface(proxy, PACKAGEKIT_DBUS_INTERFACE)
- try:
- iface.Exit()
- except dbus.DBusException:
- pass
-
-def run():
- """
- Start the apt backend
- """
- loop = dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
- bus = dbus.SystemBus(mainloop=loop)
- bus_name = dbus.service.BusName(PACKAGEKIT_DBUS_SERVICE, bus=bus)
- manager = PackageKitAptBackend(bus_name, PACKAGEKIT_DBUS_PATH)
- manager.run()
-
-def main():
- parser = optparse.OptionParser(description="APT backend for PackageKit")
- parser.add_option("-t", "--takeover",
- action="store_true", dest="takeover",
- help="Exit the currently running backend "
- "(Only needed by developers)")
- parser.add_option("-r", "--root",
- action="store", type="string", dest="root",
- help="Use the given directory as the system root "
- "(Only needed by developers)")
- parser.add_option("-p", "--profile",
- action="store", type="string", dest="profile",
- help="Store profiling stats in the given file "
- "(Only needed by developers)")
- parser.add_option("-d", "--debug",
- action="store_true", dest="debug",
- help="Show a lot of additional information and drop to "
- "a debugging console on unhandled exceptions "
- "(Only needed by developers)")
- (options, args) = parser.parse_args()
- if options.debug:
- pklog.setLevel(logging.DEBUG)
- sys.excepthook = debug_exception
-
- if options.root:
- config = apt_pkg.Config
- config.Set("Dir", options.root)
- config.Set("Dir::State::status",
- os.path.join(options.root, "/var/lib/dpkg/status"))
-
- if options.takeover:
- takeover()
-
- if options.profile:
- import hotshot
- prof = hotshot.Profile(options.profile)
- prof.runcall(run)
- prof.close()
- else:
- run()
-
-if __name__ == '__main__':
- main()
-
-# vim: ts=4 et sts=4
diff --git a/backends/apt/aptbackend.py b/backends/apt/aptbackend.py
new file mode 100755
index 0000000..700c325
--- /dev/null
+++ b/backends/apt/aptbackend.py
@@ -0,0 +1,2236 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+Provides an apt backend to PackageKit
+
+Copyright (C) 2007 Ali Sabil <ali.sabil at gmail.com>
+Copyright (C) 2007 Tom Parker <palfrey at tevp.net>
+Copyright (C) 2008 Sebastian Heinlein <glatzor at ubuntu.com>
+
+Licensed under the GNU General Public License Version 2
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+"""
+
+__author__ = "Sebastian Heinlein <devel at glatzor.de>"
+
+import errno
+import fcntl
+import gdbm
+import httplib
+import locale
+import logging
+import optparse
+import os
+import pty
+import re
+import signal
+import shutil
+import socket
+import stat
+import string
+import subprocess
+import sys
+import time
+import threading
+import urllib2
+import warnings
+
+import apt
+import apt.debfile
+import apt_pkg
+import dbus
+import dbus.glib
+import dbus.service
+import dbus.mainloop.glib
+import gobject
+
+from packagekit.daemonBackend import PACKAGEKIT_DBUS_INTERFACE, PACKAGEKIT_DBUS_PATH, PackageKitBaseBackend, PackagekitProgress, pklog, threaded, serialize
+from packagekit.enums import *
+
+
+warnings.filterwarnings(action='ignore', category=FutureWarning)
+
+PACKAGEKIT_DBUS_SERVICE = 'org.freedesktop.PackageKitAptBackend'
+
+apt_pkg.InitConfig()
+apt_pkg.Config.Set("DPkg::Options::", '--force-confdef')
+apt_pkg.Config.Set("DPkg::Options::", '--force-confold')
+
+# Xapian database is optionally used to speed up package description search
+XAPIAN_DB_PATH = os.environ.get("AXI_DB_PATH", "/var/lib/apt-xapian-index")
+XAPIAN_DB = XAPIAN_DB_PATH + "/index"
+XAPIAN_DB_VALUES = XAPIAN_DB_PATH + "/values"
+XAPIAN_SUPPORT = False
+try:
+ import xapian
+except ImportError:
+ pass
+else:
+ if os.access(XAPIAN_DB, os.R_OK):
+ pklog.debug("Use XAPIAN for the search")
+ XAPIAN_SUPPORT = True
+
+# SoftwareProperties is required to proivde information about repositories
+try:
+ import softwareproperties.SoftwareProperties
+except ImportError:
+ REPOS_SUPPORT = False
+else:
+ REPOS_SUPPORT = True
+
+# Check if update-manager-core is installed to get aware of the
+# latest distro releases
+try:
+ from UpdateManager.Core.MetaRelease import MetaReleaseCore
+except ImportError:
+ META_RELEASE_SUPPORT = False
+else:
+ META_RELEASE_SUPPORT = True
+
+
+# Set a timeout for the changelog download
+socket.setdefaulttimeout(2)
+
+# Required for daemon mode
+os.putenv("PATH",
+ "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")
+# Avoid questions from the maintainer scripts as far as possible
+os.putenv("DEBIAN_FRONTEND", "noninteractive")
+os.putenv("APT_LISTCHANGES_FRONTEND", "none")
+
+# Setup threading support
+gobject.threads_init()
+dbus.glib.threads_init()
+
+# Map Debian sections to the PackageKit group name space
+SECTION_GROUP_MAP = {
+ "admin" : GROUP_ADMIN_TOOLS,
+ "base" : GROUP_SYSTEM,
+ "comm" : GROUP_COMMUNICATION,
+ "devel" : GROUP_PROGRAMMING,
+ "doc" : GROUP_DOCUMENTATION,
+ "editors" : GROUP_PUBLISHING,
+ "electronics" : GROUP_ELECTRONICS,
+ "embedded" : GROUP_SYSTEM,
+ "games" : GROUP_GAMES,
+ "gnome" : GROUP_DESKTOP_GNOME,
+ "graphics" : GROUP_GRAPHICS,
+ "hamradio" : GROUP_COMMUNICATION,
+ "interpreters" : GROUP_PROGRAMMING,
+ "kde" : GROUP_DESKTOP_KDE,
+ "libdevel" : GROUP_PROGRAMMING,
+ "libs" : GROUP_SYSTEM,
+ "mail" : GROUP_INTERNET,
+ "math" : GROUP_SCIENCE,
+ "misc" : GROUP_OTHER,
+ "net" : GROUP_NETWORK,
+ "news" : GROUP_INTERNET,
+ "oldlibs" : GROUP_LEGACY,
+ "otherosfs" : GROUP_SYSTEM,
+ "perl" : GROUP_PROGRAMMING,
+ "python" : GROUP_PROGRAMMING,
+ "science" : GROUP_SCIENCE,
+ "shells" : GROUP_SYSTEM,
+ "sound" : GROUP_MULTIMEDIA,
+ "tex" : GROUP_PUBLISHING,
+ "text" : GROUP_PUBLISHING,
+ "utils" : GROUP_ACCESSORIES,
+ "web" : GROUP_INTERNET,
+ "x11" : GROUP_DESKTOP_OTHER,
+ "unknown" : GROUP_UNKNOWN,
+ "alien" : GROUP_UNKNOWN,
+ "translations" : GROUP_LOCALIZATION,
+ "metapackages" : GROUP_COLLECTIONS }
+
+# Regular expressions to detect bug numbers in changelogs according to the
+# Debian Policy Chapter 4.4. For details see the footnote 16:
+# http://www.debian.org/doc/debian-policy/footnotes.html#f16
+MATCH_BUG_CLOSES_DEBIAN=r"closes:\s*(?:bug)?\#?\s?\d+(?:,\s*(?:bug)?\#?\s?\d+)*"
+MATCH_BUG_NUMBERS=r"\#?\s?(\d+)"
+# URL pointing to a bug in the Debian bug tracker
+HREF_BUG_DEBIAN="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%s"
+
+# Regular expression to find cve references
+MATCH_CVE="CVE-\d{4}-\d{4}"
+HREF_CVE="http://web.nvd.nist.gov/view/vuln/detail?vulnId=%s"
+
+def unlock_cache_afterwards(func):
+ '''
+ Make sure that the package cache is unlocked after the decorated function
+ was called
+ '''
+ def wrapper(*args, **kwargs):
+ backend = args[0]
+ func(*args, **kwargs)
+ backend._unlock_cache()
+ wrapper.__name__ = func.__name__
+ return wrapper
+
+
+class PKError(Exception):
+ pass
+
+class PackageManagerFailedPKError(PKError):
+ def __init__(self, msg, pkg, output):
+ self.message = msg
+ self.package = pkg
+ self.output = output
+
+class InstallTimeOutPKError(PKError):
+ pass
+
+class PackageKitCache(apt.cache.Cache):
+ """
+ Enhanced version of the apt.cache.Cache class which supports some features
+ which can only be found in the consolidate branch of python-apt
+ """
+ def __iter__(self):
+ """
+ Let the cache behave like a sorted list of packages
+ """
+ for pkgname in sorted(self._dict.keys()):
+ yield self._dict[pkgname]
+ raise StopIteration
+
+ def isVirtualPackage(self, name):
+ """
+ Return True if the package of the given name is a virtual package
+ """
+ try:
+ virtual_pkg = self._cache[name]
+ except KeyError:
+ return False
+ if len(virtual_pkg.VersionList) == 0:
+ return True
+ return False
+
+ def getProvidingPackages(self, virtual):
+ """
+ Return a list of packages which provide the virtual package of the
+ specified name
+ """
+ providers = []
+ try:
+ vp = self._cache[virtual]
+ if len(vp.VersionList) != 0:
+ return providers
+ except KeyError:
+ return providers
+ for pkg in self:
+ v = self._depcache.GetCandidateVer(pkg._pkg)
+ if v == None:
+ continue
+ for p in v.ProvidesList:
+ #print virtual
+ #print p[0]
+ if virtual == p[0]:
+ # we found a pkg that provides this virtual
+ # pkg, check if the proivdes is any good
+ providers.append(pkg)
+ #cand = self._cache[pkg.name]
+ #candver = self._cache._depcache.GetCandidateVer(cand._pkg)
+ #instver = cand._pkg.CurrentVer
+ #res = apt_pkg.CheckDep(candver.VerStr,oper,ver)
+ #if res == True:
+ # self._dbg(1,"we can use %s" % pkg.name)
+ # or_found = True
+ # break
+ return providers
+
+ def clear(self):
+ """ Unmark all changes """
+ self._depcache.Init()
+
+
+class DpkgInstallProgress(apt.progress.InstallProgress):
+ """
+ Class to initiate and monitor installation of local package files with dpkg
+ """
+ #FIXME: Use the merged DpkgInstallProgress of python-apt
+ def recover(self):
+ """
+ Run "dpkg --configure -a"
+ """
+ cmd = ["/usr/bin/dpkg", "--status-fd", str(self.writefd),
+ "--root", apt_pkg.Config["Dir"],
+ "--force-confdef", "--force-confold",
+ "--configure", "-a"]
+ self.run(cmd)
+
+ def install(self, filenames):
+ """
+ Install the given package using a dpkg command line call
+ """
+ cmd = ["/usr/bin/dpkg", "--force-confdef", "--force-confold",
+ "--status-fd", str(self.writefd),
+ "--root", apt_pkg.Config["Dir"], "-i"]
+ cmd.extend(map(lambda f: str(f), filenames))
+ self.run(cmd)
+
+ def run(self, cmd):
+ """
+ Run and monitor a dpkg command line call
+ """
+ pklog.debug("Executing: %s" % cmd)
+ (self.master_fd, slave) = pty.openpty()
+ fcntl.fcntl(self.master_fd, fcntl.F_SETFL, os.O_NONBLOCK)
+ p = subprocess.Popen(cmd, stdout=slave, stdin=slave)
+ self.child_pid = p.pid
+ res = self.waitChild()
+ return res
+
+ def updateInterface(self):
+ """
+ Process status messages from dpkg
+ """
+ if self.statusfd == None:
+ return
+ try:
+ while not self.read.endswith("\n"):
+ self.read += os.read(self.statusfd.fileno(), 1)
+ except OSError, (error_no, error_str):
+ # resource temporarly unavailable is ignored
+ if error_no not in [errno.EAGAIN, errno.EWOULDBLOCK]:
+ print error_str
+ if self.read.endswith("\n"):
+ statusl = string.split(self.read, ":")
+ if len(statusl) < 3:
+ pklog.warn("got garbage from dpkg: '%s'" % self.read)
+ self.read = ""
+ status = statusl[2].strip()
+ pkg = statusl[1].strip()
+ #print status
+ if status == "error":
+ self.error(pkg, status)
+ elif status == "conffile-prompt":
+ # we get a string like this:
+ # 'current-conffile' 'new-conffile' useredited distedited
+ match = re.search(".+conffile-prompt : '(.+)' '(.+)'",
+ self.read)
+ self.conffile(match.group(1), match.group(2))
+ else:
+ pklog.debug("Dpkg status: %s" % status)
+ self.status = status
+ self.read = ""
+
+
+class PackageKitOpProgress(apt.progress.OpProgress):
+ '''
+ Handle the cache opening process
+ '''
+ def __init__(self, backend, prange=(0,100), progress=True):
+ self._backend = backend
+ apt.progress.OpProgress.__init__(self)
+ self.steps = []
+ for v in [0.12, 0.25, 0.50, 0.75, 1.00]:
+ s = prange[0] + (prange[1] - prange[0]) * v
+ self.steps.append(s)
+ self.pstart = float(prange[0])
+ self.pend = self.steps.pop(0)
+ self.pprev = None
+ self.show_progress = progress
+
+ # OpProgress callbacks
+ def update(self, percent):
+ progress = int(self.pstart + percent / 100 * (self.pend - self.pstart))
+ if self.show_progress == True and self.pprev < progress:
+ self._backend.PercentageChanged(progress)
+ self.pprev = progress
+
+ def done(self):
+ self.pstart = self.pend
+ try:
+ self.pend = self.steps.pop(0)
+ except:
+ pklog.warning("An additional step to open the cache is required")
+
+
+class PackageKitFetchProgress(apt.progress.FetchProgress):
+ '''
+ Handle the package download process
+ '''
+ def __init__(self, backend, prange=(0,100)):
+ self._backend = backend
+ apt.progress.FetchProgress.__init__(self)
+ self.pstart = prange[0]
+ self.pend = prange[1]
+ self.pprev = None
+
+ def pulse(self):
+ apt.progress.FetchProgress.pulse(self)
+ # Strange, but we seem to need this to detect a cancel immediately
+ time.sleep(0.01)
+ if self._backend._canceled.isSet():
+ return False
+ progress = int(self.pstart + self.percent/100 * \
+ (self.pend - self.pstart))
+ if self.pprev < progress:
+ self._backend.PercentageChanged(progress)
+ self.pprev = progress
+ return True
+
+ def start(self):
+ self._backend.StatusChanged(STATUS_DOWNLOAD)
+ self._backend.AllowCancel(True)
+
+ def stop(self):
+ self._backend.PercentageChanged(self.pend)
+ self._backend.AllowCancel(False)
+
+ def mediaChange(self, medium, drive):
+ #FIXME: Raise an expcetion and handle it in _commit_changes
+ # Strangly _commit_changes does not catch the expcetion
+ self._backend.Message(MESSAGE_UNKNOWN,
+ "Installing from CD-Rom (%s) is not "
+ "supported." % medium)
+ return False
+
+
+class PackageKitInstallProgress(apt.progress.InstallProgress):
+ '''
+ Handle the installation and removal process. Bits taken from
+ DistUpgradeViewNonInteractive.
+ '''
+ def __init__(self, backend, prange=(0,100)):
+ apt.progress.InstallProgress.__init__(self)
+ self._backend = backend
+ self.pstart = prange[0]
+ self.pend = prange[1]
+ self.pprev = None
+ self.last_activity = None
+ self.conffile_prompts = set()
+ # insanly long timeout to be able to kill hanging maintainer scripts
+ self.timeout = 10 * 60
+ self.start_time = None
+ self.output = ""
+ self.master_fd = None
+ self.child_pid = None
+
+ def statusChange(self, pkg, percent, status):
+ self.last_activity = time.time()
+ progress = self.pstart + percent/100 * (self.pend - self.pstart)
+ if self.pprev < progress:
+ self._backend.PercentageChanged(int(progress))
+ self.pprev = progress
+ pklog.debug("APT status: %s" % status)
+
+ def startUpdate(self):
+ # The apt system lock was set by _lock_cache() before
+ self._backend._unlock_cache()
+ self._backend.StatusChanged(STATUS_COMMIT)
+ self.last_activity = time.time()
+ self.start_time = time.time()
+
+ def fork(self):
+ pklog.debug("fork()")
+ (pid, self.master_fd) = pty.fork()
+ if pid != 0:
+ fcntl.fcntl(self.master_fd, fcntl.F_SETFL, os.O_NONBLOCK)
+ return pid
+
+ def updateInterface(self):
+ apt.progress.InstallProgress.updateInterface(self)
+ # Collect the output from the package manager
+ try:
+ out = os.read(self.master_fd, 512)
+ self.output = self.output + out
+ pklog.debug("APT out: %s " % out)
+ except OSError:
+ pass
+ # catch a time out by sending crtl+c
+ if self.last_activity + self.timeout < time.time():
+ pklog.critical("no activity for %s time sending ctrl-c" \
+ % self.timeout)
+ os.write(self.master_fd, chr(3))
+ #FIXME: include this into the normal install progress and add
+ # correct package information
+ raise InstallTimeOutPKError(self.output)
+
+ def conffile(self, current, new):
+ pklog.warning("Config file prompt: '%s' (sending no)" % current)
+ self.conffile_prompts.add(new)
+
+ def error(self, pkg, msg):
+ raise PackageManagerFailedPKError(pkg, msg, self.output)
+
+ def finishUpdate(self):
+ pklog.debug("finishUpdate()")
+ if self.conffile_prompts:
+ self._backend.Message(MESSAGE_CONFIG_FILES_CHANGED,
+ "The following conffile prompts were found "
+ "and need investiagtion: %s" % \
+ "\n".join(self.conffile_prompts))
+ # Check for required restarts
+ if os.path.exists("/var/run/reboot-required") and \
+ os.path.getmtime("/var/run/reboot-required") > self.start_time:
+ self._backend.RequireRestart(RESTART_SYSTEM, "")
+
+
+class PackageKitDpkgInstallProgress(DpkgInstallProgress,
+ PackageKitInstallProgress):
+ """
+ Class to integrate the progress of core dpkg operations into PackageKit
+ """
+ def run(self, filenames):
+ return DpkgInstallProgress.run(self, filenames)
+
+ def updateInterface(self):
+ DpkgInstallProgress.updateInterface(self)
+ try:
+ out = os.read(self.master_fd, 512)
+ self.output += out
+ if out != "": pklog.debug("Dpkg out: %s" % out)
+ except OSError:
+ pass
+ # we timed out, send ctrl-c
+ if self.last_activity + self.timeout < time.time():
+ pklog.critical("no activity for %s time sending "
+ "ctrl-c" % self.timeout)
+ os.write(self.master_fd, chr(3))
+ raise InstallTimeOutPKError(self.output)
+
+
+if REPOS_SUPPORT == True:
+ class PackageKitSoftwareProperties(softwareproperties.SoftwareProperties.SoftwareProperties):
+ """
+ Helper class to fix a siily bug in python-software-properties
+ """
+ def set_modified_sourceslist(self):
+ self.save_sourceslist()
+
+
+class PackageKitAptBackend(PackageKitBaseBackend):
+ '''
+ PackageKit backend for apt
+ '''
+ def __init__(self, bus_name, dbus_path):
+ pklog.info("Initializing APT backend")
+ signal.signal(signal.SIGQUIT, sigquit)
+ self._cache = None
+ self._canceled = threading.Event()
+ self._canceled.clear()
+ self._lock = threading.Lock()
+ self._last_cache_refresh = None
+ PackageKitBaseBackend.__init__(self, bus_name, dbus_path)
+
+ # Methods ( client -> engine -> backend )
+
+ def doInit(self):
+ pklog.info("Initializing cache")
+ self.StatusChanged(STATUS_RUNNING)
+ self.AllowCancel(False)
+ self.NoPercentageUpdates()
+ self._open_cache(progress=False)
+
+ @serialize
+ def doExit(self):
+ gobject.idle_add(self._doExitDelay)
+
+ def doCancel(self):
+ pklog.info("Canceling current action")
+ self.StatusChanged(STATUS_CANCEL)
+ self._canceled.set()
+ self._canceled.wait()
+
+ @serialize
+ @threaded
+ def doSearchFile(self, filters, filename):
+ '''
+ Implement the apt2-search-file functionality
+
+ Apt specific: Works only for installed files. Since config files are
+ not removed by default even not installed packages can be reported.
+ '''
+ pklog.info("Searching for file: %s" % filename)
+ self.StatusChanged(STATUS_QUERY)
+ self.NoPercentageUpdates()
+ self._check_init(progress=False)
+ self.AllowCancel(True)
+
+ for pkg in self._cache:
+ if self._check_canceled(): return False
+ for installed_file in self._get_installed_files(pkg):
+ if filename in installed_file:
+ self._emit_visible_package(filters, pkg)
+ break
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doSearchGroup(self, filters, group):
+ '''
+ Implement the apt2-search-group functionality
+ '''
+ pklog.info("Searching for group: %s" % group)
+ self.StatusChanged(STATUS_QUERY)
+ self.NoPercentageUpdates()
+ self._check_init(progress=False)
+ self.AllowCancel(True)
+
+ for pkg in self._cache:
+ if self._check_canceled(): return False
+ elif self._get_package_group(pkg) == group:
+ self._emit_visible_package(filters, pkg)
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doSearchName(self, filters, search):
+ '''
+ Implement the apt2-search-name functionality
+ '''
+ pklog.info("Searching for package name: %s" % search)
+ self.StatusChanged(STATUS_QUERY)
+ self.NoPercentageUpdates()
+ self._check_init(progress=False)
+ self.AllowCancel(True)
+
+ for pkg in self._cache:
+ if self._check_canceled(): return False
+ elif search in pkg.name:
+ self._emit_visible_package(filters, pkg)
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doSearchDetails(self, filters, search):
+ '''
+ Implement the apt2-search-details functionality
+ '''
+ pklog.info("Searching for package name: %s" % search)
+ self.StatusChanged(STATUS_QUERY)
+ self.NoPercentageUpdates()
+ self._check_init(progress=False)
+ self.AllowCancel(True)
+ results = []
+
+ if XAPIAN_SUPPORT == True:
+ search_flags = (xapian.QueryParser.FLAG_BOOLEAN |
+ xapian.QueryParser.FLAG_PHRASE |
+ xapian.QueryParser.FLAG_LOVEHATE |
+ xapian.QueryParser.FLAG_BOOLEAN_ANY_CASE)
+ pklog.debug("Performing xapian db based search")
+ db = xapian.Database(XAPIAN_DB)
+ parser = xapian.QueryParser()
+ query = parser.parse_query(unicode(search),
+ search_flags)
+ enquire = xapian.Enquire(db)
+ enquire.set_query(query)
+ matches = enquire.get_mset(0, 1000)
+ for r in map(lambda m: m[xapian.MSET_DOCUMENT].get_data(),
+ enquire.get_mset(0,1000)):
+ if self._cache.has_key(r):
+ results.append(self._cache[r])
+ else:
+ pklog.debug("Performing apt cache based search")
+ for p in self._cache._dict.values():
+ if self._check_canceled(): return
+ needle = search.strip().lower()
+ haystack = p.description.lower()
+ if p.name.find(needle) >= 0 or haystack.find(needle) >= 0:
+ results.append(p)
+
+ for r in results:
+ if self._check_canceled(): return
+ self._emit_visible_package(filters, r)
+
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doGetDistroUpgrades(self):
+ '''
+ Implement the {backend}-get-distro-upgrades functionality
+ '''
+ pklog.info("Get distro upgrades")
+ self.StatusChanged(STATUS_INFO)
+ self.AllowCancel(False)
+ self.NoPercentageUpdates()
+
+ if META_RELEASE_SUPPORT == False:
+ if self._cache.has_key("update-manager-core") and \
+ self._cache["update-manager-core"].isInstalled == False:
+ self.ErrorCode(ERROR_UNKNOWN,
+ "Please install the package update-manager-core to get notified "
+ "of the latest distribution releases.")
+ else:
+ self.ErrorCode(ERROR_UNKNOWN,
+ "Please make sure that update-manager-core is"
+ "correctly installed.")
+ self.Finished(EXIT_FAILED)
+ return
+
+ #FIXME Evil to start the download during init
+ meta_release = MetaReleaseCore(False, False)
+ #FIXME: should use a lock
+ while meta_release.downloading:
+ time.sleep(1)
+ #FIXME: Add support for description
+ if meta_release.new_dist != None:
+ self.DistroUpgrade("stable",
+ "%s %s" % (meta_release.new_dist.name,
+ meta_release.new_dist.version),
+ "The latest stable release")
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doGetUpdates(self, filters):
+ '''
+ Implement the {backend}-get-update functionality
+ '''
+ def succeeds_security_update(pkg):
+ """
+ Return True if an update succeeds a previous security update
+
+ An example would be a package with version 1.1 in the security
+ archive and 1.1.1 in the archive of proposed updates or the
+ same version in both archives.
+ """
+ inst_ver = pkg._pkg.CurrentVer
+ for ver in pkg._pkg.VersionList:
+ # Skip versions which are not later
+ if inst_ver and \
+ apt_pkg.VersionCompare(ver.VerStr, inst_ver.VerStr) <= 0:
+ continue
+ for(verFileIter, index) in ver.FileList:
+ if verFileIter.Origin in ["Debian", "Ubuntu"] and \
+ (verFileIter.Archive.endswith("-security") or \
+ verFileIter.Label == "Debian-Security"):
+ indexfile = pkg._list.FindIndex(verFileIter)
+ if indexfile and indexfile.IsTrusted:
+ return True
+ return False
+ #FIXME: Implment the basename filter
+ pklog.info("Get updates")
+ self.StatusChanged(STATUS_QUERY)
+ self.AllowCancel(True)
+ self.NoPercentageUpdates()
+ self._check_init(progress=False)
+ self._cache.upgrade(False)
+ updates = filter(lambda p: self._cache[p].isUpgradable,
+ self._cache.keys())
+ for pkg in self._cache.getChanges():
+ if self._check_canceled(): return False
+ else:
+ updates.remove(pkg.name)
+ info = INFO_NORMAL
+ archive = pkg.candidateOrigin[0].archive
+ origin = pkg.candidateOrigin[0].origin
+ trusted = pkg.candidateOrigin[0].trusted
+ label = pkg.candidateOrigin[0].label
+ if origin in ["Debian", "Ubuntu"] and trusted == True:
+ if archive.endswith("-security") or \
+ label == "Debian-Security":
+ info = INFO_SECURITY
+ elif succeeds_security_update(pkg):
+ pklog.debug("Update of %s succeeds a security "
+ "update. Raising its priority." % pkg.name)
+ info = INFO_SECURITY
+ elif archive.endswith("-backports"):
+ info = INFO_ENHANCEMENT
+ elif archive.endswith("-updates"):
+ info = INFO_BUGFIX
+ if origin in ["Backports.org archive"] and trusted == True:
+ info = INFO_ENHANCEMENT
+ self._emit_package(pkg, info, force_candidate=True)
+ # Report packages that are upgradable but cannot be upgraded
+ for missed in updates:
+ self._emit_package(self._cache[missed], INFO_BLOCKED)
+ self._cache.clear()
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doGetUpdateDetail(self, pkg_ids):
+ '''
+ Implement the {backend}-get-update-details functionality
+ '''
+ def get_bug_urls(changelog):
+ """
+ Create a list of urls pointing to closed bugs in the changelog
+ """
+ urls = []
+ #FIXME: Add support for Launchpad/Ubuntu
+ for r in re.findall(MATCH_BUG_CLOSES_DEBIAN, changelog,
+ re.IGNORECASE | re.MULTILINE):
+ urls.extend(map(lambda b: HREF_BUG_DEBIAN % b,
+ re.findall(MATCH_BUG_NUMBERS, r)))
+ return urls
+
+ def get_cve_urls(changelog):
+ """
+ Create a list of urls pointing to cves referred in the changelog
+ """
+ return map(lambda c: HREF_CVE % c,
+ re.findall(MATCH_CVE, changelog, re.MULTILINE))
+
+ pklog.info("Get update details of %s" % pkg_ids)
+ self.StatusChanged(STATUS_INFO)
+ self.NoPercentageUpdates()
+ self.AllowCancel(True)
+ self._check_init(progress=False)
+ for pkg_id in pkg_ids:
+ if self._check_canceled(): return
+ pkg = self._find_package_by_id(pkg_id)
+ if pkg == None:
+ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+ "Package %s isn't available" % id)
+ self.Finished(EXIT_FAILED)
+ return
+ # FIXME add some real data
+ updates = self.get_id_from_package(pkg, force_candidate=False)
+ obsoletes = ""
+ vendor_url = ""
+ restart = ""
+ update_text = ""
+ state = ""
+ issued = ""
+ updated = ""
+ #FIXME: Replace this method with the python-apt one as soon as the
+ # consolidate branch gets merged
+ self.StatusChanged(STATUS_DOWNLOAD_CHANGELOG)
+ changelog = self._get_changelog(pkg)
+ self.StatusChanged(STATUS_INFO)
+ bugzilla_url = ";".join(get_bug_urls(changelog))
+ cve_url = ";".join(get_cve_urls(changelog))
+ self.UpdateDetail(pkg_id, updates, obsoletes, vendor_url,
+ bugzilla_url, cve_url, restart, update_text,
+ changelog, state, issued, updated)
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doGetDetails(self, pkg_ids):
+ '''
+ Implement the {backend}-get-details functionality
+ '''
+ pklog.info("Get details of %s" % pkg_ids)
+ self.StatusChanged(STATUS_DEP_RESOLVE)
+ self.NoPercentageUpdates()
+ self.AllowCancel(True)
+ self._check_init(progress=False)
+ for pkg_id in pkg_ids:
+ if self._check_canceled(): return
+ pkg = self._find_package_by_id(pkg_id)
+ if pkg == None:
+ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+ "Package %s isn't available" % id)
+ self.Finished(EXIT_FAILED)
+ return
+ desc = self._get_package_description(pkg)
+ #FIXME: We need more fine grained license information!
+ candidate = pkg.candidateOrigin
+ if candidate != None and \
+ candidate[0].component in ["main", "universe"] and \
+ candidate[0].origin in ["Debian", "Ubuntu"]:
+ license = "free"
+ else:
+ license = "unknown"
+ group = self._get_package_group(pkg)
+ self.Details(pkg_id, license, group, desc,
+ pkg.homepage, pkg.packageSize)
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ @unlock_cache_afterwards
+ def doUpdateSystem(self):
+ '''
+ Implement the {backend}-update-system functionality
+ '''
+ pklog.info("Upgrading system")
+ if not self._lock_cache(): return
+ self.StatusChanged(STATUS_UPDATE)
+ self.AllowCancel(False)
+ self.PercentageChanged(0)
+ self._check_init(prange=(0,5))
+ try:
+ self._cache.upgrade(distUpgrade=False)
+ except:
+ self._cache.clear()
+ self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
+ "Failed to upgrade the system.")
+ self.Finished(EXIT_FAILED)
+ return
+ if not self._commit_changes(): return False
+ self.PercentageChanged(100)
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ @unlock_cache_afterwards
+ def doRemovePackages(self, ids, deps=True, auto=False):
+ '''
+ Implement the {backend}-remove functionality
+ '''
+ pklog.info("Removing package(s): id %s" % ids)
+ if not self._lock_cache(): return
+ self.StatusChanged(STATUS_REMOVE)
+ self.AllowCancel(False)
+ self.PercentageChanged(0)
+ self._check_init(prange=(0,10))
+ pkgs=[]
+ for id in ids:
+ pkg = self._find_package_by_id(id)
+ if pkg == None:
+ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+ "Package %s isn't available" % id)
+ self.Finished(EXIT_FAILED)
+ return
+ if not pkg.isInstalled:
+ self.ErrorCode(ERROR_PACKAGE_NOT_INSTALLED,
+ "Package %s isn't installed" % pkg.name)
+ self.Finished(EXIT_FAILED)
+ return
+ pkgs.append(pkg.name[:])
+ if pkg._pkg.Essential == True:
+ self.ErrorCode(ERROR_CANNOT_REMOVE_SYSTEM_PACKAGE,
+ "Package %s cannot be removed." % pkg.name)
+ self.Finished(EXIT_FAILED)
+ return
+ try:
+ pkg.markDelete()
+ except:
+ self._open_cache(prange=(90,99))
+ self.ErrorCode(ERROR_UNKNOWN, "Removal of %s failed" % pkg.name)
+ self.Finished(EXIT_FAILED)
+ return
+ if not self._commit_changes(fetch_range=(10,10),
+ install_range=(10,90)):
+ return False
+ self._open_cache(prange=(90,99))
+ for p in pkgs:
+ if self._cache.has_key(p) and self._cache[p].isInstalled:
+ self.ErrorCode(ERROR_UNKNOWN, "%s is still installed" % p)
+ self.Finished(EXIT_FAILED)
+ return
+ self.PercentageChanged(100)
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doGetRepoList(self, filters):
+ '''
+ Implement the {backend}-get-repo-list functionality
+
+ FIXME: should we use the abstration of software-properties or provide
+ low level access using pure aptsources?
+ '''
+ pklog.info("Getting repository list: %s" % filters)
+ self.StatusChanged(STATUS_INFO)
+ self.AllowCancel(False)
+ self.PercentageChanged(0)
+ if REPOS_SUPPORT == False:
+ if self._cache.has_key("python-software-properties") and \
+ self._cache["python-software-properties"].isInstalled == False:
+ self.ErrorCode(ERROR_UNKNOWN,
+ "Please install the package "
+ "python-software-properties to handle repositories")
+ else:
+ self.ErrorCode(ERROR_UNKNOWN,
+ "Please make sure that python-software-properties is"
+ "correctly installed.")
+ self.Finished(EXIT_FAILED)
+ return
+ filter_list = filters.split(";")
+ repos = PackageKitSoftwareProperties()
+ # Emit distro components as virtual repositories
+ for comp in repos.distro.source_template.components:
+ repo_id = "%s_comp_%s" % (repos.distro.id, comp.name)
+ description = "%s %s - %s (%s)" % (repos.distro.id,
+ repos.distro.release,
+ comp.get_description(),
+ comp.name)
+ #FIXME: There is no inconsitent state in PackageKit
+ enabled = repos.get_comp_download_state(comp)[0]
+ if not FILTER_DEVELOPMENT in filter_list:
+ self.RepoDetail(repo_id, description, enabled)
+ # Emit distro's virtual update repositories
+ for template in repos.distro.source_template.children:
+ repo_id = "%s_child_%s" % (repos.distro.id, template.name)
+ description = "%s %s - %s (%s)" % (repos.distro.id,
+ repos.distro.release,
+ template.description,
+ template.name)
+ #FIXME: There is no inconsitent state in PackageKit
+ enabled = repos.get_comp_child_state(template)[0]
+ if not FILTER_DEVELOPMENT in filter_list:
+ self.RepoDetail(repo_id, description, enabled)
+ # Emit distro's cdrom sources
+ for source in repos.get_cdrom_sources():
+ if FILTER_NOT_DEVELOPMENT in filter_list and \
+ source.type in ("deb-src", "rpm-src"):
+ continue
+ enabled = not source.disabled
+ # Remove markups from the description
+ description = re.sub(r"</?b>", "", repos.render_source(source))
+ repo_id = "cdrom_%s_%s" % (source.uri, source.dist)
+ repo_id.join(map(lambda c: "_%s" % c, source.comps))
+ self.RepoDetail(repo_id, description, enabled)
+ # Emit distro's virtual source code repositoriy
+ if not FILTER_NOT_DEVELOPMENT in filter_list:
+ repo_id = "%s_source" % repos.distro.id
+ enabled = repos.get_source_code_state() or False
+ #FIXME: no translation :(
+ description = "%s %s - Source code" % (repos.distro.id,
+ repos.distro.release)
+ self.RepoDetail(repo_id, description, enabled)
+ # Emit third party repositories
+ for source in repos.get_isv_sources():
+ if FILTER_NOT_DEVELOPMENT in filter_list and \
+ source.type in ("deb-src", "rpm-src"):
+ continue
+ enabled = not source.disabled
+ # Remove markups from the description
+ description = re.sub(r"</?b>", "", repos.render_source(source))
+ repo_id = "isv_%s_%s" % (source.uri, source.dist)
+ repo_id.join(map(lambda c: "_%s" % c, source.comps))
+ self.RepoDetail(repo_id, description, enabled)
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doRepoEnable(self, repo_id, enable):
+ '''
+ Implement the {backend}-repo-enable functionality
+
+ FIXME: should we use the abstration of software-properties or provide
+ low level access using pure aptsources?
+ '''
+ pklog.info("Enabling repository: %s %s" % (repo_id, enable))
+ self.StatusChanged(STATUS_RUNNING)
+ self.AllowCancel(False)
+ self.PercentageChanged(0)
+ if REPOS_SUPPORT == False:
+ if self._cache.has_key("python-software-properties") and \
+ self._cache["python-software-properties"].isInstalled == False:
+ self.ErrorCode(ERROR_UNKNOWN,
+ "Please install the package "
+ "python-software-properties to handle repositories")
+ else:
+ self.ErrorCode(ERROR_UNKNOWN,
+ "Please make sure that python-software-properties is"
+ "correctly installed.")
+ self.Finished(EXIT_FAILED)
+ return
+ repos = PackageKitSoftwareProperties()
+
+ found = False
+ # Check if the repo_id matches a distro component, e.g. main
+ if repo_id.startswith("%s_comp_" % repos.distro.id):
+ for comp in repos.distro.source_template.components:
+ if repo_id == "%s_comp_%s" % (repos.distro.id, comp.name):
+ if enable == repos.get_comp_download_state(comp)[0]:
+ pklog.debug("Repository is already enabled")
+ pass
+ if enable == True:
+ repos.enable_component(comp.name)
+ else:
+ repos.disable_component(comp.name)
+ found = True
+ break
+ # Check if the repo_id matches a distro child repository, e.g. hardy-updates
+ elif repo_id.startswith("%s_child_" % repos.distro.id):
+ for template in repos.distro.source_template.children:
+ if repo_id == "%s_child_%s" % (repos.distro.id, template.name):
+ if enable == repos.get_comp_child_state(template)[0]:
+ pklog.debug("Repository is already enabled")
+ pass
+ elif enable == True:
+ repos.enable_child_source(template)
+ else:
+ repos.disable_child_source(template)
+ found = True
+ break
+ # Check if the repo_id matches a cdrom repository
+ elif repo_id.startswith("cdrom_"):
+ for source in repos.get_isv_sources():
+ source_id = "cdrom_%s_%s" % (source.uri, source.dist)
+ source_id.join(map(lambda c: "_%s" % c, source.comps))
+ if repo_id == source_id:
+ if source.disabled == enable:
+ source.disabled = not enable
+ repos.save_sourceslist()
+ else:
+ pklog.debug("Repository is already enabled")
+ found = True
+ break
+ # Check if the repo_id matches an isv repository
+ elif repo_id.startswith("isv_"):
+ for source in repos.get_isv_sources():
+ source_id = "isv_%s_%s" % (source.uri, source.dist)
+ source_id.join(map(lambda c: "_%s" % c, source.comps))
+ if repo_id == source_id:
+ if source.disabled == enable:
+ source.disabled = not enable
+ repos.save_sourceslist()
+ else:
+ pklog.debug("Repository is already enabled")
+ found = True
+ break
+ if found == False:
+ self.ErrorCode(ERROR_REPO_NOT_AVAILABLE,
+ "The repository of the id %s isn't available" % repo_id)
+ self.Finished(EXIT_FAILED)
+ return
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ @unlock_cache_afterwards
+ def doUpdatePackages(self, ids):
+ '''
+ Implement the {backend}-update functionality
+ '''
+ pklog.info("Updating package with id %s" % ids)
+ if not self._lock_cache(): return
+ self.StatusChanged(STATUS_UPDATE)
+ self.AllowCancel(False)
+ self.PercentageChanged(0)
+ self._check_init(prange=(0,10))
+ pkgs=[]
+ for id in ids:
+ pkg = self._find_package_by_id(id)
+ if pkg == None:
+ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+ "Package %s isn't available" % id)
+ self.Finished(EXIT_FAILED)
+ return
+ if not pkg.isUpgradable:
+ self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,
+ "Package %s is already up-to-date" % pkg.name)
+ self.Finished(EXIT_FAILED)
+ return
+ pkgs.append(pkg.name[:])
+ try:
+ pkg.markUpgrade()
+ except:
+ self._open_cache(prange=(90,100))
+ self.ErrorCode(ERROR_UNKNOWN, "%s could not be queued for "
+ "update" % pkg.name)
+ self.Finished(EXIT_FAILED)
+ return
+ if not self._commit_changes(): return False
+ self._open_cache(prange=(90,100))
+ self.PercentageChanged(100)
+ pklog.debug("Checking success of operation")
+ for p in pkgs:
+ if not self._cache.has_key(p) or not self._cache[p].isInstalled \
+ or self._cache[p].isUpgradable:
+ self.ErrorCode(ERROR_UNKNOWN, "%s was not updated" % p)
+ self.Finished(EXIT_FAILED)
+ return
+ pklog.debug("Sending success signal")
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doDownloadPackages(self, ids, dest):
+ '''
+ Implement the {backend}-download-packages functionality
+ '''
+ pklog.info("Downloading packages: %s" % ids)
+ self.StatusChanged(STATUS_DOWNLOAD)
+ self.AllowCancel(True)
+ self.PercentageChanged(0)
+ # Check the destination directory
+ if not os.path.isdir(dest) or not os.access(dest, os.W_OK):
+ self.ErrorCode(ERROR_UNKNOWN,
+ "The directory '%s' is not writable" % dest)
+ self.Finished(EXIT_FAILED)
+ return
+ # Setup the fetcher
+ self._check_init(prange=(0,10))
+ progress = PackageKitFetchProgress(self, prange=(10,90))
+ fetcher = apt_pkg.GetAcquire(progress)
+ pm = apt_pkg.GetPackageManager(self._cache._depcache)
+ recs = apt_pkg.GetPkgRecords(self._cache._cache)
+ list = apt_pkg.GetPkgSourceList()
+ list.ReadMainList()
+ # Mark installed packages for reinstallation and not installed packages
+ # for installation without dependencies
+ for id in ids:
+ if self._check_canceled(): return
+ pkg = self._find_package_by_id(id)
+ if pkg == None:
+ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+ "There is no package %s" % id)
+ self.Finished(EXIT_FAILED)
+ return
+ if pkg.isInstalled:
+ self._cache._depcache.SetReInstall(pkg._pkg, True)
+ else:
+ self._cache._depcache.MarkInstall(pkg._pkg, False)
+ # Download
+ pm.GetArchives(fetcher, list, recs)
+ res = fetcher.Run()
+ self._cache.clear()
+ self.PercentageChanged(95)
+ # Copy files from cache to final destination
+ for item in fetcher.Items:
+ if self._check_canceled(): return
+ pklog.debug("Download item: %s" % item)
+ if (item.Status != item.StatDone and not item.StatIdle) or \
+ res == fetcher.ResultCancelled:
+ self.ErrorCode(ERROR_PACKAGE_DOWNLOAD_FAILED,
+ "Failed to download %s" % item.DescURI)
+ self.Finished(EXIT_FAILED)
+ return
+ pklog.debug("Copying %s to %s ..." % (item.DestFile, dest))
+ try:
+ shutil.copy(item.DestFile, dest)
+ except Exception, e:
+ self.ErrorCode(ERROR_INTERNAL_ERROR,
+ "Failed to copy %s to %s: %s" % (item.DestFile,
+ dest, e))
+ self.Finished(EXIT_FAILED)
+ return
+ self.PercentageChanged(100)
+ pklog.debug("Sending success signal")
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ @unlock_cache_afterwards
+ def doInstallPackages(self, ids):
+ '''
+ Implement the {backend}-install functionality
+ '''
+ pklog.info("Installing package with id %s" % ids)
+ if not self._lock_cache(): return
+ self.StatusChanged(STATUS_INSTALL)
+ self.AllowCancel(False)
+ self.PercentageChanged(0)
+ self._check_init(prange=(0,10))
+ pkgs=[]
+ for id in ids:
+ pkg = self._find_package_by_id(id)
+ if pkg == None:
+ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+ "Package %s isn't available" % id)
+ self.Finished(EXIT_FAILED)
+ return
+ if pkg.isInstalled:
+ self.ErrorCode(ERROR_PACKAGE_ALREADY_INSTALLED,
+ "Package %s is already installed" % pkg.name)
+ self.Finished(EXIT_FAILED)
+ return
+ pkgs.append(pkg.name[:])
+ try:
+ pkg.markInstall()
+ except Exception, e:
+ self._open_cache(prange=(90,100))
+ self.ErrorCode(ERROR_UNKNOWN, "%s could not be queued for "
+ "installation: %s" % (pkg.name,e))
+ self.Finished(EXIT_FAILED)
+ return
+ if not self._commit_changes(): return False
+ self._open_cache(prange=(90,100))
+ self.PercentageChanged(100)
+ pklog.debug("Checking success of operation")
+ for p in pkgs:
+ if not self._cache.has_key(p) or not self._cache[p].isInstalled:
+ self.ErrorCode(ERROR_UNKNOWN, "%s was not installed" % p)
+ self.Finished(EXIT_FAILED)
+ return
+ pklog.debug("Sending success signal")
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ @unlock_cache_afterwards
+ def doInstallFiles(self, trusted, full_paths):
+ '''
+ Implement install-files for the apt backend
+ Install local Debian package files
+ '''
+ pklog.info("Installing package files: %s" % full_paths)
+ if not self._lock_cache(): return
+ self.StatusChanged(STATUS_INSTALL)
+ self.AllowCancel(False)
+ self.PercentageChanged(0)
+ self._check_init(prange=(0,10))
+ packages = []
+ # Collect all dependencies which need to be installed
+ self.StatusChanged(STATUS_DEP_RESOLVE)
+ for path in full_paths:
+ deb = apt.debfile.DebPackage(path, self._cache)
+ packages.append(deb)
+ if not deb.check():
+ self.ErrorCode(ERROR_UNKNOWN, deb._failureString)
+ self.Finished(EXIT_FAILED)
+ return
+ (install, remove, unauthenticated) = deb.requiredChanges
+ pklog.debug("Changes: Install %s, Remove %s, Unauthenticated "
+ "%s" % (install, remove, unauthenticated))
+ if len(remove) > 0:
+ self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
+ "Remove the following packages "
+ "before: %s" % remove)
+ self.Finished(EXIT_FAILED)
+ return
+ if deb.compare_to_version_in_cache() == \
+ apt.debfile.VERSION_OUTDATED:
+ self.Message(MESSAGE_NEWER_PACKAGE_EXISTS,
+ "There is a later version of %s "
+ "available in the repositories." % deb.pkgname)
+ if len(self._cache.getChanges()) > 0 and not \
+ self._commit_changes((10,25), (25,50)):
+ return False
+ # Install the Debian package files
+ d = PackageKitDpkgInstallProgress(self)
+ try:
+ d.startUpdate()
+ d.install(full_paths)
+ d.finishUpdate()
+ except InstallTimeOutPKError, e:
+ self._recover()
+ #FIXME: should provide more information
+ self.ErrorCode(ERROR_UNKNOWN,
+ "Transaction was cancelled since the installation "
+ "of a package hung.\n"
+ "This can be caused by maintainer scripts which "
+ "require input on the terminal:\n%s" % e.message)
+ self.Finished(EXIT_KILLED)
+ return
+ except PackageManagerFailedPKError, e:
+ self._recover()
+ self.ErrorCode(ERROR_UNKNOWN, "%s\n%s" % (e.message, e.output))
+ self.Finished(EXIT_FAILED)
+ return
+ except Exception, e:
+ self._recover()
+ self.ErrorCode(ERROR_INTERNAL_ERROR, e.message)
+ self.Finished(EXIT_FAILED)
+ return
+ self.PercentageChanged(100)
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ @unlock_cache_afterwards
+ def doRefreshCache(self, force):
+ '''
+ Implement the {backend}-refresh_cache functionality
+ '''
+ pklog.info("Refresh cache")
+ if not self._lock_cache(): return
+ self.StatusChanged(STATUS_REFRESH_CACHE)
+ self.last_action_time = time.time()
+ self.AllowCancel(False);
+ self.PercentageChanged(0)
+ self._check_init((0,10))
+ try:
+ self._cache.update(PackageKitFetchProgress(self, prange=(10,95)))
+ except Exception, e:
+ self._open_cache(prange=(95,100))
+ if self._check_canceled(): return False
+ self.ErrorCode(ERROR_UNKNOWN, "Refreshing cache failed: %s" % e)
+ self.Finished(EXIT_FAILED)
+ return
+ self._open_cache(prange=(95,100))
+ self.PercentageChanged(100)
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doGetPackages(self, filters):
+ '''
+ Implement the apt2-get-packages functionality
+ '''
+ pklog.info("Get all packages")
+ self.StatusChanged(STATUS_QUERY)
+ self.NoPercentageUpdates()
+ self._check_init(progress=False)
+ self.AllowCancel(True)
+
+ for pkg in self._cache:
+ if self._check_canceled(): return False
+ elif self._is_package_visible(pkg, filters):
+ self._emit_package(pkg)
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doResolve(self, filters, names):
+ '''
+ Implement the apt2-resolve functionality
+ '''
+ pklog.info("Resolve")
+ self.StatusChanged(STATUS_QUERY)
+ self.NoPercentageUpdates()
+ self._check_init(progress=False)
+ self.AllowCancel(False)
+
+ for name in names:
+ if self._cache.has_key(name):
+ self._emit_visible_package(filters, self._cache[name])
+ else:
+ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+ "Package name %s could not be resolved" % name)
+ self.Finished(EXIT_FAILED)
+ return
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doGetDepends(self, filter, ids, recursive=False):
+ '''
+ Implement the apt2-get-depends functionality
+
+ Emit all packages that need to be installed or updated to install
+ the given package ids. It behaves like a preview of the changes
+ required for the installation. An error will be emitted if the
+ dependecies cannot be satisfied.
+ In contrast to the yum backend the whole dependency resoltions is done
+ by the package manager. Therefor the list of satisfied packages cannot
+ be computed easily. GDebi features this. Perhaps this should be moved
+ to python-apt.
+ '''
+ pklog.info("Get depends (%s,%s,%s)" % (filter, ids, recursive))
+ #FIXME: recursive is not yet implemented
+ if recursive == True:
+ pklog.warn("Recursive dependencies are not implemented")
+ self.StatusChanged(STATUS_QUERY)
+ self.NoPercentageUpdates()
+ self._check_init(progress=False)
+ self.AllowCancel(True)
+
+ # Mark all packages for installation
+ pkgs = []
+ for id in ids:
+ if self._check_canceled(): return
+ pkg = self._find_package_by_id(id)
+ if pkg == None:
+ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+ "Package %s isn't available" % id)
+ self.Finished(EXIT_FAILED)
+ return
+ try:
+ pkg.markInstall()
+ except Exception, e:
+ #FIXME: Introduce a new info enumerate PK_INFO_MISSING for
+ # missing dependecies
+ self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
+ "Dependecies for %s cannot be satisfied: %s" % e)
+ self.Finished(EXIT_FAILED)
+ return
+ pkgs.append(pkg)
+ # Check the status of the resulting changes
+ for p in self._cache.getChanges():
+ if self._check_canceled(): return
+ if p in pkgs: continue
+ if p.markedDelete:
+ # Packagekit policy forbids removing packages for installation
+ self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
+ "Remove the package %s before" % p.name)
+ self.Finished(EXIT_FAILED)
+ return
+ elif p.markedInstall or p.markedUpgrade:
+ if self._is_package_visible(p, filter):
+ self._emit_package(p)
+ else:
+ self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
+ "Please use an advanced package management tool "
+ "e.g. Synaptic or aptitude, since there is a "
+ "complex dependency situation.")
+ self.Finished(EXIT_FAILED)
+ return
+ # Clean up
+ self._cache.clear()
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doGetRequires(self, filter, ids, recursive=False):
+ '''
+ Implement the apt2-get-requires functionality
+ '''
+ pklog.info("Get requires (%s,%s,%s)" % (filter, ids, recursive))
+ #FIXME: recursive is not yet implemented
+ if recursive == True:
+ pklog.warn("Recursive dependencies are not implemented")
+ self.StatusChanged(STATUS_DEP_RESOLVE)
+ self.NoPercentageUpdates()
+ self._check_init(progress=False)
+ self.AllowCancel(True)
+ pkgs = []
+
+ # Mark all packages for installation
+ for id in ids:
+ if self._check_canceled(): return
+ pkg = self._find_package_by_id(id)
+ if pkg == None:
+ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+ "Package %s isn't available" % id)
+ self.Finished(EXIT_FAILED)
+ return
+ if pkg._pkg.Essential == True:
+ self.ErrorCode(ERROR_CANNOT_REMOVE_SYSTEM_PACKAGE,
+ "Package %s cannot be removed." % pkg.name)
+ self.Finished(EXIT_FAILED)
+ return
+ pkgs.append(pkg)
+ try:
+ pkg.markDelete()
+ except Exception, e:
+ #FIXME: Introduce a new info enumerate PK_INFO_MISSING for
+ # missing dependecies
+ self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
+ "Error removing %s: %s" % (pkg.name, e))
+ self.Finished(EXIT_FAILED)
+ return
+ # Check the status of the resulting changes
+ for p in self._cache.getChanges():
+ if self._check_canceled(): return
+ if p.markedDelete:
+ if not p in pkgs and self._is_package_visible(p, filter):
+ self._emit_package(p)
+ else:
+ self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
+ "Please use an advanced package management tool "
+ "e.g. Synaptic or aptitude, since there is a "
+ "complex dependency situation.")
+ self.Finished(EXIT_FAILED)
+ return
+ # Clean up
+ self._cache.clear()
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doWhatProvides(self, filters, provides_type, search):
+ def get_mapping_db(path):
+ """
+ Return the gdbm database at the given path or send an
+ appropriate error message
+ """
+ if not os.access(path, os.R_OK):
+ if self._cache.has_key("app-install-data") and \
+ self._cache["app-install-data"].isInstalled == False:
+ self.ErrorCode(ERROR_UNKNOWN,
+ "Please install the package "
+ "app-install data for a list of "
+ "applications that can handle files of "
+ "the given type")
+ else:
+ self.ErrorCode(ERROR_UNKNOWN,
+ "The list of applications that can handle "
+ "files of the given type cannot be opened.\n"
+ "Try to reinstall the package "
+ "app-install-data.")
+ return None
+ try:
+ db = gdbm.open(path)
+ except:
+ self.ErrorCode(ERROR_UNKNOWN,
+ "The list of applications that can handle "
+ "files of the given type cannot be opened.\n"
+ "Try to reinstall the package "
+ "app-install-data.")
+ return None
+ else:
+ return db
+
+ self.StatusChanged(STATUS_QUERY)
+ self.NoPercentageUpdates()
+ self._check_init(progress=False)
+ self.AllowCancel(False)
+ if provides_type == PROVIDES_CODEC:
+ # The search term from the codec helper looks like this one:
+ match = re.match(r"gstreamer([0-9\.]+)\((.+?)\)", search)
+ if not match:
+ self.ErrorCode(ERROR_UNKNOWN,
+ "The search term is invalid")
+ self.Finished(EXIT_FAILED)
+ return
+ codec = "%s:%s" % (match.group(1), match.group(2))
+ db = get_mapping_db("/var/cache/app-install/gai-codec-map.gdbm")
+ if db == None:
+ self.ErrorCode(ERROR_INTERNAL_ERROR,
+ "Failed to open codec mapping database")
+ self.Finished(EXIT_FAILED)
+ return
+ if db.has_key(codec):
+ # The codec mapping db stores the packages as a string
+ # separated by spaces. Each package has its section
+ # prefixed and separated by a slash
+ # FIXME: Should make use of the section and emit a
+ # RepositoryRequired signal if the package does
+ # not exist
+ pkgs = map(lambda s: s.split("/")[1],
+ db[codec].split(" "))
+ self._emit_visible_packages_by_name(filters, pkgs)
+ elif provides_type == PROVIDES_MIMETYPE:
+ # Emit packages that contain an application that can handle
+ # the given mime type
+ handlers = set()
+ db = get_mapping_db("/var/cache/app-install/gai-mime-map.gdbm")
+ if db == None:
+ self.Finished(EXIT_FAILED)
+ return
+ if db.has_key(search):
+ pklog.debug("Mime type is registered: %s" % db[search])
+ # The mime type handler db stores the packages as a string
+ # separated by spaces. Each package has its section
+ # prefixed and separated by a slash
+ # FIXME: Should make use of the section and emit a
+ # RepositoryRequired signal if the package does not exist
+ handlers = map(lambda s: s.split("/")[1],
+ db[search].split(" "))
+ self._emit_visible_packages_by_name(filters, handlers)
+ else:
+ self.ErrorCode(ERROR_NOT_SUPPORTED,
+ "This function is not implemented in this backend")
+ self.Finished(EXIT_FAILED)
+ return
+ self.Finished(EXIT_SUCCESS)
+
+ @serialize
+ @threaded
+ def doGetFiles(self, package_ids):
+ """
+ Emit the Files signal which includes the files included in a package
+ Apt only supports this for installed packages
+ """
+ self.StatusChanged(STATUS_INFO)
+ for id in package_ids:
+ pkg = self._find_package_by_id(id)
+ if pkg == None:
+ self.ErrorCode(ERROR_PACKAGE_NOT_FOUND,
+ "Package %s doesn't exist" % pkg.name)
+ self.Finished(EXIT_FAILED)
+ return
+ files = string.join(self._get_installed_files(pkg), ";")
+ self.Files(id, files)
+ self.Finished(EXIT_SUCCESS)
+
+ def doSetProxy(self, http_proxy, ftp_proxy):
+ '''
+ Set a proxy server for http and ftp transfer
+ '''
+ if http_proxy:
+ pklog.debug("Set http proxy to %s" % http_proxy)
+ apt_pkg.Config.set("http::Proxy", http_proxy)
+ if ftp_proxy:
+ pklog.debug("Set ftp proxy to %s" % ftp_proxy)
+ apt_pkg.Config.set("ftp::Proxy", ftp_proxy)
+
+ def doSetLocale(self, code):
+ '''
+ Set the locale of the daemon
+
+ '''
+ #FIXME: Needs testing
+ if code != "":
+ pklog.debug("Setting language to %s" % code)
+ locale.setlocale("LANG", code)
+
+ # Helpers
+
+ def _lock_cache(self):
+ """
+ Emit an error message and return true if the apt system lock cannot
+ be acquired.
+ """
+ try:
+ apt_pkg.PkgSystemLock()
+ except SystemError:
+ self.ErrorCode(ERROR_CANNOT_GET_LOCK,
+ "Only use one package management programme at the "
+ "the same time.")
+ self.Finished(EXIT_FAILED)
+ return False
+ return True
+
+ def _unlock_cache(self):
+ """
+ Unlock the system package cache
+ """
+ try:
+ apt_pkg.PkgSystemUnLock()
+ except SystemError:
+ return False
+ return True
+
+ def _open_cache(self, prange=(0,100), progress=True):
+ '''
+ (Re)Open the APT cache
+ '''
+ pklog.debug("Open APT cache")
+ self.StatusChanged(STATUS_LOADING_CACHE)
+ try:
+ self._cache = PackageKitCache(PackageKitOpProgress(self, prange,
+ progress))
+ except:
+ self.ErrorCode(ERROR_NO_CACHE, "Package cache could not be opened")
+ self.Finished(EXIT_FAILED)
+ self.Exit()
+ return
+ if self._cache._depcache.BrokenCount > 0:
+ self.ErrorCode(ERROR_DEP_RESOLUTION_FAILED,
+ "There are broken dependecies on your system. "
+ "Please use an advanced package manage e.g. "
+ "Synaptic or aptitude to resolve this situation.")
+ self.Finished(EXIT_FAILED)
+ self.Exit()
+ return
+ self._last_cache_refresh = time.time()
+
+ def _recover(self, prange=(95,100)):
+ """
+ Try to recover from a package manager failure
+ """
+ self.StatusChanged(STATUS_CLEANUP)
+ self.NoPercentageUpdates()
+ try:
+ d = PackageKitDpkgInstallProgress(self)
+ d.startUpdate()
+ d.recover()
+ d.finishUpdate()
+ except:
+ pass
+ self._open_cache(prange)
+
+ def _commit_changes(self, fetch_range=(5,50), install_range=(50,90)):
+ """
+ Commit changes to the cache and handle errors
+ """
+ try:
+ self._cache.commit(PackageKitFetchProgress(self, fetch_range),
+ PackageKitInstallProgress(self, install_range))
+ except apt.cache.FetchFailedException, e:
+ self._open_cache(prange=(95,100))
+ self.ErrorCode(ERROR_PACKAGE_DOWNLOAD_FAILED, e.message)
+ self.Finished(EXIT_FAILED)
+ except apt.cache.FetchCancelledException:
+ self._open_cache(prange=(95,100))
+ self.Finished(EXIT_CANCELLED)
+ self._canceled.clear()
+ except InstallTimeOutPKError, e:
+ self._recover()
+ self._open_cache(prange=(95,100))
+ #FIXME: should provide more information
+ self.ErrorCode(ERROR_UNKNOWN,
+ "Transaction was cancelled since the installation "
+ "of a package hung.\n"
+ "This can be caused by maintainer scripts which "
+ "require input on the terminal:\n%s" % e.message)
+ self.Finished(EXIT_KILLED)
+ except PackageManagerFailedPKError, e:
+ self._recover()
+ self.ErrorCode(ERROR_UNKNOWN, "%s\n%s" % (e.message, e.output))
+ self.Finished(EXIT_FAILED)
+ else:
+ return True
+ return False
+
+ def _check_init(self, prange=(0,10), progress=True):
+ '''
+ Check if the backend was initialized well and try to recover from
+ a broken setup
+ '''
+ pklog.debug("Checking apt cache and xapian database")
+ pkg_cache = os.path.join(apt_pkg.Config["Dir"],
+ apt_pkg.Config["Dir::Cache"],
+ apt_pkg.Config["Dir::Cache::pkgcache"])
+ src_cache = os.path.join(apt_pkg.Config["Dir"],
+ apt_pkg.Config["Dir::Cache"],
+ apt_pkg.Config["Dir::Cache::srcpkgcache"])
+ # Check if the cache instance is of the coorect class type, contains
+ # any broken packages and if the dpkg status or apt cache files have
+ # been changed since the last refresh
+ if not isinstance(self._cache, apt.cache.Cache) or \
+ (self._cache._depcache.BrokenCount > 0) or \
+ (os.stat(apt_pkg.Config["Dir::State::status"])[stat.ST_MTIME] > \
+ self._last_cache_refresh) or \
+ (os.stat(pkg_cache)[stat.ST_MTIME] > self._last_cache_refresh) or \
+ (os.stat(src_cache)[stat.ST_MTIME] > self._last_cache_refresh):
+ pklog.debug("Reloading the cache is required")
+ self._open_cache(prange, progress)
+ else:
+ self._cache.clear()
+
+ def _check_canceled(self):
+ '''
+ Check if the current transaction was canceled. If so send the
+ corresponding error message and return True
+ '''
+ if self._canceled.isSet():
+ self.Finished(EXIT_CANCELLED)
+ self._canceled.clear()
+ return True
+ return False
+
+ def get_id_from_package(self, pkg, force_candidate=False):
+ '''
+ Return the packagekit id of package. By default this will be the
+ installed version for installed packages and the candidate version
+ for not installed packages.
+
+ The force_candidate option will also report the id of the candidate
+ version for installed packages.
+ '''
+ origin = ""
+ cand_origin = pkg.candidateOrigin
+ if not pkg.isInstalled or force_candidate:
+ version = pkg.candidateVersion
+ if cand_origin:
+ origin = cand_origin[0].label
+ else:
+ version = pkg.installedVersion
+ if cand_origin and cand_origin[0].site != "" and \
+ pkg.installedVersion == pkg.candidateVersion:
+ origin = cand_origin[0].label
+ id = self._get_package_id(pkg.name, version, pkg.architecture, origin)
+ return id
+
+ def _emit_package(self, pkg, info=None, force_candidate=False):
+ '''
+ Send the Package signal for a given apt package
+ '''
+ id = self.get_id_from_package(pkg, force_candidate)
+ section = pkg.section.split("/")[-1]
+ if info == None:
+ if pkg.isInstalled:
+ if section == "metapackages":
+ info = INFO_COLLECTION_INSTALLED
+ else:
+ info = INFO_INSTALLED
+ else:
+ if section == "metapackages":
+ info = INFO_COLLECTION_AVAILABLE
+ else:
+ info = INFO_AVAILABLE
+ summary = pkg.summary
+ self.Package(info, id, summary)
+
+ def _emit_visible_package(self, filters, pkg, info=None):
+ """
+ Filter and emit a package
+ """
+ if self._is_package_visible(pkg, filters):
+ self._emit_package(pkg, info)
+
+ def _emit_visible_packages(self, filters, pkgs, info=None):
+ """
+ Filter and emit packages
+ """
+ for p in pkgs:
+ if self._is_package_visible(p, filters):
+ self._emit_package(p, info)
+
+ def _emit_visible_packages_by_name(self, filters, pkgs, info=None):
+ """
+ Find the packages with the given namens. Afterwards filter and emit
+ them
+ """
+ for name in pkgs:
+ if self._cache.has_key(name) and \
+ self._is_package_visible(self._cache[name], filters):
+ self._emit_package(self._cache[name], info)
+
+
+ def _is_package_visible(self, pkg, filters):
+ '''
+ Return True if the package should be shown in the user interface
+ '''
+ if filters == FILTER_NONE:
+ return True
+ for filter in filters.split(";"):
+ if (filter == FILTER_INSTALLED and not pkg.isInstalled) or \
+ (filter == FILTER_NOT_INSTALLED and pkg.isInstalled) or \
+ (filter == FILTER_SUPPORTED and not \
+ self._is_package_supported(pkg)) or \
+ (filter == FILTER_NOT_SUPPORTED and \
+ self._is_package_supported(pkg)) or \
+ (filter == FILTER_FREE and not self._is_package_free(pkg)) or \
+ (filter == FILTER_NOT_FREE and \
+ not self._is_package_not_free(pkg)) or \
+ (filter == FILTER_GUI and not self._has_package_gui(pkg)) or \
+ (filter == FILTER_NOT_GUI and self._has_package_gui(pkg)) or \
+ (filter == FILTER_COLLECTIONS and not \
+ self._is_package_collection(pkg)) or \
+ (filter == FILTER_NOT_COLLECTIONS and \
+ self._is_package_collection(pkg)) or\
+ (filter == FILTER_DEVELOPMENT and not \
+ self._is_package_devel(pkg)) or \
+ (filter == FILTER_NOT_DEVELOPMENT and \
+ self._is_package_devel(pkg)):
+ return False
+ return True
+
+ def _is_package_not_free(self, pkg):
+ """
+ Return True if we can be sure that the package's license isn't any
+ free one
+ """
+ candidate = pkg.candidateOrigin
+ return candidate != None and \
+ ((candidate[0].origin == "Ubuntu" and \
+ candidate[0].component in ["multiverse", "restricted"]) or \
+ (candidate[0].origin == "Debian" and \
+ candidate[0].component in ["contrib", "non-free"])) and \
+ candidate[0].trusted == True
+
+ def _is_package_collection(self, pkg):
+ """
+ Return True if the package is a metapackge
+ """
+ section = pkg.section.split("/")[-1]
+ return section == "metapackages"
+
+ def _is_package_free(self, pkg):
+ """
+ Return True if we can be sure that the package has got a free license
+ """
+ candidate = pkg.candidateOrigin
+ return candidate != None and \
+ ((candidate[0].origin == "Ubuntu" and \
+ candidate[0].component in ["main", "universe"]) or \
+ (candidate[0].origin == "Debian" and \
+ candidate[0].component == "main")) and\
+ candidate[0].trusted == True
+
+ def _has_package_gui(self, pkg):
+ #FIXME: should go to a modified Package class
+ #FIXME: take application data into account. perhaps checking for
+ # property in the xapian database
+ return pkg.section.split('/')[-1].lower() in ['x11', 'gnome', 'kde']
+
+ def _is_package_devel(self, pkg):
+ #FIXME: should go to a modified Package class
+ return pkg.name.endswith("-dev") or pkg.name.endswith("-dbg") or \
+ pkg.section.split('/')[-1].lower() in ['devel', 'libdevel']
+
+ def _is_package_supported(self, pkg):
+ candidate = pkg.candidateOrigin[0]
+ return candidate != None and \
+ candidate[0].origin == "Ubuntu" and \
+ candidate[0].component in ["main", "restricted"] and \
+ candidate[0].trusted == True
+
+ def _find_package_by_id(self, id):
+ '''
+ Return a package matching to the given package id
+ '''
+ # FIXME: Perform more checks
+ name, version, arch, data = self.get_package_from_id(id)
+ if self._cache.has_key(name):
+ return self._cache[name]
+ else:
+ return None
+
+ def _get_installed_files(self, pkg):
+ """
+ Return the list of unicode names of the files which have
+ been installed by the package
+
+ This method should be obsolete by the apt.package.Package.installedFiles
+ attribute as soon as the consolidate branch of python-apt gets merged
+ """
+ path = os.path.join(apt_pkg.Config["Dir"],
+ "var/lib/dpkg/info/%s.list" % pkg.name)
+ try:
+ list = open(path)
+ files = list.read().decode().split("\n")
+ list.close()
+ except:
+ return []
+ return files
+
+ def _get_changelog(self, pkg, uri=None, cancel_lock=None):
+ """
+ Download the changelog of the package and return it as unicode
+ string
+
+ This method is already part of the consolidate branch of python-apt
+
+ uri: Is the uri to the changelog file. The following named variables
+ will be substituted: src_section, prefix, src_pkg and src_ver
+ For example the Ubuntu changelog:
+ uri = "http://changelogs.ubuntu.com/changelogs/pool" \\
+ "/%(src_section)s/%(prefix)s/%(src_pkg)s" \\
+ "/%(src_pkg)s_%(src_ver)s/changelog"
+ cancel_lock: If this threading.Lock() is set, the download will be
+ canceled
+ """
+ if uri == None:
+ if pkg.candidateOrigin[0].origin == "Debian":
+ uri = "http://packages.debian.org/changelogs/pool" \
+ "/%(src_section)s/%(prefix)s/%(src_pkg)s" \
+ "/%(src_pkg)s_%(src_ver)s/changelog"
+ elif pkg.candidateOrigin[0].origin == "Ubuntu":
+ uri = "http://changelogs.ubuntu.com/changelogs/pool" \
+ "/%(src_section)s/%(prefix)s/%(src_pkg)s" \
+ "/%(src_pkg)s_%(src_ver)s/changelog"
+ else:
+ return "The list of changes is not available"
+
+ # get the src package name
+ src_pkg = pkg.sourcePackageName
+
+ # assume "main" section
+ src_section = "main"
+ # use the section of the candidate as a starting point
+ section = pkg._depcache.GetCandidateVer(pkg._pkg).Section
+
+ # get the source version, start with the binaries version
+ bin_ver = pkg.candidateVersion
+ src_ver = pkg.candidateVersion
+ #print "bin: %s" % binver
+ try:
+ # try to get the source version of the pkg, this differs
+ # for some (e.g. libnspr4 on ubuntu)
+ # this feature only works if the correct deb-src are in the
+ # sources.list
+ # otherwise we fall back to the binary version number
+ src_records = apt_pkg.GetPkgSrcRecords()
+ src_rec = src_records.Lookup(src_pkg)
+ if src_rec:
+ src_ver = src_records.Version
+ #if apt_pkg.VersionCompare(binver, srcver) > 0:
+ # srcver = binver
+ if not src_ver:
+ src_ver = bin_ver
+ #print "srcver: %s" % src_ver
+ section = src_records.Section
+ #print "srcsect: %s" % section
+ else:
+ # fail into the error handler
+ raise SystemError
+ except SystemError, e:
+ src_ver = bin_ver
+
+ l = section.split("/")
+ if len(l) > 1:
+ src_section = l[0]
+
+ # lib is handled special
+ prefix = src_pkg[0]
+ if src_pkg.startswith("lib"):
+ prefix = "lib" + src_pkg[3]
+
+ # stip epoch
+ l = src_ver.split(":")
+ if len(l) > 1:
+ src_ver = "".join(l[1:])
+
+ uri = uri % {"src_section" : src_section,
+ "prefix" : prefix,
+ "src_pkg" : src_pkg,
+ "src_ver" : src_ver}
+ try:
+ # Check if the download was canceled
+ if cancel_lock and cancel_lock.isSet(): return ""
+ changelog_file = urllib2.urlopen(uri)
+ # do only get the lines that are new
+ changelog = ""
+ regexp = "^%s \((.*)\)(.*)$" % (re.escape(src_pkg))
+
+ i=0
+ while True:
+ # Check if the download was canceled
+ if cancel_lock and cancel_lock.isSet(): return ""
+ # Read changelog line by line
+ line_raw = changelog_file.readline()
+ if line_raw == "":
+ break
+ # The changelog is encoded in utf-8, but since there isn't any
+ # http header, urllib2 seems to treat it as ascii
+ line = line_raw.decode("utf-8")
+
+ #print line.encode('utf-8')
+ match = re.match(regexp, line)
+ if match:
+ # strip epoch from installed version
+ # and from changelog too
+ installed = pkg.installedVersion
+ if installed and ":" in installed:
+ installed = installed.split(":",1)[1]
+ changelog_ver = match.group(1)
+ if changelog_ver and ":" in changelog_ver:
+ changelog_ver = changelog_ver.split(":", 1)[1]
+ if installed and \
+ apt_pkg.VersionCompare(changelog_ver, installed) <= 0:
+ break
+ # EOF (shouldn't really happen)
+ changelog += line
+
+ # Print an error if we failed to extract a changelog
+ if len(changelog) == 0:
+ changelog = "The list of changes is not available"
+ except urllib2.HTTPError,e:
+ return "The list of changes is not available yet.\n\n" \
+ "Please use http://launchpad.net/ubuntu/+source/%s/%s/" \
+ "+changelog\n" \
+ "until the changes become available or try again " \
+ "later." % (src_pkg, src_ver)
+ except IOError, httplib.BadStatusLine:
+ return "Failed to download the list of changes.\nPlease " \
+ "check your Internet connection."
+ return changelog
+
+ def _get_package_group(self, pkg):
+ """
+ Return the packagekit group corresponding to the package's section
+ """
+ section = pkg.section.split("/")[-1]
+ if SECTION_GROUP_MAP.has_key(section):
+ return SECTION_GROUP_MAP[section]
+ else:
+ pklog.debug("Unkown package section %s of %s" % (pkg.section,
+ pkg.name))
+ return GROUP_UNKNOWN
+
+ def _get_package_description(self, pkg):
+ """
+ Return the formated long description according to the Debian policy
+ (Chapter 5.6.13).
+ See http://www.debian.org/doc/debian-policy/ch-controlfields.html
+ for more information.
+ """
+ if not pkg._lookupRecord():
+ return ""
+ # get the translated description
+ ver = pkg._depcache.GetCandidateVer(pkg._pkg)
+ desc_iter = ver.TranslatedDescription
+ pkg._records.Lookup(desc_iter.FileList.pop(0))
+ desc = ""
+ try:
+ s = unicode(pkg._records.LongDesc,"utf-8")
+ except UnicodeDecodeError,e:
+ s = "Invalid unicode in description for '%s' (%s)" % (pkg.name, e)
+ lines = string.split(s, "\n")
+ for i in range(len(lines)):
+ # Skip the first line, since its a duplication of the summary
+ if i == 0: continue
+ raw_line = lines[i]
+ if raw_line.strip() == ".":
+ # The line is just line break
+ if not desc.endswith("\n"):
+ desc += "\n"
+ continue
+ elif raw_line.startswith(" "):
+ # The line should be displayed verbatim without word wrapping
+ if not desc.endswith("\n"):
+ line = "\n%s\n" % raw_line[2:]
+ else:
+ line = "%s\n" % raw_line[2:]
+ elif raw_line.startswith(" "):
+ # The line is part of a paragraph.
+ if desc.endswith("\n") or desc == "":
+ # Skip the leading white space
+ line = raw_line[1:]
+ else:
+ line = raw_line
+ else:
+ line = raw_line
+ pklog.debug("invalid line %s in description for %s:\n%s" % \
+ (i, pkg.name, pkg.rawDescription))
+ # Use dots for lists
+ line = re.sub(r"^(\s*)(\*|0|o|-) ", ur"\1\u2022 ", line, 1)
+ # Add current line to the description
+ desc += line
+ return desc
+
+
+def sigquit(signum, frame):
+ pklog.error("Was killed")
+ sys.exit(1)
+
+def debug_exception(type, value, tb):
+ """
+ Provides an interactive debugging session on unhandled exceptions
+ See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65287
+ """
+ if hasattr(sys, 'ps1') or not sys.stderr.isatty() or \
+ not sys.stdin.isatty() or not sys.stdout.isatty() or type==SyntaxError:
+ # Calls the default handler in interactive mode, if output is·
+ # redirected or on syntax errors
+ sys.__excepthook__(type, value, tb)
+ else:
+ import traceback, pdb
+ traceback.print_exception(type, value, tb)
+ print
+ pdb.pm()
+
+def takeover():
+ """
+ Exit the currently running backend
+ """
+ PACKAGEKIT_DBUS_SERVICE = 'org.freedesktop.PackageKitAptBackend'
+ PACKAGEKIT_DBUS_INTERFACE = 'org.freedesktop.PackageKitBackend'
+ PACKAGEKIT_DBUS_PATH = '/org/freedesktop/PackageKitBackend'
+ try:
+ bus = dbus.SystemBus()
+ except dbus.DBusException, e:
+ pklog.critical("Unable to connect to dbus: %s" % e)
+ sys.exit(1)
+ proxy = bus.get_object(PACKAGEKIT_DBUS_SERVICE, PACKAGEKIT_DBUS_PATH)
+ iface = dbus.Interface(proxy, PACKAGEKIT_DBUS_INTERFACE)
+ try:
+ iface.Exit()
+ except dbus.DBusException:
+ pass
+
+def run():
+ """
+ Start the apt backend
+ """
+ loop = dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+ bus = dbus.SystemBus(mainloop=loop)
+ bus_name = dbus.service.BusName(PACKAGEKIT_DBUS_SERVICE, bus=bus)
+ manager = PackageKitAptBackend(bus_name, PACKAGEKIT_DBUS_PATH)
+ manager.run()
+
+def main():
+ parser = optparse.OptionParser(description="APT backend for PackageKit")
+ parser.add_option("-t", "--takeover",
+ action="store_true", dest="takeover",
+ help="Exit the currently running backend "
+ "(Only needed by developers)")
+ parser.add_option("-r", "--root",
+ action="store", type="string", dest="root",
+ help="Use the given directory as the system root "
+ "(Only needed by developers)")
+ parser.add_option("-p", "--profile",
+ action="store", type="string", dest="profile",
+ help="Store profiling stats in the given file "
+ "(Only needed by developers)")
+ parser.add_option("-d", "--debug",
+ action="store_true", dest="debug",
+ help="Show a lot of additional information and drop to "
+ "a debugging console on unhandled exceptions "
+ "(Only needed by developers)")
+ (options, args) = parser.parse_args()
+ if options.debug:
+ pklog.setLevel(logging.DEBUG)
+ sys.excepthook = debug_exception
+
+ if options.root:
+ config = apt_pkg.Config
+ config.Set("Dir", options.root)
+ config.Set("Dir::State::status",
+ os.path.join(options.root, "/var/lib/dpkg/status"))
+
+ if options.takeover:
+ takeover()
+
+ if options.profile:
+ import hotshot
+ prof = hotshot.Profile(options.profile)
+ prof.runcall(run)
+ prof.close()
+ else:
+ run()
+
+if __name__ == '__main__':
+ main()
+
+# vim: ts=4 et sts=4
diff --git a/backends/apt/pk-backend-apt.py b/backends/apt/pk-backend-apt.py
new file mode 100644
index 0000000..0b057d8
--- /dev/null
+++ b/backends/apt/pk-backend-apt.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+pk-backend-apt - Runs the PackageKit apt backend
+"""
+# Copyright (C) 2008 Sebastian Heinlein <devel at glatzor.de>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# any later version.
+#
+# 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.
+
+__author__ = "Sebastian Heinlein <devel at glatzor.de>"
+
+from packagekit.aptbackend import main
+
+main()
+
+# vim:ts=4:sw=4:et
diff --git a/data/org.freedesktop.PackageKitAptBackend.service.in b/data/org.freedesktop.PackageKitAptBackend.service.in
index 2e3d5d5..9326019 100644
--- a/data/org.freedesktop.PackageKitAptBackend.service.in
+++ b/data/org.freedesktop.PackageKitAptBackend.service.in
@@ -1,5 +1,5 @@
[D-BUS Service]
Name=org.freedesktop.PackageKitAptBackend
-Exec=@servicedir@/aptDBUSBackend.py
+Exec=@servicedir@/pk-backend-apt.py
User=@PK_BACKEND_USER@
commit 101a40ec584c7cc1f1df3bb5146096c86c3c5a47
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Mon Feb 9 05:42:53 2009 +0100
APT: Fix an API change in debfile
diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
index 88ae820..700c325 100755
--- a/backends/apt/aptDBUSBackend.py
+++ b/backends/apt/aptDBUSBackend.py
@@ -1261,7 +1261,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
for path in full_paths:
deb = apt.debfile.DebPackage(path, self._cache)
packages.append(deb)
- if not deb.checkDeb():
+ if not deb.check():
self.ErrorCode(ERROR_UNKNOWN, deb._failureString)
self.Finished(EXIT_FAILED)
return
commit 550c71f2bceac89440de6944724731c501136984
Author: Sebastian Heinlein <devel at glatzor.de>
Date: Mon Feb 9 05:35:46 2009 +0100
APT: Use the merged debfile module of python-apt
diff --git a/backends/apt/aptDBUSBackend.py b/backends/apt/aptDBUSBackend.py
index f8b93b2..88ae820 100755
--- a/backends/apt/aptDBUSBackend.py
+++ b/backends/apt/aptDBUSBackend.py
@@ -40,6 +40,7 @@ import urllib2
import warnings
import apt
+import apt.debfile
import apt_pkg
import dbus
import dbus.glib
@@ -50,7 +51,6 @@ import gobject
from packagekit.daemonBackend import PACKAGEKIT_DBUS_INTERFACE, PACKAGEKIT_DBUS_PATH, PackageKitBaseBackend, PackagekitProgress, pklog, threaded, serialize
from packagekit.enums import *
-import debfile
warnings.filterwarnings(action='ignore', category=FutureWarning)
@@ -250,6 +250,7 @@ class DpkgInstallProgress(apt.progress.InstallProgress):
"""
Class to initiate and monitor installation of local package files with dpkg
"""
+ #FIXME: Use the merged DpkgInstallProgress of python-apt
def recover(self):
"""
Run "dpkg --configure -a"
@@ -1258,7 +1259,7 @@ class PackageKitAptBackend(PackageKitBaseBackend):
# Collect all dependencies which need to be installed
self.StatusChanged(STATUS_DEP_RESOLVE)
for path in full_paths:
- deb = debfile.DebPackage(path, self._cache)
+ deb = apt.debfile.DebPackage(path, self._cache)
packages.append(deb)
if not deb.checkDeb():
self.ErrorCode(ERROR_UNKNOWN, deb._failureString)
@@ -1273,14 +1274,15 @@ class PackageKitAptBackend(PackageKitBaseBackend):
"before: %s" % remove)
self.Finished(EXIT_FAILED)
return
- if deb.compareToVersionInCache() == debfile.VERSION_OUTDATED:
+ if deb.compare_to_version_in_cache() == \
+ apt.debfile.VERSION_OUTDATED:
self.Message(MESSAGE_NEWER_PACKAGE_EXISTS,
"There is a later version of %s "
"available in the repositories." % deb.pkgname)
if len(self._cache.getChanges()) > 0 and not \
self._commit_changes((10,25), (25,50)):
return False
- # Install the Debian package files
+ # Install the Debian package files
d = PackageKitDpkgInstallProgress(self)
try:
d.startUpdate()
diff --git a/backends/apt/debfile.py b/backends/apt/debfile.py
deleted file mode 100644
index 6e664da..0000000
--- a/backends/apt/debfile.py
+++ /dev/null
@@ -1,536 +0,0 @@
-# Copyright (c) 2005-2007 Canonical
-#
-# AUTHOR:
-# Michael Vogt <mvo at ubuntu.com>
-#
-# This file is part of GDebi
-#
-# GDebi is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as published
-# by the Free Software Foundation; either version 2 of the License, or (at
-# your option) any later version.
-#
-# GDebi 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 GDebi; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-
-import warnings
-warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning)
-import apt_inst, apt_pkg
-import sys
-import os
-from gettext import gettext as _
-
-# Constants for comparing the local package file with the version in the cache
-(VERSION_NONE,
- VERSION_OUTDATED,
- VERSION_SAME,
- VERSION_NEWER) = range(4)
-
-class NoDebArchiveException(IOError):
- pass
-
-class DebPackage(object):
-
- _supported_data_members = ("data.tar.gz", "data.tar.bz2", "data.tar.lzma")
-
- debug = 0
-
- def __init__(self, filename=None, cache=None):
- self._cache = cache
- self.file = filename
- self._needPkgs = []
- self._sections = {}
- self._installedConflicts = set()
- self._failureString = ""
- if filename:
- self.open(filename)
-
- def open(self, filename):
- " open given debfile "
- self.filename = filename
- if not apt_inst.arCheckMember(open(self.filename), "debian-binary"):
- raise NoDebArchiveException, "This is not a valid DEB archive, missing '%s' member" % "debian-binary"
- control = apt_inst.debExtractControl(open(self.filename))
- self._sections = apt_pkg.ParseSection(control)
- self.pkgname = self._sections["Package"]
-
- def __getitem__(self, key):
- return self._sections[key]
-
- def filelist(self):
- """ return the list of files in the deb """
- files = []
- def extract_cb(What,Name,Link,Mode,UID,GID,Size,MTime,Major,Minor):
- #print "%s '%s','%s',%u,%u,%u,%u,%u,%u,%u"\
- # % (What,Name,Link,Mode,UID,GID,Size, MTime, Major, Minor)
- files.append(Name)
- for member in self._supported_data_members:
- if apt_inst.arCheckMember(open(self.filename), member):
- try:
- apt_inst.debExtract(open(self.filename), extract_cb, member)
- break
- except SystemError, e:
- return ["List of files for '%s'could not be read" % self.filename]
- return files
- filelist = property(filelist)
-
- def _isOrGroupSatisfied(self, or_group):
- """ this function gets a 'or_group' and analyzes if
- at least one dependency of this group is already satisfied """
- self._dbg(2,"_checkOrGroup(): %s " % (or_group))
-
- for dep in or_group:
- depname = dep[0]
- ver = dep[1]
- oper = dep[2]
-
- # check for virtual pkgs
- if not self._cache.has_key(depname):
- if self._cache.isVirtualPackage(depname):
- self._dbg(3,"_isOrGroupSatisfied(): %s is virtual dep" % depname)
- for pkg in self._cache.getProvidingPackages(depname):
- if pkg.isInstalled:
- return True
- continue
-
- inst = self._cache[depname]
- instver = inst.installedVersion
- if instver != None and apt_pkg.CheckDep(instver,oper,ver) == True:
- return True
- return False
-
-
- def _satisfyOrGroup(self, or_group):
- """ try to satisfy the or_group """
-
- or_found = False
- virtual_pkg = None
-
- for dep in or_group:
- depname = dep[0]
- ver = dep[1]
- oper = dep[2]
-
- # if we don't have it in the cache, it may be virtual
- if not self._cache.has_key(depname):
- if not self._cache.isVirtualPackage(depname):
- continue
- providers = self._cache.getProvidingPackages(depname)
- # if a package just has a single virtual provider, we
- # just pick that (just like apt)
- if len(providers) != 1:
- continue
- depname = providers[0].name
-
- # now check if we can satisfy the deps with the candidate(s)
- # in the cache
- cand = self._cache[depname]
- candver = self._cache._depcache.GetCandidateVer(cand._pkg)
- if not candver:
- continue
- if not apt_pkg.CheckDep(candver.VerStr,oper,ver):
- continue
-
- # check if we need to install it
- self._dbg(2,"Need to get: %s" % depname)
- self._needPkgs.append(depname)
- return True
-
- # if we reach this point, we failed
- or_str = ""
- for dep in or_group:
- or_str += dep[0]
- if dep != or_group[len(or_group)-1]:
- or_str += "|"
- self._failureString +="Dependency is not satisfiable: %s\n" % or_str
- return False
-
- def _checkSinglePkgConflict(self, pkgname, ver, oper):
- """ returns true if a pkg conflicts with a real installed/marked
- pkg """
- # FIXME: deal with conflicts against its own provides
- # (e.g. Provides: ftp-server, Conflicts: ftp-server)
- self._dbg(3, "_checkSinglePkgConflict() pkg='%s' ver='%s' oper='%s'" % (pkgname, ver, oper))
- pkgver = None
- cand = self._cache[pkgname]
- if cand.isInstalled:
- pkgver = cand.installedVersion
- elif cand.markedInstall:
- pkgver = cand.candidateVersion
- #print "pkg: %s" % pkgname
- #print "ver: %s" % ver
- #print "pkgver: %s " % pkgver
- #print "oper: %s " % oper
- if (pkgver and apt_pkg.CheckDep(pkgver,oper,ver) and
- not self.replacesRealPkg(pkgname, oper, ver)):
- self._failureString += "Conflicts with the installed package '%s'" % cand.name
- return True
- return False
-
- def _checkConflictsOrGroup(self, or_group):
- """ check the or-group for conflicts with installed pkgs """
- self._dbg(2,"_checkConflictsOrGroup(): %s " % (or_group))
-
- or_found = False
- virtual_pkg = None
-
- for dep in or_group:
- depname = dep[0]
- ver = dep[1]
- oper = dep[2]
-
- # check conflicts with virtual pkgs
- if not self._cache.has_key(depname):
- # FIXME: we have to check for virtual replaces here as
- # well (to pass tests/gdebi-test8.deb)
- if self._cache.isVirtualPackage(depname):
- for pkg in self._cache.getProvidingPackages(depname):
- self._dbg(3, "conflicts virtual check: %s" % pkg.name)
- # P/C/R on virtal pkg, e.g. ftpd
- if self.pkgName == pkg.name:
- self._dbg(3, "conflict on self, ignoring")
- continue
- if self._checkSinglePkgConflict(pkg.name,ver,oper):
- self._installedConflicts.add(pkg.name)
- continue
- if self._checkSinglePkgConflict(depname,ver,oper):
- self._installedConflicts.add(depname)
- return len(self._installedConflicts) != 0
-
- def getConflicts(self):
- """
- Return list of package names conflicting with this package.
-
- WARNING: This method will is deprecated. Please use the
- attribute DebPackage.depends instead.
- """
- return self.conflicts
-
- def conflicts(self):
- """
- List of package names conflicting with this package
- """
- conflicts = []
- key = "Conflicts"
- if self._sections.has_key(key):
- conflicts = apt_pkg.ParseDepends(self._sections[key])
- return conflicts
- conflicts = property(conflicts)
-
- def getDepends(self):
- """
- Return list of package names on which this package depends on.
-
- WARNING: This method will is deprecated. Please use the
- attribute DebPackage.depends instead.
- """
- return self.depends
-
- def depends(self):
- """
- List of package names on which this package depends on
- """
- depends = []
- # find depends
- for key in ["Depends","PreDepends"]:
- if self._sections.has_key(key):
- depends.extend(apt_pkg.ParseDepends(self._sections[key]))
- return depends
- depends = property(depends)
-
- def getProvides(self):
- """
- Return list of virtual packages which are provided by this package.
-
- WARNING: This method will is deprecated. Please use the
- attribute DebPackage.provides instead.
- """
- return self.provides
-
- def provides(self):
- """
- List of virtual packages which are provided by this package
- """
- provides = []
- key = "Provides"
- if self._sections.has_key(key):
- provides = apt_pkg.ParseDepends(self._sections[key])
- return provides
- provides = property(provides)
-
- def getReplaces(self):
- """
- Return list of packages which are replaced by this package.
-
- WARNING: This method will is deprecated. Please use the
- attribute DebPackage.replaces instead.
- """
- return self.replaces
-
- def replaces(self):
- """
- List of packages which are replaced by this package
- """
- replaces = []
- key = "Replaces"
- if self._sections.has_key(key):
- replaces = apt_pkg.ParseDepends(self._sections[key])
- return replaces
- replaces = property(replaces)
-
- def replacesRealPkg(self, pkgname, oper, ver):
- """
- return True if the deb packages replaces a real (not virtual)
- packages named pkgname, oper, ver
- """
- self._dbg(3, "replacesPkg() %s %s %s" % (pkgname,oper,ver))
- pkgver = None
- cand = self._cache[pkgname]
- if cand.isInstalled:
- pkgver = cand.installedVersion
- elif cand.markedInstall:
- pkgver = cand.candidateVersion
- for or_group in self.getReplaces():
- for (name, ver, oper) in or_group:
- if (name == pkgname and
- apt_pkg.CheckDep(pkgver,oper,ver)):
- self._dbg(3, "we have a replaces in our package for the conflict against '%s'" % (pkgname))
- return True
- return False
-
- def checkConflicts(self):
- """ check if the pkg conflicts with a existing or to be installed
- package. Return True if the pkg is ok """
- res = True
- for or_group in self.getConflicts():
- if self._checkConflictsOrGroup(or_group):
- #print "Conflicts with a exisiting pkg!"
- #self._failureString = "Conflicts with a exisiting pkg!"
- res = False
- return res
-
-
- def compareToVersionInCache(self, useInstalled=True):
- """ checks if the pkg is already installed or availabe in the cache
- and if so in what version, returns if the version of the deb
- is not available,older,same,newer
- """
- self._dbg(3,"compareToVersionInCache")
- pkgname = self._sections["Package"]
- debver = self._sections["Version"]
- self._dbg(1,"debver: %s" % debver)
- if self._cache.has_key(pkgname):
- if useInstalled:
- cachever = self._cache[pkgname].installedVersion
- else:
- cachever = self._cache[pkgname].candidateVersion
- if cachever != None:
- cmp = apt_pkg.VersionCompare(cachever,debver)
- self._dbg(1, "CompareVersion(debver,instver): %s" % cmp)
- if cmp == 0:
- return VERSION_SAME
- elif cmp < 0:
- return VERSION_NEWER
- elif cmp > 0:
- return VERSION_OUTDATED
- return VERSION_NONE
-
- def checkDeb(self):
- self._dbg(3,"checkDepends")
-
- # check arch
- arch = self._sections["Architecture"]
- if arch != "all" and arch != apt_pkg.Config.Find("APT::Architecture"):
- self._dbg(1,"ERROR: Wrong architecture dude!")
- self._failureString = "Wrong architecture '%s'" % arch
- return False
-
- # check version
- res = self.compareToVersionInCache()
- if res == VERSION_OUTDATED: # the deb is older than the installed
- self._failureString = "A later version is already installed"
- return False
-
- # FIXME: this sort of error handling sux
- self._failureString = ""
-
- # check conflicts
- if not self.checkConflicts():
- return False
-
- # try to satisfy the dependencies
- res = self._satisfyDepends(self.getDepends())
- if not res:
- return False
-
- # check for conflicts again (this time with the packages that are
- # makeed for install)
- if not self.checkConflicts():
- return False
-
- if self._cache._depcache.BrokenCount > 0:
- self._failureString = "Failed to satisfy all dependencies (broken cache)"
- # clean the cache again
- self._cache.clear()
- return False
- return True
-
- def satisfyDependsStr(self, dependsstr):
- return self._satisfyDepends(apt_pkg.ParseDepends(dependsstr))
-
- def _satisfyDepends(self, depends):
- # turn off MarkAndSweep via a action group (if available)
- try:
- _actiongroup = apt_pkg.GetPkgActionGroup(self._cache._depcache)
- except AttributeError, e:
- pass
- # check depends
- for or_group in depends:
- #print "or_group: %s" % or_group
- #print "or_group satified: %s" % self._isOrGroupSatisfied(or_group)
- if not self._isOrGroupSatisfied(or_group):
- if not self._satisfyOrGroup(or_group):
- return False
- # now try it out in the cache
- for pkg in self._needPkgs:
- try:
- self._cache[pkg].markInstall(fromUser=False)
- except SystemError, e:
- self._failureString = "Cannot install '%s'" % pkg
- self._cache.clear()
- return False
- return True
-
- def missingDeps(self):
- self._dbg(1, "Installing: %s" % self._needPkgs)
- if self._needPkgs == None:
- self.checkDeb()
- return self._needPkgs
- missingDeps = property(missingDeps)
-
- def requiredChanges(self):
- """ gets the required changes to satisfy the depends.
- returns a tuple with (install, remove, unauthenticated)
- """
- install = []
- remove = []
- unauthenticated = []
- for pkg in self._cache:
- if pkg.markedInstall or pkg.markedUpgrade:
- install.append(pkg.name)
- # check authentication, one authenticated origin is enough
- # libapt will skip non-authenticated origins then
- authenticated = False
- for origin in pkg.candidateOrigin:
- authenticated |= origin.trusted
- if not authenticated:
- unauthenticated.append(pkg.name)
- if pkg.markedDelete:
- remove.append(pkg.name)
- return (install,remove, unauthenticated)
- requiredChanges = property(requiredChanges)
-
- def _dbg(self, level, msg):
- """Write debugging output to sys.stderr.
- """
- if level <= self.debug:
- print >> sys.stderr, msg
-
- def install(self, installProgress=None):
- """ Install the package """
- if installProgress == None:
- res = os.system("/usr/sbin/dpkg -i %s" % self.filename)
- else:
- installProgress.startUpdate()
- res = installProgress.run(self.filename)
- installProgress.finishUpdate()
- return res
-
-class DscSrcPackage(DebPackage):
- def __init__(self, filename=None, cache=None):
- DebPackage.__init__(self, filename, cache)
- self.depends = []
- self.conflicts = []
- self.binaries = []
- if filename != None:
- self.open(filename)
- def getConflicts(self):
- return self.conflicts
- def getDepends(self):
- return self.depends
- def open(self, file):
- depends_tags = ["Build-Depends:", "Build-Depends-Indep:"]
- conflicts_tags = ["Build-Conflicts:", "Build-Conflicts-Indep:"]
- for line in open(file):
- # check b-d and b-c
- for tag in depends_tags:
- if line.startswith(tag):
- key = line[len(tag):].strip()
- self.depends.extend(apt_pkg.ParseSrcDepends(key))
- for tag in conflicts_tags:
- if line.startswith(tag):
- key = line[len(tag):].strip()
- self.conflicts.extend(apt_pkg.ParseSrcDepends(key))
- # check binary and source and version
- if line.startswith("Source:"):
- self.pkgName = line[len("Source:"):].strip()
- if line.startswith("Binary:"):
- self.binaries = [pkg.strip() for pkg in line[len("Binary:"):].split(",")]
- if line.startswith("Version:"):
- self._sections["Version"] = line[len("Version:"):].strip()
- # we are at the end
- if line.startswith("-----BEGIN PGP SIGNATURE-"):
- break
- s = "Install Build-Dependencies for source package '%s' that builds %s\n" % (self.pkgName, " ".join(self.binaries))
- self._sections["Description"] = s
-
- def checkDeb(self):
- if not self.checkConflicts():
- for pkgname in self._installedConflicts:
- if self._cache[pkgname]._pkg.Essential:
- raise Exception, "A essential package would be removed"
- self._cache[pkgname].markDelete()
- # FIXME: a additional run of the checkConflicts()
- # after _satisfyDepends() should probably be done
- return self._satisfyDepends(self.depends)
-
-if __name__ == "__main__":
- from cache import Cache
- from progress import DpkgInstallProgress
-
- cache = Cache()
-
- vp = "www-browser"
- print "%s virtual: %s" % (vp,cache.isVirtualPackage(vp))
- providers = cache.getProvidingPackages(vp)
- print "Providers for %s :" % vp
- for pkg in providers:
- print " %s" % pkg.name
-
- d = DebPackage(sys.argv[1], cache)
- print "Deb: %s" % d.pkgname
- if not d.checkDeb():
- print "can't be satified"
- print d._failureString
- print "missing deps: %s" % d.missingDeps
- print d.requiredChanges
-
- print "Installing ..."
- ret = d.install(DpkgInstallProgress())
- print ret
-
- #s = DscSrcPackage(cache, "../tests/3ddesktop_0.2.9-6.dsc")
- #s.checkDep()
- #print "Missing deps: ",s.missingDeps
- #print "Print required changes: ", s.requiredChanges
-
- s = DscSrcPackage(cache=cache)
- d = "libc6 (>= 2.3.2), libaio (>= 0.3.96) | libaio1 (>= 0.3.96)"
- print s._satisfyDepends(apt_pkg.ParseDepends(d))
More information about the PackageKit-commit
mailing list